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/ErrorHandling.h"
15 #include "llvm/Support/YAMLTraits.h"
23 typedef object::Elf_Sym_Impl
<ELFT
> Elf_Sym
;
24 typedef typename
ELFT::Dyn Elf_Dyn
;
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
;
31 ArrayRef
<Elf_Sym
> SymTable
;
33 DenseMap
<StringRef
, uint32_t> UsedSectionNames
;
34 std::vector
<std::string
> SectionNames
;
36 DenseMap
<StringRef
, uint32_t> UsedSymbolNames
;
37 std::vector
<std::string
> SymbolNames
;
39 Expected
<StringRef
> getUniquedSectionName(const Elf_Shdr
*Sec
);
40 Expected
<StringRef
> getUniquedSymbolName(const Elf_Sym
*Sym
,
42 const Elf_Shdr
*SymTab
);
44 const object::ELFFile
<ELFT
> &Obj
;
45 ArrayRef
<Elf_Word
> ShndxTable
;
47 std::error_code
dumpSymbols(const Elf_Shdr
*Symtab
,
48 std::vector
<ELFYAML::Symbol
> &Symbols
);
49 std::error_code
dumpSymbol(const Elf_Sym
*Sym
, const Elf_Shdr
*SymTab
,
50 StringRef StrTable
, ELFYAML::Symbol
&S
);
51 std::error_code
dumpCommonSection(const Elf_Shdr
*Shdr
, ELFYAML::Section
&S
);
52 std::error_code
dumpCommonRelocationSection(const Elf_Shdr
*Shdr
,
53 ELFYAML::RelocationSection
&S
);
55 std::error_code
dumpRelocation(const RelT
*Rel
, const Elf_Shdr
*SymTab
,
56 ELFYAML::Relocation
&R
);
58 ErrorOr
<ELFYAML::DynamicSection
*> dumpDynamicSection(const Elf_Shdr
*Shdr
);
59 ErrorOr
<ELFYAML::RelocationSection
*> dumpRelocSection(const Elf_Shdr
*Shdr
);
60 ErrorOr
<ELFYAML::RawContentSection
*>
61 dumpContentSection(const Elf_Shdr
*Shdr
);
62 ErrorOr
<ELFYAML::NoBitsSection
*> dumpNoBitsSection(const Elf_Shdr
*Shdr
);
63 ErrorOr
<ELFYAML::VerdefSection
*> dumpVerdefSection(const Elf_Shdr
*Shdr
);
64 ErrorOr
<ELFYAML::SymverSection
*> dumpSymverSection(const Elf_Shdr
*Shdr
);
65 ErrorOr
<ELFYAML::VerneedSection
*> dumpVerneedSection(const Elf_Shdr
*Shdr
);
66 ErrorOr
<ELFYAML::Group
*> dumpGroup(const Elf_Shdr
*Shdr
);
67 ErrorOr
<ELFYAML::MipsABIFlags
*> dumpMipsABIFlags(const Elf_Shdr
*Shdr
);
70 ELFDumper(const object::ELFFile
<ELFT
> &O
);
71 ErrorOr
<ELFYAML::Object
*> dump();
77 ELFDumper
<ELFT
>::ELFDumper(const object::ELFFile
<ELFT
> &O
)
82 ELFDumper
<ELFT
>::getUniquedSectionName(const Elf_Shdr
*Sec
) {
83 unsigned SecIndex
= Sec
- &Sections
[0];
84 assert(&Sections
[SecIndex
] == Sec
);
85 if (!SectionNames
[SecIndex
].empty())
86 return SectionNames
[SecIndex
];
88 auto NameOrErr
= Obj
.getSectionName(Sec
);
91 StringRef Name
= *NameOrErr
;
92 std::string
&Ret
= SectionNames
[SecIndex
];
94 auto It
= UsedSectionNames
.insert({Name
, 0});
96 Ret
= (Name
+ " [" + Twine(++It
.first
->second
) + "]").str();
102 template <class ELFT
>
104 ELFDumper
<ELFT
>::getUniquedSymbolName(const Elf_Sym
*Sym
, StringRef StrTable
,
105 const Elf_Shdr
*SymTab
) {
106 Expected
<StringRef
> SymbolNameOrErr
= Sym
->getName(StrTable
);
107 if (!SymbolNameOrErr
)
108 return SymbolNameOrErr
;
109 StringRef Name
= *SymbolNameOrErr
;
110 if (Name
.empty() && Sym
->getType() == ELF::STT_SECTION
) {
111 auto ShdrOrErr
= Obj
.getSection(Sym
, SymTab
, ShndxTable
);
113 return ShdrOrErr
.takeError();
114 return getUniquedSectionName(*ShdrOrErr
);
117 // Symbols in .symtab can have duplicate names. For example, it is a common
118 // situation for local symbols in a relocatable object. Here we assign unique
119 // suffixes for such symbols so that we can differentiate them.
120 if (SymTab
->sh_type
== ELF::SHT_SYMTAB
) {
121 unsigned Index
= Sym
- SymTable
.data();
122 if (!SymbolNames
[Index
].empty())
123 return SymbolNames
[Index
];
125 auto It
= UsedSymbolNames
.insert({Name
, 0});
128 (Name
+ " [" + Twine(++It
.first
->second
) + "]").str();
130 SymbolNames
[Index
] = Name
;
131 return SymbolNames
[Index
];
137 template <class ELFT
> ErrorOr
<ELFYAML::Object
*> ELFDumper
<ELFT
>::dump() {
138 auto Y
= make_unique
<ELFYAML::Object
>();
140 // Dump header. We do not dump SHEntSize, SHOffset, SHNum and SHStrNdx field.
141 // When not explicitly set, the values are set by yaml2obj automatically
142 // and there is no need to dump them here.
143 Y
->Header
.Class
= ELFYAML::ELF_ELFCLASS(Obj
.getHeader()->getFileClass());
144 Y
->Header
.Data
= ELFYAML::ELF_ELFDATA(Obj
.getHeader()->getDataEncoding());
145 Y
->Header
.OSABI
= Obj
.getHeader()->e_ident
[ELF::EI_OSABI
];
146 Y
->Header
.ABIVersion
= Obj
.getHeader()->e_ident
[ELF::EI_ABIVERSION
];
147 Y
->Header
.Type
= Obj
.getHeader()->e_type
;
148 Y
->Header
.Machine
= Obj
.getHeader()->e_machine
;
149 Y
->Header
.Flags
= Obj
.getHeader()->e_flags
;
150 Y
->Header
.Entry
= Obj
.getHeader()->e_entry
;
153 auto SectionsOrErr
= Obj
.sections();
155 return errorToErrorCode(SectionsOrErr
.takeError());
156 Sections
= *SectionsOrErr
;
157 SectionNames
.resize(Sections
.size());
159 // Dump symbols. We need to do this early because other sections might want
160 // to access the deduplicated symbol names that we also create here.
161 for (const Elf_Shdr
&Sec
: Sections
) {
162 if (Sec
.sh_type
== ELF::SHT_SYMTAB
)
163 if (auto EC
= dumpSymbols(&Sec
, Y
->Symbols
))
165 if (Sec
.sh_type
== ELF::SHT_DYNSYM
)
166 if (auto EC
= dumpSymbols(&Sec
, Y
->DynamicSymbols
))
170 for (const Elf_Shdr
&Sec
: Sections
) {
171 switch (Sec
.sh_type
) {
172 case ELF::SHT_DYNAMIC
: {
173 ErrorOr
<ELFYAML::DynamicSection
*> S
= dumpDynamicSection(&Sec
);
174 if (std::error_code EC
= S
.getError())
176 Y
->Sections
.push_back(std::unique_ptr
<ELFYAML::Section
>(S
.get()));
180 case ELF::SHT_STRTAB
:
181 case ELF::SHT_SYMTAB
:
182 case ELF::SHT_DYNSYM
:
183 // Do not dump these sections.
185 case ELF::SHT_SYMTAB_SHNDX
: {
186 auto TableOrErr
= Obj
.getSHNDXTable(Sec
);
188 return errorToErrorCode(TableOrErr
.takeError());
189 ShndxTable
= *TableOrErr
;
193 case ELF::SHT_RELA
: {
194 ErrorOr
<ELFYAML::RelocationSection
*> S
= dumpRelocSection(&Sec
);
195 if (std::error_code EC
= S
.getError())
197 Y
->Sections
.push_back(std::unique_ptr
<ELFYAML::Section
>(S
.get()));
200 case ELF::SHT_GROUP
: {
201 ErrorOr
<ELFYAML::Group
*> G
= dumpGroup(&Sec
);
202 if (std::error_code EC
= G
.getError())
204 Y
->Sections
.push_back(std::unique_ptr
<ELFYAML::Section
>(G
.get()));
207 case ELF::SHT_MIPS_ABIFLAGS
: {
208 ErrorOr
<ELFYAML::MipsABIFlags
*> G
= dumpMipsABIFlags(&Sec
);
209 if (std::error_code EC
= G
.getError())
211 Y
->Sections
.push_back(std::unique_ptr
<ELFYAML::Section
>(G
.get()));
214 case ELF::SHT_NOBITS
: {
215 ErrorOr
<ELFYAML::NoBitsSection
*> S
= dumpNoBitsSection(&Sec
);
216 if (std::error_code EC
= S
.getError())
218 Y
->Sections
.push_back(std::unique_ptr
<ELFYAML::Section
>(S
.get()));
221 case ELF::SHT_GNU_verdef
: {
222 ErrorOr
<ELFYAML::VerdefSection
*> S
= dumpVerdefSection(&Sec
);
223 if (std::error_code EC
= S
.getError())
225 Y
->Sections
.push_back(std::unique_ptr
<ELFYAML::Section
>(S
.get()));
228 case ELF::SHT_GNU_versym
: {
229 ErrorOr
<ELFYAML::SymverSection
*> S
= dumpSymverSection(&Sec
);
230 if (std::error_code EC
= S
.getError())
232 Y
->Sections
.push_back(std::unique_ptr
<ELFYAML::Section
>(S
.get()));
235 case ELF::SHT_GNU_verneed
: {
236 ErrorOr
<ELFYAML::VerneedSection
*> S
= dumpVerneedSection(&Sec
);
237 if (std::error_code EC
= S
.getError())
239 Y
->Sections
.push_back(std::unique_ptr
<ELFYAML::Section
>(S
.get()));
243 ErrorOr
<ELFYAML::RawContentSection
*> S
= dumpContentSection(&Sec
);
244 if (std::error_code EC
= S
.getError())
246 Y
->Sections
.push_back(std::unique_ptr
<ELFYAML::Section
>(S
.get()));
254 template <class ELFT
>
256 ELFDumper
<ELFT
>::dumpSymbols(const Elf_Shdr
*Symtab
,
257 std::vector
<ELFYAML::Symbol
> &Symbols
) {
259 return std::error_code();
261 auto StrTableOrErr
= Obj
.getStringTableForSymtab(*Symtab
);
263 return errorToErrorCode(StrTableOrErr
.takeError());
264 StringRef StrTable
= *StrTableOrErr
;
266 auto SymtabOrErr
= Obj
.symbols(Symtab
);
268 return errorToErrorCode(SymtabOrErr
.takeError());
270 if (Symtab
->sh_type
== ELF::SHT_SYMTAB
) {
271 SymTable
= *SymtabOrErr
;
272 SymbolNames
.resize(SymTable
.size());
275 for (const auto &Sym
: (*SymtabOrErr
).drop_front()) {
277 if (auto EC
= dumpSymbol(&Sym
, Symtab
, StrTable
, S
))
279 Symbols
.push_back(S
);
282 return std::error_code();
285 template <class ELFT
>
287 ELFDumper
<ELFT
>::dumpSymbol(const Elf_Sym
*Sym
, const Elf_Shdr
*SymTab
,
288 StringRef StrTable
, ELFYAML::Symbol
&S
) {
289 S
.Type
= Sym
->getType();
290 S
.Value
= Sym
->st_value
;
291 S
.Size
= Sym
->st_size
;
292 S
.Other
= Sym
->st_other
;
293 S
.Binding
= Sym
->getBinding();
295 Expected
<StringRef
> SymbolNameOrErr
=
296 getUniquedSymbolName(Sym
, StrTable
, SymTab
);
297 if (!SymbolNameOrErr
)
298 return errorToErrorCode(SymbolNameOrErr
.takeError());
299 S
.Name
= SymbolNameOrErr
.get();
301 if (Sym
->st_shndx
>= ELF::SHN_LORESERVE
) {
302 if (Sym
->st_shndx
== ELF::SHN_XINDEX
)
303 return obj2yaml_error::not_implemented
;
304 S
.Index
= (ELFYAML::ELF_SHN
)Sym
->st_shndx
;
305 return obj2yaml_error::success
;
308 auto ShdrOrErr
= Obj
.getSection(Sym
, SymTab
, ShndxTable
);
310 return errorToErrorCode(ShdrOrErr
.takeError());
311 const Elf_Shdr
*Shdr
= *ShdrOrErr
;
313 return obj2yaml_error::success
;
315 auto NameOrErr
= getUniquedSectionName(Shdr
);
317 return errorToErrorCode(NameOrErr
.takeError());
318 S
.Section
= NameOrErr
.get();
320 return obj2yaml_error::success
;
323 template <class ELFT
>
324 template <class RelT
>
325 std::error_code ELFDumper
<ELFT
>::dumpRelocation(const RelT
*Rel
,
326 const Elf_Shdr
*SymTab
,
327 ELFYAML::Relocation
&R
) {
328 R
.Type
= Rel
->getType(Obj
.isMips64EL());
329 R
.Offset
= Rel
->r_offset
;
332 auto SymOrErr
= Obj
.getRelocationSymbol(Rel
, SymTab
);
334 return errorToErrorCode(SymOrErr
.takeError());
335 const Elf_Sym
*Sym
= *SymOrErr
;
336 auto StrTabSec
= Obj
.getSection(SymTab
->sh_link
);
338 return errorToErrorCode(StrTabSec
.takeError());
339 auto StrTabOrErr
= Obj
.getStringTable(*StrTabSec
);
341 return errorToErrorCode(StrTabOrErr
.takeError());
342 StringRef StrTab
= *StrTabOrErr
;
345 Expected
<StringRef
> NameOrErr
= getUniquedSymbolName(Sym
, StrTab
, SymTab
);
347 return errorToErrorCode(NameOrErr
.takeError());
348 R
.Symbol
= NameOrErr
.get();
350 // We have some edge cases of relocations without a symbol associated,
351 // e.g. an object containing the invalid (according to the System V
352 // ABI) R_X86_64_NONE reloc. Create a symbol with an empty name instead
357 return obj2yaml_error::success
;
360 template <class ELFT
>
361 std::error_code ELFDumper
<ELFT
>::dumpCommonSection(const Elf_Shdr
*Shdr
,
362 ELFYAML::Section
&S
) {
363 // Dump fields. We do not dump the ShOffset field. When not explicitly
364 // set, the value is set by yaml2obj automatically.
365 S
.Type
= Shdr
->sh_type
;
367 S
.Flags
= static_cast<ELFYAML::ELF_SHF
>(Shdr
->sh_flags
);
368 S
.Address
= Shdr
->sh_addr
;
369 S
.AddressAlign
= Shdr
->sh_addralign
;
370 if (Shdr
->sh_entsize
)
371 S
.EntSize
= static_cast<llvm::yaml::Hex64
>(Shdr
->sh_entsize
);
373 auto NameOrErr
= getUniquedSectionName(Shdr
);
375 return errorToErrorCode(NameOrErr
.takeError());
376 S
.Name
= NameOrErr
.get();
378 if (Shdr
->sh_link
!= ELF::SHN_UNDEF
) {
379 auto LinkSection
= Obj
.getSection(Shdr
->sh_link
);
380 if (LinkSection
.takeError())
381 return errorToErrorCode(LinkSection
.takeError());
382 NameOrErr
= getUniquedSectionName(*LinkSection
);
384 return errorToErrorCode(NameOrErr
.takeError());
385 S
.Link
= NameOrErr
.get();
388 return obj2yaml_error::success
;
391 template <class ELFT
>
393 ELFDumper
<ELFT
>::dumpCommonRelocationSection(const Elf_Shdr
*Shdr
,
394 ELFYAML::RelocationSection
&S
) {
395 if (std::error_code EC
= dumpCommonSection(Shdr
, S
))
398 auto InfoSection
= Obj
.getSection(Shdr
->sh_info
);
400 return errorToErrorCode(InfoSection
.takeError());
402 auto NameOrErr
= getUniquedSectionName(*InfoSection
);
404 return errorToErrorCode(NameOrErr
.takeError());
405 S
.RelocatableSec
= NameOrErr
.get();
407 return obj2yaml_error::success
;
410 template <class ELFT
>
411 ErrorOr
<ELFYAML::DynamicSection
*>
412 ELFDumper
<ELFT
>::dumpDynamicSection(const Elf_Shdr
*Shdr
) {
413 auto S
= make_unique
<ELFYAML::DynamicSection
>();
414 if (std::error_code EC
= dumpCommonSection(Shdr
, *S
))
417 auto DynTagsOrErr
= Obj
.template getSectionContentsAsArray
<Elf_Dyn
>(Shdr
);
419 return errorToErrorCode(DynTagsOrErr
.takeError());
421 for (const Elf_Dyn
&Dyn
: *DynTagsOrErr
)
422 S
->Entries
.push_back({(ELFYAML::ELF_DYNTAG
)Dyn
.getTag(), Dyn
.getVal()});
427 template <class ELFT
>
428 ErrorOr
<ELFYAML::RelocationSection
*>
429 ELFDumper
<ELFT
>::dumpRelocSection(const Elf_Shdr
*Shdr
) {
430 auto S
= make_unique
<ELFYAML::RelocationSection
>();
431 if (std::error_code EC
= dumpCommonRelocationSection(Shdr
, *S
))
434 auto SymTabOrErr
= Obj
.getSection(Shdr
->sh_link
);
436 return errorToErrorCode(SymTabOrErr
.takeError());
437 const Elf_Shdr
*SymTab
= *SymTabOrErr
;
439 if (Shdr
->sh_type
== ELF::SHT_REL
) {
440 auto Rels
= Obj
.rels(Shdr
);
442 return errorToErrorCode(Rels
.takeError());
443 for (const Elf_Rel
&Rel
: *Rels
) {
444 ELFYAML::Relocation R
;
445 if (std::error_code EC
= dumpRelocation(&Rel
, SymTab
, R
))
447 S
->Relocations
.push_back(R
);
450 auto Rels
= Obj
.relas(Shdr
);
452 return errorToErrorCode(Rels
.takeError());
453 for (const Elf_Rela
&Rel
: *Rels
) {
454 ELFYAML::Relocation R
;
455 if (std::error_code EC
= dumpRelocation(&Rel
, SymTab
, R
))
457 R
.Addend
= Rel
.r_addend
;
458 S
->Relocations
.push_back(R
);
465 template <class ELFT
>
466 ErrorOr
<ELFYAML::RawContentSection
*>
467 ELFDumper
<ELFT
>::dumpContentSection(const Elf_Shdr
*Shdr
) {
468 auto S
= make_unique
<ELFYAML::RawContentSection
>();
470 if (std::error_code EC
= dumpCommonSection(Shdr
, *S
))
473 auto ContentOrErr
= Obj
.getSectionContents(Shdr
);
475 return errorToErrorCode(ContentOrErr
.takeError());
476 ArrayRef
<uint8_t> Content
= *ContentOrErr
;
477 if (!Content
.empty())
478 S
->Content
= yaml::BinaryRef(Content
);
480 S
->Info
= static_cast<llvm::yaml::Hex64
>(Shdr
->sh_info
);
484 template <class ELFT
>
485 ErrorOr
<ELFYAML::NoBitsSection
*>
486 ELFDumper
<ELFT
>::dumpNoBitsSection(const Elf_Shdr
*Shdr
) {
487 auto S
= make_unique
<ELFYAML::NoBitsSection
>();
489 if (std::error_code EC
= dumpCommonSection(Shdr
, *S
))
491 S
->Size
= Shdr
->sh_size
;
496 template <class ELFT
>
497 ErrorOr
<ELFYAML::VerdefSection
*>
498 ELFDumper
<ELFT
>::dumpVerdefSection(const Elf_Shdr
*Shdr
) {
499 typedef typename
ELFT::Verdef Elf_Verdef
;
500 typedef typename
ELFT::Verdaux Elf_Verdaux
;
502 auto S
= make_unique
<ELFYAML::VerdefSection
>();
503 if (std::error_code EC
= dumpCommonSection(Shdr
, *S
))
506 S
->Info
= Shdr
->sh_info
;
508 auto StringTableShdrOrErr
= Obj
.getSection(Shdr
->sh_link
);
509 if (!StringTableShdrOrErr
)
510 return errorToErrorCode(StringTableShdrOrErr
.takeError());
512 auto StringTableOrErr
= Obj
.getStringTable(*StringTableShdrOrErr
);
513 if (!StringTableOrErr
)
514 return errorToErrorCode(StringTableOrErr
.takeError());
516 auto Contents
= Obj
.getSectionContents(Shdr
);
518 return errorToErrorCode(Contents
.takeError());
520 llvm::ArrayRef
<uint8_t> Data
= *Contents
;
521 const uint8_t *Buf
= Data
.data();
523 const Elf_Verdef
*Verdef
= reinterpret_cast<const Elf_Verdef
*>(Buf
);
524 ELFYAML::VerdefEntry Entry
;
525 Entry
.Version
= Verdef
->vd_version
;
526 Entry
.Flags
= Verdef
->vd_flags
;
527 Entry
.VersionNdx
= Verdef
->vd_ndx
;
528 Entry
.Hash
= Verdef
->vd_hash
;
530 const uint8_t *BufAux
= Buf
+ Verdef
->vd_aux
;
532 const Elf_Verdaux
*Verdaux
=
533 reinterpret_cast<const Elf_Verdaux
*>(BufAux
);
534 Entry
.VerNames
.push_back(
535 StringTableOrErr
->drop_front(Verdaux
->vda_name
).data());
536 BufAux
= Verdaux
->vda_next
? BufAux
+ Verdaux
->vda_next
: nullptr;
539 S
->Entries
.push_back(Entry
);
540 Buf
= Verdef
->vd_next
? Buf
+ Verdef
->vd_next
: nullptr;
546 template <class ELFT
>
547 ErrorOr
<ELFYAML::SymverSection
*>
548 ELFDumper
<ELFT
>::dumpSymverSection(const Elf_Shdr
*Shdr
) {
549 typedef typename
ELFT::Half Elf_Half
;
551 auto S
= make_unique
<ELFYAML::SymverSection
>();
552 if (std::error_code EC
= dumpCommonSection(Shdr
, *S
))
555 auto VersionsOrErr
= Obj
.template getSectionContentsAsArray
<Elf_Half
>(Shdr
);
557 return errorToErrorCode(VersionsOrErr
.takeError());
558 for (const Elf_Half
&E
: *VersionsOrErr
)
559 S
->Entries
.push_back(E
);
564 template <class ELFT
>
565 ErrorOr
<ELFYAML::VerneedSection
*>
566 ELFDumper
<ELFT
>::dumpVerneedSection(const Elf_Shdr
*Shdr
) {
567 typedef typename
ELFT::Verneed Elf_Verneed
;
568 typedef typename
ELFT::Vernaux Elf_Vernaux
;
570 auto S
= make_unique
<ELFYAML::VerneedSection
>();
571 if (std::error_code EC
= dumpCommonSection(Shdr
, *S
))
574 S
->Info
= Shdr
->sh_info
;
576 auto Contents
= Obj
.getSectionContents(Shdr
);
578 return errorToErrorCode(Contents
.takeError());
580 auto StringTableShdrOrErr
= Obj
.getSection(Shdr
->sh_link
);
581 if (!StringTableShdrOrErr
)
582 return errorToErrorCode(StringTableShdrOrErr
.takeError());
584 auto StringTableOrErr
= Obj
.getStringTable(*StringTableShdrOrErr
);
585 if (!StringTableOrErr
)
586 return errorToErrorCode(StringTableOrErr
.takeError());
588 llvm::ArrayRef
<uint8_t> Data
= *Contents
;
589 const uint8_t *Buf
= Data
.data();
591 const Elf_Verneed
*Verneed
= reinterpret_cast<const Elf_Verneed
*>(Buf
);
593 ELFYAML::VerneedEntry Entry
;
594 Entry
.Version
= Verneed
->vn_version
;
596 StringRef(StringTableOrErr
->drop_front(Verneed
->vn_file
).data());
598 const uint8_t *BufAux
= Buf
+ Verneed
->vn_aux
;
600 const Elf_Vernaux
*Vernaux
=
601 reinterpret_cast<const Elf_Vernaux
*>(BufAux
);
603 ELFYAML::VernauxEntry Aux
;
604 Aux
.Hash
= Vernaux
->vna_hash
;
605 Aux
.Flags
= Vernaux
->vna_flags
;
606 Aux
.Other
= Vernaux
->vna_other
;
608 StringRef(StringTableOrErr
->drop_front(Vernaux
->vna_name
).data());
610 Entry
.AuxV
.push_back(Aux
);
611 BufAux
= Vernaux
->vna_next
? BufAux
+ Vernaux
->vna_next
: nullptr;
614 S
->VerneedV
.push_back(Entry
);
615 Buf
= Verneed
->vn_next
? Buf
+ Verneed
->vn_next
: nullptr;
621 template <class ELFT
>
622 ErrorOr
<ELFYAML::Group
*> ELFDumper
<ELFT
>::dumpGroup(const Elf_Shdr
*Shdr
) {
623 auto S
= make_unique
<ELFYAML::Group
>();
624 if (std::error_code EC
= dumpCommonSection(Shdr
, *S
))
627 auto SymtabOrErr
= Obj
.getSection(Shdr
->sh_link
);
629 return errorToErrorCode(SymtabOrErr
.takeError());
630 // Get symbol with index sh_info which name is the signature of the group.
631 const Elf_Shdr
*Symtab
= *SymtabOrErr
;
632 auto SymOrErr
= Obj
.getSymbol(Symtab
, Shdr
->sh_info
);
634 return errorToErrorCode(SymOrErr
.takeError());
635 auto StrTabOrErr
= Obj
.getStringTableForSymtab(*Symtab
);
637 return errorToErrorCode(StrTabOrErr
.takeError());
639 Expected
<StringRef
> SymbolName
=
640 getUniquedSymbolName(*SymOrErr
, *StrTabOrErr
, Symtab
);
642 return errorToErrorCode(SymbolName
.takeError());
643 S
->Signature
= *SymbolName
;
645 auto MembersOrErr
= Obj
.template getSectionContentsAsArray
<Elf_Word
>(Shdr
);
647 return errorToErrorCode(MembersOrErr
.takeError());
649 for (Elf_Word Member
: *MembersOrErr
) {
650 if (Member
== llvm::ELF::GRP_COMDAT
) {
651 S
->Members
.push_back({"GRP_COMDAT"});
655 auto SHdrOrErr
= Obj
.getSection(Member
);
657 return errorToErrorCode(SHdrOrErr
.takeError());
658 auto NameOrErr
= getUniquedSectionName(*SHdrOrErr
);
660 return errorToErrorCode(NameOrErr
.takeError());
661 S
->Members
.push_back({*NameOrErr
});
666 template <class ELFT
>
667 ErrorOr
<ELFYAML::MipsABIFlags
*>
668 ELFDumper
<ELFT
>::dumpMipsABIFlags(const Elf_Shdr
*Shdr
) {
669 assert(Shdr
->sh_type
== ELF::SHT_MIPS_ABIFLAGS
&&
670 "Section type is not SHT_MIPS_ABIFLAGS");
671 auto S
= make_unique
<ELFYAML::MipsABIFlags
>();
672 if (std::error_code EC
= dumpCommonSection(Shdr
, *S
))
675 auto ContentOrErr
= Obj
.getSectionContents(Shdr
);
677 return errorToErrorCode(ContentOrErr
.takeError());
679 auto *Flags
= reinterpret_cast<const object::Elf_Mips_ABIFlags
<ELFT
> *>(
680 ContentOrErr
.get().data());
681 S
->Version
= Flags
->version
;
682 S
->ISALevel
= Flags
->isa_level
;
683 S
->ISARevision
= Flags
->isa_rev
;
684 S
->GPRSize
= Flags
->gpr_size
;
685 S
->CPR1Size
= Flags
->cpr1_size
;
686 S
->CPR2Size
= Flags
->cpr2_size
;
687 S
->FpABI
= Flags
->fp_abi
;
688 S
->ISAExtension
= Flags
->isa_ext
;
689 S
->ASEs
= Flags
->ases
;
690 S
->Flags1
= Flags
->flags1
;
691 S
->Flags2
= Flags
->flags2
;
695 template <class ELFT
>
696 static std::error_code
elf2yaml(raw_ostream
&Out
,
697 const object::ELFFile
<ELFT
> &Obj
) {
698 ELFDumper
<ELFT
> Dumper(Obj
);
699 ErrorOr
<ELFYAML::Object
*> YAMLOrErr
= Dumper
.dump();
700 if (std::error_code EC
= YAMLOrErr
.getError())
703 std::unique_ptr
<ELFYAML::Object
> YAML(YAMLOrErr
.get());
704 yaml::Output
Yout(Out
);
707 return std::error_code();
710 std::error_code
elf2yaml(raw_ostream
&Out
, const object::ObjectFile
&Obj
) {
711 if (const auto *ELFObj
= dyn_cast
<object::ELF32LEObjectFile
>(&Obj
))
712 return elf2yaml(Out
, *ELFObj
->getELFFile());
714 if (const auto *ELFObj
= dyn_cast
<object::ELF32BEObjectFile
>(&Obj
))
715 return elf2yaml(Out
, *ELFObj
->getELFFile());
717 if (const auto *ELFObj
= dyn_cast
<object::ELF64LEObjectFile
>(&Obj
))
718 return elf2yaml(Out
, *ELFObj
->getELFFile());
720 if (const auto *ELFObj
= dyn_cast
<object::ELF64BEObjectFile
>(&Obj
))
721 return elf2yaml(Out
, *ELFObj
->getELFFile());
723 return obj2yaml_error::unsupported_obj_file_format
;