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 //===----------------------------------------------------------------------===//
12 #include "llvm/ADT/DenseSet.h"
13 #include "llvm/ADT/STLExtras.h"
14 #include "llvm/Object/ELFObjectFile.h"
15 #include "llvm/ObjectYAML/ELFYAML.h"
16 #include "llvm/Support/ErrorHandling.h"
17 #include "llvm/Support/YAMLTraits.h"
25 typedef object::Elf_Sym_Impl
<ELFT
> Elf_Sym
;
26 typedef typename
object::ELFFile
<ELFT
>::Elf_Shdr Elf_Shdr
;
27 typedef typename
object::ELFFile
<ELFT
>::Elf_Word Elf_Word
;
28 typedef typename
object::ELFFile
<ELFT
>::Elf_Rel Elf_Rel
;
29 typedef typename
object::ELFFile
<ELFT
>::Elf_Rela Elf_Rela
;
31 ArrayRef
<Elf_Shdr
> Sections
;
33 // If the file has multiple sections with the same name, we add a
34 // suffix to make them unique.
36 DenseSet
<StringRef
> UsedSectionNames
;
37 std::vector
<std::string
> SectionNames
;
38 Expected
<StringRef
> getUniquedSectionName(const Elf_Shdr
*Sec
);
39 Expected
<StringRef
> getSymbolName(const Elf_Sym
*Sym
, StringRef StrTable
,
40 const Elf_Shdr
*SymTab
);
42 const object::ELFFile
<ELFT
> &Obj
;
43 ArrayRef
<Elf_Word
> ShndxTable
;
45 std::error_code
dumpSymbol(const Elf_Sym
*Sym
, const Elf_Shdr
*SymTab
,
46 StringRef StrTable
, ELFYAML::Symbol
&S
);
47 std::error_code
dumpCommonSection(const Elf_Shdr
*Shdr
, ELFYAML::Section
&S
);
48 std::error_code
dumpCommonRelocationSection(const Elf_Shdr
*Shdr
,
49 ELFYAML::RelocationSection
&S
);
51 std::error_code
dumpRelocation(const RelT
*Rel
, const Elf_Shdr
*SymTab
,
52 ELFYAML::Relocation
&R
);
54 ErrorOr
<ELFYAML::RelocationSection
*> dumpRelSection(const Elf_Shdr
*Shdr
);
55 ErrorOr
<ELFYAML::RelocationSection
*> dumpRelaSection(const Elf_Shdr
*Shdr
);
56 ErrorOr
<ELFYAML::RawContentSection
*>
57 dumpContentSection(const Elf_Shdr
*Shdr
);
58 ErrorOr
<ELFYAML::NoBitsSection
*> dumpNoBitsSection(const Elf_Shdr
*Shdr
);
59 ErrorOr
<ELFYAML::Group
*> dumpGroup(const Elf_Shdr
*Shdr
);
60 ErrorOr
<ELFYAML::MipsABIFlags
*> dumpMipsABIFlags(const Elf_Shdr
*Shdr
);
63 ELFDumper(const object::ELFFile
<ELFT
> &O
);
64 ErrorOr
<ELFYAML::Object
*> dump();
70 ELFDumper
<ELFT
>::ELFDumper(const object::ELFFile
<ELFT
> &O
)
75 ELFDumper
<ELFT
>::getUniquedSectionName(const Elf_Shdr
*Sec
) {
76 unsigned SecIndex
= Sec
- &Sections
[0];
77 assert(&Sections
[SecIndex
] == Sec
);
78 if (!SectionNames
[SecIndex
].empty())
79 return SectionNames
[SecIndex
];
81 auto NameOrErr
= Obj
.getSectionName(Sec
);
84 StringRef Name
= *NameOrErr
;
85 std::string
&Ret
= SectionNames
[SecIndex
];
87 while (!UsedSectionNames
.insert(Ret
).second
)
88 Ret
= (Name
+ to_string(++Suffix
)).str();
93 Expected
<StringRef
> ELFDumper
<ELFT
>::getSymbolName(const Elf_Sym
*Sym
,
95 const Elf_Shdr
*SymTab
) {
96 Expected
<StringRef
> SymbolNameOrErr
= Sym
->getName(StrTable
);
98 return SymbolNameOrErr
;
99 StringRef Name
= *SymbolNameOrErr
;
100 if (Name
.empty() && Sym
->getType() == ELF::STT_SECTION
) {
101 auto ShdrOrErr
= Obj
.getSection(Sym
, SymTab
, ShndxTable
);
103 return ShdrOrErr
.takeError();
104 return getUniquedSectionName(*ShdrOrErr
);
109 template <class ELFT
> ErrorOr
<ELFYAML::Object
*> ELFDumper
<ELFT
>::dump() {
110 auto Y
= make_unique
<ELFYAML::Object
>();
113 Y
->Header
.Class
= ELFYAML::ELF_ELFCLASS(Obj
.getHeader()->getFileClass());
114 Y
->Header
.Data
= ELFYAML::ELF_ELFDATA(Obj
.getHeader()->getDataEncoding());
115 Y
->Header
.OSABI
= Obj
.getHeader()->e_ident
[ELF::EI_OSABI
];
116 Y
->Header
.Type
= Obj
.getHeader()->e_type
;
117 Y
->Header
.Machine
= Obj
.getHeader()->e_machine
;
118 Y
->Header
.Flags
= Obj
.getHeader()->e_flags
;
119 Y
->Header
.Entry
= Obj
.getHeader()->e_entry
;
121 const Elf_Shdr
*Symtab
= nullptr;
124 auto SectionsOrErr
= Obj
.sections();
126 return errorToErrorCode(SectionsOrErr
.takeError());
127 Sections
= *SectionsOrErr
;
128 SectionNames
.resize(Sections
.size());
129 for (const Elf_Shdr
&Sec
: Sections
) {
130 switch (Sec
.sh_type
) {
132 case ELF::SHT_DYNSYM
:
133 case ELF::SHT_STRTAB
:
134 // Do not dump these sections.
136 case ELF::SHT_SYMTAB
:
139 case ELF::SHT_SYMTAB_SHNDX
: {
140 auto TableOrErr
= Obj
.getSHNDXTable(Sec
);
142 return errorToErrorCode(TableOrErr
.takeError());
143 ShndxTable
= *TableOrErr
;
146 case ELF::SHT_RELA
: {
147 ErrorOr
<ELFYAML::RelocationSection
*> S
= dumpRelaSection(&Sec
);
148 if (std::error_code EC
= S
.getError())
150 Y
->Sections
.push_back(std::unique_ptr
<ELFYAML::Section
>(S
.get()));
154 ErrorOr
<ELFYAML::RelocationSection
*> S
= dumpRelSection(&Sec
);
155 if (std::error_code EC
= S
.getError())
157 Y
->Sections
.push_back(std::unique_ptr
<ELFYAML::Section
>(S
.get()));
160 case ELF::SHT_GROUP
: {
161 ErrorOr
<ELFYAML::Group
*> G
= dumpGroup(&Sec
);
162 if (std::error_code EC
= G
.getError())
164 Y
->Sections
.push_back(std::unique_ptr
<ELFYAML::Section
>(G
.get()));
167 case ELF::SHT_MIPS_ABIFLAGS
: {
168 ErrorOr
<ELFYAML::MipsABIFlags
*> G
= dumpMipsABIFlags(&Sec
);
169 if (std::error_code EC
= G
.getError())
171 Y
->Sections
.push_back(std::unique_ptr
<ELFYAML::Section
>(G
.get()));
174 case ELF::SHT_NOBITS
: {
175 ErrorOr
<ELFYAML::NoBitsSection
*> S
= dumpNoBitsSection(&Sec
);
176 if (std::error_code EC
= S
.getError())
178 Y
->Sections
.push_back(std::unique_ptr
<ELFYAML::Section
>(S
.get()));
182 ErrorOr
<ELFYAML::RawContentSection
*> S
= dumpContentSection(&Sec
);
183 if (std::error_code EC
= S
.getError())
185 Y
->Sections
.push_back(std::unique_ptr
<ELFYAML::Section
>(S
.get()));
192 return Y
.release(); // if the symbol table is missing return early
193 auto StrTableOrErr
= Obj
.getStringTableForSymtab(*Symtab
);
195 return errorToErrorCode(StrTableOrErr
.takeError());
196 StringRef StrTable
= *StrTableOrErr
;
198 bool IsFirstSym
= true;
199 auto SymtabOrErr
= Obj
.symbols(Symtab
);
201 return errorToErrorCode(SymtabOrErr
.takeError());
202 for (const Elf_Sym
&Sym
: *SymtabOrErr
) {
209 if (std::error_code EC
=
210 ELFDumper
<ELFT
>::dumpSymbol(&Sym
, Symtab
, StrTable
, S
))
213 switch (Sym
.getBinding())
216 Y
->Symbols
.Local
.push_back(S
);
218 case ELF::STB_GLOBAL
:
219 Y
->Symbols
.Global
.push_back(S
);
222 Y
->Symbols
.Weak
.push_back(S
);
225 llvm_unreachable("Unknown ELF symbol binding");
232 template <class ELFT
>
234 ELFDumper
<ELFT
>::dumpSymbol(const Elf_Sym
*Sym
, const Elf_Shdr
*SymTab
,
235 StringRef StrTable
, ELFYAML::Symbol
&S
) {
236 S
.Type
= Sym
->getType();
237 S
.Value
= Sym
->st_value
;
238 S
.Size
= Sym
->st_size
;
239 S
.Other
= Sym
->st_other
;
241 Expected
<StringRef
> SymbolNameOrErr
= getSymbolName(Sym
, StrTable
, SymTab
);
242 if (!SymbolNameOrErr
)
243 return errorToErrorCode(SymbolNameOrErr
.takeError());
244 S
.Name
= SymbolNameOrErr
.get();
246 auto ShdrOrErr
= Obj
.getSection(Sym
, SymTab
, ShndxTable
);
248 return errorToErrorCode(ShdrOrErr
.takeError());
249 const Elf_Shdr
*Shdr
= *ShdrOrErr
;
251 return obj2yaml_error::success
;
253 auto NameOrErr
= getUniquedSectionName(Shdr
);
255 return errorToErrorCode(NameOrErr
.takeError());
256 S
.Section
= NameOrErr
.get();
258 return obj2yaml_error::success
;
261 template <class ELFT
>
262 template <class RelT
>
263 std::error_code ELFDumper
<ELFT
>::dumpRelocation(const RelT
*Rel
,
264 const Elf_Shdr
*SymTab
,
265 ELFYAML::Relocation
&R
) {
266 R
.Type
= Rel
->getType(Obj
.isMips64EL());
267 R
.Offset
= Rel
->r_offset
;
270 auto SymOrErr
= Obj
.getRelocationSymbol(Rel
, SymTab
);
272 return errorToErrorCode(SymOrErr
.takeError());
273 const Elf_Sym
*Sym
= *SymOrErr
;
274 auto StrTabSec
= Obj
.getSection(SymTab
->sh_link
);
276 return errorToErrorCode(StrTabSec
.takeError());
277 auto StrTabOrErr
= Obj
.getStringTable(*StrTabSec
);
279 return errorToErrorCode(StrTabOrErr
.takeError());
280 StringRef StrTab
= *StrTabOrErr
;
283 Expected
<StringRef
> NameOrErr
= getSymbolName(Sym
, StrTab
, SymTab
);
285 return errorToErrorCode(NameOrErr
.takeError());
286 R
.Symbol
= NameOrErr
.get();
288 // We have some edge cases of relocations without a symbol associated,
289 // e.g. an object containing the invalid (according to the System V
290 // ABI) R_X86_64_NONE reloc. Create a symbol with an empty name instead
295 return obj2yaml_error::success
;
298 template <class ELFT
>
299 std::error_code ELFDumper
<ELFT
>::dumpCommonSection(const Elf_Shdr
*Shdr
,
300 ELFYAML::Section
&S
) {
301 S
.Type
= Shdr
->sh_type
;
302 S
.Flags
= Shdr
->sh_flags
;
303 S
.Address
= Shdr
->sh_addr
;
304 S
.AddressAlign
= Shdr
->sh_addralign
;
306 auto NameOrErr
= getUniquedSectionName(Shdr
);
308 return errorToErrorCode(NameOrErr
.takeError());
309 S
.Name
= NameOrErr
.get();
311 if (Shdr
->sh_link
!= ELF::SHN_UNDEF
) {
312 auto LinkSection
= Obj
.getSection(Shdr
->sh_link
);
313 if (LinkSection
.takeError())
314 return errorToErrorCode(LinkSection
.takeError());
315 NameOrErr
= getUniquedSectionName(*LinkSection
);
317 return errorToErrorCode(NameOrErr
.takeError());
318 S
.Link
= NameOrErr
.get();
321 return obj2yaml_error::success
;
324 template <class ELFT
>
326 ELFDumper
<ELFT
>::dumpCommonRelocationSection(const Elf_Shdr
*Shdr
,
327 ELFYAML::RelocationSection
&S
) {
328 if (std::error_code EC
= dumpCommonSection(Shdr
, S
))
331 auto InfoSection
= Obj
.getSection(Shdr
->sh_info
);
333 return errorToErrorCode(InfoSection
.takeError());
335 auto NameOrErr
= getUniquedSectionName(*InfoSection
);
337 return errorToErrorCode(NameOrErr
.takeError());
338 S
.Info
= NameOrErr
.get();
340 return obj2yaml_error::success
;
343 template <class ELFT
>
344 ErrorOr
<ELFYAML::RelocationSection
*>
345 ELFDumper
<ELFT
>::dumpRelSection(const Elf_Shdr
*Shdr
) {
346 assert(Shdr
->sh_type
== ELF::SHT_REL
&& "Section type is not SHT_REL");
347 auto S
= make_unique
<ELFYAML::RelocationSection
>();
349 if (std::error_code EC
= dumpCommonRelocationSection(Shdr
, *S
))
352 auto SymTabOrErr
= Obj
.getSection(Shdr
->sh_link
);
354 return errorToErrorCode(SymTabOrErr
.takeError());
355 const Elf_Shdr
*SymTab
= *SymTabOrErr
;
357 auto Rels
= Obj
.rels(Shdr
);
359 return errorToErrorCode(Rels
.takeError());
360 for (const Elf_Rel
&Rel
: *Rels
) {
361 ELFYAML::Relocation R
;
362 if (std::error_code EC
= dumpRelocation(&Rel
, SymTab
, R
))
364 S
->Relocations
.push_back(R
);
370 template <class ELFT
>
371 ErrorOr
<ELFYAML::RelocationSection
*>
372 ELFDumper
<ELFT
>::dumpRelaSection(const Elf_Shdr
*Shdr
) {
373 assert(Shdr
->sh_type
== ELF::SHT_RELA
&& "Section type is not SHT_RELA");
374 auto S
= make_unique
<ELFYAML::RelocationSection
>();
376 if (std::error_code EC
= dumpCommonRelocationSection(Shdr
, *S
))
379 auto SymTabOrErr
= Obj
.getSection(Shdr
->sh_link
);
381 return errorToErrorCode(SymTabOrErr
.takeError());
382 const Elf_Shdr
*SymTab
= *SymTabOrErr
;
384 auto Rels
= Obj
.relas(Shdr
);
386 return errorToErrorCode(Rels
.takeError());
387 for (const Elf_Rela
&Rel
: *Rels
) {
388 ELFYAML::Relocation R
;
389 if (std::error_code EC
= dumpRelocation(&Rel
, SymTab
, R
))
391 R
.Addend
= Rel
.r_addend
;
392 S
->Relocations
.push_back(R
);
398 template <class ELFT
>
399 ErrorOr
<ELFYAML::RawContentSection
*>
400 ELFDumper
<ELFT
>::dumpContentSection(const Elf_Shdr
*Shdr
) {
401 auto S
= make_unique
<ELFYAML::RawContentSection
>();
403 if (std::error_code EC
= dumpCommonSection(Shdr
, *S
))
406 auto ContentOrErr
= Obj
.getSectionContents(Shdr
);
408 return errorToErrorCode(ContentOrErr
.takeError());
409 S
->Content
= yaml::BinaryRef(ContentOrErr
.get());
410 S
->Size
= S
->Content
.binary_size();
415 template <class ELFT
>
416 ErrorOr
<ELFYAML::NoBitsSection
*>
417 ELFDumper
<ELFT
>::dumpNoBitsSection(const Elf_Shdr
*Shdr
) {
418 auto S
= make_unique
<ELFYAML::NoBitsSection
>();
420 if (std::error_code EC
= dumpCommonSection(Shdr
, *S
))
422 S
->Size
= Shdr
->sh_size
;
427 template <class ELFT
>
428 ErrorOr
<ELFYAML::Group
*> ELFDumper
<ELFT
>::dumpGroup(const Elf_Shdr
*Shdr
) {
429 auto S
= make_unique
<ELFYAML::Group
>();
431 if (std::error_code EC
= dumpCommonSection(Shdr
, *S
))
433 // Get sh_info which is the signature.
434 auto SymtabOrErr
= Obj
.getSection(Shdr
->sh_link
);
436 return errorToErrorCode(SymtabOrErr
.takeError());
437 const Elf_Shdr
*Symtab
= *SymtabOrErr
;
438 auto SymOrErr
= Obj
.getSymbol(Symtab
, Shdr
->sh_info
);
440 return errorToErrorCode(SymOrErr
.takeError());
441 const Elf_Sym
*symbol
= *SymOrErr
;
442 auto StrTabOrErr
= Obj
.getStringTableForSymtab(*Symtab
);
444 return errorToErrorCode(StrTabOrErr
.takeError());
445 StringRef StrTab
= *StrTabOrErr
;
446 auto sectionContents
= Obj
.getSectionContents(Shdr
);
447 if (!sectionContents
)
448 return errorToErrorCode(sectionContents
.takeError());
449 Expected
<StringRef
> symbolName
= getSymbolName(symbol
, StrTab
, Symtab
);
451 return errorToErrorCode(symbolName
.takeError());
452 S
->Info
= *symbolName
;
453 const Elf_Word
*groupMembers
=
454 reinterpret_cast<const Elf_Word
*>(sectionContents
->data());
455 const long count
= (Shdr
->sh_size
) / sizeof(Elf_Word
);
456 ELFYAML::SectionOrType s
;
457 for (int i
= 0; i
< count
; i
++) {
458 if (groupMembers
[i
] == llvm::ELF::GRP_COMDAT
) {
459 s
.sectionNameOrType
= "GRP_COMDAT";
461 auto sHdr
= Obj
.getSection(groupMembers
[i
]);
463 return errorToErrorCode(sHdr
.takeError());
464 auto sectionName
= getUniquedSectionName(*sHdr
);
466 return errorToErrorCode(sectionName
.takeError());
467 s
.sectionNameOrType
= *sectionName
;
469 S
->Members
.push_back(s
);
474 template <class ELFT
>
475 ErrorOr
<ELFYAML::MipsABIFlags
*>
476 ELFDumper
<ELFT
>::dumpMipsABIFlags(const Elf_Shdr
*Shdr
) {
477 assert(Shdr
->sh_type
== ELF::SHT_MIPS_ABIFLAGS
&&
478 "Section type is not SHT_MIPS_ABIFLAGS");
479 auto S
= make_unique
<ELFYAML::MipsABIFlags
>();
480 if (std::error_code EC
= dumpCommonSection(Shdr
, *S
))
483 auto ContentOrErr
= Obj
.getSectionContents(Shdr
);
485 return errorToErrorCode(ContentOrErr
.takeError());
487 auto *Flags
= reinterpret_cast<const object::Elf_Mips_ABIFlags
<ELFT
> *>(
488 ContentOrErr
.get().data());
489 S
->Version
= Flags
->version
;
490 S
->ISALevel
= Flags
->isa_level
;
491 S
->ISARevision
= Flags
->isa_rev
;
492 S
->GPRSize
= Flags
->gpr_size
;
493 S
->CPR1Size
= Flags
->cpr1_size
;
494 S
->CPR2Size
= Flags
->cpr2_size
;
495 S
->FpABI
= Flags
->fp_abi
;
496 S
->ISAExtension
= Flags
->isa_ext
;
497 S
->ASEs
= Flags
->ases
;
498 S
->Flags1
= Flags
->flags1
;
499 S
->Flags2
= Flags
->flags2
;
503 template <class ELFT
>
504 static std::error_code
elf2yaml(raw_ostream
&Out
,
505 const object::ELFFile
<ELFT
> &Obj
) {
506 ELFDumper
<ELFT
> Dumper(Obj
);
507 ErrorOr
<ELFYAML::Object
*> YAMLOrErr
= Dumper
.dump();
508 if (std::error_code EC
= YAMLOrErr
.getError())
511 std::unique_ptr
<ELFYAML::Object
> YAML(YAMLOrErr
.get());
512 yaml::Output
Yout(Out
);
515 return std::error_code();
518 std::error_code
elf2yaml(raw_ostream
&Out
, const object::ObjectFile
&Obj
) {
519 if (const auto *ELFObj
= dyn_cast
<object::ELF32LEObjectFile
>(&Obj
))
520 return elf2yaml(Out
, *ELFObj
->getELFFile());
522 if (const auto *ELFObj
= dyn_cast
<object::ELF32BEObjectFile
>(&Obj
))
523 return elf2yaml(Out
, *ELFObj
->getELFFile());
525 if (const auto *ELFObj
= dyn_cast
<object::ELF64LEObjectFile
>(&Obj
))
526 return elf2yaml(Out
, *ELFObj
->getELFFile());
528 if (const auto *ELFObj
= dyn_cast
<object::ELF64BEObjectFile
>(&Obj
))
529 return elf2yaml(Out
, *ELFObj
->getELFFile());
531 return obj2yaml_error::unsupported_obj_file_format
;