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::HashSection
*> dumpHashSection(const Elf_Shdr
*Shdr
);
67 Expected
<ELFYAML::VerdefSection
*> dumpVerdefSection(const Elf_Shdr
*Shdr
);
68 Expected
<ELFYAML::SymverSection
*> dumpSymverSection(const Elf_Shdr
*Shdr
);
69 Expected
<ELFYAML::VerneedSection
*> dumpVerneedSection(const Elf_Shdr
*Shdr
);
70 Expected
<ELFYAML::Group
*> dumpGroup(const Elf_Shdr
*Shdr
);
71 Expected
<ELFYAML::MipsABIFlags
*> dumpMipsABIFlags(const Elf_Shdr
*Shdr
);
72 Expected
<ELFYAML::StackSizesSection
*>
73 dumpStackSizesSection(const Elf_Shdr
*Shdr
);
75 Expected
<ELFYAML::Section
*> dumpSpecialSection(const Elf_Shdr
*Shdr
);
78 ELFDumper(const object::ELFFile
<ELFT
> &O
);
79 Expected
<ELFYAML::Object
*> dump();
85 ELFDumper
<ELFT
>::ELFDumper(const object::ELFFile
<ELFT
> &O
)
90 ELFDumper
<ELFT
>::getUniquedSectionName(const Elf_Shdr
*Sec
) {
91 unsigned SecIndex
= Sec
- &Sections
[0];
92 assert(&Sections
[SecIndex
] == Sec
);
93 if (!SectionNames
[SecIndex
].empty())
94 return SectionNames
[SecIndex
];
96 auto NameOrErr
= Obj
.getSectionName(Sec
);
99 StringRef Name
= *NameOrErr
;
100 std::string
&Ret
= SectionNames
[SecIndex
];
102 auto It
= UsedSectionNames
.insert({Name
, 0});
104 Ret
= (Name
+ " [" + Twine(++It
.first
->second
) + "]").str();
110 template <class ELFT
>
112 ELFDumper
<ELFT
>::getUniquedSymbolName(const Elf_Sym
*Sym
, StringRef StrTable
,
113 const Elf_Shdr
*SymTab
) {
114 Expected
<StringRef
> SymbolNameOrErr
= Sym
->getName(StrTable
);
115 if (!SymbolNameOrErr
)
116 return SymbolNameOrErr
;
117 StringRef Name
= *SymbolNameOrErr
;
118 if (Name
.empty() && Sym
->getType() == ELF::STT_SECTION
) {
119 auto ShdrOrErr
= Obj
.getSection(Sym
, SymTab
, ShndxTable
);
121 return ShdrOrErr
.takeError();
122 return getUniquedSectionName(*ShdrOrErr
);
125 // Symbols in .symtab can have duplicate names. For example, it is a common
126 // situation for local symbols in a relocatable object. Here we assign unique
127 // suffixes for such symbols so that we can differentiate them.
128 if (SymTab
->sh_type
== ELF::SHT_SYMTAB
) {
129 unsigned Index
= Sym
- SymTable
.data();
130 if (!SymbolNames
[Index
].empty())
131 return SymbolNames
[Index
];
133 auto It
= UsedSymbolNames
.insert({Name
, 0});
136 (Name
+ " [" + Twine(++It
.first
->second
) + "]").str();
138 SymbolNames
[Index
] = Name
;
139 return SymbolNames
[Index
];
145 template <class ELFT
> Expected
<ELFYAML::Object
*> ELFDumper
<ELFT
>::dump() {
146 auto Y
= std::make_unique
<ELFYAML::Object
>();
148 // Dump header. We do not dump SHEntSize, SHOff, SHNum and SHStrNdx fields.
149 // When not explicitly set, the values are set by yaml2obj automatically
150 // and there is no need to dump them here.
151 Y
->Header
.Class
= ELFYAML::ELF_ELFCLASS(Obj
.getHeader()->getFileClass());
152 Y
->Header
.Data
= ELFYAML::ELF_ELFDATA(Obj
.getHeader()->getDataEncoding());
153 Y
->Header
.OSABI
= Obj
.getHeader()->e_ident
[ELF::EI_OSABI
];
154 Y
->Header
.ABIVersion
= Obj
.getHeader()->e_ident
[ELF::EI_ABIVERSION
];
155 Y
->Header
.Type
= Obj
.getHeader()->e_type
;
156 Y
->Header
.Machine
= Obj
.getHeader()->e_machine
;
157 Y
->Header
.Flags
= Obj
.getHeader()->e_flags
;
158 Y
->Header
.Entry
= Obj
.getHeader()->e_entry
;
161 auto SectionsOrErr
= Obj
.sections();
163 return SectionsOrErr
.takeError();
164 Sections
= *SectionsOrErr
;
165 SectionNames
.resize(Sections
.size());
167 // Dump symbols. We need to do this early because other sections might want
168 // to access the deduplicated symbol names that we also create here.
169 const Elf_Shdr
*SymTab
= nullptr;
170 const Elf_Shdr
*SymTabShndx
= nullptr;
171 const Elf_Shdr
*DynSymTab
= nullptr;
173 for (const Elf_Shdr
&Sec
: Sections
) {
174 if (Sec
.sh_type
== ELF::SHT_SYMTAB
) {
176 } else if (Sec
.sh_type
== ELF::SHT_DYNSYM
) {
178 } else if (Sec
.sh_type
== ELF::SHT_SYMTAB_SHNDX
) {
179 // ABI allows us to have one SHT_SYMTAB_SHNDX for each symbol table.
180 // We only support having the SHT_SYMTAB_SHNDX for SHT_SYMTAB now.
182 return createStringError(obj2yaml_error::not_implemented
,
183 "multiple SHT_SYMTAB_SHNDX sections are not supported");
188 // We need to locate the SHT_SYMTAB_SHNDX section early, because it might be
189 // needed for dumping symbols.
191 if (!SymTab
|| SymTabShndx
->sh_link
!= SymTab
- Sections
.begin())
192 return createStringError(
193 obj2yaml_error::not_implemented
,
194 "only SHT_SYMTAB_SHNDX associated with SHT_SYMTAB are supported");
196 auto TableOrErr
= Obj
.getSHNDXTable(*SymTabShndx
);
198 return TableOrErr
.takeError();
199 ShndxTable
= *TableOrErr
;
202 if (Error E
= dumpSymbols(SymTab
, Y
->Symbols
))
205 if (Error E
= dumpSymbols(DynSymTab
, Y
->DynamicSymbols
))
208 for (const Elf_Shdr
&Sec
: Sections
) {
209 switch (Sec
.sh_type
) {
210 case ELF::SHT_DYNAMIC
: {
211 Expected
<ELFYAML::DynamicSection
*> SecOrErr
= dumpDynamicSection(&Sec
);
213 return SecOrErr
.takeError();
214 Y
->Sections
.emplace_back(*SecOrErr
);
217 case ELF::SHT_STRTAB
:
218 case ELF::SHT_SYMTAB
:
219 case ELF::SHT_DYNSYM
:
220 // Do not dump these sections.
222 case ELF::SHT_SYMTAB_SHNDX
: {
223 Expected
<ELFYAML::SymtabShndxSection
*> SecOrErr
=
224 dumpSymtabShndxSection(&Sec
);
226 return SecOrErr
.takeError();
227 Y
->Sections
.emplace_back(*SecOrErr
);
231 case ELF::SHT_RELA
: {
232 Expected
<ELFYAML::RelocationSection
*> SecOrErr
= dumpRelocSection(&Sec
);
234 return SecOrErr
.takeError();
235 Y
->Sections
.emplace_back(*SecOrErr
);
238 case ELF::SHT_GROUP
: {
239 Expected
<ELFYAML::Group
*> GroupOrErr
= dumpGroup(&Sec
);
241 return GroupOrErr
.takeError();
242 Y
->Sections
.emplace_back(*GroupOrErr
);
245 case ELF::SHT_MIPS_ABIFLAGS
: {
246 Expected
<ELFYAML::MipsABIFlags
*> SecOrErr
= dumpMipsABIFlags(&Sec
);
248 return SecOrErr
.takeError();
249 Y
->Sections
.emplace_back(*SecOrErr
);
252 case ELF::SHT_NOBITS
: {
253 Expected
<ELFYAML::NoBitsSection
*> SecOrErr
= dumpNoBitsSection(&Sec
);
255 return SecOrErr
.takeError();
256 Y
->Sections
.emplace_back(*SecOrErr
);
259 case ELF::SHT_HASH
: {
260 Expected
<ELFYAML::HashSection
*> SecOrErr
= dumpHashSection(&Sec
);
262 return SecOrErr
.takeError();
263 Y
->Sections
.emplace_back(*SecOrErr
);
266 case ELF::SHT_GNU_verdef
: {
267 Expected
<ELFYAML::VerdefSection
*> SecOrErr
= dumpVerdefSection(&Sec
);
269 return SecOrErr
.takeError();
270 Y
->Sections
.emplace_back(*SecOrErr
);
273 case ELF::SHT_GNU_versym
: {
274 Expected
<ELFYAML::SymverSection
*> SecOrErr
= dumpSymverSection(&Sec
);
276 return SecOrErr
.takeError();
277 Y
->Sections
.emplace_back(*SecOrErr
);
280 case ELF::SHT_GNU_verneed
: {
281 Expected
<ELFYAML::VerneedSection
*> SecOrErr
= dumpVerneedSection(&Sec
);
283 return SecOrErr
.takeError();
284 Y
->Sections
.emplace_back(*SecOrErr
);
287 case ELF::SHT_NULL
: {
288 // We only dump the SHT_NULL section at index 0 when it
289 // has at least one non-null field, because yaml2obj
290 // normally creates the zero section at index 0 implicitly.
291 if (&Sec
== &Sections
[0]) {
292 const uint8_t *Begin
= reinterpret_cast<const uint8_t *>(&Sec
);
293 const uint8_t *End
= Begin
+ sizeof(Elf_Shdr
);
294 if (std::find_if(Begin
, End
, [](uint8_t V
) { return V
!= 0; }) == End
)
300 // Recognize some special SHT_PROGBITS sections by name.
301 if (Sec
.sh_type
== ELF::SHT_PROGBITS
) {
302 Expected
<ELFYAML::Section
*> SpecialSecOrErr
= dumpSpecialSection(&Sec
);
303 if (!SpecialSecOrErr
)
304 return SpecialSecOrErr
.takeError();
305 if (*SpecialSecOrErr
) {
306 Y
->Sections
.emplace_back(*SpecialSecOrErr
);
311 Expected
<ELFYAML::RawContentSection
*> SecOrErr
=
312 dumpContentSection(&Sec
);
314 return SecOrErr
.takeError();
315 Y
->Sections
.emplace_back(*SecOrErr
);
323 template <class ELFT
>
324 Error ELFDumper
<ELFT
>::dumpSymbols(const Elf_Shdr
*Symtab
,
325 std::vector
<ELFYAML::Symbol
> &Symbols
) {
327 return Error::success();
329 auto StrTableOrErr
= Obj
.getStringTableForSymtab(*Symtab
);
331 return StrTableOrErr
.takeError();
332 StringRef StrTable
= *StrTableOrErr
;
334 auto SymtabOrErr
= Obj
.symbols(Symtab
);
336 return SymtabOrErr
.takeError();
338 if (Symtab
->sh_type
== ELF::SHT_SYMTAB
) {
339 SymTable
= *SymtabOrErr
;
340 SymbolNames
.resize(SymTable
.size());
343 for (const auto &Sym
: (*SymtabOrErr
).drop_front()) {
345 if (auto EC
= dumpSymbol(&Sym
, Symtab
, StrTable
, S
))
347 Symbols
.push_back(S
);
350 return Error::success();
353 template <class ELFT
>
354 Error ELFDumper
<ELFT
>::dumpSymbol(const Elf_Sym
*Sym
, const Elf_Shdr
*SymTab
,
355 StringRef StrTable
, ELFYAML::Symbol
&S
) {
356 S
.Type
= Sym
->getType();
357 S
.Value
= Sym
->st_value
;
358 S
.Size
= Sym
->st_size
;
359 S
.Other
= Sym
->st_other
;
360 S
.Binding
= Sym
->getBinding();
362 Expected
<StringRef
> SymbolNameOrErr
=
363 getUniquedSymbolName(Sym
, StrTable
, SymTab
);
364 if (!SymbolNameOrErr
)
365 return SymbolNameOrErr
.takeError();
366 S
.Name
= SymbolNameOrErr
.get();
368 if (Sym
->st_shndx
>= ELF::SHN_LORESERVE
) {
369 S
.Index
= (ELFYAML::ELF_SHN
)Sym
->st_shndx
;
370 return Error::success();
373 auto ShdrOrErr
= Obj
.getSection(Sym
, SymTab
, ShndxTable
);
375 return ShdrOrErr
.takeError();
376 const Elf_Shdr
*Shdr
= *ShdrOrErr
;
378 return Error::success();
380 auto NameOrErr
= getUniquedSectionName(Shdr
);
382 return NameOrErr
.takeError();
383 S
.Section
= NameOrErr
.get();
385 return Error::success();
388 template <class ELFT
>
389 template <class RelT
>
390 Error ELFDumper
<ELFT
>::dumpRelocation(const RelT
*Rel
, const Elf_Shdr
*SymTab
,
391 ELFYAML::Relocation
&R
) {
392 R
.Type
= Rel
->getType(Obj
.isMips64EL());
393 R
.Offset
= Rel
->r_offset
;
396 auto SymOrErr
= Obj
.getRelocationSymbol(Rel
, SymTab
);
398 return SymOrErr
.takeError();
399 const Elf_Sym
*Sym
= *SymOrErr
;
400 auto StrTabSec
= Obj
.getSection(SymTab
->sh_link
);
402 return StrTabSec
.takeError();
403 auto StrTabOrErr
= Obj
.getStringTable(*StrTabSec
);
405 return StrTabOrErr
.takeError();
406 StringRef StrTab
= *StrTabOrErr
;
409 Expected
<StringRef
> NameOrErr
= getUniquedSymbolName(Sym
, StrTab
, SymTab
);
411 return NameOrErr
.takeError();
412 R
.Symbol
= NameOrErr
.get();
414 // We have some edge cases of relocations without a symbol associated,
415 // e.g. an object containing the invalid (according to the System V
416 // ABI) R_X86_64_NONE reloc. Create a symbol with an empty name instead
421 return Error::success();
424 template <class ELFT
>
425 Error ELFDumper
<ELFT
>::dumpCommonSection(const Elf_Shdr
*Shdr
,
426 ELFYAML::Section
&S
) {
427 // Dump fields. We do not dump the ShOffset field. When not explicitly
428 // set, the value is set by yaml2obj automatically.
429 S
.Type
= Shdr
->sh_type
;
431 S
.Flags
= static_cast<ELFYAML::ELF_SHF
>(Shdr
->sh_flags
);
432 S
.Address
= Shdr
->sh_addr
;
433 S
.AddressAlign
= Shdr
->sh_addralign
;
434 if (Shdr
->sh_entsize
)
435 S
.EntSize
= static_cast<llvm::yaml::Hex64
>(Shdr
->sh_entsize
);
437 auto NameOrErr
= getUniquedSectionName(Shdr
);
439 return NameOrErr
.takeError();
440 S
.Name
= NameOrErr
.get();
442 if (Shdr
->sh_link
!= ELF::SHN_UNDEF
) {
443 auto LinkSection
= Obj
.getSection(Shdr
->sh_link
);
445 return make_error
<StringError
>(
446 "unable to resolve sh_link reference in section '" + S
.Name
+
447 "': " + toString(LinkSection
.takeError()),
448 inconvertibleErrorCode());
450 NameOrErr
= getUniquedSectionName(*LinkSection
);
452 return NameOrErr
.takeError();
453 S
.Link
= NameOrErr
.get();
456 return Error::success();
459 template <class ELFT
>
460 Expected
<ELFYAML::Section
*>
461 ELFDumper
<ELFT
>::dumpSpecialSection(const Elf_Shdr
*Shdr
) {
462 auto NameOrErr
= getUniquedSectionName(Shdr
);
464 return NameOrErr
.takeError();
466 if (ELFYAML::StackSizesSection::nameMatches(*NameOrErr
))
467 return dumpStackSizesSection(Shdr
);
471 template <class ELFT
>
472 Error ELFDumper
<ELFT
>::dumpCommonRelocationSection(
473 const Elf_Shdr
*Shdr
, ELFYAML::RelocationSection
&S
) {
474 if (Error E
= dumpCommonSection(Shdr
, S
))
477 auto InfoSection
= Obj
.getSection(Shdr
->sh_info
);
479 return InfoSection
.takeError();
481 auto NameOrErr
= getUniquedSectionName(*InfoSection
);
483 return NameOrErr
.takeError();
484 S
.RelocatableSec
= NameOrErr
.get();
486 return Error::success();
489 template <class ELFT
>
490 Expected
<ELFYAML::StackSizesSection
*>
491 ELFDumper
<ELFT
>::dumpStackSizesSection(const Elf_Shdr
*Shdr
) {
492 auto S
= std::make_unique
<ELFYAML::StackSizesSection
>();
493 if (Error E
= dumpCommonSection(Shdr
, *S
))
496 auto ContentOrErr
= Obj
.getSectionContents(Shdr
);
498 return ContentOrErr
.takeError();
500 ArrayRef
<uint8_t> Content
= *ContentOrErr
;
501 DataExtractor
Data(Content
, Obj
.isLE(), ELFT::Is64Bits
? 8 : 4);
503 std::vector
<ELFYAML::StackSizeEntry
> Entries
;
504 DataExtractor::Cursor
Cur(0);
505 while (Cur
&& Cur
.tell() < Content
.size()) {
506 uint64_t Address
= Data
.getAddress(Cur
);
507 uint64_t Size
= Data
.getULEB128(Cur
);
508 Entries
.push_back({Address
, Size
});
511 if (Content
.empty() || !Cur
) {
512 // If .stack_sizes cannot be decoded, we dump it as an array of bytes.
513 consumeError(Cur
.takeError());
514 S
->Content
= yaml::BinaryRef(Content
);
516 S
->Entries
= std::move(Entries
);
522 template <class ELFT
>
523 Expected
<ELFYAML::DynamicSection
*>
524 ELFDumper
<ELFT
>::dumpDynamicSection(const Elf_Shdr
*Shdr
) {
525 auto S
= std::make_unique
<ELFYAML::DynamicSection
>();
526 if (Error E
= dumpCommonSection(Shdr
, *S
))
529 auto DynTagsOrErr
= Obj
.template getSectionContentsAsArray
<Elf_Dyn
>(Shdr
);
531 return DynTagsOrErr
.takeError();
533 for (const Elf_Dyn
&Dyn
: *DynTagsOrErr
)
534 S
->Entries
.push_back({(ELFYAML::ELF_DYNTAG
)Dyn
.getTag(), Dyn
.getVal()});
539 template <class ELFT
>
540 Expected
<ELFYAML::RelocationSection
*>
541 ELFDumper
<ELFT
>::dumpRelocSection(const Elf_Shdr
*Shdr
) {
542 auto S
= std::make_unique
<ELFYAML::RelocationSection
>();
543 if (auto E
= dumpCommonRelocationSection(Shdr
, *S
))
546 auto SymTabOrErr
= Obj
.getSection(Shdr
->sh_link
);
548 return SymTabOrErr
.takeError();
549 const Elf_Shdr
*SymTab
= *SymTabOrErr
;
551 if (Shdr
->sh_type
== ELF::SHT_REL
) {
552 auto Rels
= Obj
.rels(Shdr
);
554 return Rels
.takeError();
555 for (const Elf_Rel
&Rel
: *Rels
) {
556 ELFYAML::Relocation R
;
557 if (Error E
= dumpRelocation(&Rel
, SymTab
, R
))
559 S
->Relocations
.push_back(R
);
562 auto Rels
= Obj
.relas(Shdr
);
564 return Rels
.takeError();
565 for (const Elf_Rela
&Rel
: *Rels
) {
566 ELFYAML::Relocation R
;
567 if (Error E
= dumpRelocation(&Rel
, SymTab
, R
))
569 R
.Addend
= Rel
.r_addend
;
570 S
->Relocations
.push_back(R
);
577 template <class ELFT
>
578 Expected
<ELFYAML::RawContentSection
*>
579 ELFDumper
<ELFT
>::dumpContentSection(const Elf_Shdr
*Shdr
) {
580 auto S
= std::make_unique
<ELFYAML::RawContentSection
>();
581 if (Error E
= dumpCommonSection(Shdr
, *S
))
584 unsigned SecIndex
= Shdr
- &Sections
[0];
585 if (SecIndex
!= 0 || Shdr
->sh_type
!= ELF::SHT_NULL
) {
586 auto ContentOrErr
= Obj
.getSectionContents(Shdr
);
588 return ContentOrErr
.takeError();
589 ArrayRef
<uint8_t> Content
= *ContentOrErr
;
590 if (!Content
.empty())
591 S
->Content
= yaml::BinaryRef(Content
);
593 S
->Size
= static_cast<llvm::yaml::Hex64
>(Shdr
->sh_size
);
597 S
->Info
= static_cast<llvm::yaml::Hex64
>(Shdr
->sh_info
);
601 template <class ELFT
>
602 Expected
<ELFYAML::SymtabShndxSection
*>
603 ELFDumper
<ELFT
>::dumpSymtabShndxSection(const Elf_Shdr
*Shdr
) {
604 auto S
= std::make_unique
<ELFYAML::SymtabShndxSection
>();
605 if (Error E
= dumpCommonSection(Shdr
, *S
))
608 auto EntriesOrErr
= Obj
.template getSectionContentsAsArray
<Elf_Word
>(Shdr
);
610 return EntriesOrErr
.takeError();
611 for (const Elf_Word
&E
: *EntriesOrErr
)
612 S
->Entries
.push_back(E
);
616 template <class ELFT
>
617 Expected
<ELFYAML::NoBitsSection
*>
618 ELFDumper
<ELFT
>::dumpNoBitsSection(const Elf_Shdr
*Shdr
) {
619 auto S
= std::make_unique
<ELFYAML::NoBitsSection
>();
620 if (Error E
= dumpCommonSection(Shdr
, *S
))
622 S
->Size
= Shdr
->sh_size
;
627 template <class ELFT
>
628 Expected
<ELFYAML::HashSection
*>
629 ELFDumper
<ELFT
>::dumpHashSection(const Elf_Shdr
*Shdr
) {
630 auto S
= std::make_unique
<ELFYAML::HashSection
>();
631 if (Error E
= dumpCommonSection(Shdr
, *S
))
634 auto ContentOrErr
= Obj
.getSectionContents(Shdr
);
636 return ContentOrErr
.takeError();
638 ArrayRef
<uint8_t> Content
= *ContentOrErr
;
639 if (Content
.size() % 4 != 0 || Content
.size() < 8) {
640 S
->Content
= yaml::BinaryRef(Content
);
644 DataExtractor::Cursor
Cur(0);
645 DataExtractor
Data(Content
, Obj
.isLE(), /*AddressSize=*/0);
646 uint32_t NBucket
= Data
.getU32(Cur
);
647 uint32_t NChain
= Data
.getU32(Cur
);
648 if (Content
.size() != (2 + NBucket
+ NChain
) * 4) {
649 S
->Content
= yaml::BinaryRef(Content
);
653 S
->Bucket
.emplace(NBucket
);
654 for (uint32_t &V
: *S
->Bucket
)
655 V
= Data
.getU32(Cur
);
657 S
->Chain
.emplace(NChain
);
658 for (uint32_t &V
: *S
->Chain
)
659 V
= Data
.getU32(Cur
);
662 llvm_unreachable("entries were not read correctly");
666 template <class ELFT
>
667 Expected
<ELFYAML::VerdefSection
*>
668 ELFDumper
<ELFT
>::dumpVerdefSection(const Elf_Shdr
*Shdr
) {
669 typedef typename
ELFT::Verdef Elf_Verdef
;
670 typedef typename
ELFT::Verdaux Elf_Verdaux
;
672 auto S
= std::make_unique
<ELFYAML::VerdefSection
>();
673 if (Error E
= dumpCommonSection(Shdr
, *S
))
676 S
->Info
= Shdr
->sh_info
;
678 auto StringTableShdrOrErr
= Obj
.getSection(Shdr
->sh_link
);
679 if (!StringTableShdrOrErr
)
680 return StringTableShdrOrErr
.takeError();
682 auto StringTableOrErr
= Obj
.getStringTable(*StringTableShdrOrErr
);
683 if (!StringTableOrErr
)
684 return StringTableOrErr
.takeError();
686 auto Contents
= Obj
.getSectionContents(Shdr
);
688 return Contents
.takeError();
690 llvm::ArrayRef
<uint8_t> Data
= *Contents
;
691 const uint8_t *Buf
= Data
.data();
693 const Elf_Verdef
*Verdef
= reinterpret_cast<const Elf_Verdef
*>(Buf
);
694 ELFYAML::VerdefEntry Entry
;
695 Entry
.Version
= Verdef
->vd_version
;
696 Entry
.Flags
= Verdef
->vd_flags
;
697 Entry
.VersionNdx
= Verdef
->vd_ndx
;
698 Entry
.Hash
= Verdef
->vd_hash
;
700 const uint8_t *BufAux
= Buf
+ Verdef
->vd_aux
;
702 const Elf_Verdaux
*Verdaux
=
703 reinterpret_cast<const Elf_Verdaux
*>(BufAux
);
704 Entry
.VerNames
.push_back(
705 StringTableOrErr
->drop_front(Verdaux
->vda_name
).data());
706 BufAux
= Verdaux
->vda_next
? BufAux
+ Verdaux
->vda_next
: nullptr;
709 S
->Entries
.push_back(Entry
);
710 Buf
= Verdef
->vd_next
? Buf
+ Verdef
->vd_next
: nullptr;
716 template <class ELFT
>
717 Expected
<ELFYAML::SymverSection
*>
718 ELFDumper
<ELFT
>::dumpSymverSection(const Elf_Shdr
*Shdr
) {
719 typedef typename
ELFT::Half Elf_Half
;
721 auto S
= std::make_unique
<ELFYAML::SymverSection
>();
722 if (Error E
= dumpCommonSection(Shdr
, *S
))
725 auto VersionsOrErr
= Obj
.template getSectionContentsAsArray
<Elf_Half
>(Shdr
);
727 return VersionsOrErr
.takeError();
728 for (const Elf_Half
&E
: *VersionsOrErr
)
729 S
->Entries
.push_back(E
);
734 template <class ELFT
>
735 Expected
<ELFYAML::VerneedSection
*>
736 ELFDumper
<ELFT
>::dumpVerneedSection(const Elf_Shdr
*Shdr
) {
737 typedef typename
ELFT::Verneed Elf_Verneed
;
738 typedef typename
ELFT::Vernaux Elf_Vernaux
;
740 auto S
= std::make_unique
<ELFYAML::VerneedSection
>();
741 if (Error E
= dumpCommonSection(Shdr
, *S
))
744 S
->Info
= Shdr
->sh_info
;
746 auto Contents
= Obj
.getSectionContents(Shdr
);
748 return Contents
.takeError();
750 auto StringTableShdrOrErr
= Obj
.getSection(Shdr
->sh_link
);
751 if (!StringTableShdrOrErr
)
752 return StringTableShdrOrErr
.takeError();
754 auto StringTableOrErr
= Obj
.getStringTable(*StringTableShdrOrErr
);
755 if (!StringTableOrErr
)
756 return StringTableOrErr
.takeError();
758 llvm::ArrayRef
<uint8_t> Data
= *Contents
;
759 const uint8_t *Buf
= Data
.data();
761 const Elf_Verneed
*Verneed
= reinterpret_cast<const Elf_Verneed
*>(Buf
);
763 ELFYAML::VerneedEntry Entry
;
764 Entry
.Version
= Verneed
->vn_version
;
766 StringRef(StringTableOrErr
->drop_front(Verneed
->vn_file
).data());
768 const uint8_t *BufAux
= Buf
+ Verneed
->vn_aux
;
770 const Elf_Vernaux
*Vernaux
=
771 reinterpret_cast<const Elf_Vernaux
*>(BufAux
);
773 ELFYAML::VernauxEntry Aux
;
774 Aux
.Hash
= Vernaux
->vna_hash
;
775 Aux
.Flags
= Vernaux
->vna_flags
;
776 Aux
.Other
= Vernaux
->vna_other
;
778 StringRef(StringTableOrErr
->drop_front(Vernaux
->vna_name
).data());
780 Entry
.AuxV
.push_back(Aux
);
781 BufAux
= Vernaux
->vna_next
? BufAux
+ Vernaux
->vna_next
: nullptr;
784 S
->VerneedV
.push_back(Entry
);
785 Buf
= Verneed
->vn_next
? Buf
+ Verneed
->vn_next
: nullptr;
791 template <class ELFT
>
792 Expected
<ELFYAML::Group
*> ELFDumper
<ELFT
>::dumpGroup(const Elf_Shdr
*Shdr
) {
793 auto S
= std::make_unique
<ELFYAML::Group
>();
794 if (Error E
= dumpCommonSection(Shdr
, *S
))
797 auto SymtabOrErr
= Obj
.getSection(Shdr
->sh_link
);
799 return SymtabOrErr
.takeError();
800 // Get symbol with index sh_info which name is the signature of the group.
801 const Elf_Shdr
*Symtab
= *SymtabOrErr
;
802 auto SymOrErr
= Obj
.getSymbol(Symtab
, Shdr
->sh_info
);
804 return SymOrErr
.takeError();
805 auto StrTabOrErr
= Obj
.getStringTableForSymtab(*Symtab
);
807 return StrTabOrErr
.takeError();
809 Expected
<StringRef
> SymbolName
=
810 getUniquedSymbolName(*SymOrErr
, *StrTabOrErr
, Symtab
);
812 return SymbolName
.takeError();
813 S
->Signature
= *SymbolName
;
815 auto MembersOrErr
= Obj
.template getSectionContentsAsArray
<Elf_Word
>(Shdr
);
817 return MembersOrErr
.takeError();
819 for (Elf_Word Member
: *MembersOrErr
) {
820 if (Member
== llvm::ELF::GRP_COMDAT
) {
821 S
->Members
.push_back({"GRP_COMDAT"});
825 auto SHdrOrErr
= Obj
.getSection(Member
);
827 return SHdrOrErr
.takeError();
828 auto NameOrErr
= getUniquedSectionName(*SHdrOrErr
);
830 return NameOrErr
.takeError();
831 S
->Members
.push_back({*NameOrErr
});
836 template <class ELFT
>
837 Expected
<ELFYAML::MipsABIFlags
*>
838 ELFDumper
<ELFT
>::dumpMipsABIFlags(const Elf_Shdr
*Shdr
) {
839 assert(Shdr
->sh_type
== ELF::SHT_MIPS_ABIFLAGS
&&
840 "Section type is not SHT_MIPS_ABIFLAGS");
841 auto S
= std::make_unique
<ELFYAML::MipsABIFlags
>();
842 if (Error E
= dumpCommonSection(Shdr
, *S
))
845 auto ContentOrErr
= Obj
.getSectionContents(Shdr
);
847 return ContentOrErr
.takeError();
849 auto *Flags
= reinterpret_cast<const object::Elf_Mips_ABIFlags
<ELFT
> *>(
850 ContentOrErr
.get().data());
851 S
->Version
= Flags
->version
;
852 S
->ISALevel
= Flags
->isa_level
;
853 S
->ISARevision
= Flags
->isa_rev
;
854 S
->GPRSize
= Flags
->gpr_size
;
855 S
->CPR1Size
= Flags
->cpr1_size
;
856 S
->CPR2Size
= Flags
->cpr2_size
;
857 S
->FpABI
= Flags
->fp_abi
;
858 S
->ISAExtension
= Flags
->isa_ext
;
859 S
->ASEs
= Flags
->ases
;
860 S
->Flags1
= Flags
->flags1
;
861 S
->Flags2
= Flags
->flags2
;
865 template <class ELFT
>
866 static Error
elf2yaml(raw_ostream
&Out
, const object::ELFFile
<ELFT
> &Obj
) {
867 ELFDumper
<ELFT
> Dumper(Obj
);
868 Expected
<ELFYAML::Object
*> YAMLOrErr
= Dumper
.dump();
870 return YAMLOrErr
.takeError();
872 std::unique_ptr
<ELFYAML::Object
> YAML(YAMLOrErr
.get());
873 yaml::Output
Yout(Out
);
876 return Error::success();
879 Error
elf2yaml(raw_ostream
&Out
, const object::ObjectFile
&Obj
) {
880 if (const auto *ELFObj
= dyn_cast
<object::ELF32LEObjectFile
>(&Obj
))
881 return elf2yaml(Out
, *ELFObj
->getELFFile());
883 if (const auto *ELFObj
= dyn_cast
<object::ELF32BEObjectFile
>(&Obj
))
884 return elf2yaml(Out
, *ELFObj
->getELFFile());
886 if (const auto *ELFObj
= dyn_cast
<object::ELF64LEObjectFile
>(&Obj
))
887 return elf2yaml(Out
, *ELFObj
->getELFFile());
889 if (const auto *ELFObj
= dyn_cast
<object::ELF64BEObjectFile
>(&Obj
))
890 return elf2yaml(Out
, *ELFObj
->getELFFile());
892 llvm_unreachable("unknown ELF file format");