llvm.org GIT mirror llvm / 70c478d
Reverts change r261907 and r261918 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@261927 91177308-0d34-0410-b5e6-96231b3b80d8 Hemant Kulkarni 4 years ago
5 changed file(s) with 270 addition(s) and 750 deletion(s). Raw diff Collapse all Expand all
+0
-28
test/tools/llvm-readobj/gnu-relocations.test less more
None RUN: llvm-readobj -r %p/Inputs/relocs.obj.elf-i386 --elf-output-style=GNU \
1 RUN: | FileCheck %s -check-prefix ELF32
2 RUN: llvm-readobj -r %p/Inputs/relocs.obj.elf-x86_64 --elf-output-style=GNU \
3 RUN: | FileCheck %s -check-prefix ELF64
4
5 ELF32: Relocation section '.rel.text' at offset 0x318 contains 41 entries:
6 ELF32-NEXT: Offset Info Type Sym. Value Symbol's Name
7 ELF32-NEXT: 00000002 00000500 R_386_NONE 00000000 sym
8 ELF32-NEXT: 00000008 00000501 R_386_32 00000000 sym
9 ELF32-NEXT: 0000000e 00000502 R_386_PC32 00000000 sym
10 ELF32-NEXT: 00000014 00000503 R_386_GOT32 00000000 sym
11 ELF32-NEXT: 0000001a 00000504 R_386_PLT32 00000000 sym
12 ELF32-NEXT: 00000020 00000505 R_386_COPY 00000000 sym
13 ELF32-NEXT: 00000026 00000506 R_386_GLOB_DAT 00000000 sym
14 ELF32-NEXT: 0000002c 00000507 R_386_JUMP_SLOT 00000000 sym
15 ELF32-NEXT: 00000032 00000508 R_386_RELATIVE 00000000 sym
16 ELF32-NEXT: 00000038 00000509 R_386_GOTOFF 00000000 sym
17
18 ELF64: Relocation section '.rela.text' at offset 0x430 contains 38 entries:
19 ELF64-NEXT: Offset Info Type Symbol's Value Symbol's Name + Addend
20 ELF64-NEXT: 0000000000000003 0000000500000000 R_X86_64_NONE 0000000000000000 sym - 4
21 ELF64-NEXT: 000000000000000a 0000000500000001 R_X86_64_64 0000000000000000 sym - 4
22 ELF64-NEXT: 0000000000000011 0000000500000002 R_X86_64_PC32 0000000000000000 sym - 4
23 ELF64-NEXT: 0000000000000018 0000000500000003 R_X86_64_GOT32 0000000000000000 sym - 4
24 ELF64-NEXT: 000000000000001f 0000000500000004 R_X86_64_PLT32 0000000000000000 sym - 4
25 ELF64-NEXT: 0000000000000026 0000000500000005 R_X86_64_COPY 0000000000000000 sym - 4
26 ELF64-NEXT: 000000000000002d 0000000500000006 R_X86_64_GLOB_DAT 0000000000000000 sym - 4
27 ELF64-NEXT: 0000000000000034 0000000500000007 R_X86_64_JUMP_SLOT 0000000000000000 sym - 4
+0
-35
test/tools/llvm-readobj/gnu-sections.test less more
None RUN: llvm-readobj -s %p/Inputs/relocs.obj.elf-i386 --elf-output-style=GNU \
1 RUN: | FileCheck %s -check-prefix ELF32
2 RUN: llvm-readobj -s %p/Inputs/relocs.obj.elf-x86_64 --elf-output-style=GNU \
3 RUN: | FileCheck %s -check-prefix ELF64
4
5 ELF32: Section Headers:
6 ELF32-NEXT: [Nr] Name Type Address Off Size ES Flg Lk Inf Al
7 ELF32-NEXT: [ 0] NULL 00000000 000000 000000 00 0 0 0
8 ELF32-NEXT: [ 1] .text PROGBITS 00000000 000034 0000f6 00 AX 0 0 4
9 ELF32-NEXT: [ 2] .rel.text REL 00000000 000318 000148 08 6 1 4
10 ELF32-NEXT: [ 3] .data PROGBITS 00000000 00012c 000000 00 WA 0 0 4
11 ELF32-NEXT: [ 4] .bss NOBITS 00000000 00012c 000000 00 WA 0 0 4
12 ELF32-NEXT: [ 5] .shstrtab STRTAB 00000000 00012c 000030 00 0 0 1
13 ELF32-NEXT: [ 6] .symtab SYMTAB 00000000 00029c 000060 10 7 4 4
14 ELF32-NEXT: [ 7] .strtab STRTAB 00000000 0002fc 00001b 00 0 0 1
15 ELF32-NEXT: Key to Flags:
16 ELF32-NEXT: W (write), A (alloc), X (execute), M (merge), S (strings), l (large)
17 ELF32-NEXT: I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
18 ELF32-NEXT: O (extra OS processing required) o (OS specific), p (processor specific)
19
20 ELF64: There are 8 section headers, starting at offset 0x180:
21 ELF64: Section Headers:
22 ELF64-NEXT: [Nr] Name Type Address Off Size ES Flg Lk Inf Al
23 ELF64-NEXT: [ 0] NULL 0000000000000000 000000 000000 00 0 0 0
24 ELF64-NEXT: [ 1] .text PROGBITS 0000000000000000 000040 00010a 00 AX 0 0 4
25 ELF64-NEXT: [ 2] .rela.text RELA 0000000000000000 000430 000390 18 6 1 8
26 ELF64-NEXT: [ 3] .data PROGBITS 0000000000000000 00014c 000000 00 WA 0 0 4
27 ELF64-NEXT: [ 4] .bss NOBITS 0000000000000000 00014c 000000 00 WA 0 0 4
28 ELF64-NEXT: [ 5] .shstrtab STRTAB 0000000000000000 00014c 000031 00 0 0 1
29 ELF64-NEXT: [ 6] .symtab SYMTAB 0000000000000000 000380 000090 18 7 4 8
30 ELF64-NEXT: [ 7] .strtab STRTAB 0000000000000000 000410 00001b 00 0 0 1
31 ELF64-NEXT: Key to Flags:
32 ELF64-NEXT: W (write), A (alloc), X (execute), M (merge), S (strings), l (large)
33 ELF64-NEXT: I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
34 ELF64-NEXT: O (extra OS processing required) o (OS specific), p (processor specific)
4242
4343 #define ENUM_ENT_1(enum) \
4444 { #enum, #enum, ELF::enum }
45
46 #define TYPEDEF_ELF_TYPES(ELFT) \
47 typedef ELFFile ELFO; \
48 typedef typename ELFO::Elf_Shdr Elf_Shdr; \
49 typedef typename ELFO::Elf_Sym Elf_Sym; \
50 typedef typename ELFO::Elf_Dyn Elf_Dyn; \
51 typedef typename ELFO::Elf_Dyn_Range Elf_Dyn_Range; \
52 typedef typename ELFO::Elf_Rel Elf_Rel; \
53 typedef typename ELFO::Elf_Rela Elf_Rela; \
54 typedef typename ELFO::Elf_Rela_Range Elf_Rela_Range; \
55 typedef typename ELFO::Elf_Phdr Elf_Phdr; \
56 typedef typename ELFO::Elf_Half Elf_Half; \
57 typedef typename ELFO::Elf_Ehdr Elf_Ehdr; \
58 typedef typename ELFO::Elf_Word Elf_Word; \
59 typedef typename ELFO::uintX_t uintX_t;
6045
6146 namespace {
6247
158143
159144 void parseDynamicTable(ArrayRef LoadSegments);
160145
146 void printSymbolsHelper(bool IsDynamic);
161147 void printSymbol(const Elf_Sym *Symbol, const Elf_Sym *FirstSym,
162148 StringRef StrTable, bool IsDynamic);
163149
150 void printDynamicRelocation(Elf_Rela Rel);
151 void printRelocations(const Elf_Shdr *Sec);
152 void printRelocation(Elf_Rela Rel, const Elf_Shdr *SymTab);
164153 void printValue(uint64_t Type, uint64_t Value);
165154
155 Elf_Rel_Range dyn_rels() const;
156 Elf_Rela_Range dyn_relas() const;
166157 StringRef getDynamicString(uint64_t Offset) const;
167158 StringRef getSymbolVersion(StringRef StrTab, const Elf_Sym *symb,
168 bool &IsDefault) const;
169 void LoadVersionMap() const;
159 bool &IsDefault);
160 void LoadVersionMap();
170161 void LoadVersionNeeds(const Elf_Shdr *ec) const;
171162 void LoadVersionDefs(const Elf_Shdr *sec) const;
172163
219210 return DynSymRegion.getAsRange();
220211 }
221212
222 Elf_Rel_Range dyn_rels() const;
223 Elf_Rela_Range dyn_relas() const;
224213 std::string getFullSymbolName(const Elf_Sym *Symbol, StringRef StrTable,
225 bool IsDynamic) const;
214 bool IsDynamic);
226215 const Elf_Shdr *getDotSymtabSec() const { return DotSymtabSec; }
227 ArrayRef getShndxTable() const { return ShndxTable; }
216 ArrayRef getShndxTable() { return ShndxTable; }
228217 StringRef getDynamicStringTable() const { return DynamicStringTable; }
229 const DynRegionInfo &getDynRelRegion() const { return DynRelRegion; }
230 const DynRegionInfo &getDynRelaRegion()const { return DynRelaRegion; }
231 const DynRegionInfo &getDynPLTRelRegion()const { return DynPLTRelRegion; }
232218 };
233219
234220 template class DumpStyle {
235221 public:
236 TYPEDEF_ELF_TYPES(ELFT)
237 virtual void printFileHeaders(const ELFO *Obj) = 0;
222 virtual void printFileHeaders(const ELFFile *Obj) = 0;
238223 virtual ~DumpStyle() { }
239 DumpStyle(ELFDumper *Dumper) : Dumper(Dumper) {}
240 virtual void printRelocations(const ELFO *Obj) = 0;
241 virtual void printSections(const ELFO *Obj) = 0;
242 virtual void printSymbols(const ELFO *Obj) = 0;
243 virtual void printDynamicSymbols(const ELFO *Obj) = 0;
244 virtual void printDynamicRelocations(const ELFO *Obj) = 0;
245 const ELFDumper *dumper() const { return Dumper; }
246
247 private:
248 const ELFDumper *Dumper;
249224 };
250225
251226 template class GNUStyle : public DumpStyle {
252227 formatted_raw_ostream OS;
228
253229 public:
254 TYPEDEF_ELF_TYPES(ELFT)
255 GNUStyle(StreamWriter &W, ELFDumper *Dumper)
256 : DumpStyle(Dumper), OS(W.getOStream()) {}
257 void printFileHeaders(const ELFO *Obj) override;
258 void printRelocations(const ELFO *Obj) override;
259 void printSections(const ELFO *Obj) override;
260 void printSymbols(const ELFO *Obj) override;
261 void printDynamicSymbols(const ELFO *Obj) override;
262 void printDynamicRelocations(const ELFO *Obj) override;
230 typedef typename ELFFile::Elf_Ehdr Elf_Ehdr;
231 GNUStyle(StreamWriter &W) : OS(W.getOStream()) {}
232 void printFileHeaders(const ELFFile *Obj) override;
263233
264234 private:
265 struct Field {
266 StringRef Str;
267 unsigned Column;
268 Field(StringRef S, unsigned Col) : Str(S), Column(Col) {}
269 Field(unsigned Col) : Str(""), Column(Col) {}
270 Field &operator=(StringRef S) {
271 Str = S;
272 return *this;
273 }
274 };
275
276235 template
277236 std::string printEnum(T Value, ArrayRef> EnumValues) {
278237 for (const auto &EnumItem : EnumValues)
279238 if (EnumItem.Value == Value)
280239 return EnumItem.AltName;
281 return to_hexString(Value, false);
282 }
283 formatted_raw_ostream &printField(struct Field F) {
284 if (F.Column != 0)
285 OS.PadToColumn(F.Column);
286 OS << F.Str;
287 OS.flush();
288 return OS;
289 }
290 void printRelocation(const ELFO *Obj, const Elf_Shdr *SymTab,
291 const Elf_Rela &R, bool IsRela);
240 return to_hexString(Value);
241 }
292242 };
293243
294244 template class LLVMStyle : public DumpStyle {
295245 public:
296 TYPEDEF_ELF_TYPES(ELFT)
297 LLVMStyle(StreamWriter &W, ELFDumper *Dumper)
298 : DumpStyle(Dumper), W(W) {}
299
300 void printFileHeaders(const ELFO *Obj) override;
301 void printRelocations(const ELFO *Obj) override;
302 void printRelocations(const Elf_Shdr *Sec, const ELFO *Obj);
303 void printSections(const ELFO *Obj) override;
304 void printSymbolsHelper(const ELFO *Obj, bool IsDynamic);
305 void printSymbols(const ELFO *Obj) override;
306 void printDynamicSymbols(const ELFO *Obj) override;
307 void printDynamicRelocations(const ELFO *Obj) override;
246 typedef typename ELFFile::Elf_Ehdr Elf_Ehdr;
247 LLVMStyle(StreamWriter &W) : W(W) {}
248
249 void printFileHeaders(const ELFFile *Obj) override;
308250
309251 private:
310 void printRelocation(const ELFO* Obj, Elf_Rela Rel, const Elf_Shdr *SymTab);
311 void printSymbol(const ELFO *Obj, const Elf_Sym *Symbol, const Elf_Sym *First,
312 StringRef StrTable, bool IsDynamic);
313 void printDynamicRelocation(const ELFO *Obj, Elf_Rela Rel);
314
315252 StreamWriter &W;
316253 };
317254
410347 }
411348 }
412349
413 template void ELFDumper::LoadVersionMap() const {
350 template void ELFDumper::LoadVersionMap() {
414351 // If there is no dynamic symtab or version table, there is nothing to do.
415352 if (!DynSymRegion.Addr || !dot_gnu_version_sec)
416353 return;
519456 template
520457 StringRef ELFDumper::getSymbolVersion(StringRef StrTab,
521458 const Elf_Sym *symb,
522 bool &IsDefault) const {
459 bool &IsDefault) {
523460 // This is a dynamic symbol. Look in the GNU symbol version table.
524461 if (!dot_gnu_version_sec) {
525462 // No version table.
568505 template
569506 std::string ELFDumper::getFullSymbolName(const Elf_Sym *Symbol,
570507 StringRef StrTable,
571 bool IsDynamic) const {
508 bool IsDynamic) {
572509 StringRef SymbolName = unwrapOrError(Symbol->getName(StrTable));
573510 if (!IsDynamic)
574511 return SymbolName;
955892 LLVM_READOBJ_ENUM_ENT(ELF, SHF_X86_64_LARGE)
956893 };
957894
958 static std::string getGNUFlags(uint64_t flags) {
959 std::string str;
960 for (auto entry : ElfSectionFlags) {
961 uint64_t flag = entry.Value & flags;
962 switch (flag) {
963 case ELF::SHF_WRITE:
964 str += "W";
965 break;
966 case ELF::SHF_ALLOC:
967 str += "A";
968 break;
969 case ELF::SHF_EXECINSTR:
970 str += "X";
971 break;
972 case ELF::SHF_MERGE:
973 str += "M";
974 break;
975 case ELF::SHF_STRINGS:
976 str += "S";
977 break;
978 case ELF::SHF_INFO_LINK:
979 str += "I";
980 break;
981 case ELF::SHF_LINK_ORDER:
982 str += "L";
983 break;
984 case ELF::SHF_OS_NONCONFORMING:
985 str += "O";
986 break;
987 case ELF::SHF_GROUP:
988 str += "G";
989 break;
990 case ELF::SHF_TLS:
991 str += "T";
992 break;
993 case ELF::SHF_EXCLUDE:
994 str += "E";
995 break;
996 default:
997 if (flags & ELF::SHF_MASKOS)
998 str += "o";
999 else if (flags & ELF::SHF_MASKPROC)
1000 str += "p";
1001 else if (flag)
1002 str += "x";
1003 }
1004 }
1005 return str;
1006 }
1007
1008895 static const char *getElfSegmentType(unsigned Arch, unsigned Type) {
1009896 // Check potentially overlapped processor-specific
1010897 // program header type.
11521039 parseDynamicTable(LoadSegments);
11531040
11541041 if (opts::Output == opts::GNU)
1155 ELFDumperStyle.reset(new GNUStyle(Writer, this));
1042 ELFDumperStyle.reset(new GNUStyle(Writer));
11561043 else
1157 ELFDumperStyle.reset(new LLVMStyle(Writer, this));
1044 ELFDumperStyle.reset(new LLVMStyle(Writer));
11581045 }
11591046
11601047 template
12571144
12581145 template
12591146 void ELFDumper::printSections() {
1260 ELFDumperStyle->printSections(Obj);
1147 ListScope SectionsD(W, "Sections");
1148
1149 int SectionIndex = -1;
1150 for (const Elf_Shdr &Sec : Obj->sections()) {
1151 ++SectionIndex;
1152
1153 StringRef Name = unwrapOrError(Obj->getSectionName(&Sec));
1154
1155 DictScope SectionD(W, "Section");
1156 W.printNumber("Index", SectionIndex);
1157 W.printNumber("Name", Name, Sec.sh_name);
1158 W.printHex("Type",
1159 getElfSectionType(Obj->getHeader()->e_machine, Sec.sh_type),
1160 Sec.sh_type);
1161 std::vector> SectionFlags(std::begin(ElfSectionFlags),
1162 std::end(ElfSectionFlags));
1163 switch (Obj->getHeader()->e_machine) {
1164 case EM_AMDGPU:
1165 SectionFlags.insert(SectionFlags.end(), std::begin(ElfAMDGPUSectionFlags),
1166 std::end(ElfAMDGPUSectionFlags));
1167 break;
1168 case EM_HEXAGON:
1169 SectionFlags.insert(SectionFlags.end(),
1170 std::begin(ElfHexagonSectionFlags),
1171 std::end(ElfHexagonSectionFlags));
1172 break;
1173 case EM_MIPS:
1174 SectionFlags.insert(SectionFlags.end(), std::begin(ElfMipsSectionFlags),
1175 std::end(ElfMipsSectionFlags));
1176 break;
1177 case EM_X86_64:
1178 SectionFlags.insert(SectionFlags.end(), std::begin(ElfX86_64SectionFlags),
1179 std::end(ElfX86_64SectionFlags));
1180 break;
1181 default:
1182 // Nothing to do.
1183 break;
1184 }
1185 W.printFlags("Flags", Sec.sh_flags, makeArrayRef(SectionFlags));
1186 W.printHex("Address", Sec.sh_addr);
1187 W.printHex("Offset", Sec.sh_offset);
1188 W.printNumber("Size", Sec.sh_size);
1189 W.printNumber("Link", Sec.sh_link);
1190 W.printNumber("Info", Sec.sh_info);
1191 W.printNumber("AddressAlignment", Sec.sh_addralign);
1192 W.printNumber("EntrySize", Sec.sh_entsize);
1193
1194 if (opts::SectionRelocations) {
1195 ListScope D(W, "Relocations");
1196 printRelocations(&Sec);
1197 }
1198
1199 if (opts::SectionSymbols) {
1200 ListScope D(W, "Symbols");
1201 const Elf_Shdr *Symtab = DotSymtabSec;
1202 StringRef StrTable = unwrapOrError(Obj->getStringTableForSymtab(*Symtab));
1203
1204 for (const Elf_Sym &Sym : Obj->symbols(Symtab)) {
1205 const Elf_Shdr *SymSec =
1206 unwrapOrError(Obj->getSection(&Sym, Symtab, ShndxTable));
1207 if (SymSec == &Sec)
1208 printSymbol(&Sym, Obj->symbol_begin(Symtab), StrTable, false);
1209 }
1210 }
1211
1212 if (opts::SectionData && Sec.sh_type != ELF::SHT_NOBITS) {
1213 ArrayRef Data = unwrapOrError(Obj->getSectionContents(&Sec));
1214 W.printBinaryBlock("SectionData",
1215 StringRef((const char *)Data.data(), Data.size()));
1216 }
1217 }
12611218 }
12621219
12631220 template
12641221 void ELFDumper::printRelocations() {
1265 ELFDumperStyle->printRelocations(Obj);
1222 ListScope D(W, "Relocations");
1223
1224 int SectionNumber = -1;
1225 for (const Elf_Shdr &Sec : Obj->sections()) {
1226 ++SectionNumber;
1227
1228 if (Sec.sh_type != ELF::SHT_REL && Sec.sh_type != ELF::SHT_RELA)
1229 continue;
1230
1231 StringRef Name = unwrapOrError(Obj->getSectionName(&Sec));
1232
1233 W.startLine() << "Section (" << SectionNumber << ") " << Name << " {\n";
1234 W.indent();
1235
1236 printRelocations(&Sec);
1237
1238 W.unindent();
1239 W.startLine() << "}\n";
1240 }
12661241 }
12671242
12681243 template void ELFDumper::printDynamicRelocations() {
1269 ELFDumperStyle->printDynamicRelocations(Obj);
1270 }
1271
1244 if (DynRelRegion.Size && DynRelaRegion.Size)
1245 report_fatal_error("There are both REL and RELA dynamic relocations");
1246 W.startLine() << "Dynamic Relocations {\n";
1247 W.indent();
1248 if (DynRelaRegion.Size > 0)
1249 for (const Elf_Rela &Rela : dyn_relas())
1250 printDynamicRelocation(Rela);
1251 else
1252 for (const Elf_Rel &Rel : dyn_rels()) {
1253 Elf_Rela Rela;
1254 Rela.r_offset = Rel.r_offset;
1255 Rela.r_info = Rel.r_info;
1256 Rela.r_addend = 0;
1257 printDynamicRelocation(Rela);
1258 }
1259 if (DynPLTRelRegion.EntSize == sizeof(Elf_Rela))
1260 for (const Elf_Rela &Rela : DynPLTRelRegion.getAsRange())
1261 printDynamicRelocation(Rela);
1262 else
1263 for (const Elf_Rel &Rel : DynPLTRelRegion.getAsRange()) {
1264 Elf_Rela Rela;
1265 Rela.r_offset = Rel.r_offset;
1266 Rela.r_info = Rel.r_info;
1267 Rela.r_addend = 0;
1268 printDynamicRelocation(Rela);
1269 }
1270 W.unindent();
1271 W.startLine() << "}\n";
1272 }
1273
1274 template
1275 void ELFDumper::printRelocations(const Elf_Shdr *Sec) {
1276 const Elf_Shdr *SymTab = unwrapOrError(Obj->getSection(Sec->sh_link));
1277
1278 switch (Sec->sh_type) {
1279 case ELF::SHT_REL:
1280 for (const Elf_Rel &R : Obj->rels(Sec)) {
1281 Elf_Rela Rela;
1282 Rela.r_offset = R.r_offset;
1283 Rela.r_info = R.r_info;
1284 Rela.r_addend = 0;
1285 printRelocation(Rela, SymTab);
1286 }
1287 break;
1288 case ELF::SHT_RELA:
1289 for (const Elf_Rela &R : Obj->relas(Sec))
1290 printRelocation(R, SymTab);
1291 break;
1292 }
1293 }
1294
1295 template
1296 void ELFDumper::printRelocation(Elf_Rela Rel, const Elf_Shdr *SymTab) {
1297 SmallString<32> RelocName;
1298 Obj->getRelocationTypeName(Rel.getType(Obj->isMips64EL()), RelocName);
1299 StringRef TargetName;
1300 const Elf_Sym *Sym = Obj->getRelocationSymbol(&Rel, SymTab);
1301 if (Sym && Sym->getType() == ELF::STT_SECTION) {
1302 const Elf_Shdr *Sec =
1303 unwrapOrError(Obj->getSection(Sym, SymTab, ShndxTable));
1304 TargetName = unwrapOrError(Obj->getSectionName(Sec));
1305 } else if (Sym) {
1306 StringRef StrTable = unwrapOrError(Obj->getStringTableForSymtab(*SymTab));
1307 TargetName = unwrapOrError(Sym->getName(StrTable));
1308 }
1309
1310 if (opts::ExpandRelocs) {
1311 DictScope Group(W, "Relocation");
1312 W.printHex("Offset", Rel.r_offset);
1313 W.printNumber("Type", RelocName, (int)Rel.getType(Obj->isMips64EL()));
1314 W.printNumber("Symbol", TargetName.size() > 0 ? TargetName : "-",
1315 Rel.getSymbol(Obj->isMips64EL()));
1316 W.printHex("Addend", Rel.r_addend);
1317 } else {
1318 raw_ostream& OS = W.startLine();
1319 OS << W.hex(Rel.r_offset) << " " << RelocName << " "
1320 << (TargetName.size() > 0 ? TargetName : "-") << " "
1321 << W.hex(Rel.r_addend) << "\n";
1322 }
1323 }
1324
1325 template
1326 void ELFDumper::printDynamicRelocation(Elf_Rela Rel) {
1327 SmallString<32> RelocName;
1328 Obj->getRelocationTypeName(Rel.getType(Obj->isMips64EL()), RelocName);
1329 StringRef SymbolName;
1330 uint32_t SymIndex = Rel.getSymbol(Obj->isMips64EL());
1331 const Elf_Sym *Sym = dynamic_symbols().begin() + SymIndex;
1332 SymbolName = unwrapOrError(Sym->getName(DynamicStringTable));
1333 if (opts::ExpandRelocs) {
1334 DictScope Group(W, "Relocation");
1335 W.printHex("Offset", Rel.r_offset);
1336 W.printNumber("Type", RelocName, (int)Rel.getType(Obj->isMips64EL()));
1337 W.printString("Symbol", SymbolName.size() > 0 ? SymbolName : "-");
1338 W.printHex("Addend", Rel.r_addend);
1339 } else {
1340 raw_ostream &OS = W.startLine();
1341 OS << W.hex(Rel.r_offset) << " " << RelocName << " "
1342 << (SymbolName.size() > 0 ? SymbolName : "-") << " "
1343 << W.hex(Rel.r_addend) << "\n";
1344 }
1345 }
1346
1347 template
1348 void ELFDumper::printSymbolsHelper(bool IsDynamic) {
1349 StringRef StrTable;
1350 Elf_Sym_Range Syms(nullptr, nullptr);
1351
1352 if (IsDynamic) {
1353 StrTable = DynamicStringTable;
1354 Syms = dynamic_symbols();
1355 } else {
1356 if (!DotSymtabSec)
1357 return;
1358 StrTable = unwrapOrError(Obj->getStringTableForSymtab(*DotSymtabSec));
1359 Syms = Obj->symbols(DotSymtabSec);
1360 }
1361 for (const Elf_Sym &Sym : Syms)
1362 printSymbol(&Sym, Syms.begin(), StrTable, IsDynamic);
1363 }
12721364
12731365 template
12741366 void ELFDumper::printSymbols() {
1275 ELFDumperStyle->printSymbols(Obj);
1367 ListScope Group(W, "Symbols");
1368 printSymbolsHelper(false);
12761369 }
12771370
12781371 template
12791372 void ELFDumper::printDynamicSymbols() {
1280 ELFDumperStyle->printDynamicSymbols(Obj);
1281 }
1282
1373 ListScope Group(W, "DynamicSymbols");
1374 printSymbolsHelper(true);
1375 }
1376
1377 template
1378 void ELFDumper::printSymbol(const Elf_Sym *Symbol,
1379 const Elf_Sym *FirstSym, StringRef StrTable,
1380 bool IsDynamic) {
1381 unsigned SectionIndex = 0;
1382 StringRef SectionName;
1383 getSectionNameIndex(*Obj, Symbol, FirstSym, ShndxTable, SectionName,
1384 SectionIndex);
1385 std::string FullSymbolName = getFullSymbolName(Symbol, StrTable, IsDynamic);
1386 unsigned char SymbolType = Symbol->getType();
1387
1388 DictScope D(W, "Symbol");
1389 W.printNumber("Name", FullSymbolName, Symbol->st_name);
1390 W.printHex ("Value", Symbol->st_value);
1391 W.printNumber("Size", Symbol->st_size);
1392 W.printEnum ("Binding", Symbol->getBinding(),
1393 makeArrayRef(ElfSymbolBindings));
1394 if (Obj->getHeader()->e_machine == ELF::EM_AMDGPU &&
1395 SymbolType >= ELF::STT_LOOS && SymbolType < ELF::STT_HIOS)
1396 W.printEnum ("Type", SymbolType, makeArrayRef(AMDGPUSymbolTypes));
1397 else
1398 W.printEnum ("Type", SymbolType, makeArrayRef(ElfSymbolTypes));
1399 W.printNumber("Other", Symbol->st_other);
1400 W.printHex("Section", SectionName, SectionIndex);
1401 }
12831402
12841403 #define LLVM_READOBJ_TYPE_CASE(name) \
12851404 case DT_##name: return #name
21722291 OS.flush();
21732292 }
21742293
2175 template void GNUStyle::printFileHeaders(const ELFO *Obj) {
2294 template
2295 void GNUStyle::printFileHeaders(const ELFFile *Obj) {
21762296 const Elf_Ehdr *e = Obj->getHeader();
21772297 OS << "ELF Header:\n";
21782298 OS << " Magic: ";
22252345 }
22262346
22272347 template
2228 void GNUStyle::printRelocation(const ELFO *Obj, const Elf_Shdr *SymTab,
2229 const Elf_Rela &R, bool IsRela) {
2230 std::string r_offset, r_info, r_addend = "", s_value;
2231 SmallString<32> RelocName;
2232 StringRef StrTable = unwrapOrError(Obj->getStringTableForSymtab(*SymTab));
2233 StringRef TargetName;
2234 const Elf_Sym *Sym = nullptr;
2235 unsigned bias;
2236 const char *FmtCharHex;
2237 if (ELFT::Is64Bits) {
2238 bias = 8;
2239 FmtCharHex = "%016" PRIx64;
2240 } else {
2241 bias = 0;
2242 FmtCharHex = "%08" PRIx32;
2243 }
2244 Field fields[5] = {0, 10 + bias, 19 + 2 * bias, 42 + 2 * bias, 53 + 2 * bias};
2245 Obj->getRelocationTypeName(R.getType(Obj->isMips64EL()), RelocName);
2246 Sym = Obj->getRelocationSymbol(&R, SymTab);
2247 if (Sym && Sym->getType() == ELF::STT_SECTION) {
2248 const Elf_Shdr *Sec = unwrapOrError(
2249 Obj->getSection(Sym, SymTab, this->dumper()->getShndxTable()));
2250 TargetName = unwrapOrError(Obj->getSectionName(Sec));
2251 } else if (Sym) {
2252 TargetName = unwrapOrError(Sym->getName(StrTable));
2253 }
2254
2255 if (Sym && IsRela) {
2256 if (R.r_addend < 0)
2257 r_addend = " - ";
2258 else
2259 r_addend = " + ";
2260 }
2261 r_offset = to_hexString(format(FmtCharHex, R.r_offset));
2262 r_info = to_hexString(format(FmtCharHex, R.r_info));
2263 if (IsRela)
2264 r_addend +=
2265 R.r_addend == 0 ? std::string("0") : to_hexString(std::abs(R.r_addend), false);
2266 if (Sym)
2267 s_value = to_hexString(format(FmtCharHex, Sym->getValue()));
2268
2269 fields[0] = r_offset;
2270 fields[1] = r_info;
2271 fields[2] = RelocName;
2272 fields[3] = s_value;
2273 fields[4] = TargetName;
2274 for (auto &field : fields)
2275 printField(field);
2276 if (IsRela)
2277 OS << r_addend;
2278 OS << "\n";
2279 }
2280
2281 template void GNUStyle::printRelocations(const ELFO *Obj) {
2282 bool hasRelocSections = false;
2283 for (const Elf_Shdr &Sec : Obj->sections()) {
2284 if (Sec.sh_type != ELF::SHT_REL && Sec.sh_type != ELF::SHT_RELA)
2285 continue;
2286 hasRelocSections = true;
2287 StringRef Name = unwrapOrError(Obj->getSectionName(&Sec));
2288 unsigned entries = Sec.getEntityCount();
2289 uintX_t offset = Sec.sh_offset;
2290 OS << "\nRelocation section '" << Name << "' at offset 0x"
2291 << to_hexString(offset, false) << " contains " << to_string(entries)
2292 << " entries:\n";
2293 if (ELFT::Is64Bits)
2294 OS << " Offset Info Type"
2295 << " Symbol's Value Symbol's Name";
2296 else
2297 OS << " Offset Info Type Sym. Value "
2298 << "Symbol's Name";
2299 OS << ((Sec.sh_type == ELF::SHT_RELA) ? " + Addend" : "") << "\n";
2300
2301 const Elf_Shdr *SymTab = unwrapOrError(Obj->getSection(Sec.sh_link));
2302 if (Sec.sh_type == ELF::SHT_REL) {
2303 for (const auto &R : Obj->rels(&Sec)) {
2304 Elf_Rela Rela;
2305 Rela.r_offset = R.r_offset;
2306 Rela.r_info = R.r_info;
2307 Rela.r_addend = 0;
2308 printRelocation(Obj, SymTab, Rela, false);
2309 }
2310 } else {
2311 for (const auto &R : Obj->relas(&Sec))
2312 printRelocation(Obj, SymTab, R, true);
2313 }
2314 }
2315 if (!hasRelocSections)
2316 OS << "\nThere are no relocations in this file.\n";
2317 }
2318
2319 std::string getSectiontypeString(unsigned arch, unsigned type) {
2320 using namespace ELF;
2321 switch (arch) {
2322 case EM_ARM:
2323 switch (type) {
2324 case SHT_ARM_EXIDX:
2325 return "ARM_EXIDX";
2326 case SHT_ARM_PREEMPTMAP:
2327 return "ARM_PREEMPTMAP";
2328 case SHT_ARM_ATTRIBUTES:
2329 return "ARM_ATTRIBUTES";
2330 case SHT_ARM_DEBUGOVERLAY:
2331 return "ARM_DEBUGOVERLAY";
2332 case SHT_ARM_OVERLAYSECTION:
2333 return "ARM_OVERLAYSECTION";
2334 }
2335 case EM_X86_64:
2336 switch (type) {
2337 case SHT_X86_64_UNWIND:
2338 return "X86_64_UNWIND";
2339 }
2340 case EM_MIPS:
2341 case EM_MIPS_RS3_LE:
2342 switch (type) {
2343 case SHT_MIPS_REGINFO:
2344 return "MIPS_REGINFO";
2345 case SHT_MIPS_OPTIONS:
2346 return "MIPS_OPTIONS";
2347 case SHT_MIPS_ABIFLAGS:
2348 return "MIPS_ABIFLAGS";
2349 }
2350 }
2351 switch (type) {
2352 case SHT_NULL:
2353 return "NULL";
2354 case SHT_PROGBITS:
2355 return "PROGBITS";
2356 case SHT_SYMTAB:
2357 return "SYMTAB";
2358 case SHT_STRTAB:
2359 return "STRTAB";
2360 case SHT_RELA:
2361 return "RELA";
2362 case SHT_HASH:
2363 return "HASH";
2364 case SHT_DYNAMIC:
2365 return "DYNAMIC";
2366 case SHT_NOTE:
2367 return "NOTE";
2368 case SHT_NOBITS:
2369 return "NOBITS";
2370 case SHT_REL:
2371 return "REL";
2372 case SHT_SHLIB:
2373 return "SHLIB";
2374 case SHT_DYNSYM:
2375 return "DYNSYM";
2376 case SHT_INIT_ARRAY:
2377 return "INIT_ARRAY";
2378 case SHT_FINI_ARRAY:
2379 return "FINI_ARRAY";
2380 case SHT_PREINIT_ARRAY:
2381 return "PREINIT_ARRAY";
2382 case SHT_GROUP:
2383 return "GROUP";
2384 case SHT_SYMTAB_SHNDX:
2385 return "SYMTAB SECTION INDICES";
2386 // FIXME: Parse processor specific GNU attributes
2387 case SHT_GNU_ATTRIBUTES:
2388 return "ATTRIBUTES";
2389 case SHT_GNU_HASH:
2390 return "GNU_HASH";
2391 case SHT_GNU_verdef:
2392 return "VERDEF";
2393 case SHT_GNU_verneed:
2394 return "VERNEED";
2395 case SHT_GNU_versym:
2396 return "VERSYM";
2397 default:
2398 return "";
2399 }
2400 return "";
2401 }
2402
2403 template void GNUStyle::printSections(const ELFO *Obj) {
2404 size_t sectionIndex = 0;
2405 std::string number, type, size, address, offset, flags, link, info, entrysize,
2406 alignment;
2407 unsigned bias;
2408 const char *FmtChar;
2409
2410 if (ELFT::Is64Bits) {
2411 bias = 0;
2412 FmtChar = "%016" PRIx64;
2413 } else {
2414 bias = 8;
2415 FmtChar = "%08" PRIx32;
2416 }
2417 OS << "There are " << to_string(Obj->getHeader()->e_shnum)
2418 << " section headers, starting at offset "
2419 << "0x" << to_hexString(Obj->getHeader()->e_shoff, false) << ":\n\n";
2420 OS << "Section Headers:\n";
2421 Field fields[11] = {{"[Nr]", 2},
2422 {"Name", 7},
2423 {"Type", 25},
2424 {"Address", 41},
2425 {"Off", 58 - bias},
2426 {"Size", 65 - bias},
2427 {"ES", 72 - bias},
2428 {"Flg", 75 - bias},
2429 {"Lk", 79 - bias},
2430 {"Inf", 82 - bias},
2431 {"Al", 86 - bias}};
2432 for (auto &f : fields)
2433 printField(f);
2434 OS << "\n";
2435
2436 for (const Elf_Shdr &Sec : Obj->sections()) {
2437 number = to_string(sectionIndex);
2438 fields[0] = number;
2439 fields[1] = unwrapOrError(Obj->getSectionName(&Sec));
2440 type = getSectiontypeString(Obj->getHeader()->e_machine, Sec.sh_type);
2441 fields[2] = type;
2442 address = to_hexString(format(FmtChar, Sec.sh_addr));
2443 fields[3] = address;
2444 offset = to_hexString(format("%6.6x", Sec.sh_offset));
2445 fields[4] = offset;
2446 size = to_hexString(format("%6.6x", Sec.sh_size));
2447 fields[5] = size;
2448 entrysize = to_hexString(format("%2.2x", Sec.sh_entsize));
2449 fields[6] = entrysize;
2450 flags = getGNUFlags(Sec.sh_flags);
2451 fields[7] = flags;
2452 link = to_string(Sec.sh_link);
2453 fields[8] = link;
2454 info = to_string(Sec.sh_info);
2455 fields[9] = info;
2456 alignment = to_string(Sec.sh_addralign);
2457 fields[10] = alignment;
2458 OS.PadToColumn(fields[0].Column);
2459 OS << "[" << right_justify(fields[0].Str, 2) << "]";
2460 for (int i = 1; i < 7; i++)
2461 printField(fields[i]);
2462 OS.PadToColumn(fields[7].Column);
2463 OS << right_justify(fields[7].Str, 3);
2464 OS.PadToColumn(fields[8].Column);
2465 OS << right_justify(fields[8].Str, 2);
2466 OS.PadToColumn(fields[9].Column);
2467 OS << right_justify(fields[9].Str, 3);
2468 OS.PadToColumn(fields[10].Column);
2469 OS << right_justify(fields[10].Str, 2);
2470 OS << "\n";
2471 ++sectionIndex;
2472 }
2473 OS << "Key to Flags:\n"
2474 << " W (write), A (alloc), X (execute), M (merge), S (strings), l "
2475 "(large)\n"
2476 << " I (info), L (link order), G (group), T (TLS), E (exclude),\
2477 x (unknown)\n"
2478 << " O (extra OS processing required) o (OS specific),\
2479 p (processor specific)\n";
2480 }
2481
2482 template void GNUStyle::printSymbols(const ELFO *Obj) {
2483 OS << "GNU style symbols not implemented!\n";
2484 }
2485
2486 template
2487 void GNUStyle::printDynamicSymbols(const ELFO *Obj) {
2488 OS << "GNU style dynamic symbols not implemented!\n";
2489 }
2490
2491 template
2492 void GNUStyle::printDynamicRelocations(const ELFO *Obj) {
2493 OS << "GNU style dynamic relocations not implemented!\n";
2494 }
2495
2496 template void LLVMStyle::printFileHeaders(const ELFO *Obj) {
2348 void LLVMStyle::printFileHeaders(const ELFFile *Obj) {
24972349 const Elf_Ehdr *e = Obj->getHeader();
24982350 {
24992351 DictScope D(W, "ElfHeader");
25362388 W.printNumber("StringTableSectionIndex", e->e_shstrndx);
25372389 }
25382390 }
2539
2540 template void LLVMStyle::printRelocations(const ELFO *Obj) {
2541 ListScope D(W, "Relocations");
2542
2543 int SectionNumber = -1;
2544 for (const Elf_Shdr &Sec : Obj->sections()) {
2545 ++SectionNumber;
2546
2547 if (Sec.sh_type != ELF::SHT_REL && Sec.sh_type != ELF::SHT_RELA)
2548 continue;
2549
2550 StringRef Name = unwrapOrError(Obj->getSectionName(&Sec));
2551
2552 W.startLine() << "Section (" << SectionNumber << ") " << Name << " {\n";
2553 W.indent();
2554
2555 printRelocations(&Sec, Obj);
2556
2557 W.unindent();
2558 W.startLine() << "}\n";
2559 }
2560 }
2561
2562 template
2563 void LLVMStyle::printRelocations(const Elf_Shdr *Sec, const ELFO *Obj) {
2564 const Elf_Shdr *SymTab = unwrapOrError(Obj->getSection(Sec->sh_link));
2565
2566 switch (Sec->sh_type) {
2567 case ELF::SHT_REL:
2568 for (const Elf_Rel &R : Obj->rels(Sec)) {
2569 Elf_Rela Rela;
2570 Rela.r_offset = R.r_offset;
2571 Rela.r_info = R.r_info;
2572 Rela.r_addend = 0;
2573 printRelocation(Obj, Rela, SymTab);
2574 }
2575 break;
2576 case ELF::SHT_RELA:
2577 for (const Elf_Rela &R : Obj->relas(Sec))
2578 printRelocation(Obj, R, SymTab);
2579 break;
2580 }
2581 }
2582
2583 template
2584 void LLVMStyle::printRelocation(const ELFO *Obj, Elf_Rela Rel,
2585 const Elf_Shdr *SymTab) {
2586 SmallString<32> RelocName;
2587 Obj->getRelocationTypeName(Rel.getType(Obj->isMips64EL()), RelocName);
2588 StringRef TargetName;
2589 const Elf_Sym *Sym = Obj->getRelocationSymbol(&Rel, SymTab);
2590 if (Sym && Sym->getType() == ELF::STT_SECTION) {
2591 const Elf_Shdr *Sec = unwrapOrError(
2592 Obj->getSection(Sym, SymTab, this->dumper()->getShndxTable()));
2593 TargetName = unwrapOrError(Obj->getSectionName(Sec));
2594 } else if (Sym) {
2595 StringRef StrTable = unwrapOrError(Obj->getStringTableForSymtab(*SymTab));
2596 TargetName = unwrapOrError(Sym->getName(StrTable));
2597 }
2598
2599 if (opts::ExpandRelocs) {
2600 DictScope Group(W, "Relocation");
2601 W.printHex("Offset", Rel.r_offset);
2602 W.printNumber("Type", RelocName, (int)Rel.getType(Obj->isMips64EL()));
2603 W.printNumber("Symbol", TargetName.size() > 0 ? TargetName : "-",
2604 Rel.getSymbol(Obj->isMips64EL()));
2605 W.printHex("Addend", Rel.r_addend);
2606 } else {
2607 raw_ostream &OS = W.startLine();
2608 OS << W.hex(Rel.r_offset) << " " << RelocName << " "
2609 << (TargetName.size() > 0 ? TargetName : "-") << " "
2610 << W.hex(Rel.r_addend) << "\n";
2611 }
2612 }
2613
2614 template void LLVMStyle::printSections(const ELFO *Obj) {
2615 ListScope SectionsD(W, "Sections");
2616
2617 int SectionIndex = -1;
2618 for (const Elf_Shdr &Sec : Obj->sections()) {
2619 ++SectionIndex;
2620
2621 StringRef Name = unwrapOrError(Obj->getSectionName(&Sec));
2622
2623 DictScope SectionD(W, "Section");
2624 W.printNumber("Index", SectionIndex);
2625 W.printNumber("Name", Name, Sec.sh_name);
2626 W.printHex("Type",
2627 getElfSectionType(Obj->getHeader()->e_machine, Sec.sh_type),
2628 Sec.sh_type);
2629 std::vector> SectionFlags(std::begin(ElfSectionFlags),
2630 std::end(ElfSectionFlags));
2631 switch (Obj->getHeader()->e_machine) {
2632 case EM_AMDGPU:
2633 SectionFlags.insert(SectionFlags.end(), std::begin(ElfAMDGPUSectionFlags),
2634 std::end(ElfAMDGPUSectionFlags));
2635 break;
2636 case EM_HEXAGON:
2637 SectionFlags.insert(SectionFlags.end(),
2638 std::begin(ElfHexagonSectionFlags),
2639 std::end(ElfHexagonSectionFlags));
2640 break;
2641 case EM_MIPS:
2642 SectionFlags.insert(SectionFlags.end(), std::begin(ElfMipsSectionFlags),
2643 std::end(ElfMipsSectionFlags));
2644 break;
2645 case EM_X86_64:
2646 SectionFlags.insert(SectionFlags.end(), std::begin(ElfX86_64SectionFlags),
2647 std::end(ElfX86_64SectionFlags));
2648 break;
2649 default:
2650 // Nothing to do.
2651 break;
2652 }
2653 W.printFlags("Flags", Sec.sh_flags, makeArrayRef(SectionFlags));
2654 W.printHex("Address", Sec.sh_addr);
2655 W.printHex("Offset", Sec.sh_offset);
2656 W.printNumber("Size", Sec.sh_size);
2657 W.printNumber("Link", Sec.sh_link);
2658 W.printNumber("Info", Sec.sh_info);
2659 W.printNumber("AddressAlignment", Sec.sh_addralign);
2660 W.printNumber("EntrySize", Sec.sh_entsize);
2661
2662 if (opts::SectionRelocations) {
2663 ListScope D(W, "Relocations");
2664 printRelocations(&Sec, Obj);
2665 }
2666
2667 if (opts::SectionSymbols) {
2668 ListScope D(W, "Symbols");
2669 const Elf_Shdr *Symtab = this->dumper()->getDotSymtabSec();
2670 StringRef StrTable = unwrapOrError(Obj->getStringTableForSymtab(*Symtab));
2671
2672 for (const Elf_Sym &Sym : Obj->symbols(Symtab)) {
2673 const Elf_Shdr *SymSec = unwrapOrError(
2674 Obj->getSection(&Sym, Symtab, this->dumper()->getShndxTable()));
2675 if (SymSec == &Sec)
2676 printSymbol(Obj, &Sym, Obj->symbol_begin(Symtab), StrTable, false);
2677 }
2678 }
2679
2680 if (opts::SectionData && Sec.sh_type != ELF::SHT_NOBITS) {
2681 ArrayRef Data = unwrapOrError(Obj->getSectionContents(&Sec));
2682 W.printBinaryBlock("SectionData",
2683 StringRef((const char *)Data.data(), Data.size()));
2684 }
2685 }
2686 }
2687
2688 template
2689 void LLVMStyle::printSymbol(const ELFO *Obj, const Elf_Sym *Symbol,
2690 const Elf_Sym *First, StringRef StrTable,
2691 bool IsDynamic) {
2692 unsigned SectionIndex = 0;
2693 StringRef SectionName;
2694 getSectionNameIndex(*Obj, Symbol, First, this->dumper()->getShndxTable(),
2695 SectionName, SectionIndex);
2696 std::string FullSymbolName =
2697 this->dumper()->getFullSymbolName(Symbol, StrTable, IsDynamic);
2698 unsigned char SymbolType = Symbol->getType();
2699
2700 DictScope D(W, "Symbol");
2701 W.printNumber("Name", FullSymbolName, Symbol->st_name);
2702 W.printHex("Value", Symbol->st_value);
2703 W.printNumber("Size", Symbol->st_size);
2704 W.printEnum("Binding", Symbol->getBinding(), makeArrayRef(ElfSymbolBindings));
2705 if (Obj->getHeader()->e_machine == ELF::EM_AMDGPU &&
2706 SymbolType >= ELF::STT_LOOS && SymbolType < ELF::STT_HIOS)
2707 W.printEnum("Type", SymbolType, makeArrayRef(AMDGPUSymbolTypes));
2708 else
2709 W.printEnum("Type", SymbolType, makeArrayRef(ElfSymbolTypes));
2710 W.printNumber("Other", Symbol->st_other);
2711 W.printHex("Section", SectionName, SectionIndex);
2712 }
2713
2714 template
2715 void LLVMStyle::printSymbolsHelper(const ELFO *Obj, bool IsDynamic) {
2716 StringRef StrTable;
2717 typename ELFO::Elf_Sym_Range Syms(nullptr, nullptr);
2718 if (IsDynamic) {
2719 StrTable = this->dumper()->getDynamicStringTable();
2720 Syms = this->dumper()->dynamic_symbols();
2721 } else {
2722 if (!this->dumper()->getDotSymtabSec())
2723 return;
2724 const auto DotSymtabSec = this->dumper()->getDotSymtabSec();
2725 StrTable = unwrapOrError(Obj->getStringTableForSymtab(*DotSymtabSec));
2726 Syms = Obj->symbols(DotSymtabSec);
2727 }
2728 for (const Elf_Sym &Sym : Syms)
2729 printSymbol(Obj, &Sym, Syms.begin(), StrTable, IsDynamic);
2730 }
2731
2732 template void LLVMStyle::printSymbols(const ELFO *Obj) {
2733 ListScope Group(W, "Symbols");
2734 printSymbolsHelper(Obj, false);
2735 }
2736
2737 template
2738 void LLVMStyle::printDynamicSymbols(const ELFO *Obj) {
2739 ListScope Group(W, "DynamicSymbols");
2740 printSymbolsHelper(Obj, true);
2741 }
2742
2743 template
2744 void LLVMStyle::printDynamicRelocations(const ELFO *Obj) {
2745 const DynRegionInfo &DynRelRegion = this->dumper()->getDynRelRegion();
2746 const DynRegionInfo &DynRelaRegion = this->dumper()->getDynRelaRegion();
2747 const DynRegionInfo &DynPLTRelRegion = this->dumper()->getDynPLTRelRegion();
2748 if (DynRelRegion.Size && DynRelaRegion.Size)
2749 report_fatal_error("There are both REL and RELA dynamic relocations");
2750 W.startLine() << "Dynamic Relocations {\n";
2751 W.indent();
2752 if (DynRelaRegion.Size > 0)
2753 for (const Elf_Rela &Rela : this->dumper()->dyn_relas())
2754 printDynamicRelocation(Obj, Rela);
2755 else
2756 for (const Elf_Rel &Rel : this->dumper()->dyn_rels()) {
2757 Elf_Rela Rela;
2758 Rela.r_offset = Rel.r_offset;
2759 Rela.r_info = Rel.r_info;
2760 Rela.r_addend = 0;
2761 printDynamicRelocation(Obj, Rela);
2762 }
2763 if (DynPLTRelRegion.EntSize == sizeof(Elf_Rela))
2764 for (const Elf_Rela &Rela : DynPLTRelRegion.getAsRange())
2765 printDynamicRelocation(Obj, Rela);
2766 else
2767 for (const Elf_Rel &Rel : DynPLTRelRegion.getAsRange()) {
2768 Elf_Rela Rela;
2769 Rela.r_offset = Rel.r_offset;
2770 Rela.r_info = Rel.r_info;
2771 Rela.r_addend = 0;
2772 printDynamicRelocation(Obj, Rela);
2773 }
2774 W.unindent();
2775 W.startLine() << "}\n";
2776 }
2777
2778 template
2779 void LLVMStyle::printDynamicRelocation(const ELFO *Obj, Elf_Rela Rel) {
2780 SmallString<32> RelocName;
2781 Obj->getRelocationTypeName(Rel.getType(Obj->isMips64EL()), RelocName);
2782 StringRef SymbolName;
2783 uint32_t SymIndex = Rel.getSymbol(Obj->isMips64EL());
2784 const Elf_Sym *Sym = this->dumper()->dynamic_symbols().begin() + SymIndex;
2785 SymbolName =
2786 unwrapOrError(Sym->getName(this->dumper()->getDynamicStringTable()));
2787 if (opts::ExpandRelocs) {
2788 DictScope Group(W, "Relocation");
2789 W.printHex("Offset", Rel.r_offset);
2790 W.printNumber("Type", RelocName, (int)Rel.getType(Obj->isMips64EL()));
2791 W.printString("Symbol", SymbolName.size() > 0 ? SymbolName : "-");
2792 W.printHex("Addend", Rel.r_addend);
2793 } else {
2794 raw_ostream &OS = W.startLine();
2795 OS << W.hex(Rel.r_offset) << " " << RelocName << " "
2796 << (SymbolName.size() > 0 ? SymbolName : "-") << " "
2797 << W.hex(Rel.r_addend) << "\n";
2798 }
2799 }
2222 std::string number;
2323 llvm::raw_string_ostream stream(number);
2424 stream << format_decimal(Value, 1);
25 return stream.str();
26 }
27
28 const std::string to_hexString(const format_object_base &obj) {
29 std::string number;
30 llvm::raw_string_ostream stream(number);
31 stream << obj;
3225 return stream.str();
3326 }
3427
6161 const std::string to_hexString(uint64_t Value, bool UpperCase = true);
6262 const std::string to_string(uint64_t Value);
6363
64 const std::string to_hexString(const format_object_base &obj);
6564 class StreamWriter {
6665 public:
6766 StreamWriter(raw_ostream &OS)