Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/tools/lld/ELF/MapFile.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- MapFile.cpp --------------------------------------------------------===//
2
//
3
//                             The LLVM Linker
4
//
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
7
//
8
//===----------------------------------------------------------------------===//
9
//
10
// This file implements the -Map option. It shows lists in order and
11
// hierarchically the output sections, input sections, input files and
12
// symbol:
13
//
14
//   Address  Size     Align Out     In      Symbol
15
//   00201000 00000015     4 .text
16
//   00201000 0000000e     4         test.o:(.text)
17
//   0020100e 00000000     0                 local
18
//   00201005 00000000     0                 f(int)
19
//
20
//===----------------------------------------------------------------------===//
21
22
#include "MapFile.h"
23
#include "InputFiles.h"
24
#include "LinkerScript.h"
25
#include "OutputSections.h"
26
#include "Strings.h"
27
#include "SymbolTable.h"
28
#include "SyntheticSections.h"
29
#include "Threads.h"
30
31
#include "llvm/Support/raw_ostream.h"
32
33
using namespace llvm;
34
using namespace llvm::object;
35
36
using namespace lld;
37
using namespace lld::elf;
38
39
typedef DenseMap<const SectionBase *, SmallVector<Defined *, 4>> SymbolMapTy;
40
41
// Print out the first three columns of a line.
42
static void writeHeader(raw_ostream &OS, uint64_t Addr, uint64_t Size,
43
                        uint64_t Align) {
44
  int W = Config->Is64 ? 16 : 8;
45
  OS << format("%0*llx %0*llx %5lld ", W, Addr, W, Size, Align);
46
}
47
48
static std::string indent(int Depth) { return std::string(Depth * 8, ' '); }
49
50
// Returns a list of all symbols that we want to print out.
51
4
template <class ELFT> static std::vector<Defined *> getSymbols() {
52
4
  std::vector<Defined *> V;
53
13
  for (InputFile *File : ObjectFiles) {
54
59
    for (SymbolBody *B : File->getSymbols()) {
55
59
      if (auto *
DR59
= dyn_cast<DefinedRegular>(B)) {
56
43
        if (
DR->getFile() == File && 43
!DR->isSection()31
&&
DR->Section28
&&
57
25
            DR->Section->Live)
58
24
          V.push_back(DR);
59
59
      } else 
if (auto *16
DC16
= dyn_cast<DefinedCommon>(B)) {
60
3
        if (DC->Section)
61
3
          V.push_back(DC);
62
16
      }
63
59
    }
64
13
  }
65
4
  return V;
66
4
}
Unexecuted instantiation: MapFile.cpp:std::__1::vector<lld::elf::Defined*, std::__1::allocator<lld::elf::Defined*> > getSymbols<llvm::object::ELFType<(llvm::support::endianness)0, true> >()
MapFile.cpp:std::__1::vector<lld::elf::Defined*, std::__1::allocator<lld::elf::Defined*> > getSymbols<llvm::object::ELFType<(llvm::support::endianness)1, true> >()
Line
Count
Source
51
4
template <class ELFT> static std::vector<Defined *> getSymbols() {
52
4
  std::vector<Defined *> V;
53
13
  for (InputFile *File : ObjectFiles) {
54
59
    for (SymbolBody *B : File->getSymbols()) {
55
59
      if (auto *
DR59
= dyn_cast<DefinedRegular>(B)) {
56
43
        if (
DR->getFile() == File && 43
!DR->isSection()31
&&
DR->Section28
&&
57
25
            DR->Section->Live)
58
24
          V.push_back(DR);
59
59
      } else 
if (auto *16
DC16
= dyn_cast<DefinedCommon>(B)) {
60
3
        if (DC->Section)
61
3
          V.push_back(DC);
62
16
      }
63
59
    }
64
13
  }
65
4
  return V;
66
4
}
Unexecuted instantiation: MapFile.cpp:std::__1::vector<lld::elf::Defined*, std::__1::allocator<lld::elf::Defined*> > getSymbols<llvm::object::ELFType<(llvm::support::endianness)0, false> >()
Unexecuted instantiation: MapFile.cpp:std::__1::vector<lld::elf::Defined*, std::__1::allocator<lld::elf::Defined*> > getSymbols<llvm::object::ELFType<(llvm::support::endianness)1, false> >()
67
68
// Returns a map from sections to their symbols.
69
4
static SymbolMapTy getSectionSyms(ArrayRef<Defined *> Syms) {
70
4
  SymbolMapTy Ret;
71
27
  for (Defined *S : Syms) {
72
27
    if (auto *DR = dyn_cast<DefinedRegular>(S))
73
24
      Ret[DR->Section].push_back(S);
74
3
    else 
if (auto *3
DC3
= dyn_cast<DefinedCommon>(S))
75
3
      Ret[DC->Section].push_back(S);
76
27
  }
77
4
78
4
  // Sort symbols by address. We want to print out symbols in the
79
4
  // order in the output file rather than the order they appeared
80
4
  // in the input files.
81
18
  for (auto &It : Ret) {
82
18
    SmallVectorImpl<Defined *> &V = It.second;
83
18
    std::sort(V.begin(), V.end(),
84
9
              [](Defined *A, Defined *B) { return A->getVA() < B->getVA(); });
85
18
  }
86
4
  return Ret;
87
4
}
88
89
// Construct a map from symbols to their stringified representations.
90
// Demangling symbols (which is what toString() does) is slow, so
91
// we do that in batch using parallel-for.
92
template <class ELFT>
93
static DenseMap<Defined *, std::string>
94
4
getSymbolStrings(ArrayRef<Defined *> Syms) {
95
4
  std::vector<std::string> Str(Syms.size());
96
27
  parallelForEachN(0, Syms.size(), [&](size_t I) {
97
27
    raw_string_ostream OS(Str[I]);
98
27
    writeHeader(OS, Syms[I]->getVA(), Syms[I]->template getSize<ELFT>(), 0);
99
27
    OS << indent(2) << toString(*Syms[I]);
100
27
  });
Unexecuted instantiation: MapFile.cpp:llvm::DenseMap<lld::elf::Defined*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, llvm::DenseMapInfo<lld::elf::Defined*>, llvm::detail::DenseMapPair<lld::elf::Defined*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > getSymbolStrings<llvm::object::ELFType<(llvm::support::endianness)1, false> >(llvm::ArrayRef<lld::elf::Defined*>)::'lambda'(unsigned long)::operator()(unsigned long) const
Unexecuted instantiation: MapFile.cpp:llvm::DenseMap<lld::elf::Defined*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, llvm::DenseMapInfo<lld::elf::Defined*>, llvm::detail::DenseMapPair<lld::elf::Defined*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > getSymbolStrings<llvm::object::ELFType<(llvm::support::endianness)0, false> >(llvm::ArrayRef<lld::elf::Defined*>)::'lambda'(unsigned long)::operator()(unsigned long) const
MapFile.cpp:llvm::DenseMap<lld::elf::Defined*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, llvm::DenseMapInfo<lld::elf::Defined*>, llvm::detail::DenseMapPair<lld::elf::Defined*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > getSymbolStrings<llvm::object::ELFType<(llvm::support::endianness)1, true> >(llvm::ArrayRef<lld::elf::Defined*>)::'lambda'(unsigned long)::operator()(unsigned long) const
Line
Count
Source
96
27
  parallelForEachN(0, Syms.size(), [&](size_t I) {
97
27
    raw_string_ostream OS(Str[I]);
98
27
    writeHeader(OS, Syms[I]->getVA(), Syms[I]->template getSize<ELFT>(), 0);
99
27
    OS << indent(2) << toString(*Syms[I]);
100
27
  });
Unexecuted instantiation: MapFile.cpp:llvm::DenseMap<lld::elf::Defined*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, llvm::DenseMapInfo<lld::elf::Defined*>, llvm::detail::DenseMapPair<lld::elf::Defined*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > getSymbolStrings<llvm::object::ELFType<(llvm::support::endianness)0, true> >(llvm::ArrayRef<lld::elf::Defined*>)::'lambda'(unsigned long)::operator()(unsigned long) const
101
4
102
4
  DenseMap<Defined *, std::string> Ret;
103
31
  for (size_t I = 0, E = Syms.size(); 
I < E31
;
++I27
)
104
27
    Ret[Syms[I]] = std::move(Str[I]);
105
4
  return Ret;
106
4
}
Unexecuted instantiation: MapFile.cpp:llvm::DenseMap<lld::elf::Defined*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, llvm::DenseMapInfo<lld::elf::Defined*>, llvm::detail::DenseMapPair<lld::elf::Defined*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > getSymbolStrings<llvm::object::ELFType<(llvm::support::endianness)1, false> >(llvm::ArrayRef<lld::elf::Defined*>)
Unexecuted instantiation: MapFile.cpp:llvm::DenseMap<lld::elf::Defined*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, llvm::DenseMapInfo<lld::elf::Defined*>, llvm::detail::DenseMapPair<lld::elf::Defined*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > getSymbolStrings<llvm::object::ELFType<(llvm::support::endianness)0, false> >(llvm::ArrayRef<lld::elf::Defined*>)
MapFile.cpp:llvm::DenseMap<lld::elf::Defined*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, llvm::DenseMapInfo<lld::elf::Defined*>, llvm::detail::DenseMapPair<lld::elf::Defined*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > getSymbolStrings<llvm::object::ELFType<(llvm::support::endianness)1, true> >(llvm::ArrayRef<lld::elf::Defined*>)
Line
Count
Source
94
4
getSymbolStrings(ArrayRef<Defined *> Syms) {
95
4
  std::vector<std::string> Str(Syms.size());
96
4
  parallelForEachN(0, Syms.size(), [&](size_t I) {
97
4
    raw_string_ostream OS(Str[I]);
98
4
    writeHeader(OS, Syms[I]->getVA(), Syms[I]->template getSize<ELFT>(), 0);
99
4
    OS << indent(2) << toString(*Syms[I]);
100
4
  });
101
4
102
4
  DenseMap<Defined *, std::string> Ret;
103
31
  for (size_t I = 0, E = Syms.size(); 
I < E31
;
++I27
)
104
27
    Ret[Syms[I]] = std::move(Str[I]);
105
4
  return Ret;
106
4
}
Unexecuted instantiation: MapFile.cpp:llvm::DenseMap<lld::elf::Defined*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, llvm::DenseMapInfo<lld::elf::Defined*>, llvm::detail::DenseMapPair<lld::elf::Defined*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > getSymbolStrings<llvm::object::ELFType<(llvm::support::endianness)0, true> >(llvm::ArrayRef<lld::elf::Defined*>)
107
108
1.48k
template <class ELFT> void elf::writeMapFile() {
109
1.48k
  if (Config->MapFile.empty())
110
1.48k
    return;
111
4
112
4
  // Open a map file for writing.
113
4
  std::error_code EC;
114
4
  raw_fd_ostream OS(Config->MapFile, EC, sys::fs::F_None);
115
4
  if (
EC4
) {
116
0
    error("cannot open " + Config->MapFile + ": " + EC.message());
117
0
    return;
118
0
  }
119
4
120
4
  // Collect symbol info that we want to print out.
121
4
  std::vector<Defined *> Syms = getSymbols<ELFT>();
122
4
  SymbolMapTy SectionSyms = getSectionSyms(Syms);
123
4
  DenseMap<Defined *, std::string> SymStr = getSymbolStrings<ELFT>(Syms);
124
4
125
4
  // Print out the header line.
126
4
  int W = ELFT::Is64Bits ? 
164
:
80
;
127
4
  OS << left_justify("Address", W) << ' ' << left_justify("Size", W)
128
4
     << " Align Out     In      Symbol\n";
129
4
130
4
  // Print out file contents.
131
25
  for (OutputSection *OSec : OutputSections) {
132
25
    writeHeader(OS, OSec->Addr, OSec->Size, OSec->Alignment);
133
25
    OS << OSec->Name << '\n';
134
25
135
25
    // Dump symbols for each input section.
136
25
    for (BaseCommand *Base : OSec->Commands) {
137
25
      auto *ISD = dyn_cast<InputSectionDescription>(Base);
138
25
      if (!ISD)
139
0
        continue;
140
25
      
for (InputSection *IS : ISD->Sections) 25
{
141
37
        writeHeader(OS, OSec->Addr + IS->OutSecOff, IS->getSize(),
142
37
                    IS->Alignment);
143
37
        OS << indent(1) << toString(IS) << '\n';
144
37
        for (Defined *Sym : SectionSyms[IS])
145
27
          OS << SymStr[Sym] << '\n';
146
37
      }
147
25
    }
148
25
  }
149
1.48k
}
void lld::elf::writeMapFile<llvm::object::ELFType<(llvm::support::endianness)0, true> >()
Line
Count
Source
108
42
template <class ELFT> void elf::writeMapFile() {
109
42
  if (Config->MapFile.empty())
110
42
    return;
111
0
112
0
  // Open a map file for writing.
113
0
  std::error_code EC;
114
0
  raw_fd_ostream OS(Config->MapFile, EC, sys::fs::F_None);
115
0
  if (
EC0
) {
116
0
    error("cannot open " + Config->MapFile + ": " + EC.message());
117
0
    return;
118
0
  }
119
0
120
0
  // Collect symbol info that we want to print out.
121
0
  std::vector<Defined *> Syms = getSymbols<ELFT>();
122
0
  SymbolMapTy SectionSyms = getSectionSyms(Syms);
123
0
  DenseMap<Defined *, std::string> SymStr = getSymbolStrings<ELFT>(Syms);
124
0
125
0
  // Print out the header line.
126
0
  int W = ELFT::Is64Bits ? 
160
:
80
;
127
0
  OS << left_justify("Address", W) << ' ' << left_justify("Size", W)
128
0
     << " Align Out     In      Symbol\n";
129
0
130
0
  // Print out file contents.
131
0
  for (OutputSection *OSec : OutputSections) {
132
0
    writeHeader(OS, OSec->Addr, OSec->Size, OSec->Alignment);
133
0
    OS << OSec->Name << '\n';
134
0
135
0
    // Dump symbols for each input section.
136
0
    for (BaseCommand *Base : OSec->Commands) {
137
0
      auto *ISD = dyn_cast<InputSectionDescription>(Base);
138
0
      if (!ISD)
139
0
        continue;
140
0
      
for (InputSection *IS : ISD->Sections) 0
{
141
0
        writeHeader(OS, OSec->Addr + IS->OutSecOff, IS->getSize(),
142
0
                    IS->Alignment);
143
0
        OS << indent(1) << toString(IS) << '\n';
144
0
        for (Defined *Sym : SectionSyms[IS])
145
0
          OS << SymStr[Sym] << '\n';
146
0
      }
147
0
    }
148
0
  }
149
42
}
void lld::elf::writeMapFile<llvm::object::ELFType<(llvm::support::endianness)1, true> >()
Line
Count
Source
108
1.17k
template <class ELFT> void elf::writeMapFile() {
109
1.17k
  if (Config->MapFile.empty())
110
1.16k
    return;
111
4
112
4
  // Open a map file for writing.
113
4
  std::error_code EC;
114
4
  raw_fd_ostream OS(Config->MapFile, EC, sys::fs::F_None);
115
4
  if (
EC4
) {
116
0
    error("cannot open " + Config->MapFile + ": " + EC.message());
117
0
    return;
118
0
  }
119
4
120
4
  // Collect symbol info that we want to print out.
121
4
  std::vector<Defined *> Syms = getSymbols<ELFT>();
122
4
  SymbolMapTy SectionSyms = getSectionSyms(Syms);
123
4
  DenseMap<Defined *, std::string> SymStr = getSymbolStrings<ELFT>(Syms);
124
4
125
4
  // Print out the header line.
126
4
  int W = ELFT::Is64Bits ? 
164
:
80
;
127
4
  OS << left_justify("Address", W) << ' ' << left_justify("Size", W)
128
4
     << " Align Out     In      Symbol\n";
129
4
130
4
  // Print out file contents.
131
25
  for (OutputSection *OSec : OutputSections) {
132
25
    writeHeader(OS, OSec->Addr, OSec->Size, OSec->Alignment);
133
25
    OS << OSec->Name << '\n';
134
25
135
25
    // Dump symbols for each input section.
136
25
    for (BaseCommand *Base : OSec->Commands) {
137
25
      auto *ISD = dyn_cast<InputSectionDescription>(Base);
138
25
      if (!ISD)
139
0
        continue;
140
25
      
for (InputSection *IS : ISD->Sections) 25
{
141
37
        writeHeader(OS, OSec->Addr + IS->OutSecOff, IS->getSize(),
142
37
                    IS->Alignment);
143
37
        OS << indent(1) << toString(IS) << '\n';
144
37
        for (Defined *Sym : SectionSyms[IS])
145
27
          OS << SymStr[Sym] << '\n';
146
37
      }
147
25
    }
148
25
  }
149
1.17k
}
void lld::elf::writeMapFile<llvm::object::ELFType<(llvm::support::endianness)1, false> >()
Line
Count
Source
108
182
template <class ELFT> void elf::writeMapFile() {
109
182
  if (Config->MapFile.empty())
110
182
    return;
111
0
112
0
  // Open a map file for writing.
113
0
  std::error_code EC;
114
0
  raw_fd_ostream OS(Config->MapFile, EC, sys::fs::F_None);
115
0
  if (
EC0
) {
116
0
    error("cannot open " + Config->MapFile + ": " + EC.message());
117
0
    return;
118
0
  }
119
0
120
0
  // Collect symbol info that we want to print out.
121
0
  std::vector<Defined *> Syms = getSymbols<ELFT>();
122
0
  SymbolMapTy SectionSyms = getSectionSyms(Syms);
123
0
  DenseMap<Defined *, std::string> SymStr = getSymbolStrings<ELFT>(Syms);
124
0
125
0
  // Print out the header line.
126
0
  int W = ELFT::Is64Bits ? 
160
:
80
;
127
0
  OS << left_justify("Address", W) << ' ' << left_justify("Size", W)
128
0
     << " Align Out     In      Symbol\n";
129
0
130
0
  // Print out file contents.
131
0
  for (OutputSection *OSec : OutputSections) {
132
0
    writeHeader(OS, OSec->Addr, OSec->Size, OSec->Alignment);
133
0
    OS << OSec->Name << '\n';
134
0
135
0
    // Dump symbols for each input section.
136
0
    for (BaseCommand *Base : OSec->Commands) {
137
0
      auto *ISD = dyn_cast<InputSectionDescription>(Base);
138
0
      if (!ISD)
139
0
        continue;
140
0
      
for (InputSection *IS : ISD->Sections) 0
{
141
0
        writeHeader(OS, OSec->Addr + IS->OutSecOff, IS->getSize(),
142
0
                    IS->Alignment);
143
0
        OS << indent(1) << toString(IS) << '\n';
144
0
        for (Defined *Sym : SectionSyms[IS])
145
0
          OS << SymStr[Sym] << '\n';
146
0
      }
147
0
    }
148
0
  }
149
182
}
void lld::elf::writeMapFile<llvm::object::ELFType<(llvm::support::endianness)0, false> >()
Line
Count
Source
108
90
template <class ELFT> void elf::writeMapFile() {
109
90
  if (Config->MapFile.empty())
110
90
    return;
111
0
112
0
  // Open a map file for writing.
113
0
  std::error_code EC;
114
0
  raw_fd_ostream OS(Config->MapFile, EC, sys::fs::F_None);
115
0
  if (
EC0
) {
116
0
    error("cannot open " + Config->MapFile + ": " + EC.message());
117
0
    return;
118
0
  }
119
0
120
0
  // Collect symbol info that we want to print out.
121
0
  std::vector<Defined *> Syms = getSymbols<ELFT>();
122
0
  SymbolMapTy SectionSyms = getSectionSyms(Syms);
123
0
  DenseMap<Defined *, std::string> SymStr = getSymbolStrings<ELFT>(Syms);
124
0
125
0
  // Print out the header line.
126
0
  int W = ELFT::Is64Bits ? 
160
:
80
;
127
0
  OS << left_justify("Address", W) << ' ' << left_justify("Size", W)
128
0
     << " Align Out     In      Symbol\n";
129
0
130
0
  // Print out file contents.
131
0
  for (OutputSection *OSec : OutputSections) {
132
0
    writeHeader(OS, OSec->Addr, OSec->Size, OSec->Alignment);
133
0
    OS << OSec->Name << '\n';
134
0
135
0
    // Dump symbols for each input section.
136
0
    for (BaseCommand *Base : OSec->Commands) {
137
0
      auto *ISD = dyn_cast<InputSectionDescription>(Base);
138
0
      if (!ISD)
139
0
        continue;
140
0
      
for (InputSection *IS : ISD->Sections) 0
{
141
0
        writeHeader(OS, OSec->Addr + IS->OutSecOff, IS->getSize(),
142
0
                    IS->Alignment);
143
0
        OS << indent(1) << toString(IS) << '\n';
144
0
        for (Defined *Sym : SectionSyms[IS])
145
0
          OS << SymStr[Sym] << '\n';
146
0
      }
147
0
    }
148
0
  }
149
90
}
150
151
template void elf::writeMapFile<ELF32LE>();
152
template void elf::writeMapFile<ELF32BE>();
153
template void elf::writeMapFile<ELF64LE>();
154
template void elf::writeMapFile<ELF64BE>();