1 //===------ utils/elf2yaml.cpp - obj2yaml conversion tool -------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 #include "llvm/ADT/DenseSet.h"
12 #include "llvm/ADT/STLExtras.h"
13 #include "llvm/Object/ELFObjectFile.h"
14 #include "llvm/ObjectYAML/ELFYAML.h"
15 #include "llvm/Support/ErrorHandling.h"
16 #include "llvm/Support/YAMLTraits.h"
24 typedef object::Elf_Sym_Impl
<ELFT
> Elf_Sym
;
25 typedef typename
ELFT::Shdr Elf_Shdr
;
26 typedef typename
ELFT::Word Elf_Word
;
27 typedef typename
ELFT::Rel Elf_Rel
;
28 typedef typename
ELFT::Rela Elf_Rela
;
30 ArrayRef
<Elf_Shdr
> Sections
;
32 // If the file has multiple sections with the same name, we add a
33 // suffix to make them unique.
35 DenseSet
<StringRef
> UsedSectionNames
;
36 std::vector
<std::string
> SectionNames
;
37 Expected
<StringRef
> getUniquedSectionName(const Elf_Shdr
*Sec
);
38 Expected
<StringRef
> getSymbolName(const Elf_Sym
*Sym
, StringRef StrTable
,
39 const Elf_Shdr
*SymTab
);
41 const object::ELFFile
<ELFT
> &Obj
;
42 ArrayRef
<Elf_Word
> ShndxTable
;
44 std::error_code
dumpSymbols(const Elf_Shdr
*Symtab
,
45 ELFYAML::LocalGlobalWeakSymbols
&Symbols
);
46 std::error_code
dumpSymbol(const Elf_Sym
*Sym
, const Elf_Shdr
*SymTab
,
47 StringRef StrTable
, ELFYAML::Symbol
&S
);
48 std::error_code
dumpCommonSection(const Elf_Shdr
*Shdr
, ELFYAML::Section
&S
);
49 std::error_code
dumpCommonRelocationSection(const Elf_Shdr
*Shdr
,
50 ELFYAML::RelocationSection
&S
);
52 std::error_code
dumpRelocation(const RelT
*Rel
, const Elf_Shdr
*SymTab
,
53 ELFYAML::Relocation
&R
);
55 ErrorOr
<ELFYAML::RelocationSection
*> dumpRelSection(const Elf_Shdr
*Shdr
);
56 ErrorOr
<ELFYAML::RelocationSection
*> dumpRelaSection(const Elf_Shdr
*Shdr
);
57 ErrorOr
<ELFYAML::RawContentSection
*>
58 dumpContentSection(const Elf_Shdr
*Shdr
);
59 ErrorOr
<ELFYAML::NoBitsSection
*> dumpNoBitsSection(const Elf_Shdr
*Shdr
);
60 ErrorOr
<ELFYAML::Group
*> dumpGroup(const Elf_Shdr
*Shdr
);
61 ErrorOr
<ELFYAML::MipsABIFlags
*> dumpMipsABIFlags(const Elf_Shdr
*Shdr
);
64 ELFDumper(const object::ELFFile
<ELFT
> &O
);
65 ErrorOr
<ELFYAML::Object
*> dump();
71 ELFDumper
<ELFT
>::ELFDumper(const object::ELFFile
<ELFT
> &O
)
76 ELFDumper
<ELFT
>::getUniquedSectionName(const Elf_Shdr
*Sec
) {
77 unsigned SecIndex
= Sec
- &Sections
[0];
78 assert(&Sections
[SecIndex
] == Sec
);
79 if (!SectionNames
[SecIndex
].empty())
80 return SectionNames
[SecIndex
];
82 auto NameOrErr
= Obj
.getSectionName(Sec
);
85 StringRef Name
= *NameOrErr
;
86 std::string
&Ret
= SectionNames
[SecIndex
];
88 while (!UsedSectionNames
.insert(Ret
).second
)
89 Ret
= (Name
+ to_string(++Suffix
)).str();
94 Expected
<StringRef
> ELFDumper
<ELFT
>::getSymbolName(const Elf_Sym
*Sym
,
96 const Elf_Shdr
*SymTab
) {
97 Expected
<StringRef
> SymbolNameOrErr
= Sym
->getName(StrTable
);
99 return SymbolNameOrErr
;
100 StringRef Name
= *SymbolNameOrErr
;
101 if (Name
.empty() && Sym
->getType() == ELF::STT_SECTION
) {
102 auto ShdrOrErr
= Obj
.getSection(Sym
, SymTab
, ShndxTable
);
104 return ShdrOrErr
.takeError();
105 return getUniquedSectionName(*ShdrOrErr
);
110 template <class ELFT
> ErrorOr
<ELFYAML::Object
*> ELFDumper
<ELFT
>::dump() {
111 auto Y
= make_unique
<ELFYAML::Object
>();
114 Y
->Header
.Class
= ELFYAML::ELF_ELFCLASS(Obj
.getHeader()->getFileClass());
115 Y
->Header
.Data
= ELFYAML::ELF_ELFDATA(Obj
.getHeader()->getDataEncoding());
116 Y
->Header
.OSABI
= Obj
.getHeader()->e_ident
[ELF::EI_OSABI
];
117 Y
->Header
.Type
= Obj
.getHeader()->e_type
;
118 Y
->Header
.Machine
= Obj
.getHeader()->e_machine
;
119 Y
->Header
.Flags
= Obj
.getHeader()->e_flags
;
120 Y
->Header
.Entry
= Obj
.getHeader()->e_entry
;
122 const Elf_Shdr
*Symtab
= nullptr;
123 const Elf_Shdr
*DynSymtab
= nullptr;
126 auto SectionsOrErr
= Obj
.sections();
128 return errorToErrorCode(SectionsOrErr
.takeError());
129 Sections
= *SectionsOrErr
;
130 SectionNames
.resize(Sections
.size());
131 for (const Elf_Shdr
&Sec
: Sections
) {
132 switch (Sec
.sh_type
) {
134 case ELF::SHT_STRTAB
:
135 // Do not dump these sections.
137 case ELF::SHT_SYMTAB
:
140 case ELF::SHT_DYNSYM
:
143 case ELF::SHT_SYMTAB_SHNDX
: {
144 auto TableOrErr
= Obj
.getSHNDXTable(Sec
);
146 return errorToErrorCode(TableOrErr
.takeError());
147 ShndxTable
= *TableOrErr
;
150 case ELF::SHT_RELA
: {
151 ErrorOr
<ELFYAML::RelocationSection
*> S
= dumpRelaSection(&Sec
);
152 if (std::error_code EC
= S
.getError())
154 Y
->Sections
.push_back(std::unique_ptr
<ELFYAML::Section
>(S
.get()));
158 ErrorOr
<ELFYAML::RelocationSection
*> S
= dumpRelSection(&Sec
);
159 if (std::error_code EC
= S
.getError())
161 Y
->Sections
.push_back(std::unique_ptr
<ELFYAML::Section
>(S
.get()));
164 case ELF::SHT_GROUP
: {
165 ErrorOr
<ELFYAML::Group
*> G
= dumpGroup(&Sec
);
166 if (std::error_code EC
= G
.getError())
168 Y
->Sections
.push_back(std::unique_ptr
<ELFYAML::Section
>(G
.get()));
171 case ELF::SHT_MIPS_ABIFLAGS
: {
172 ErrorOr
<ELFYAML::MipsABIFlags
*> G
= dumpMipsABIFlags(&Sec
);
173 if (std::error_code EC
= G
.getError())
175 Y
->Sections
.push_back(std::unique_ptr
<ELFYAML::Section
>(G
.get()));
178 case ELF::SHT_NOBITS
: {
179 ErrorOr
<ELFYAML::NoBitsSection
*> S
= dumpNoBitsSection(&Sec
);
180 if (std::error_code EC
= S
.getError())
182 Y
->Sections
.push_back(std::unique_ptr
<ELFYAML::Section
>(S
.get()));
186 ErrorOr
<ELFYAML::RawContentSection
*> S
= dumpContentSection(&Sec
);
187 if (std::error_code EC
= S
.getError())
189 Y
->Sections
.push_back(std::unique_ptr
<ELFYAML::Section
>(S
.get()));
194 if (auto EC
= dumpSymbols(Symtab
, Y
->Symbols
))
196 if (auto EC
= dumpSymbols(DynSymtab
, Y
->DynamicSymbols
))
202 template <class ELFT
>
204 ELFDumper
<ELFT
>::dumpSymbols(const Elf_Shdr
*Symtab
,
205 ELFYAML::LocalGlobalWeakSymbols
&Symbols
) {
207 return std::error_code();
209 auto StrTableOrErr
= Obj
.getStringTableForSymtab(*Symtab
);
211 return errorToErrorCode(StrTableOrErr
.takeError());
212 StringRef StrTable
= *StrTableOrErr
;
214 auto SymtabOrErr
= Obj
.symbols(Symtab
);
216 return errorToErrorCode(SymtabOrErr
.takeError());
218 bool IsFirstSym
= true;
219 for (const auto &Sym
: *SymtabOrErr
) {
226 if (auto EC
= dumpSymbol(&Sym
, Symtab
, StrTable
, S
))
229 switch (Sym
.getBinding()) {
231 Symbols
.Local
.push_back(S
);
233 case ELF::STB_GLOBAL
:
234 Symbols
.Global
.push_back(S
);
237 Symbols
.Weak
.push_back(S
);
240 llvm_unreachable("Unknown ELF symbol binding");
244 return std::error_code();
247 template <class ELFT
>
249 ELFDumper
<ELFT
>::dumpSymbol(const Elf_Sym
*Sym
, const Elf_Shdr
*SymTab
,
250 StringRef StrTable
, ELFYAML::Symbol
&S
) {
251 S
.Type
= Sym
->getType();
252 S
.Value
= Sym
->st_value
;
253 S
.Size
= Sym
->st_size
;
254 S
.Other
= Sym
->st_other
;
256 Expected
<StringRef
> SymbolNameOrErr
= getSymbolName(Sym
, StrTable
, SymTab
);
257 if (!SymbolNameOrErr
)
258 return errorToErrorCode(SymbolNameOrErr
.takeError());
259 S
.Name
= SymbolNameOrErr
.get();
261 auto ShdrOrErr
= Obj
.getSection(Sym
, SymTab
, ShndxTable
);
263 return errorToErrorCode(ShdrOrErr
.takeError());
264 const Elf_Shdr
*Shdr
= *ShdrOrErr
;
266 return obj2yaml_error::success
;
268 auto NameOrErr
= getUniquedSectionName(Shdr
);
270 return errorToErrorCode(NameOrErr
.takeError());
271 S
.Section
= NameOrErr
.get();
273 return obj2yaml_error::success
;
276 template <class ELFT
>
277 template <class RelT
>
278 std::error_code ELFDumper
<ELFT
>::dumpRelocation(const RelT
*Rel
,
279 const Elf_Shdr
*SymTab
,
280 ELFYAML::Relocation
&R
) {
281 R
.Type
= Rel
->getType(Obj
.isMips64EL());
282 R
.Offset
= Rel
->r_offset
;
285 auto SymOrErr
= Obj
.getRelocationSymbol(Rel
, SymTab
);
287 return errorToErrorCode(SymOrErr
.takeError());
288 const Elf_Sym
*Sym
= *SymOrErr
;
289 auto StrTabSec
= Obj
.getSection(SymTab
->sh_link
);
291 return errorToErrorCode(StrTabSec
.takeError());
292 auto StrTabOrErr
= Obj
.getStringTable(*StrTabSec
);
294 return errorToErrorCode(StrTabOrErr
.takeError());
295 StringRef StrTab
= *StrTabOrErr
;
298 Expected
<StringRef
> NameOrErr
= getSymbolName(Sym
, StrTab
, SymTab
);
300 return errorToErrorCode(NameOrErr
.takeError());
301 R
.Symbol
= NameOrErr
.get();
303 // We have some edge cases of relocations without a symbol associated,
304 // e.g. an object containing the invalid (according to the System V
305 // ABI) R_X86_64_NONE reloc. Create a symbol with an empty name instead
310 return obj2yaml_error::success
;
313 template <class ELFT
>
314 std::error_code ELFDumper
<ELFT
>::dumpCommonSection(const Elf_Shdr
*Shdr
,
315 ELFYAML::Section
&S
) {
316 S
.Type
= Shdr
->sh_type
;
317 S
.Flags
= Shdr
->sh_flags
;
318 S
.Address
= Shdr
->sh_addr
;
319 S
.AddressAlign
= Shdr
->sh_addralign
;
321 auto NameOrErr
= getUniquedSectionName(Shdr
);
323 return errorToErrorCode(NameOrErr
.takeError());
324 S
.Name
= NameOrErr
.get();
326 if (Shdr
->sh_link
!= ELF::SHN_UNDEF
) {
327 auto LinkSection
= Obj
.getSection(Shdr
->sh_link
);
328 if (LinkSection
.takeError())
329 return errorToErrorCode(LinkSection
.takeError());
330 NameOrErr
= getUniquedSectionName(*LinkSection
);
332 return errorToErrorCode(NameOrErr
.takeError());
333 S
.Link
= NameOrErr
.get();
336 return obj2yaml_error::success
;
339 template <class ELFT
>
341 ELFDumper
<ELFT
>::dumpCommonRelocationSection(const Elf_Shdr
*Shdr
,
342 ELFYAML::RelocationSection
&S
) {
343 if (std::error_code EC
= dumpCommonSection(Shdr
, S
))
346 auto InfoSection
= Obj
.getSection(Shdr
->sh_info
);
348 return errorToErrorCode(InfoSection
.takeError());
350 auto NameOrErr
= getUniquedSectionName(*InfoSection
);
352 return errorToErrorCode(NameOrErr
.takeError());
353 S
.Info
= NameOrErr
.get();
355 return obj2yaml_error::success
;
358 template <class ELFT
>
359 ErrorOr
<ELFYAML::RelocationSection
*>
360 ELFDumper
<ELFT
>::dumpRelSection(const Elf_Shdr
*Shdr
) {
361 assert(Shdr
->sh_type
== ELF::SHT_REL
&& "Section type is not SHT_REL");
362 auto S
= make_unique
<ELFYAML::RelocationSection
>();
364 if (std::error_code EC
= dumpCommonRelocationSection(Shdr
, *S
))
367 auto SymTabOrErr
= Obj
.getSection(Shdr
->sh_link
);
369 return errorToErrorCode(SymTabOrErr
.takeError());
370 const Elf_Shdr
*SymTab
= *SymTabOrErr
;
372 auto Rels
= Obj
.rels(Shdr
);
374 return errorToErrorCode(Rels
.takeError());
375 for (const Elf_Rel
&Rel
: *Rels
) {
376 ELFYAML::Relocation R
;
377 if (std::error_code EC
= dumpRelocation(&Rel
, SymTab
, R
))
379 S
->Relocations
.push_back(R
);
385 template <class ELFT
>
386 ErrorOr
<ELFYAML::RelocationSection
*>
387 ELFDumper
<ELFT
>::dumpRelaSection(const Elf_Shdr
*Shdr
) {
388 assert(Shdr
->sh_type
== ELF::SHT_RELA
&& "Section type is not SHT_RELA");
389 auto S
= make_unique
<ELFYAML::RelocationSection
>();
391 if (std::error_code EC
= dumpCommonRelocationSection(Shdr
, *S
))
394 auto SymTabOrErr
= Obj
.getSection(Shdr
->sh_link
);
396 return errorToErrorCode(SymTabOrErr
.takeError());
397 const Elf_Shdr
*SymTab
= *SymTabOrErr
;
399 auto Rels
= Obj
.relas(Shdr
);
401 return errorToErrorCode(Rels
.takeError());
402 for (const Elf_Rela
&Rel
: *Rels
) {
403 ELFYAML::Relocation R
;
404 if (std::error_code EC
= dumpRelocation(&Rel
, SymTab
, R
))
406 R
.Addend
= Rel
.r_addend
;
407 S
->Relocations
.push_back(R
);
413 template <class ELFT
>
414 ErrorOr
<ELFYAML::RawContentSection
*>
415 ELFDumper
<ELFT
>::dumpContentSection(const Elf_Shdr
*Shdr
) {
416 auto S
= make_unique
<ELFYAML::RawContentSection
>();
418 if (std::error_code EC
= dumpCommonSection(Shdr
, *S
))
421 auto ContentOrErr
= Obj
.getSectionContents(Shdr
);
423 return errorToErrorCode(ContentOrErr
.takeError());
424 S
->Content
= yaml::BinaryRef(ContentOrErr
.get());
425 S
->Size
= S
->Content
.binary_size();
430 template <class ELFT
>
431 ErrorOr
<ELFYAML::NoBitsSection
*>
432 ELFDumper
<ELFT
>::dumpNoBitsSection(const Elf_Shdr
*Shdr
) {
433 auto S
= make_unique
<ELFYAML::NoBitsSection
>();
435 if (std::error_code EC
= dumpCommonSection(Shdr
, *S
))
437 S
->Size
= Shdr
->sh_size
;
442 template <class ELFT
>
443 ErrorOr
<ELFYAML::Group
*> ELFDumper
<ELFT
>::dumpGroup(const Elf_Shdr
*Shdr
) {
444 auto S
= make_unique
<ELFYAML::Group
>();
446 if (std::error_code EC
= dumpCommonSection(Shdr
, *S
))
448 // Get sh_info which is the signature.
449 auto SymtabOrErr
= Obj
.getSection(Shdr
->sh_link
);
451 return errorToErrorCode(SymtabOrErr
.takeError());
452 const Elf_Shdr
*Symtab
= *SymtabOrErr
;
453 auto SymOrErr
= Obj
.getSymbol(Symtab
, Shdr
->sh_info
);
455 return errorToErrorCode(SymOrErr
.takeError());
456 const Elf_Sym
*symbol
= *SymOrErr
;
457 auto StrTabOrErr
= Obj
.getStringTableForSymtab(*Symtab
);
459 return errorToErrorCode(StrTabOrErr
.takeError());
460 StringRef StrTab
= *StrTabOrErr
;
461 auto sectionContents
= Obj
.getSectionContents(Shdr
);
462 if (!sectionContents
)
463 return errorToErrorCode(sectionContents
.takeError());
464 Expected
<StringRef
> symbolName
= getSymbolName(symbol
, StrTab
, Symtab
);
466 return errorToErrorCode(symbolName
.takeError());
467 S
->Info
= *symbolName
;
468 const Elf_Word
*groupMembers
=
469 reinterpret_cast<const Elf_Word
*>(sectionContents
->data());
470 const long count
= (Shdr
->sh_size
) / sizeof(Elf_Word
);
471 ELFYAML::SectionOrType s
;
472 for (int i
= 0; i
< count
; i
++) {
473 if (groupMembers
[i
] == llvm::ELF::GRP_COMDAT
) {
474 s
.sectionNameOrType
= "GRP_COMDAT";
476 auto sHdr
= Obj
.getSection(groupMembers
[i
]);
478 return errorToErrorCode(sHdr
.takeError());
479 auto sectionName
= getUniquedSectionName(*sHdr
);
481 return errorToErrorCode(sectionName
.takeError());
482 s
.sectionNameOrType
= *sectionName
;
484 S
->Members
.push_back(s
);
489 template <class ELFT
>
490 ErrorOr
<ELFYAML::MipsABIFlags
*>
491 ELFDumper
<ELFT
>::dumpMipsABIFlags(const Elf_Shdr
*Shdr
) {
492 assert(Shdr
->sh_type
== ELF::SHT_MIPS_ABIFLAGS
&&
493 "Section type is not SHT_MIPS_ABIFLAGS");
494 auto S
= make_unique
<ELFYAML::MipsABIFlags
>();
495 if (std::error_code EC
= dumpCommonSection(Shdr
, *S
))
498 auto ContentOrErr
= Obj
.getSectionContents(Shdr
);
500 return errorToErrorCode(ContentOrErr
.takeError());
502 auto *Flags
= reinterpret_cast<const object::Elf_Mips_ABIFlags
<ELFT
> *>(
503 ContentOrErr
.get().data());
504 S
->Version
= Flags
->version
;
505 S
->ISALevel
= Flags
->isa_level
;
506 S
->ISARevision
= Flags
->isa_rev
;
507 S
->GPRSize
= Flags
->gpr_size
;
508 S
->CPR1Size
= Flags
->cpr1_size
;
509 S
->CPR2Size
= Flags
->cpr2_size
;
510 S
->FpABI
= Flags
->fp_abi
;
511 S
->ISAExtension
= Flags
->isa_ext
;
512 S
->ASEs
= Flags
->ases
;
513 S
->Flags1
= Flags
->flags1
;
514 S
->Flags2
= Flags
->flags2
;
518 template <class ELFT
>
519 static std::error_code
elf2yaml(raw_ostream
&Out
,
520 const object::ELFFile
<ELFT
> &Obj
) {
521 ELFDumper
<ELFT
> Dumper(Obj
);
522 ErrorOr
<ELFYAML::Object
*> YAMLOrErr
= Dumper
.dump();
523 if (std::error_code EC
= YAMLOrErr
.getError())
526 std::unique_ptr
<ELFYAML::Object
> YAML(YAMLOrErr
.get());
527 yaml::Output
Yout(Out
);
530 return std::error_code();
533 std::error_code
elf2yaml(raw_ostream
&Out
, const object::ObjectFile
&Obj
) {
534 if (const auto *ELFObj
= dyn_cast
<object::ELF32LEObjectFile
>(&Obj
))
535 return elf2yaml(Out
, *ELFObj
->getELFFile());
537 if (const auto *ELFObj
= dyn_cast
<object::ELF32BEObjectFile
>(&Obj
))
538 return elf2yaml(Out
, *ELFObj
->getELFFile());
540 if (const auto *ELFObj
= dyn_cast
<object::ELF64LEObjectFile
>(&Obj
))
541 return elf2yaml(Out
, *ELFObj
->getELFFile());
543 if (const auto *ELFObj
= dyn_cast
<object::ELF64BEObjectFile
>(&Obj
))
544 return elf2yaml(Out
, *ELFObj
->getELFFile());
546 return obj2yaml_error::unsupported_obj_file_format
;