llvm.org GIT mirror llvm / a7904d3
[llvm-readobj] Impl GNU style printing of sections and relocations Differential Revision: http://reviews.llvm.org/D17523 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@263561 91177308-0d34-0410-b5e6-96231b3b80d8 Hemant Kulkarni 4 years ago
5 changed file(s) with 714 addition(s) and 274 deletion(s). Raw diff Collapse all Expand all
0 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 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)
158158
159159 void parseDynamicTable(ArrayRef LoadSegments);
160160
161 void printSymbolsHelper(bool IsDynamic);
162161 void printSymbol(const Elf_Sym *Symbol, const Elf_Sym *FirstSym,
163162 StringRef StrTable, bool IsDynamic);
164163
165 void printDynamicRelocation(Elf_Rela Rel);
166 void printRelocations(const Elf_Shdr *Sec);
167 void printRelocation(Elf_Rela Rel, const Elf_Shdr *SymTab);
168164 void printValue(uint64_t Type, uint64_t Value);
169165
170 Elf_Rel_Range dyn_rels() const;
171 Elf_Rela_Range dyn_relas() const;
172166 StringRef getDynamicString(uint64_t Offset) const;
173167 StringRef getSymbolVersion(StringRef StrTab, const Elf_Sym *symb,
174 bool &IsDefault);
175 void LoadVersionMap();
168 bool &IsDefault) const;
169 void LoadVersionMap() const;
176170 void LoadVersionNeeds(const Elf_Shdr *ec) const;
177171 void LoadVersionDefs(const Elf_Shdr *sec) const;
178172
225219 return DynSymRegion.getAsRange();
226220 }
227221
222 Elf_Rel_Range dyn_rels() const;
223 Elf_Rela_Range dyn_relas() const;
228224 std::string getFullSymbolName(const Elf_Sym *Symbol, StringRef StrTable,
229 bool IsDynamic);
225 bool IsDynamic) const;
230226 const Elf_Shdr *getDotSymtabSec() const { return DotSymtabSec; }
231 ArrayRef getShndxTable() { return ShndxTable; }
227 ArrayRef getShndxTable() const { return ShndxTable; }
232228 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; }
233232 };
234233
235234 template class DumpStyle {
236235 public:
237236 virtual void printFileHeaders(const ELFFile *Obj) = 0;
238237 virtual ~DumpStyle() { }
238 DumpStyle(ELFDumper *Dumper) : Dumper(Dumper) {}
239239 virtual void printGroupSections(const ELFFile *Obj) = 0;
240 virtual void printRelocations(const ELFFile *Obj) = 0;
241 virtual void printSections(const ELFFile *Obj) = 0;
242 virtual void printSymbols(const ELFFile *Obj) = 0;
243 virtual void printDynamicSymbols(const ELFFile *Obj) = 0;
244 virtual void printDynamicRelocations(const ELFFile *Obj) = 0;
245 const ELFDumper *dumper() const { return Dumper; }
246
247 private:
248 const ELFDumper *Dumper;
240249 };
241250
242251 template class GNUStyle : public DumpStyle {
243252 formatted_raw_ostream OS;
244
245253 public:
246254 TYPEDEF_ELF_TYPES(ELFT)
247 GNUStyle(StreamWriter &W) : OS(W.getOStream()) {}
248 void printFileHeaders(const ELFFile *Obj) override;
255 GNUStyle(StreamWriter &W, ELFDumper *Dumper)
256 : DumpStyle(Dumper), OS(W.getOStream()) {}
257 void printFileHeaders(const ELFO *Obj) override;
249258 void printGroupSections(const ELFFile *Obj) override;
259 void printRelocations(const ELFO *Obj) override;
260 void printSections(const ELFO *Obj) override;
261 void printSymbols(const ELFO *Obj) override;
262 void printDynamicSymbols(const ELFO *Obj) override;
263 void printDynamicRelocations(const ELFO *Obj) override;
250264
251265 private:
266 struct Field {
267 StringRef Str;
268 unsigned Column;
269 Field(StringRef S, unsigned Col) : Str(S), Column(Col) {}
270 Field(unsigned Col) : Str(""), Column(Col) {}
271 };
272
252273 template
253274 std::string printEnum(T Value, ArrayRef> EnumValues) {
254275 for (const auto &EnumItem : EnumValues)
255276 if (EnumItem.Value == Value)
256277 return EnumItem.AltName;
257 return to_hexString(Value);
258 }
278 return to_hexString(Value, false);
279 }
280 formatted_raw_ostream &printField(struct Field F) {
281 if (F.Column != 0)
282 OS.PadToColumn(F.Column);
283 OS << F.Str;
284 OS.flush();
285 return OS;
286 }
287 void printRelocation(const ELFO *Obj, const Elf_Shdr *SymTab,
288 const Elf_Rela &R, bool IsRela);
259289 };
260290
261291 template class LLVMStyle : public DumpStyle {
262292 public:
263293 TYPEDEF_ELF_TYPES(ELFT)
264 LLVMStyle(StreamWriter &W) : W(W) {}
265 void printFileHeaders(const ELFFile *Obj) override;
294 LLVMStyle(StreamWriter &W, ELFDumper *Dumper)
295 : DumpStyle(Dumper), W(W) {}
296
297 void printFileHeaders(const ELFO *Obj) override;
266298 void printGroupSections(const ELFFile *Obj) override;
299 void printRelocations(const ELFO *Obj) override;
300 void printRelocations(const Elf_Shdr *Sec, const ELFO *Obj);
301 void printSections(const ELFO *Obj) override;
302 void printSymbolsHelper(const ELFO *Obj, bool IsDynamic);
303 void printSymbols(const ELFO *Obj) override;
304 void printDynamicSymbols(const ELFO *Obj) override;
305 void printDynamicRelocations(const ELFO *Obj) override;
267306
268307 private:
308 void printRelocation(const ELFO *Obj, Elf_Rela Rel, const Elf_Shdr *SymTab);
309 void printSymbol(const ELFO *Obj, const Elf_Sym *Symbol, const Elf_Sym *First,
310 StringRef StrTable, bool IsDynamic);
311 void printDynamicRelocation(const ELFO *Obj, Elf_Rela Rel);
312
269313 StreamWriter &W;
270314 };
271315
364408 }
365409 }
366410
367 template void ELFDumper::LoadVersionMap() {
411 template void ELFDumper::LoadVersionMap() const {
368412 // If there is no dynamic symtab or version table, there is nothing to do.
369413 if (!DynSymRegion.Addr || !dot_gnu_version_sec)
370414 return;
473517 template
474518 StringRef ELFDumper::getSymbolVersion(StringRef StrTab,
475519 const Elf_Sym *symb,
476 bool &IsDefault) {
520 bool &IsDefault) const {
477521 // This is a dynamic symbol. Look in the GNU symbol version table.
478522 if (!dot_gnu_version_sec) {
479523 // No version table.
522566 template
523567 std::string ELFDumper::getFullSymbolName(const Elf_Sym *Symbol,
524568 StringRef StrTable,
525 bool IsDynamic) {
569 bool IsDynamic) const {
526570 StringRef SymbolName = unwrapOrError(Symbol->getName(StrTable));
527571 if (!IsDynamic)
528572 return SymbolName;
910954 LLVM_READOBJ_ENUM_ENT(ELF, SHF_X86_64_LARGE)
911955 };
912956
957 static std::string getGNUFlags(uint64_t Flags) {
958 std::string Str;
959 for (auto Entry : ElfSectionFlags) {
960 uint64_t Flag = Entry.Value & Flags;
961 Flags &= ~Entry.Value;
962 switch (Flag) {
963 case ELF::SHF_WRITE:
964 case ELF::SHF_ALLOC:
965 case ELF::SHF_EXECINSTR:
966 case ELF::SHF_MERGE:
967 case ELF::SHF_STRINGS:
968 case ELF::SHF_INFO_LINK:
969 case ELF::SHF_LINK_ORDER:
970 case ELF::SHF_OS_NONCONFORMING:
971 case ELF::SHF_GROUP:
972 case ELF::SHF_TLS:
973 case ELF::SHF_EXCLUDE:
974 Str += Entry.AltName;
975 break;
976 default:
977 if (Flags & ELF::SHF_MASKOS)
978 Str += "o";
979 else if (Flags & ELF::SHF_MASKPROC)
980 Str += "p";
981 else if (Flag)
982 Str += "x";
983 }
984 }
985 return Str;
986 }
987
913988 static const char *getElfSegmentType(unsigned Arch, unsigned Type) {
914989 // Check potentially overlapped processor-specific
915990 // program header type.
10571132 parseDynamicTable(LoadSegments);
10581133
10591134 if (opts::Output == opts::GNU)
1060 ELFDumperStyle.reset(new GNUStyle(Writer));
1135 ELFDumperStyle.reset(new GNUStyle(Writer, this));
10611136 else
1062 ELFDumperStyle.reset(new LLVMStyle(Writer));
1137 ELFDumperStyle.reset(new LLVMStyle(Writer, this));
10631138 }
10641139
10651140 template
11621237
11631238 template
11641239 void ELFDumper::printSections() {
1165 ListScope SectionsD(W, "Sections");
1166
1167 int SectionIndex = -1;
1168 for (const Elf_Shdr &Sec : Obj->sections()) {
1169 ++SectionIndex;
1170
1171 StringRef Name = unwrapOrError(Obj->getSectionName(&Sec));
1172
1173 DictScope SectionD(W, "Section");
1174 W.printNumber("Index", SectionIndex);
1175 W.printNumber("Name", Name, Sec.sh_name);
1176 W.printHex("Type",
1177 getElfSectionType(Obj->getHeader()->e_machine, Sec.sh_type),
1178 Sec.sh_type);
1179 std::vector> SectionFlags(std::begin(ElfSectionFlags),
1180 std::end(ElfSectionFlags));
1181 switch (Obj->getHeader()->e_machine) {
1182 case EM_AMDGPU:
1183 SectionFlags.insert(SectionFlags.end(), std::begin(ElfAMDGPUSectionFlags),
1184 std::end(ElfAMDGPUSectionFlags));
1185 break;
1186 case EM_HEXAGON:
1187 SectionFlags.insert(SectionFlags.end(),
1188 std::begin(ElfHexagonSectionFlags),
1189 std::end(ElfHexagonSectionFlags));
1190 break;
1191 case EM_MIPS:
1192 SectionFlags.insert(SectionFlags.end(), std::begin(ElfMipsSectionFlags),
1193 std::end(ElfMipsSectionFlags));
1194 break;
1195 case EM_X86_64:
1196 SectionFlags.insert(SectionFlags.end(), std::begin(ElfX86_64SectionFlags),
1197 std::end(ElfX86_64SectionFlags));
1198 break;
1199 default:
1200 // Nothing to do.
1201 break;
1202 }
1203 W.printFlags("Flags", Sec.sh_flags, makeArrayRef(SectionFlags));
1204 W.printHex("Address", Sec.sh_addr);
1205 W.printHex("Offset", Sec.sh_offset);
1206 W.printNumber("Size", Sec.sh_size);
1207 W.printNumber("Link", Sec.sh_link);
1208 W.printNumber("Info", Sec.sh_info);
1209 W.printNumber("AddressAlignment", Sec.sh_addralign);
1210 W.printNumber("EntrySize", Sec.sh_entsize);
1211
1212 if (opts::SectionRelocations) {
1213 ListScope D(W, "Relocations");
1214 printRelocations(&Sec);
1215 }
1216
1217 if (opts::SectionSymbols) {
1218 ListScope D(W, "Symbols");
1219 const Elf_Shdr *Symtab = DotSymtabSec;
1220 StringRef StrTable = unwrapOrError(Obj->getStringTableForSymtab(*Symtab));
1221
1222 for (const Elf_Sym &Sym : Obj->symbols(Symtab)) {
1223 const Elf_Shdr *SymSec =
1224 unwrapOrError(Obj->getSection(&Sym, Symtab, ShndxTable));
1225 if (SymSec == &Sec)
1226 printSymbol(&Sym, Obj->symbol_begin(Symtab), StrTable, false);
1227 }
1228 }
1229
1230 if (opts::SectionData && Sec.sh_type != ELF::SHT_NOBITS) {
1231 ArrayRef Data = unwrapOrError(Obj->getSectionContents(&Sec));
1232 W.printBinaryBlock("SectionData",
1233 StringRef((const char *)Data.data(), Data.size()));
1234 }
1235 }
1240 ELFDumperStyle->printSections(Obj);
12361241 }
12371242
12381243 template
12391244 void ELFDumper::printRelocations() {
1240 ListScope D(W, "Relocations");
1241
1242 int SectionNumber = -1;
1243 for (const Elf_Shdr &Sec : Obj->sections()) {
1244 ++SectionNumber;
1245
1246 if (Sec.sh_type != ELF::SHT_REL && Sec.sh_type != ELF::SHT_RELA)
1247 continue;
1248
1249 StringRef Name = unwrapOrError(Obj->getSectionName(&Sec));
1250
1251 W.startLine() << "Section (" << SectionNumber << ") " << Name << " {\n";
1252 W.indent();
1253
1254 printRelocations(&Sec);
1255
1256 W.unindent();
1257 W.startLine() << "}\n";
1258 }
1245 ELFDumperStyle->printRelocations(Obj);
12591246 }
12601247
12611248 template void ELFDumper::printDynamicRelocations() {
1262 if (DynRelRegion.Size && DynRelaRegion.Size)
1263 report_fatal_error("There are both REL and RELA dynamic relocations");
1264 W.startLine() << "Dynamic Relocations {\n";
1265 W.indent();
1266 if (DynRelaRegion.Size > 0)
1267 for (const Elf_Rela &Rela : dyn_relas())
1268 printDynamicRelocation(Rela);
1269 else
1270 for (const Elf_Rel &Rel : dyn_rels()) {
1271 Elf_Rela Rela;
1272 Rela.r_offset = Rel.r_offset;
1273 Rela.r_info = Rel.r_info;
1274 Rela.r_addend = 0;
1275 printDynamicRelocation(Rela);
1276 }
1277 if (DynPLTRelRegion.EntSize == sizeof(Elf_Rela))
1278 for (const Elf_Rela &Rela : DynPLTRelRegion.getAsRange())
1279 printDynamicRelocation(Rela);
1280 else
1281 for (const Elf_Rel &Rel : DynPLTRelRegion.getAsRange()) {
1282 Elf_Rela Rela;
1283 Rela.r_offset = Rel.r_offset;
1284 Rela.r_info = Rel.r_info;
1285 Rela.r_addend = 0;
1286 printDynamicRelocation(Rela);
1287 }
1288 W.unindent();
1289 W.startLine() << "}\n";
1290 }
1291
1292 template
1293 void ELFDumper::printRelocations(const Elf_Shdr *Sec) {
1294 const Elf_Shdr *SymTab = unwrapOrError(Obj->getSection(Sec->sh_link));
1295
1296 switch (Sec->sh_type) {
1297 case ELF::SHT_REL:
1298 for (const Elf_Rel &R : Obj->rels(Sec)) {
1299 Elf_Rela Rela;
1300 Rela.r_offset = R.r_offset;
1301 Rela.r_info = R.r_info;
1302 Rela.r_addend = 0;
1303 printRelocation(Rela, SymTab);
1304 }
1305 break;
1306 case ELF::SHT_RELA:
1307 for (const Elf_Rela &R : Obj->relas(Sec))
1308 printRelocation(R, SymTab);
1309 break;
1310 }
1311 }
1312
1313 template
1314 void ELFDumper::printRelocation(Elf_Rela Rel, const Elf_Shdr *SymTab) {
1315 SmallString<32> RelocName;
1316 Obj->getRelocationTypeName(Rel.getType(Obj->isMips64EL()), RelocName);
1317 StringRef TargetName;
1318 const Elf_Sym *Sym = Obj->getRelocationSymbol(&Rel, SymTab);
1319 if (Sym && Sym->getType() == ELF::STT_SECTION) {
1320 const Elf_Shdr *Sec =
1321 unwrapOrError(Obj->getSection(Sym, SymTab, ShndxTable));
1322 TargetName = unwrapOrError(Obj->getSectionName(Sec));
1323 } else if (Sym) {
1324 StringRef StrTable = unwrapOrError(Obj->getStringTableForSymtab(*SymTab));
1325 TargetName = unwrapOrError(Sym->getName(StrTable));
1326 }
1327
1328 if (opts::ExpandRelocs) {
1329 DictScope Group(W, "Relocation");
1330 W.printHex("Offset", Rel.r_offset);
1331 W.printNumber("Type", RelocName, (int)Rel.getType(Obj->isMips64EL()));
1332 W.printNumber("Symbol", TargetName.size() > 0 ? TargetName : "-",
1333 Rel.getSymbol(Obj->isMips64EL()));
1334 W.printHex("Addend", Rel.r_addend);
1335 } else {
1336 raw_ostream& OS = W.startLine();
1337 OS << W.hex(Rel.r_offset) << " " << RelocName << " "
1338 << (TargetName.size() > 0 ? TargetName : "-") << " "
1339 << W.hex(Rel.r_addend) << "\n";
1340 }
1341 }
1342
1343 template
1344 void ELFDumper::printDynamicRelocation(Elf_Rela Rel) {
1345 SmallString<32> RelocName;
1346 Obj->getRelocationTypeName(Rel.getType(Obj->isMips64EL()), RelocName);
1347 StringRef SymbolName;
1348 uint32_t SymIndex = Rel.getSymbol(Obj->isMips64EL());
1349 const Elf_Sym *Sym = dynamic_symbols().begin() + SymIndex;
1350 SymbolName = unwrapOrError(Sym->getName(DynamicStringTable));
1351 if (opts::ExpandRelocs) {
1352 DictScope Group(W, "Relocation");
1353 W.printHex("Offset", Rel.r_offset);
1354 W.printNumber("Type", RelocName, (int)Rel.getType(Obj->isMips64EL()));
1355 W.printString("Symbol", SymbolName.size() > 0 ? SymbolName : "-");
1356 W.printHex("Addend", Rel.r_addend);
1357 } else {
1358 raw_ostream &OS = W.startLine();
1359 OS << W.hex(Rel.r_offset) << " " << RelocName << " "
1360 << (SymbolName.size() > 0 ? SymbolName : "-") << " "
1361 << W.hex(Rel.r_addend) << "\n";
1362 }
1363 }
1364
1365 template
1366 void ELFDumper::printSymbolsHelper(bool IsDynamic) {
1367 StringRef StrTable;
1368 Elf_Sym_Range Syms(nullptr, nullptr);
1369
1370 if (IsDynamic) {
1371 StrTable = DynamicStringTable;
1372 Syms = dynamic_symbols();
1373 } else {
1374 if (!DotSymtabSec)
1375 return;
1376 StrTable = unwrapOrError(Obj->getStringTableForSymtab(*DotSymtabSec));
1377 Syms = Obj->symbols(DotSymtabSec);
1378 }
1379 for (const Elf_Sym &Sym : Syms)
1380 printSymbol(&Sym, Syms.begin(), StrTable, IsDynamic);
1381 }
1249 ELFDumperStyle->printDynamicRelocations(Obj);
1250 }
1251
13821252
13831253 template
13841254 void ELFDumper::printSymbols() {
1385 ListScope Group(W, "Symbols");
1386 printSymbolsHelper(false);
1255 ELFDumperStyle->printSymbols(Obj);
13871256 }
13881257
13891258 template
13901259 void ELFDumper::printDynamicSymbols() {
1391 ListScope Group(W, "DynamicSymbols");
1392 printSymbolsHelper(true);
1393 }
1394
1395 template
1396 void ELFDumper::printSymbol(const Elf_Sym *Symbol,
1397 const Elf_Sym *FirstSym, StringRef StrTable,
1398 bool IsDynamic) {
1399 unsigned SectionIndex = 0;
1400 StringRef SectionName;
1401 getSectionNameIndex(*Obj, Symbol, FirstSym, ShndxTable, SectionName,
1402 SectionIndex);
1403 std::string FullSymbolName = getFullSymbolName(Symbol, StrTable, IsDynamic);
1404 unsigned char SymbolType = Symbol->getType();
1405
1406 DictScope D(W, "Symbol");
1407 W.printNumber("Name", FullSymbolName, Symbol->st_name);
1408 W.printHex ("Value", Symbol->st_value);
1409 W.printNumber("Size", Symbol->st_size);
1410 W.printEnum ("Binding", Symbol->getBinding(),
1411 makeArrayRef(ElfSymbolBindings));
1412 if (Obj->getHeader()->e_machine == ELF::EM_AMDGPU &&
1413 SymbolType >= ELF::STT_LOOS && SymbolType < ELF::STT_HIOS)
1414 W.printEnum ("Type", SymbolType, makeArrayRef(AMDGPUSymbolTypes));
1415 else
1416 W.printEnum ("Type", SymbolType, makeArrayRef(ElfSymbolTypes));
1417 W.printNumber("Other", Symbol->st_other);
1418 W.printHex("Section", SectionName, SectionIndex);
1419 }
1260 ELFDumperStyle->printDynamicSymbols(Obj);
1261 }
1262
14201263
14211264 #define LLVM_READOBJ_TYPE_CASE(name) \
14221265 case DT_##name: return #name
22792122 OS.flush();
22802123 }
22812124
2282 template
2283 void GNUStyle::printFileHeaders(const ELFFile *Obj) {
2125 template void GNUStyle::printFileHeaders(const ELFO *Obj) {
22842126 const Elf_Ehdr *e = Obj->getHeader();
22852127 OS << "ELF Header:\n";
22862128 OS << " Magic: ";
23642206 }
23652207
23662208 template
2367 void LLVMStyle::printFileHeaders(const ELFFile *Obj) {
2209 void GNUStyle::printRelocation(const ELFO *Obj, const Elf_Shdr *SymTab,
2210 const Elf_Rela &R, bool IsRela) {
2211 std::string Offset, Info, Addend = "", Value;
2212 SmallString<32> RelocName;
2213 StringRef StrTable = unwrapOrError(Obj->getStringTableForSymtab(*SymTab));
2214 StringRef TargetName;
2215 const Elf_Sym *Sym = nullptr;
2216 unsigned Bias;
2217 unsigned Width;
2218
2219 if (ELFT::Is64Bits) {
2220 Bias = 8;
2221 Width = 16;
2222 } else {
2223 Bias = 0;
2224 Width = 8;
2225 }
2226
2227 // First two fields are bit width dependent. The rest of them are after are
2228 // fixed width.
2229 Field Fields[5] = {0, 10 + Bias, 19 + 2 * Bias, 42 + 2 * Bias, 53 + 2 * Bias};
2230 Obj->getRelocationTypeName(R.getType(Obj->isMips64EL()), RelocName);
2231 Sym = Obj->getRelocationSymbol(&R, SymTab);
2232 if (Sym && Sym->getType() == ELF::STT_SECTION) {
2233 const Elf_Shdr *Sec = unwrapOrError(
2234 Obj->getSection(Sym, SymTab, this->dumper()->getShndxTable()));
2235 TargetName = unwrapOrError(Obj->getSectionName(Sec));
2236 } else if (Sym) {
2237 TargetName = unwrapOrError(Sym->getName(StrTable));
2238 }
2239
2240 if (Sym && IsRela) {
2241 if (R.r_addend < 0)
2242 Addend = " - ";
2243 else
2244 Addend = " + ";
2245 }
2246
2247 Offset = to_string(format_hex_no_prefix(R.r_offset, Width));
2248 Info = to_string(format_hex_no_prefix(R.r_info, Width));
2249
2250 int64_t RelAddend = R.r_addend;
2251 if (IsRela)
2252 Addend += to_hexString(std::abs(RelAddend), false);
2253
2254 if (Sym)
2255 Value = to_string(format_hex_no_prefix(Sym->getValue(), Width));
2256
2257 Fields[0].Str = Offset;
2258 Fields[1].Str = Info;
2259 Fields[2].Str = RelocName;
2260 Fields[3].Str = Value;
2261 Fields[4].Str = TargetName;
2262 for (auto &field : Fields)
2263 printField(field);
2264 if (IsRela)
2265 OS << Addend;
2266 OS << "\n";
2267 }
2268
2269 template void GNUStyle::printRelocations(const ELFO *Obj) {
2270 bool HasRelocSections = false;
2271 for (const Elf_Shdr &Sec : Obj->sections()) {
2272 if (Sec.sh_type != ELF::SHT_REL && Sec.sh_type != ELF::SHT_RELA)
2273 continue;
2274 HasRelocSections = true;
2275 StringRef Name = unwrapOrError(Obj->getSectionName(&Sec));
2276 unsigned Entries = Sec.getEntityCount();
2277 uintX_t Offset = Sec.sh_offset;
2278 OS << "\nRelocation section '" << Name << "' at offset 0x"
2279 << to_hexString(Offset, false) << " contains " << Entries
2280 << " entries:\n";
2281 if (ELFT::Is64Bits)
2282 OS << " Offset Info Type"
2283 << " Symbol's Value Symbol's Name";
2284 else
2285 OS << " Offset Info Type Sym. Value "
2286 << "Symbol's Name";
2287 OS << ((Sec.sh_type == ELF::SHT_RELA) ? " + Addend" : "") << "\n";
2288
2289 const Elf_Shdr *SymTab = unwrapOrError(Obj->getSection(Sec.sh_link));
2290 if (Sec.sh_type == ELF::SHT_REL) {
2291 for (const auto &R : Obj->rels(&Sec)) {
2292 Elf_Rela Rela;
2293 Rela.r_offset = R.r_offset;
2294 Rela.r_info = R.r_info;
2295 Rela.r_addend = 0;
2296 printRelocation(Obj, SymTab, Rela, false);
2297 }
2298 } else {
2299 for (const auto &R : Obj->relas(&Sec))
2300 printRelocation(Obj, SymTab, R, true);
2301 }
2302 }
2303 if (!HasRelocSections)
2304 OS << "\nThere are no relocations in this file.\n";
2305 }
2306
2307 std::string getSectionTypeString(unsigned Arch, unsigned Type) {
2308 using namespace ELF;
2309 switch (Arch) {
2310 case EM_ARM:
2311 switch (Type) {
2312 case SHT_ARM_EXIDX:
2313 return "ARM_EXIDX";
2314 case SHT_ARM_PREEMPTMAP:
2315 return "ARM_PREEMPTMAP";
2316 case SHT_ARM_ATTRIBUTES:
2317 return "ARM_ATTRIBUTES";
2318 case SHT_ARM_DEBUGOVERLAY:
2319 return "ARM_DEBUGOVERLAY";
2320 case SHT_ARM_OVERLAYSECTION:
2321 return "ARM_OVERLAYSECTION";
2322 }
2323 case EM_X86_64:
2324 switch (Type) {
2325 case SHT_X86_64_UNWIND:
2326 return "X86_64_UNWIND";
2327 }
2328 case EM_MIPS:
2329 case EM_MIPS_RS3_LE:
2330 switch (Type) {
2331 case SHT_MIPS_REGINFO:
2332 return "MIPS_REGINFO";
2333 case SHT_MIPS_OPTIONS:
2334 return "MIPS_OPTIONS";
2335 case SHT_MIPS_ABIFLAGS:
2336 return "MIPS_ABIFLAGS";
2337 }
2338 }
2339 switch (Type) {
2340 case SHT_NULL:
2341 return "NULL";
2342 case SHT_PROGBITS:
2343 return "PROGBITS";
2344 case SHT_SYMTAB:
2345 return "SYMTAB";
2346 case SHT_STRTAB:
2347 return "STRTAB";
2348 case SHT_RELA:
2349 return "RELA";
2350 case SHT_HASH:
2351 return "HASH";
2352 case SHT_DYNAMIC:
2353 return "DYNAMIC";
2354 case SHT_NOTE:
2355 return "NOTE";
2356 case SHT_NOBITS:
2357 return "NOBITS";
2358 case SHT_REL:
2359 return "REL";
2360 case SHT_SHLIB:
2361 return "SHLIB";
2362 case SHT_DYNSYM:
2363 return "DYNSYM";
2364 case SHT_INIT_ARRAY:
2365 return "INIT_ARRAY";
2366 case SHT_FINI_ARRAY:
2367 return "FINI_ARRAY";
2368 case SHT_PREINIT_ARRAY:
2369 return "PREINIT_ARRAY";
2370 case SHT_GROUP:
2371 return "GROUP";
2372 case SHT_SYMTAB_SHNDX:
2373 return "SYMTAB SECTION INDICES";
2374 // FIXME: Parse processor specific GNU attributes
2375 case SHT_GNU_ATTRIBUTES:
2376 return "ATTRIBUTES";
2377 case SHT_GNU_HASH:
2378 return "GNU_HASH";
2379 case SHT_GNU_verdef:
2380 return "VERDEF";
2381 case SHT_GNU_verneed:
2382 return "VERNEED";
2383 case SHT_GNU_versym:
2384 return "VERSYM";
2385 default:
2386 return "";
2387 }
2388 return "";
2389 }
2390
2391 template void GNUStyle::printSections(const ELFO *Obj) {
2392 size_t SectionIndex = 0;
2393 std::string Number, Type, Size, Address, Offset, Flags, Link, Info, EntrySize,
2394 Alignment;
2395 unsigned Bias;
2396 unsigned Width;
2397
2398 if (ELFT::Is64Bits) {
2399 Bias = 0;
2400 Width = 16;
2401 } else {
2402 Bias = 8;
2403 Width = 8;
2404 }
2405 OS << "There are " << to_string(Obj->getHeader()->e_shnum)
2406 << " section headers, starting at offset "
2407 << "0x" << to_hexString(Obj->getHeader()->e_shoff, false) << ":\n\n";
2408 OS << "Section Headers:\n";
2409 Field Fields[11] = {{"[Nr]", 2},
2410 {"Name", 7},
2411 {"Type", 25},
2412 {"Address", 41},
2413 {"Off", 58 - Bias},
2414 {"Size", 65 - Bias},
2415 {"ES", 72 - Bias},
2416 {"Flg", 75 - Bias},
2417 {"Lk", 79 - Bias},
2418 {"Inf", 82 - Bias},
2419 {"Al", 86 - Bias}};
2420 for (auto &f : Fields)
2421 printField(f);
2422 OS << "\n";
2423
2424 for (const Elf_Shdr &Sec : Obj->sections()) {
2425 Number = to_string(SectionIndex);
2426 Fields[0].Str = Number;
2427 Fields[1].Str = unwrapOrError(Obj->getSectionName(&Sec));
2428 Type = getSectionTypeString(Obj->getHeader()->e_machine, Sec.sh_type);
2429 Fields[2].Str = Type;
2430 Address = to_string(format_hex_no_prefix(Sec.sh_addr, Width));
2431 Fields[3].Str = Address;
2432 Offset = to_string(format_hex_no_prefix(Sec.sh_offset, 6));
2433 Fields[4].Str = Offset;
2434 Size = to_string(format_hex_no_prefix(Sec.sh_size, 6));
2435 Fields[5].Str = Size;
2436 EntrySize = to_string(format_hex_no_prefix(Sec.sh_entsize, 2));
2437 Fields[6].Str = EntrySize;
2438 Flags = getGNUFlags(Sec.sh_flags);
2439 Fields[7].Str = Flags;
2440 Link = to_string(Sec.sh_link);
2441 Fields[8].Str = Link;
2442 Info = to_string(Sec.sh_info);
2443 Fields[9].Str = Info;
2444 Alignment = to_string(Sec.sh_addralign);
2445 Fields[10].Str = Alignment;
2446 OS.PadToColumn(Fields[0].Column);
2447 OS << "[" << right_justify(Fields[0].Str, 2) << "]";
2448 for (int i = 1; i < 7; i++)
2449 printField(Fields[i]);
2450 OS.PadToColumn(Fields[7].Column);
2451 OS << right_justify(Fields[7].Str, 3);
2452 OS.PadToColumn(Fields[8].Column);
2453 OS << right_justify(Fields[8].Str, 2);
2454 OS.PadToColumn(Fields[9].Column);
2455 OS << right_justify(Fields[9].Str, 3);
2456 OS.PadToColumn(Fields[10].Column);
2457 OS << right_justify(Fields[10].Str, 2);
2458 OS << "\n";
2459 ++SectionIndex;
2460 }
2461 OS << "Key to Flags:\n"
2462 << " W (write), A (alloc), X (execute), M (merge), S (strings), l "
2463 "(large)\n"
2464 << " I (info), L (link order), G (group), T (TLS), E (exclude),\
2465 x (unknown)\n"
2466 << " O (extra OS processing required) o (OS specific),\
2467 p (processor specific)\n";
2468 }
2469
2470 template void GNUStyle::printSymbols(const ELFO *Obj) {
2471 OS << "GNU style symbols not implemented!\n";
2472 }
2473
2474 template
2475 void GNUStyle::printDynamicSymbols(const ELFO *Obj) {
2476 OS << "GNU style dynamic symbols not implemented!\n";
2477 }
2478
2479 template
2480 void GNUStyle::printDynamicRelocations(const ELFO *Obj) {
2481 OS << "GNU style dynamic relocations not implemented!\n";
2482 }
2483
2484 template void LLVMStyle::printFileHeaders(const ELFO *Obj) {
23682485 const Elf_Ehdr *e = Obj->getHeader();
23692486 {
23702487 DictScope D(W, "ElfHeader");
24422559 if (!HasGroups)
24432560 W.startLine() << "There are no group sections in the file.\n";
24442561 }
2562
2563 template void LLVMStyle::printRelocations(const ELFO *Obj) {
2564 ListScope D(W, "Relocations");
2565
2566 int SectionNumber = -1;
2567 for (const Elf_Shdr &Sec : Obj->sections()) {
2568 ++SectionNumber;
2569
2570 if (Sec.sh_type != ELF::SHT_REL && Sec.sh_type != ELF::SHT_RELA)
2571 continue;
2572
2573 StringRef Name = unwrapOrError(Obj->getSectionName(&Sec));
2574
2575 W.startLine() << "Section (" << SectionNumber << ") " << Name << " {\n";
2576 W.indent();
2577
2578 printRelocations(&Sec, Obj);
2579
2580 W.unindent();
2581 W.startLine() << "}\n";
2582 }
2583 }
2584
2585 template
2586 void LLVMStyle::printRelocations(const Elf_Shdr *Sec, const ELFO *Obj) {
2587 const Elf_Shdr *SymTab = unwrapOrError(Obj->getSection(Sec->sh_link));
2588
2589 switch (Sec->sh_type) {
2590 case ELF::SHT_REL:
2591 for (const Elf_Rel &R : Obj->rels(Sec)) {
2592 Elf_Rela Rela;
2593 Rela.r_offset = R.r_offset;
2594 Rela.r_info = R.r_info;
2595 Rela.r_addend = 0;
2596 printRelocation(Obj, Rela, SymTab);
2597 }
2598 break;
2599 case ELF::SHT_RELA:
2600 for (const Elf_Rela &R : Obj->relas(Sec))
2601 printRelocation(Obj, R, SymTab);
2602 break;
2603 }
2604 }
2605
2606 template
2607 void LLVMStyle::printRelocation(const ELFO *Obj, Elf_Rela Rel,
2608 const Elf_Shdr *SymTab) {
2609 SmallString<32> RelocName;
2610 Obj->getRelocationTypeName(Rel.getType(Obj->isMips64EL()), RelocName);
2611 StringRef TargetName;
2612 const Elf_Sym *Sym = Obj->getRelocationSymbol(&Rel, SymTab);
2613 if (Sym && Sym->getType() == ELF::STT_SECTION) {
2614 const Elf_Shdr *Sec = unwrapOrError(
2615 Obj->getSection(Sym, SymTab, this->dumper()->getShndxTable()));
2616 TargetName = unwrapOrError(Obj->getSectionName(Sec));
2617 } else if (Sym) {
2618 StringRef StrTable = unwrapOrError(Obj->getStringTableForSymtab(*SymTab));
2619 TargetName = unwrapOrError(Sym->getName(StrTable));
2620 }
2621
2622 if (opts::ExpandRelocs) {
2623 DictScope Group(W, "Relocation");
2624 W.printHex("Offset", Rel.r_offset);
2625 W.printNumber("Type", RelocName, (int)Rel.getType(Obj->isMips64EL()));
2626 W.printNumber("Symbol", TargetName.size() > 0 ? TargetName : "-",
2627 Rel.getSymbol(Obj->isMips64EL()));
2628 W.printHex("Addend", Rel.r_addend);
2629 } else {
2630 raw_ostream &OS = W.startLine();
2631 OS << W.hex(Rel.r_offset) << " " << RelocName << " "
2632 << (TargetName.size() > 0 ? TargetName : "-") << " "
2633 << W.hex(Rel.r_addend) << "\n";
2634 }
2635 }
2636
2637 template void LLVMStyle::printSections(const ELFO *Obj) {
2638 ListScope SectionsD(W, "Sections");
2639
2640 int SectionIndex = -1;
2641 for (const Elf_Shdr &Sec : Obj->sections()) {
2642 ++SectionIndex;
2643
2644 StringRef Name = unwrapOrError(Obj->getSectionName(&Sec));
2645
2646 DictScope SectionD(W, "Section");
2647 W.printNumber("Index", SectionIndex);
2648 W.printNumber("Name", Name, Sec.sh_name);
2649 W.printHex("Type",
2650 getElfSectionType(Obj->getHeader()->e_machine, Sec.sh_type),
2651 Sec.sh_type);
2652 std::vector> SectionFlags(std::begin(ElfSectionFlags),
2653 std::end(ElfSectionFlags));
2654 switch (Obj->getHeader()->e_machine) {
2655 case EM_AMDGPU:
2656 SectionFlags.insert(SectionFlags.end(), std::begin(ElfAMDGPUSectionFlags),
2657 std::end(ElfAMDGPUSectionFlags));
2658 break;
2659 case EM_HEXAGON:
2660 SectionFlags.insert(SectionFlags.end(),
2661 std::begin(ElfHexagonSectionFlags),
2662 std::end(ElfHexagonSectionFlags));
2663 break;
2664 case EM_MIPS:
2665 SectionFlags.insert(SectionFlags.end(), std::begin(ElfMipsSectionFlags),
2666 std::end(ElfMipsSectionFlags));
2667 break;
2668 case EM_X86_64:
2669 SectionFlags.insert(SectionFlags.end(), std::begin(ElfX86_64SectionFlags),
2670 std::end(ElfX86_64SectionFlags));
2671 break;
2672 default:
2673 // Nothing to do.
2674 break;
2675 }
2676 W.printFlags("Flags", Sec.sh_flags, makeArrayRef(SectionFlags));
2677 W.printHex("Address", Sec.sh_addr);
2678 W.printHex("Offset", Sec.sh_offset);
2679 W.printNumber("Size", Sec.sh_size);
2680 W.printNumber("Link", Sec.sh_link);
2681 W.printNumber("Info", Sec.sh_info);
2682 W.printNumber("AddressAlignment", Sec.sh_addralign);
2683 W.printNumber("EntrySize", Sec.sh_entsize);
2684
2685 if (opts::SectionRelocations) {
2686 ListScope D(W, "Relocations");
2687 printRelocations(&Sec, Obj);
2688 }
2689
2690 if (opts::SectionSymbols) {
2691 ListScope D(W, "Symbols");
2692 const Elf_Shdr *Symtab = this->dumper()->getDotSymtabSec();
2693 StringRef StrTable = unwrapOrError(Obj->getStringTableForSymtab(*Symtab));
2694
2695 for (const Elf_Sym &Sym : Obj->symbols(Symtab)) {
2696 const Elf_Shdr *SymSec = unwrapOrError(
2697 Obj->getSection(&Sym, Symtab, this->dumper()->getShndxTable()));
2698 if (SymSec == &Sec)
2699 printSymbol(Obj, &Sym, Obj->symbol_begin(Symtab), StrTable, false);
2700 }
2701 }
2702
2703 if (opts::SectionData && Sec.sh_type != ELF::SHT_NOBITS) {
2704 ArrayRef Data = unwrapOrError(Obj->getSectionContents(&Sec));
2705 W.printBinaryBlock("SectionData",
2706 StringRef((const char *)Data.data(), Data.size()));
2707 }
2708 }
2709 }
2710
2711 template
2712 void LLVMStyle::printSymbol(const ELFO *Obj, const Elf_Sym *Symbol,
2713 const Elf_Sym *First, StringRef StrTable,
2714 bool IsDynamic) {
2715 unsigned SectionIndex = 0;
2716 StringRef SectionName;
2717 getSectionNameIndex(*Obj, Symbol, First, this->dumper()->getShndxTable(),
2718 SectionName, SectionIndex);
2719 std::string FullSymbolName =
2720 this->dumper()->getFullSymbolName(Symbol, StrTable, IsDynamic);
2721 unsigned char SymbolType = Symbol->getType();
2722
2723 DictScope D(W, "Symbol");
2724 W.printNumber("Name", FullSymbolName, Symbol->st_name);
2725 W.printHex("Value", Symbol->st_value);
2726 W.printNumber("Size", Symbol->st_size);
2727 W.printEnum("Binding", Symbol->getBinding(), makeArrayRef(ElfSymbolBindings));
2728 if (Obj->getHeader()->e_machine == ELF::EM_AMDGPU &&
2729 SymbolType >= ELF::STT_LOOS && SymbolType < ELF::STT_HIOS)
2730 W.printEnum("Type", SymbolType, makeArrayRef(AMDGPUSymbolTypes));
2731 else
2732 W.printEnum("Type", SymbolType, makeArrayRef(ElfSymbolTypes));
2733 W.printNumber("Other", Symbol->st_other);
2734 W.printHex("Section", SectionName, SectionIndex);
2735 }
2736
2737 template
2738 void LLVMStyle::printSymbolsHelper(const ELFO *Obj, bool IsDynamic) {
2739 StringRef StrTable;
2740 typename ELFO::Elf_Sym_Range Syms(nullptr, nullptr);
2741 if (IsDynamic) {
2742 StrTable = this->dumper()->getDynamicStringTable();
2743 Syms = this->dumper()->dynamic_symbols();
2744 } else {
2745 if (!this->dumper()->getDotSymtabSec())
2746 return;
2747 const auto DotSymtabSec = this->dumper()->getDotSymtabSec();
2748 StrTable = unwrapOrError(Obj->getStringTableForSymtab(*DotSymtabSec));
2749 Syms = Obj->symbols(DotSymtabSec);
2750 }
2751 for (const Elf_Sym &Sym : Syms)
2752 printSymbol(Obj, &Sym, Syms.begin(), StrTable, IsDynamic);
2753 }
2754
2755 template void LLVMStyle::printSymbols(const ELFO *Obj) {
2756 ListScope Group(W, "Symbols");
2757 printSymbolsHelper(Obj, false);
2758 }
2759
2760 template
2761 void LLVMStyle::printDynamicSymbols(const ELFO *Obj) {
2762 ListScope Group(W, "DynamicSymbols");
2763 printSymbolsHelper(Obj, true);
2764 }
2765
2766 template
2767 void LLVMStyle::printDynamicRelocations(const ELFO *Obj) {
2768 const DynRegionInfo &DynRelRegion = this->dumper()->getDynRelRegion();
2769 const DynRegionInfo &DynRelaRegion = this->dumper()->getDynRelaRegion();
2770 const DynRegionInfo &DynPLTRelRegion = this->dumper()->getDynPLTRelRegion();
2771 if (DynRelRegion.Size && DynRelaRegion.Size)
2772 report_fatal_error("There are both REL and RELA dynamic relocations");
2773 W.startLine() << "Dynamic Relocations {\n";
2774 W.indent();
2775 if (DynRelaRegion.Size > 0)
2776 for (const Elf_Rela &Rela : this->dumper()->dyn_relas())
2777 printDynamicRelocation(Obj, Rela);
2778 else
2779 for (const Elf_Rel &Rel : this->dumper()->dyn_rels()) {
2780 Elf_Rela Rela;
2781 Rela.r_offset = Rel.r_offset;
2782 Rela.r_info = Rel.r_info;
2783 Rela.r_addend = 0;
2784 printDynamicRelocation(Obj, Rela);
2785 }
2786 if (DynPLTRelRegion.EntSize == sizeof(Elf_Rela))
2787 for (const Elf_Rela &Rela : DynPLTRelRegion.getAsRange())
2788 printDynamicRelocation(Obj, Rela);
2789 else
2790 for (const Elf_Rel &Rel : DynPLTRelRegion.getAsRange()) {
2791 Elf_Rela Rela;
2792 Rela.r_offset = Rel.r_offset;
2793 Rela.r_info = Rel.r_info;
2794 Rela.r_addend = 0;
2795 printDynamicRelocation(Obj, Rela);
2796 }
2797 W.unindent();
2798 W.startLine() << "}\n";
2799 }
2800
2801 template
2802 void LLVMStyle::printDynamicRelocation(const ELFO *Obj, Elf_Rela Rel) {
2803 SmallString<32> RelocName;
2804 Obj->getRelocationTypeName(Rel.getType(Obj->isMips64EL()), RelocName);
2805 StringRef SymbolName;
2806 uint32_t SymIndex = Rel.getSymbol(Obj->isMips64EL());
2807 const Elf_Sym *Sym = this->dumper()->dynamic_symbols().begin() + SymIndex;
2808 SymbolName =
2809 unwrapOrError(Sym->getName(this->dumper()->getDynamicStringTable()));
2810 if (opts::ExpandRelocs) {
2811 DictScope Group(W, "Relocation");
2812 W.printHex("Offset", Rel.r_offset);
2813 W.printNumber("Type", RelocName, (int)Rel.getType(Obj->isMips64EL()));
2814 W.printString("Symbol", SymbolName.size() > 0 ? SymbolName : "-");
2815 W.printHex("Addend", Rel.r_addend);
2816 } else {
2817 raw_ostream &OS = W.startLine();
2818 OS << W.hex(Rel.r_offset) << " " << RelocName << " "
2819 << (SymbolName.size() > 0 ? SymbolName : "-") << " "
2820 << W.hex(Rel.r_addend) << "\n";
2821 }
2822 }
1515 std::string number;
1616 llvm::raw_string_ostream stream(number);
1717 stream << format_hex_no_prefix(Value, 1, UpperCase);
18 return stream.str();
19 }
20
21 const std::string to_string(uint64_t Value) {
22 std::string number;
23 llvm::raw_string_ostream stream(number);
24 stream << format_decimal(Value, 1);
2518 return stream.str();
2619 }
2720
5959
6060 raw_ostream &operator<<(raw_ostream &OS, const HexNumber& Value);
6161 const std::string to_hexString(uint64_t Value, bool UpperCase = true);
62 const std::string to_string(uint64_t Value);
62
63 template const std::string to_string(const T &Value) {
64 std::string number;
65 llvm::raw_string_ostream stream(number);
66 stream << Value;
67 return stream.str();
68 }
6369
6470 class StreamWriter {
6571 public: