1 //===------ utils/elf2yaml.cpp - obj2yaml conversion tool -------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
10 #include "llvm/ADT/DenseSet.h"
11 #include "llvm/ADT/STLExtras.h"
12 #include "llvm/Object/ELFObjectFile.h"
13 #include "llvm/ObjectYAML/ELFYAML.h"
14 #include "llvm/Support/DataExtractor.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::Dyn Elf_Dyn
;
26 typedef typename
ELFT::Shdr Elf_Shdr
;
27 typedef typename
ELFT::Word Elf_Word
;
28 typedef typename
ELFT::Rel Elf_Rel
;
29 typedef typename
ELFT::Rela Elf_Rela
;
31 ArrayRef
<Elf_Shdr
> Sections
;
32 ArrayRef
<Elf_Sym
> SymTable
;
34 DenseMap
<StringRef
, uint32_t> UsedSectionNames
;
35 std::vector
<std::string
> SectionNames
;
37 DenseMap
<StringRef
, uint32_t> UsedSymbolNames
;
38 std::vector
<std::string
> SymbolNames
;
40 Expected
<StringRef
> getUniquedSectionName(const Elf_Shdr
*Sec
);
41 Expected
<StringRef
> getUniquedSymbolName(const Elf_Sym
*Sym
,
43 const Elf_Shdr
*SymTab
);
45 const object::ELFFile
<ELFT
> &Obj
;
46 ArrayRef
<Elf_Word
> ShndxTable
;
48 Error
dumpSymbols(const Elf_Shdr
*Symtab
,
49 std::vector
<ELFYAML::Symbol
> &Symbols
);
50 Error
dumpSymbol(const Elf_Sym
*Sym
, const Elf_Shdr
*SymTab
,
51 StringRef StrTable
, ELFYAML::Symbol
&S
);
52 Error
dumpCommonSection(const Elf_Shdr
*Shdr
, ELFYAML::Section
&S
);
53 Error
dumpCommonRelocationSection(const Elf_Shdr
*Shdr
,
54 ELFYAML::RelocationSection
&S
);
56 Error
dumpRelocation(const RelT
*Rel
, const Elf_Shdr
*SymTab
,
57 ELFYAML::Relocation
&R
);
59 Expected
<ELFYAML::DynamicSection
*> dumpDynamicSection(const Elf_Shdr
*Shdr
);
60 Expected
<ELFYAML::RelocationSection
*> dumpRelocSection(const Elf_Shdr
*Shdr
);
61 Expected
<ELFYAML::RawContentSection
*>
62 dumpContentSection(const Elf_Shdr
*Shdr
);
63 Expected
<ELFYAML::SymtabShndxSection
*>
64 dumpSymtabShndxSection(const Elf_Shdr
*Shdr
);
65 Expected
<ELFYAML::NoBitsSection
*> dumpNoBitsSection(const Elf_Shdr
*Shdr
);
66 Expected
<ELFYAML::VerdefSection
*> dumpVerdefSection(const Elf_Shdr
*Shdr
);
67 Expected
<ELFYAML::SymverSection
*> dumpSymverSection(const Elf_Shdr
*Shdr
);
68 Expected
<ELFYAML::VerneedSection
*> dumpVerneedSection(const Elf_Shdr
*Shdr
);
69 Expected
<ELFYAML::Group
*> dumpGroup(const Elf_Shdr
*Shdr
);
70 Expected
<ELFYAML::MipsABIFlags
*> dumpMipsABIFlags(const Elf_Shdr
*Shdr
);
71 Expected
<ELFYAML::StackSizesSection
*>
72 dumpStackSizesSection(const Elf_Shdr
*Shdr
);
74 Expected
<ELFYAML::Section
*> dumpSpecialSection(const Elf_Shdr
*Shdr
);
77 ELFDumper(const object::ELFFile
<ELFT
> &O
);
78 Expected
<ELFYAML::Object
*> dump();
84 ELFDumper
<ELFT
>::ELFDumper(const object::ELFFile
<ELFT
> &O
)
89 ELFDumper
<ELFT
>::getUniquedSectionName(const Elf_Shdr
*Sec
) {
90 unsigned SecIndex
= Sec
- &Sections
[0];
91 assert(&Sections
[SecIndex
] == Sec
);
92 if (!SectionNames
[SecIndex
].empty())
93 return SectionNames
[SecIndex
];
95 auto NameOrErr
= Obj
.getSectionName(Sec
);
98 StringRef Name
= *NameOrErr
;
99 std::string
&Ret
= SectionNames
[SecIndex
];
101 auto It
= UsedSectionNames
.insert({Name
, 0});
103 Ret
= (Name
+ " [" + Twine(++It
.first
->second
) + "]").str();
109 template <class ELFT
>
111 ELFDumper
<ELFT
>::getUniquedSymbolName(const Elf_Sym
*Sym
, StringRef StrTable
,
112 const Elf_Shdr
*SymTab
) {
113 Expected
<StringRef
> SymbolNameOrErr
= Sym
->getName(StrTable
);
114 if (!SymbolNameOrErr
)
115 return SymbolNameOrErr
;
116 StringRef Name
= *SymbolNameOrErr
;
117 if (Name
.empty() && Sym
->getType() == ELF::STT_SECTION
) {
118 auto ShdrOrErr
= Obj
.getSection(Sym
, SymTab
, ShndxTable
);
120 return ShdrOrErr
.takeError();
121 return getUniquedSectionName(*ShdrOrErr
);
124 // Symbols in .symtab can have duplicate names. For example, it is a common
125 // situation for local symbols in a relocatable object. Here we assign unique
126 // suffixes for such symbols so that we can differentiate them.
127 if (SymTab
->sh_type
== ELF::SHT_SYMTAB
) {
128 unsigned Index
= Sym
- SymTable
.data();
129 if (!SymbolNames
[Index
].empty())
130 return SymbolNames
[Index
];
132 auto It
= UsedSymbolNames
.insert({Name
, 0});
135 (Name
+ " [" + Twine(++It
.first
->second
) + "]").str();
137 SymbolNames
[Index
] = Name
;
138 return SymbolNames
[Index
];
144 template <class ELFT
> Expected
<ELFYAML::Object
*> ELFDumper
<ELFT
>::dump() {
145 auto Y
= std::make_unique
<ELFYAML::Object
>();
147 // Dump header. We do not dump SHEntSize, SHOff, SHNum and SHStrNdx fields.
148 // When not explicitly set, the values are set by yaml2obj automatically
149 // and there is no need to dump them here.
150 Y
->Header
.Class
= ELFYAML::ELF_ELFCLASS(Obj
.getHeader()->getFileClass());
151 Y
->Header
.Data
= ELFYAML::ELF_ELFDATA(Obj
.getHeader()->getDataEncoding());
152 Y
->Header
.OSABI
= Obj
.getHeader()->e_ident
[ELF::EI_OSABI
];
153 Y
->Header
.ABIVersion
= Obj
.getHeader()->e_ident
[ELF::EI_ABIVERSION
];
154 Y
->Header
.Type
= Obj
.getHeader()->e_type
;
155 Y
->Header
.Machine
= Obj
.getHeader()->e_machine
;
156 Y
->Header
.Flags
= Obj
.getHeader()->e_flags
;
157 Y
->Header
.Entry
= Obj
.getHeader()->e_entry
;
160 auto SectionsOrErr
= Obj
.sections();
162 return SectionsOrErr
.takeError();
163 Sections
= *SectionsOrErr
;
164 SectionNames
.resize(Sections
.size());
166 // Dump symbols. We need to do this early because other sections might want
167 // to access the deduplicated symbol names that we also create here.
168 const Elf_Shdr
*SymTab
= nullptr;
169 const Elf_Shdr
*SymTabShndx
= nullptr;
170 const Elf_Shdr
*DynSymTab
= nullptr;
172 for (const Elf_Shdr
&Sec
: Sections
) {
173 if (Sec
.sh_type
== ELF::SHT_SYMTAB
) {
175 } else if (Sec
.sh_type
== ELF::SHT_DYNSYM
) {
177 } else if (Sec
.sh_type
== ELF::SHT_SYMTAB_SHNDX
) {
178 // ABI allows us to have one SHT_SYMTAB_SHNDX for each symbol table.
179 // We only support having the SHT_SYMTAB_SHNDX for SHT_SYMTAB now.
181 return createStringError(obj2yaml_error::not_implemented
,
182 "multiple SHT_SYMTAB_SHNDX sections are not supported");
187 // We need to locate the SHT_SYMTAB_SHNDX section early, because it might be
188 // needed for dumping symbols.
190 if (!SymTab
|| SymTabShndx
->sh_link
!= SymTab
- Sections
.begin())
191 return createStringError(
192 obj2yaml_error::not_implemented
,
193 "only SHT_SYMTAB_SHNDX associated with SHT_SYMTAB are supported");
195 auto TableOrErr
= Obj
.getSHNDXTable(*SymTabShndx
);
197 return TableOrErr
.takeError();
198 ShndxTable
= *TableOrErr
;
201 if (Error E
= dumpSymbols(SymTab
, Y
->Symbols
))
204 if (Error E
= dumpSymbols(DynSymTab
, Y
->DynamicSymbols
))
207 for (const Elf_Shdr
&Sec
: Sections
) {
208 switch (Sec
.sh_type
) {
209 case ELF::SHT_DYNAMIC
: {
210 Expected
<ELFYAML::DynamicSection
*> SecOrErr
= dumpDynamicSection(&Sec
);
212 return SecOrErr
.takeError();
213 Y
->Sections
.emplace_back(*SecOrErr
);
216 case ELF::SHT_STRTAB
:
217 case ELF::SHT_SYMTAB
:
218 case ELF::SHT_DYNSYM
:
219 // Do not dump these sections.
221 case ELF::SHT_SYMTAB_SHNDX
: {
222 Expected
<ELFYAML::SymtabShndxSection
*> SecOrErr
=
223 dumpSymtabShndxSection(&Sec
);
225 return SecOrErr
.takeError();
226 Y
->Sections
.emplace_back(*SecOrErr
);
230 case ELF::SHT_RELA
: {
231 Expected
<ELFYAML::RelocationSection
*> SecOrErr
= dumpRelocSection(&Sec
);
233 return SecOrErr
.takeError();
234 Y
->Sections
.emplace_back(*SecOrErr
);
237 case ELF::SHT_GROUP
: {
238 Expected
<ELFYAML::Group
*> GroupOrErr
= dumpGroup(&Sec
);
240 return GroupOrErr
.takeError();
241 Y
->Sections
.emplace_back(*GroupOrErr
);
244 case ELF::SHT_MIPS_ABIFLAGS
: {
245 Expected
<ELFYAML::MipsABIFlags
*> SecOrErr
= dumpMipsABIFlags(&Sec
);
247 return SecOrErr
.takeError();
248 Y
->Sections
.emplace_back(*SecOrErr
);
251 case ELF::SHT_NOBITS
: {
252 Expected
<ELFYAML::NoBitsSection
*> SecOrErr
= dumpNoBitsSection(&Sec
);
254 return SecOrErr
.takeError();
255 Y
->Sections
.emplace_back(*SecOrErr
);
258 case ELF::SHT_GNU_verdef
: {
259 Expected
<ELFYAML::VerdefSection
*> SecOrErr
= dumpVerdefSection(&Sec
);
261 return SecOrErr
.takeError();
262 Y
->Sections
.emplace_back(*SecOrErr
);
265 case ELF::SHT_GNU_versym
: {
266 Expected
<ELFYAML::SymverSection
*> SecOrErr
= dumpSymverSection(&Sec
);
268 return SecOrErr
.takeError();
269 Y
->Sections
.emplace_back(*SecOrErr
);
272 case ELF::SHT_GNU_verneed
: {
273 Expected
<ELFYAML::VerneedSection
*> SecOrErr
= dumpVerneedSection(&Sec
);
275 return SecOrErr
.takeError();
276 Y
->Sections
.emplace_back(*SecOrErr
);
279 case ELF::SHT_NULL
: {
280 // We only dump the SHT_NULL section at index 0 when it
281 // has at least one non-null field, because yaml2obj
282 // normally creates the zero section at index 0 implicitly.
283 if (&Sec
== &Sections
[0]) {
284 const uint8_t *Begin
= reinterpret_cast<const uint8_t *>(&Sec
);
285 const uint8_t *End
= Begin
+ sizeof(Elf_Shdr
);
286 if (std::find_if(Begin
, End
, [](uint8_t V
) { return V
!= 0; }) == End
)
292 // Recognize some special SHT_PROGBITS sections by name.
293 if (Sec
.sh_type
== ELF::SHT_PROGBITS
) {
294 Expected
<ELFYAML::Section
*> SpecialSecOrErr
= dumpSpecialSection(&Sec
);
295 if (!SpecialSecOrErr
)
296 return SpecialSecOrErr
.takeError();
297 if (*SpecialSecOrErr
) {
298 Y
->Sections
.emplace_back(*SpecialSecOrErr
);
303 Expected
<ELFYAML::RawContentSection
*> SecOrErr
=
304 dumpContentSection(&Sec
);
306 return SecOrErr
.takeError();
307 Y
->Sections
.emplace_back(*SecOrErr
);
315 template <class ELFT
>
316 Error ELFDumper
<ELFT
>::dumpSymbols(const Elf_Shdr
*Symtab
,
317 std::vector
<ELFYAML::Symbol
> &Symbols
) {
319 return Error::success();
321 auto StrTableOrErr
= Obj
.getStringTableForSymtab(*Symtab
);
323 return StrTableOrErr
.takeError();
324 StringRef StrTable
= *StrTableOrErr
;
326 auto SymtabOrErr
= Obj
.symbols(Symtab
);
328 return SymtabOrErr
.takeError();
330 if (Symtab
->sh_type
== ELF::SHT_SYMTAB
) {
331 SymTable
= *SymtabOrErr
;
332 SymbolNames
.resize(SymTable
.size());
335 for (const auto &Sym
: (*SymtabOrErr
).drop_front()) {
337 if (auto EC
= dumpSymbol(&Sym
, Symtab
, StrTable
, S
))
339 Symbols
.push_back(S
);
342 return Error::success();
345 template <class ELFT
>
346 Error ELFDumper
<ELFT
>::dumpSymbol(const Elf_Sym
*Sym
, const Elf_Shdr
*SymTab
,
347 StringRef StrTable
, ELFYAML::Symbol
&S
) {
348 S
.Type
= Sym
->getType();
349 S
.Value
= Sym
->st_value
;
350 S
.Size
= Sym
->st_size
;
351 S
.Other
= Sym
->st_other
;
352 S
.Binding
= Sym
->getBinding();
354 Expected
<StringRef
> SymbolNameOrErr
=
355 getUniquedSymbolName(Sym
, StrTable
, SymTab
);
356 if (!SymbolNameOrErr
)
357 return SymbolNameOrErr
.takeError();
358 S
.Name
= SymbolNameOrErr
.get();
360 if (Sym
->st_shndx
>= ELF::SHN_LORESERVE
) {
361 S
.Index
= (ELFYAML::ELF_SHN
)Sym
->st_shndx
;
362 return Error::success();
365 auto ShdrOrErr
= Obj
.getSection(Sym
, SymTab
, ShndxTable
);
367 return ShdrOrErr
.takeError();
368 const Elf_Shdr
*Shdr
= *ShdrOrErr
;
370 return Error::success();
372 auto NameOrErr
= getUniquedSectionName(Shdr
);
374 return NameOrErr
.takeError();
375 S
.Section
= NameOrErr
.get();
377 return Error::success();
380 template <class ELFT
>
381 template <class RelT
>
382 Error ELFDumper
<ELFT
>::dumpRelocation(const RelT
*Rel
, const Elf_Shdr
*SymTab
,
383 ELFYAML::Relocation
&R
) {
384 R
.Type
= Rel
->getType(Obj
.isMips64EL());
385 R
.Offset
= Rel
->r_offset
;
388 auto SymOrErr
= Obj
.getRelocationSymbol(Rel
, SymTab
);
390 return SymOrErr
.takeError();
391 const Elf_Sym
*Sym
= *SymOrErr
;
392 auto StrTabSec
= Obj
.getSection(SymTab
->sh_link
);
394 return StrTabSec
.takeError();
395 auto StrTabOrErr
= Obj
.getStringTable(*StrTabSec
);
397 return StrTabOrErr
.takeError();
398 StringRef StrTab
= *StrTabOrErr
;
401 Expected
<StringRef
> NameOrErr
= getUniquedSymbolName(Sym
, StrTab
, SymTab
);
403 return NameOrErr
.takeError();
404 R
.Symbol
= NameOrErr
.get();
406 // We have some edge cases of relocations without a symbol associated,
407 // e.g. an object containing the invalid (according to the System V
408 // ABI) R_X86_64_NONE reloc. Create a symbol with an empty name instead
413 return Error::success();
416 template <class ELFT
>
417 Error ELFDumper
<ELFT
>::dumpCommonSection(const Elf_Shdr
*Shdr
,
418 ELFYAML::Section
&S
) {
419 // Dump fields. We do not dump the ShOffset field. When not explicitly
420 // set, the value is set by yaml2obj automatically.
421 S
.Type
= Shdr
->sh_type
;
423 S
.Flags
= static_cast<ELFYAML::ELF_SHF
>(Shdr
->sh_flags
);
424 S
.Address
= Shdr
->sh_addr
;
425 S
.AddressAlign
= Shdr
->sh_addralign
;
426 if (Shdr
->sh_entsize
)
427 S
.EntSize
= static_cast<llvm::yaml::Hex64
>(Shdr
->sh_entsize
);
429 auto NameOrErr
= getUniquedSectionName(Shdr
);
431 return NameOrErr
.takeError();
432 S
.Name
= NameOrErr
.get();
434 if (Shdr
->sh_link
!= ELF::SHN_UNDEF
) {
435 auto LinkSection
= Obj
.getSection(Shdr
->sh_link
);
437 return make_error
<StringError
>(
438 "unable to resolve sh_link reference in section '" + S
.Name
+
439 "': " + toString(LinkSection
.takeError()),
440 inconvertibleErrorCode());
442 NameOrErr
= getUniquedSectionName(*LinkSection
);
444 return NameOrErr
.takeError();
445 S
.Link
= NameOrErr
.get();
448 return Error::success();
451 template <class ELFT
>
452 Expected
<ELFYAML::Section
*>
453 ELFDumper
<ELFT
>::dumpSpecialSection(const Elf_Shdr
*Shdr
) {
454 auto NameOrErr
= getUniquedSectionName(Shdr
);
456 return NameOrErr
.takeError();
458 if (ELFYAML::StackSizesSection::nameMatches(*NameOrErr
))
459 return dumpStackSizesSection(Shdr
);
463 template <class ELFT
>
464 Error ELFDumper
<ELFT
>::dumpCommonRelocationSection(
465 const Elf_Shdr
*Shdr
, ELFYAML::RelocationSection
&S
) {
466 if (Error E
= dumpCommonSection(Shdr
, S
))
469 auto InfoSection
= Obj
.getSection(Shdr
->sh_info
);
471 return InfoSection
.takeError();
473 auto NameOrErr
= getUniquedSectionName(*InfoSection
);
475 return NameOrErr
.takeError();
476 S
.RelocatableSec
= NameOrErr
.get();
478 return Error::success();
481 template <class ELFT
>
482 Expected
<ELFYAML::StackSizesSection
*>
483 ELFDumper
<ELFT
>::dumpStackSizesSection(const Elf_Shdr
*Shdr
) {
484 auto S
= std::make_unique
<ELFYAML::StackSizesSection
>();
485 if (Error E
= dumpCommonSection(Shdr
, *S
))
488 auto ContentOrErr
= Obj
.getSectionContents(Shdr
);
490 return ContentOrErr
.takeError();
492 ArrayRef
<uint8_t> Content
= *ContentOrErr
;
493 DataExtractor
Data(Content
, Obj
.isLE(), ELFT::Is64Bits
? 8 : 4);
495 std::vector
<ELFYAML::StackSizeEntry
> Entries
;
496 DataExtractor::Cursor
Cur(0);
497 while (Cur
&& Cur
.tell() < Content
.size()) {
498 uint64_t Address
= Data
.getAddress(Cur
);
499 uint64_t Size
= Data
.getULEB128(Cur
);
500 Entries
.push_back({Address
, Size
});
503 if (Content
.empty() || !Cur
) {
504 // If .stack_sizes cannot be decoded, we dump it as an array of bytes.
505 consumeError(Cur
.takeError());
506 S
->Content
= yaml::BinaryRef(Content
);
508 S
->Entries
= std::move(Entries
);
514 template <class ELFT
>
515 Expected
<ELFYAML::DynamicSection
*>
516 ELFDumper
<ELFT
>::dumpDynamicSection(const Elf_Shdr
*Shdr
) {
517 auto S
= std::make_unique
<ELFYAML::DynamicSection
>();
518 if (Error E
= dumpCommonSection(Shdr
, *S
))
521 auto DynTagsOrErr
= Obj
.template getSectionContentsAsArray
<Elf_Dyn
>(Shdr
);
523 return DynTagsOrErr
.takeError();
525 for (const Elf_Dyn
&Dyn
: *DynTagsOrErr
)
526 S
->Entries
.push_back({(ELFYAML::ELF_DYNTAG
)Dyn
.getTag(), Dyn
.getVal()});
531 template <class ELFT
>
532 Expected
<ELFYAML::RelocationSection
*>
533 ELFDumper
<ELFT
>::dumpRelocSection(const Elf_Shdr
*Shdr
) {
534 auto S
= std::make_unique
<ELFYAML::RelocationSection
>();
535 if (auto E
= dumpCommonRelocationSection(Shdr
, *S
))
538 auto SymTabOrErr
= Obj
.getSection(Shdr
->sh_link
);
540 return SymTabOrErr
.takeError();
541 const Elf_Shdr
*SymTab
= *SymTabOrErr
;
543 if (Shdr
->sh_type
== ELF::SHT_REL
) {
544 auto Rels
= Obj
.rels(Shdr
);
546 return Rels
.takeError();
547 for (const Elf_Rel
&Rel
: *Rels
) {
548 ELFYAML::Relocation R
;
549 if (Error E
= dumpRelocation(&Rel
, SymTab
, R
))
551 S
->Relocations
.push_back(R
);
554 auto Rels
= Obj
.relas(Shdr
);
556 return Rels
.takeError();
557 for (const Elf_Rela
&Rel
: *Rels
) {
558 ELFYAML::Relocation R
;
559 if (Error E
= dumpRelocation(&Rel
, SymTab
, R
))
561 R
.Addend
= Rel
.r_addend
;
562 S
->Relocations
.push_back(R
);
569 template <class ELFT
>
570 Expected
<ELFYAML::RawContentSection
*>
571 ELFDumper
<ELFT
>::dumpContentSection(const Elf_Shdr
*Shdr
) {
572 auto S
= std::make_unique
<ELFYAML::RawContentSection
>();
573 if (Error E
= dumpCommonSection(Shdr
, *S
))
576 unsigned SecIndex
= Shdr
- &Sections
[0];
577 if (SecIndex
!= 0 || Shdr
->sh_type
!= ELF::SHT_NULL
) {
578 auto ContentOrErr
= Obj
.getSectionContents(Shdr
);
580 return ContentOrErr
.takeError();
581 ArrayRef
<uint8_t> Content
= *ContentOrErr
;
582 if (!Content
.empty())
583 S
->Content
= yaml::BinaryRef(Content
);
585 S
->Size
= static_cast<llvm::yaml::Hex64
>(Shdr
->sh_size
);
589 S
->Info
= static_cast<llvm::yaml::Hex64
>(Shdr
->sh_info
);
593 template <class ELFT
>
594 Expected
<ELFYAML::SymtabShndxSection
*>
595 ELFDumper
<ELFT
>::dumpSymtabShndxSection(const Elf_Shdr
*Shdr
) {
596 auto S
= std::make_unique
<ELFYAML::SymtabShndxSection
>();
597 if (Error E
= dumpCommonSection(Shdr
, *S
))
600 auto EntriesOrErr
= Obj
.template getSectionContentsAsArray
<Elf_Word
>(Shdr
);
602 return EntriesOrErr
.takeError();
603 for (const Elf_Word
&E
: *EntriesOrErr
)
604 S
->Entries
.push_back(E
);
608 template <class ELFT
>
609 Expected
<ELFYAML::NoBitsSection
*>
610 ELFDumper
<ELFT
>::dumpNoBitsSection(const Elf_Shdr
*Shdr
) {
611 auto S
= std::make_unique
<ELFYAML::NoBitsSection
>();
612 if (Error E
= dumpCommonSection(Shdr
, *S
))
614 S
->Size
= Shdr
->sh_size
;
619 template <class ELFT
>
620 Expected
<ELFYAML::VerdefSection
*>
621 ELFDumper
<ELFT
>::dumpVerdefSection(const Elf_Shdr
*Shdr
) {
622 typedef typename
ELFT::Verdef Elf_Verdef
;
623 typedef typename
ELFT::Verdaux Elf_Verdaux
;
625 auto S
= std::make_unique
<ELFYAML::VerdefSection
>();
626 if (Error E
= dumpCommonSection(Shdr
, *S
))
629 S
->Info
= Shdr
->sh_info
;
631 auto StringTableShdrOrErr
= Obj
.getSection(Shdr
->sh_link
);
632 if (!StringTableShdrOrErr
)
633 return StringTableShdrOrErr
.takeError();
635 auto StringTableOrErr
= Obj
.getStringTable(*StringTableShdrOrErr
);
636 if (!StringTableOrErr
)
637 return StringTableOrErr
.takeError();
639 auto Contents
= Obj
.getSectionContents(Shdr
);
641 return Contents
.takeError();
643 llvm::ArrayRef
<uint8_t> Data
= *Contents
;
644 const uint8_t *Buf
= Data
.data();
646 const Elf_Verdef
*Verdef
= reinterpret_cast<const Elf_Verdef
*>(Buf
);
647 ELFYAML::VerdefEntry Entry
;
648 Entry
.Version
= Verdef
->vd_version
;
649 Entry
.Flags
= Verdef
->vd_flags
;
650 Entry
.VersionNdx
= Verdef
->vd_ndx
;
651 Entry
.Hash
= Verdef
->vd_hash
;
653 const uint8_t *BufAux
= Buf
+ Verdef
->vd_aux
;
655 const Elf_Verdaux
*Verdaux
=
656 reinterpret_cast<const Elf_Verdaux
*>(BufAux
);
657 Entry
.VerNames
.push_back(
658 StringTableOrErr
->drop_front(Verdaux
->vda_name
).data());
659 BufAux
= Verdaux
->vda_next
? BufAux
+ Verdaux
->vda_next
: nullptr;
662 S
->Entries
.push_back(Entry
);
663 Buf
= Verdef
->vd_next
? Buf
+ Verdef
->vd_next
: nullptr;
669 template <class ELFT
>
670 Expected
<ELFYAML::SymverSection
*>
671 ELFDumper
<ELFT
>::dumpSymverSection(const Elf_Shdr
*Shdr
) {
672 typedef typename
ELFT::Half Elf_Half
;
674 auto S
= std::make_unique
<ELFYAML::SymverSection
>();
675 if (Error E
= dumpCommonSection(Shdr
, *S
))
678 auto VersionsOrErr
= Obj
.template getSectionContentsAsArray
<Elf_Half
>(Shdr
);
680 return VersionsOrErr
.takeError();
681 for (const Elf_Half
&E
: *VersionsOrErr
)
682 S
->Entries
.push_back(E
);
687 template <class ELFT
>
688 Expected
<ELFYAML::VerneedSection
*>
689 ELFDumper
<ELFT
>::dumpVerneedSection(const Elf_Shdr
*Shdr
) {
690 typedef typename
ELFT::Verneed Elf_Verneed
;
691 typedef typename
ELFT::Vernaux Elf_Vernaux
;
693 auto S
= std::make_unique
<ELFYAML::VerneedSection
>();
694 if (Error E
= dumpCommonSection(Shdr
, *S
))
697 S
->Info
= Shdr
->sh_info
;
699 auto Contents
= Obj
.getSectionContents(Shdr
);
701 return Contents
.takeError();
703 auto StringTableShdrOrErr
= Obj
.getSection(Shdr
->sh_link
);
704 if (!StringTableShdrOrErr
)
705 return StringTableShdrOrErr
.takeError();
707 auto StringTableOrErr
= Obj
.getStringTable(*StringTableShdrOrErr
);
708 if (!StringTableOrErr
)
709 return StringTableOrErr
.takeError();
711 llvm::ArrayRef
<uint8_t> Data
= *Contents
;
712 const uint8_t *Buf
= Data
.data();
714 const Elf_Verneed
*Verneed
= reinterpret_cast<const Elf_Verneed
*>(Buf
);
716 ELFYAML::VerneedEntry Entry
;
717 Entry
.Version
= Verneed
->vn_version
;
719 StringRef(StringTableOrErr
->drop_front(Verneed
->vn_file
).data());
721 const uint8_t *BufAux
= Buf
+ Verneed
->vn_aux
;
723 const Elf_Vernaux
*Vernaux
=
724 reinterpret_cast<const Elf_Vernaux
*>(BufAux
);
726 ELFYAML::VernauxEntry Aux
;
727 Aux
.Hash
= Vernaux
->vna_hash
;
728 Aux
.Flags
= Vernaux
->vna_flags
;
729 Aux
.Other
= Vernaux
->vna_other
;
731 StringRef(StringTableOrErr
->drop_front(Vernaux
->vna_name
).data());
733 Entry
.AuxV
.push_back(Aux
);
734 BufAux
= Vernaux
->vna_next
? BufAux
+ Vernaux
->vna_next
: nullptr;
737 S
->VerneedV
.push_back(Entry
);
738 Buf
= Verneed
->vn_next
? Buf
+ Verneed
->vn_next
: nullptr;
744 template <class ELFT
>
745 Expected
<ELFYAML::Group
*> ELFDumper
<ELFT
>::dumpGroup(const Elf_Shdr
*Shdr
) {
746 auto S
= std::make_unique
<ELFYAML::Group
>();
747 if (Error E
= dumpCommonSection(Shdr
, *S
))
750 auto SymtabOrErr
= Obj
.getSection(Shdr
->sh_link
);
752 return SymtabOrErr
.takeError();
753 // Get symbol with index sh_info which name is the signature of the group.
754 const Elf_Shdr
*Symtab
= *SymtabOrErr
;
755 auto SymOrErr
= Obj
.getSymbol(Symtab
, Shdr
->sh_info
);
757 return SymOrErr
.takeError();
758 auto StrTabOrErr
= Obj
.getStringTableForSymtab(*Symtab
);
760 return StrTabOrErr
.takeError();
762 Expected
<StringRef
> SymbolName
=
763 getUniquedSymbolName(*SymOrErr
, *StrTabOrErr
, Symtab
);
765 return SymbolName
.takeError();
766 S
->Signature
= *SymbolName
;
768 auto MembersOrErr
= Obj
.template getSectionContentsAsArray
<Elf_Word
>(Shdr
);
770 return MembersOrErr
.takeError();
772 for (Elf_Word Member
: *MembersOrErr
) {
773 if (Member
== llvm::ELF::GRP_COMDAT
) {
774 S
->Members
.push_back({"GRP_COMDAT"});
778 auto SHdrOrErr
= Obj
.getSection(Member
);
780 return SHdrOrErr
.takeError();
781 auto NameOrErr
= getUniquedSectionName(*SHdrOrErr
);
783 return NameOrErr
.takeError();
784 S
->Members
.push_back({*NameOrErr
});
789 template <class ELFT
>
790 Expected
<ELFYAML::MipsABIFlags
*>
791 ELFDumper
<ELFT
>::dumpMipsABIFlags(const Elf_Shdr
*Shdr
) {
792 assert(Shdr
->sh_type
== ELF::SHT_MIPS_ABIFLAGS
&&
793 "Section type is not SHT_MIPS_ABIFLAGS");
794 auto S
= std::make_unique
<ELFYAML::MipsABIFlags
>();
795 if (Error E
= dumpCommonSection(Shdr
, *S
))
798 auto ContentOrErr
= Obj
.getSectionContents(Shdr
);
800 return ContentOrErr
.takeError();
802 auto *Flags
= reinterpret_cast<const object::Elf_Mips_ABIFlags
<ELFT
> *>(
803 ContentOrErr
.get().data());
804 S
->Version
= Flags
->version
;
805 S
->ISALevel
= Flags
->isa_level
;
806 S
->ISARevision
= Flags
->isa_rev
;
807 S
->GPRSize
= Flags
->gpr_size
;
808 S
->CPR1Size
= Flags
->cpr1_size
;
809 S
->CPR2Size
= Flags
->cpr2_size
;
810 S
->FpABI
= Flags
->fp_abi
;
811 S
->ISAExtension
= Flags
->isa_ext
;
812 S
->ASEs
= Flags
->ases
;
813 S
->Flags1
= Flags
->flags1
;
814 S
->Flags2
= Flags
->flags2
;
818 template <class ELFT
>
819 static Error
elf2yaml(raw_ostream
&Out
, const object::ELFFile
<ELFT
> &Obj
) {
820 ELFDumper
<ELFT
> Dumper(Obj
);
821 Expected
<ELFYAML::Object
*> YAMLOrErr
= Dumper
.dump();
823 return YAMLOrErr
.takeError();
825 std::unique_ptr
<ELFYAML::Object
> YAML(YAMLOrErr
.get());
826 yaml::Output
Yout(Out
);
829 return Error::success();
832 Error
elf2yaml(raw_ostream
&Out
, const object::ObjectFile
&Obj
) {
833 if (const auto *ELFObj
= dyn_cast
<object::ELF32LEObjectFile
>(&Obj
))
834 return elf2yaml(Out
, *ELFObj
->getELFFile());
836 if (const auto *ELFObj
= dyn_cast
<object::ELF32BEObjectFile
>(&Obj
))
837 return elf2yaml(Out
, *ELFObj
->getELFFile());
839 if (const auto *ELFObj
= dyn_cast
<object::ELF64LEObjectFile
>(&Obj
))
840 return elf2yaml(Out
, *ELFObj
->getELFFile());
842 if (const auto *ELFObj
= dyn_cast
<object::ELF64BEObjectFile
>(&Obj
))
843 return elf2yaml(Out
, *ELFObj
->getELFFile());
845 llvm_unreachable("unknown ELF file format");