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/ADT/Twine.h"
13 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
14 #include "llvm/Object/ELFObjectFile.h"
15 #include "llvm/ObjectYAML/DWARFYAML.h"
16 #include "llvm/ObjectYAML/ELFYAML.h"
17 #include "llvm/Support/DataExtractor.h"
18 #include "llvm/Support/Errc.h"
19 #include "llvm/Support/ErrorHandling.h"
20 #include "llvm/Support/YAMLTraits.h"
29 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT
)
31 ArrayRef
<Elf_Shdr
> Sections
;
32 ArrayRef
<Elf_Sym
> SymTable
;
34 DenseMap
<StringRef
, uint32_t> UsedSectionNames
;
35 std::vector
<std::string
> SectionNames
;
36 std::optional
<uint32_t> ShStrTabIndex
;
38 DenseMap
<StringRef
, uint32_t> UsedSymbolNames
;
39 std::vector
<std::string
> SymbolNames
;
41 BumpPtrAllocator StringAllocator
;
43 Expected
<StringRef
> getUniquedSectionName(const Elf_Shdr
&Sec
);
44 Expected
<StringRef
> getUniquedSymbolName(const Elf_Sym
*Sym
,
46 const Elf_Shdr
*SymTab
);
47 Expected
<StringRef
> getSymbolName(uint32_t SymtabNdx
, uint32_t SymbolNdx
);
49 const object::ELFFile
<ELFT
> &Obj
;
50 std::unique_ptr
<DWARFContext
> DWARFCtx
;
52 DenseMap
<const Elf_Shdr
*, ArrayRef
<Elf_Word
>> ShndxTables
;
54 Expected
<std::vector
<ELFYAML::ProgramHeader
>>
55 dumpProgramHeaders(ArrayRef
<std::unique_ptr
<ELFYAML::Chunk
>> Sections
);
57 std::optional
<DWARFYAML::Data
>
58 dumpDWARFSections(std::vector
<std::unique_ptr
<ELFYAML::Chunk
>> &Sections
);
60 Error
dumpSymbols(const Elf_Shdr
*Symtab
,
61 std::optional
<std::vector
<ELFYAML::Symbol
>> &Symbols
);
62 Error
dumpSymbol(const Elf_Sym
*Sym
, const Elf_Shdr
*SymTab
,
63 StringRef StrTable
, ELFYAML::Symbol
&S
);
64 Expected
<std::vector
<std::unique_ptr
<ELFYAML::Chunk
>>> dumpSections();
65 Error
dumpCommonSection(const Elf_Shdr
*Shdr
, ELFYAML::Section
&S
);
66 Error
dumpCommonRelocationSection(const Elf_Shdr
*Shdr
,
67 ELFYAML::RelocationSection
&S
);
69 Error
dumpRelocation(const RelT
*Rel
, const Elf_Shdr
*SymTab
,
70 ELFYAML::Relocation
&R
);
72 Expected
<ELFYAML::AddrsigSection
*> dumpAddrsigSection(const Elf_Shdr
*Shdr
);
73 Expected
<ELFYAML::LinkerOptionsSection
*>
74 dumpLinkerOptionsSection(const Elf_Shdr
*Shdr
);
75 Expected
<ELFYAML::DependentLibrariesSection
*>
76 dumpDependentLibrariesSection(const Elf_Shdr
*Shdr
);
77 Expected
<ELFYAML::CallGraphProfileSection
*>
78 dumpCallGraphProfileSection(const Elf_Shdr
*Shdr
);
79 Expected
<ELFYAML::DynamicSection
*> dumpDynamicSection(const Elf_Shdr
*Shdr
);
80 Expected
<ELFYAML::RelocationSection
*> dumpRelocSection(const Elf_Shdr
*Shdr
);
81 Expected
<ELFYAML::RelrSection
*> dumpRelrSection(const Elf_Shdr
*Shdr
);
82 Expected
<ELFYAML::RawContentSection
*>
83 dumpContentSection(const Elf_Shdr
*Shdr
);
84 Expected
<ELFYAML::SymtabShndxSection
*>
85 dumpSymtabShndxSection(const Elf_Shdr
*Shdr
);
86 Expected
<ELFYAML::NoBitsSection
*> dumpNoBitsSection(const Elf_Shdr
*Shdr
);
87 Expected
<ELFYAML::HashSection
*> dumpHashSection(const Elf_Shdr
*Shdr
);
88 Expected
<ELFYAML::NoteSection
*> dumpNoteSection(const Elf_Shdr
*Shdr
);
89 Expected
<ELFYAML::GnuHashSection
*> dumpGnuHashSection(const Elf_Shdr
*Shdr
);
90 Expected
<ELFYAML::VerdefSection
*> dumpVerdefSection(const Elf_Shdr
*Shdr
);
91 Expected
<ELFYAML::SymverSection
*> dumpSymverSection(const Elf_Shdr
*Shdr
);
92 Expected
<ELFYAML::VerneedSection
*> dumpVerneedSection(const Elf_Shdr
*Shdr
);
93 Expected
<ELFYAML::GroupSection
*> dumpGroupSection(const Elf_Shdr
*Shdr
);
94 Expected
<ELFYAML::ARMIndexTableSection
*>
95 dumpARMIndexTableSection(const Elf_Shdr
*Shdr
);
96 Expected
<ELFYAML::MipsABIFlags
*> dumpMipsABIFlags(const Elf_Shdr
*Shdr
);
97 Expected
<ELFYAML::StackSizesSection
*>
98 dumpStackSizesSection(const Elf_Shdr
*Shdr
);
99 Expected
<ELFYAML::BBAddrMapSection
*>
100 dumpBBAddrMapSection(const Elf_Shdr
*Shdr
);
101 Expected
<ELFYAML::RawContentSection
*>
102 dumpPlaceholderSection(const Elf_Shdr
*Shdr
);
104 bool shouldPrintSection(const ELFYAML::Section
&S
, const Elf_Shdr
&SHdr
,
105 std::optional
<DWARFYAML::Data
> DWARF
);
108 ELFDumper(const object::ELFFile
<ELFT
> &O
, std::unique_ptr
<DWARFContext
> DCtx
);
109 Expected
<ELFYAML::Object
*> dump();
114 template <class ELFT
>
115 ELFDumper
<ELFT
>::ELFDumper(const object::ELFFile
<ELFT
> &O
,
116 std::unique_ptr
<DWARFContext
> DCtx
)
117 : Obj(O
), DWARFCtx(std::move(DCtx
)) {}
119 template <class ELFT
>
121 ELFDumper
<ELFT
>::getUniquedSectionName(const Elf_Shdr
&Sec
) {
122 unsigned SecIndex
= &Sec
- &Sections
[0];
123 if (!SectionNames
[SecIndex
].empty())
124 return SectionNames
[SecIndex
];
126 auto NameOrErr
= Obj
.getSectionName(Sec
);
129 StringRef Name
= *NameOrErr
;
130 // In some specific cases we might have more than one section without a
131 // name (sh_name == 0). It normally doesn't happen, but when we have this case
132 // it doesn't make sense to uniquify their names and add noise to the output.
136 std::string
&Ret
= SectionNames
[SecIndex
];
138 auto It
= UsedSectionNames
.insert({Name
, 0});
140 Ret
= ELFYAML::appendUniqueSuffix(Name
, Twine(++It
.first
->second
));
142 Ret
= std::string(Name
);
146 template <class ELFT
>
148 ELFDumper
<ELFT
>::getUniquedSymbolName(const Elf_Sym
*Sym
, StringRef StrTable
,
149 const Elf_Shdr
*SymTab
) {
150 Expected
<StringRef
> SymbolNameOrErr
= Sym
->getName(StrTable
);
151 if (!SymbolNameOrErr
)
152 return SymbolNameOrErr
;
153 StringRef Name
= *SymbolNameOrErr
;
154 if (Name
.empty() && Sym
->getType() == ELF::STT_SECTION
) {
155 Expected
<const Elf_Shdr
*> ShdrOrErr
=
156 Obj
.getSection(*Sym
, SymTab
, ShndxTables
.lookup(SymTab
));
158 return ShdrOrErr
.takeError();
159 // The null section has no name.
160 return (*ShdrOrErr
== nullptr) ? "" : getUniquedSectionName(**ShdrOrErr
);
163 // Symbols in .symtab can have duplicate names. For example, it is a common
164 // situation for local symbols in a relocatable object. Here we assign unique
165 // suffixes for such symbols so that we can differentiate them.
166 if (SymTab
->sh_type
== ELF::SHT_SYMTAB
) {
167 unsigned Index
= Sym
- SymTable
.data();
168 if (!SymbolNames
[Index
].empty())
169 return SymbolNames
[Index
];
171 auto It
= UsedSymbolNames
.insert({Name
, 0});
174 ELFYAML::appendUniqueSuffix(Name
, Twine(++It
.first
->second
));
176 SymbolNames
[Index
] = std::string(Name
);
177 return SymbolNames
[Index
];
183 template <class ELFT
>
184 bool ELFDumper
<ELFT
>::shouldPrintSection(const ELFYAML::Section
&S
,
185 const Elf_Shdr
&SHdr
,
186 std::optional
<DWARFYAML::Data
> DWARF
) {
187 // We only print the SHT_NULL section at index 0 when it
188 // has at least one non-null field, because yaml2obj
189 // normally creates the zero section at index 0 implicitly.
190 if (S
.Type
== ELF::SHT_NULL
&& (&SHdr
== &Sections
[0])) {
191 const uint8_t *Begin
= reinterpret_cast<const uint8_t *>(&SHdr
);
192 const uint8_t *End
= Begin
+ sizeof(Elf_Shdr
);
193 return std::any_of(Begin
, End
, [](uint8_t V
) { return V
!= 0; });
196 // Normally we use "DWARF:" to describe contents of DWARF sections. Sometimes
197 // the content of DWARF sections can be successfully parsed into the "DWARF:"
198 // entry but their section headers may have special flags, entry size, address
199 // alignment, etc. We will preserve the header for them under such
201 StringRef SecName
= S
.Name
.substr(1);
202 if (DWARF
&& DWARF
->getNonEmptySectionNames().count(SecName
)) {
203 if (const ELFYAML::RawContentSection
*RawSec
=
204 dyn_cast
<const ELFYAML::RawContentSection
>(&S
)) {
205 if (RawSec
->Type
!= ELF::SHT_PROGBITS
|| RawSec
->Link
|| RawSec
->Info
||
206 RawSec
->AddressAlign
!= yaml::Hex64
{1} || RawSec
->Address
||
210 ELFYAML::ELF_SHF ShFlags
= RawSec
->Flags
.value_or(ELFYAML::ELF_SHF(0));
212 if (SecName
== "debug_str")
213 return ShFlags
!= ELFYAML::ELF_SHF(ELF::SHF_MERGE
| ELF::SHF_STRINGS
);
215 return ShFlags
!= ELFYAML::ELF_SHF
{0};
219 // Normally we use "Symbols:" and "DynamicSymbols:" to describe contents of
220 // symbol tables. We also build and emit corresponding string tables
221 // implicitly. But sometimes it is important to preserve positions and virtual
222 // addresses of allocatable sections, e.g. for creating program headers.
223 // Generally we are trying to reduce noise in the YAML output. Because
224 // of that we do not print non-allocatable versions of such sections and
225 // assume they are placed at the end.
226 // We also dump symbol tables when the Size field is set. It happens when they
227 // are empty, which should not normally happen.
228 if (S
.Type
== ELF::SHT_STRTAB
|| S
.Type
== ELF::SHT_SYMTAB
||
229 S
.Type
== ELF::SHT_DYNSYM
) {
230 return S
.Size
|| S
.Flags
.value_or(ELFYAML::ELF_SHF(0)) & ELF::SHF_ALLOC
;
236 template <class ELFT
>
237 static void dumpSectionOffsets(const typename
ELFT::Ehdr
&Header
,
238 ArrayRef
<ELFYAML::ProgramHeader
> Phdrs
,
239 std::vector
<std::unique_ptr
<ELFYAML::Chunk
>> &V
,
240 ArrayRef
<typename
ELFT::Shdr
> S
) {
244 uint64_t ExpectedOffset
;
245 if (Header
.e_phoff
> 0)
246 ExpectedOffset
= Header
.e_phoff
+ Header
.e_phentsize
* Header
.e_phnum
;
248 ExpectedOffset
= sizeof(typename
ELFT::Ehdr
);
250 for (const std::unique_ptr
<ELFYAML::Chunk
> &C
: ArrayRef(V
).drop_front()) {
251 ELFYAML::Section
&Sec
= *cast
<ELFYAML::Section
>(C
.get());
252 const typename
ELFT::Shdr
&SecHdr
= S
[Sec
.OriginalSecNdx
];
254 ExpectedOffset
= alignTo(ExpectedOffset
,
255 SecHdr
.sh_addralign
? SecHdr
.sh_addralign
: 1uLL);
257 // We only set the "Offset" field when it can't be naturally derived
258 // from the offset and size of the previous section. This reduces
259 // the noise in the YAML output.
260 if (SecHdr
.sh_offset
!= ExpectedOffset
)
261 Sec
.Offset
= (yaml::Hex64
)SecHdr
.sh_offset
;
263 if (Sec
.Type
== ELF::SHT_NOBITS
&&
264 !ELFYAML::shouldAllocateFileSpace(Phdrs
,
265 *cast
<ELFYAML::NoBitsSection
>(&Sec
)))
266 ExpectedOffset
= SecHdr
.sh_offset
;
268 ExpectedOffset
= SecHdr
.sh_offset
+ SecHdr
.sh_size
;
272 template <class ELFT
> Expected
<ELFYAML::Object
*> ELFDumper
<ELFT
>::dump() {
273 auto Y
= std::make_unique
<ELFYAML::Object
>();
275 // Dump header. We do not dump EPh* and ESh* fields. When not explicitly set,
276 // the values are set by yaml2obj automatically and there is no need to dump
278 Y
->Header
.Class
= ELFYAML::ELF_ELFCLASS(Obj
.getHeader().getFileClass());
279 Y
->Header
.Data
= ELFYAML::ELF_ELFDATA(Obj
.getHeader().getDataEncoding());
280 Y
->Header
.OSABI
= Obj
.getHeader().e_ident
[ELF::EI_OSABI
];
281 Y
->Header
.ABIVersion
= Obj
.getHeader().e_ident
[ELF::EI_ABIVERSION
];
282 Y
->Header
.Type
= Obj
.getHeader().e_type
;
283 if (Obj
.getHeader().e_machine
!= 0)
284 Y
->Header
.Machine
= ELFYAML::ELF_EM(Obj
.getHeader().e_machine
);
285 Y
->Header
.Flags
= Obj
.getHeader().e_flags
;
286 Y
->Header
.Entry
= Obj
.getHeader().e_entry
;
289 auto SectionsOrErr
= Obj
.sections();
291 return SectionsOrErr
.takeError();
292 Sections
= *SectionsOrErr
;
293 SectionNames
.resize(Sections
.size());
295 if (Sections
.size() > 0) {
296 ShStrTabIndex
= Obj
.getHeader().e_shstrndx
;
297 if (*ShStrTabIndex
== ELF::SHN_XINDEX
)
298 ShStrTabIndex
= Sections
[0].sh_link
;
299 // TODO: Set EShStrndx if the value doesn't represent a real section.
302 // Normally an object that does not have sections has e_shnum == 0.
303 // Also, e_shnum might be 0, when the number of entries in the section
304 // header table is larger than or equal to SHN_LORESERVE (0xff00). In this
305 // case the real number of entries is held in the sh_size member of the
306 // initial entry. We have a section header table when `e_shoff` is not 0.
307 if (Obj
.getHeader().e_shoff
!= 0 && Obj
.getHeader().e_shnum
== 0)
308 Y
->Header
.EShNum
= 0;
310 // Dump symbols. We need to do this early because other sections might want
311 // to access the deduplicated symbol names that we also create here.
312 const Elf_Shdr
*SymTab
= nullptr;
313 const Elf_Shdr
*DynSymTab
= nullptr;
315 for (const Elf_Shdr
&Sec
: Sections
) {
316 if (Sec
.sh_type
== ELF::SHT_SYMTAB
) {
318 } else if (Sec
.sh_type
== ELF::SHT_DYNSYM
) {
320 } else if (Sec
.sh_type
== ELF::SHT_SYMTAB_SHNDX
) {
321 // We need to locate SHT_SYMTAB_SHNDX sections early, because they
322 // might be needed for dumping symbols.
323 if (Expected
<ArrayRef
<Elf_Word
>> TableOrErr
= Obj
.getSHNDXTable(Sec
)) {
324 // The `getSHNDXTable` calls the `getSection` internally when validates
325 // the symbol table section linked to the SHT_SYMTAB_SHNDX section.
326 const Elf_Shdr
*LinkedSymTab
= cantFail(Obj
.getSection(Sec
.sh_link
));
327 if (!ShndxTables
.insert({LinkedSymTab
, *TableOrErr
}).second
)
328 return createStringError(
329 errc::invalid_argument
,
330 "multiple SHT_SYMTAB_SHNDX sections are "
331 "linked to the same symbol table with index " +
334 return createStringError(errc::invalid_argument
,
335 "unable to read extended section indexes: " +
336 toString(TableOrErr
.takeError()));
342 if (Error E
= dumpSymbols(SymTab
, Y
->Symbols
))
346 if (Error E
= dumpSymbols(DynSymTab
, Y
->DynamicSymbols
))
349 // We dump all sections first. It is simple and allows us to verify that all
350 // sections are valid and also to generalize the code. But we are not going to
351 // keep all of them in the final output (see comments for
352 // 'shouldPrintSection()'). Undesired chunks will be removed later.
353 Expected
<std::vector
<std::unique_ptr
<ELFYAML::Chunk
>>> ChunksOrErr
=
356 return ChunksOrErr
.takeError();
357 std::vector
<std::unique_ptr
<ELFYAML::Chunk
>> Chunks
= std::move(*ChunksOrErr
);
359 std::vector
<ELFYAML::Section
*> OriginalOrder
;
361 for (const std::unique_ptr
<ELFYAML::Chunk
> &C
:
362 ArrayRef(Chunks
).drop_front())
363 OriginalOrder
.push_back(cast
<ELFYAML::Section
>(C
.get()));
365 // Sometimes the order of sections in the section header table does not match
366 // their actual order. Here we sort sections by the file offset.
367 llvm::stable_sort(Chunks
, [&](const std::unique_ptr
<ELFYAML::Chunk
> &A
,
368 const std::unique_ptr
<ELFYAML::Chunk
> &B
) {
369 return Sections
[cast
<ELFYAML::Section
>(A
.get())->OriginalSecNdx
].sh_offset
<
370 Sections
[cast
<ELFYAML::Section
>(B
.get())->OriginalSecNdx
].sh_offset
;
373 // Dump program headers.
374 Expected
<std::vector
<ELFYAML::ProgramHeader
>> PhdrsOrErr
=
375 dumpProgramHeaders(Chunks
);
377 return PhdrsOrErr
.takeError();
378 Y
->ProgramHeaders
= std::move(*PhdrsOrErr
);
380 dumpSectionOffsets
<ELFT
>(Obj
.getHeader(), Y
->ProgramHeaders
, Chunks
,
383 // Dump DWARF sections.
384 Y
->DWARF
= dumpDWARFSections(Chunks
);
386 // We emit the "SectionHeaderTable" key when the order of sections in the
387 // sections header table doesn't match the file order.
388 const bool SectionsSorted
=
389 llvm::is_sorted(Chunks
, [&](const std::unique_ptr
<ELFYAML::Chunk
> &A
,
390 const std::unique_ptr
<ELFYAML::Chunk
> &B
) {
391 return cast
<ELFYAML::Section
>(A
.get())->OriginalSecNdx
<
392 cast
<ELFYAML::Section
>(B
.get())->OriginalSecNdx
;
394 if (!SectionsSorted
) {
395 std::unique_ptr
<ELFYAML::SectionHeaderTable
> SHT
=
396 std::make_unique
<ELFYAML::SectionHeaderTable
>(/*IsImplicit=*/false);
397 SHT
->Sections
.emplace();
398 for (ELFYAML::Section
*S
: OriginalOrder
)
399 SHT
->Sections
->push_back({S
->Name
});
400 Chunks
.push_back(std::move(SHT
));
403 llvm::erase_if(Chunks
, [this, &Y
](const std::unique_ptr
<ELFYAML::Chunk
> &C
) {
404 if (isa
<ELFYAML::SectionHeaderTable
>(*C
))
407 const ELFYAML::Section
&S
= cast
<ELFYAML::Section
>(*C
);
408 return !shouldPrintSection(S
, Sections
[S
.OriginalSecNdx
], Y
->DWARF
);
411 // The section header string table by default is assumed to be called
412 // ".shstrtab" and be in its own unique section. However, it's possible for it
413 // to be called something else and shared with another section. If the name
414 // isn't the default, provide this in the YAML.
415 if (ShStrTabIndex
&& *ShStrTabIndex
!= ELF::SHN_UNDEF
&&
416 *ShStrTabIndex
< Sections
.size()) {
417 StringRef ShStrtabName
;
418 if (SymTab
&& SymTab
->sh_link
== *ShStrTabIndex
) {
419 // Section header string table is shared with the symbol table. Use that
420 // section's name (usually .strtab).
421 ShStrtabName
= cantFail(Obj
.getSectionName(Sections
[SymTab
->sh_link
]));
422 } else if (DynSymTab
&& DynSymTab
->sh_link
== *ShStrTabIndex
) {
423 // Section header string table is shared with the dynamic symbol table.
424 // Use that section's name (usually .dynstr).
425 ShStrtabName
= cantFail(Obj
.getSectionName(Sections
[DynSymTab
->sh_link
]));
427 // Otherwise, the section name potentially needs uniquifying.
428 ShStrtabName
= cantFail(getUniquedSectionName(Sections
[*ShStrTabIndex
]));
430 if (ShStrtabName
!= ".shstrtab")
431 Y
->Header
.SectionHeaderStringTable
= ShStrtabName
;
434 Y
->Chunks
= std::move(Chunks
);
438 template <class ELFT
>
439 static bool isInSegment(const ELFYAML::Section
&Sec
,
440 const typename
ELFT::Shdr
&SHdr
,
441 const typename
ELFT::Phdr
&Phdr
) {
442 if (Sec
.Type
== ELF::SHT_NULL
)
445 // A section is within a segment when its location in a file is within the
446 // [p_offset, p_offset + p_filesz] region.
447 bool FileOffsetsMatch
=
448 SHdr
.sh_offset
>= Phdr
.p_offset
&&
449 (SHdr
.sh_offset
+ SHdr
.sh_size
<= Phdr
.p_offset
+ Phdr
.p_filesz
);
451 bool VirtualAddressesMatch
= SHdr
.sh_addr
>= Phdr
.p_vaddr
&&
452 SHdr
.sh_addr
<= Phdr
.p_vaddr
+ Phdr
.p_memsz
;
454 if (FileOffsetsMatch
) {
455 // An empty section on the edges of a program header can be outside of the
456 // virtual address space of the segment. This means it is not included in
457 // the segment and we should ignore it.
458 if (SHdr
.sh_size
== 0 && (SHdr
.sh_offset
== Phdr
.p_offset
||
459 SHdr
.sh_offset
== Phdr
.p_offset
+ Phdr
.p_filesz
))
460 return VirtualAddressesMatch
;
464 // SHT_NOBITS sections usually occupy no physical space in a file. Such
465 // sections belong to a segment when they reside in the segment's virtual
467 if (Sec
.Type
!= ELF::SHT_NOBITS
)
469 return VirtualAddressesMatch
;
472 template <class ELFT
>
473 Expected
<std::vector
<ELFYAML::ProgramHeader
>>
474 ELFDumper
<ELFT
>::dumpProgramHeaders(
475 ArrayRef
<std::unique_ptr
<ELFYAML::Chunk
>> Chunks
) {
476 std::vector
<ELFYAML::ProgramHeader
> Ret
;
477 Expected
<typename
ELFT::PhdrRange
> PhdrsOrErr
= Obj
.program_headers();
479 return PhdrsOrErr
.takeError();
481 for (const typename
ELFT::Phdr
&Phdr
: *PhdrsOrErr
) {
482 ELFYAML::ProgramHeader PH
;
483 PH
.Type
= Phdr
.p_type
;
484 PH
.Flags
= Phdr
.p_flags
;
485 PH
.VAddr
= Phdr
.p_vaddr
;
486 PH
.PAddr
= Phdr
.p_paddr
;
487 PH
.Offset
= Phdr
.p_offset
;
489 // yaml2obj sets the alignment of a segment to 1 by default.
490 // We do not print the default alignment to reduce noise in the output.
491 if (Phdr
.p_align
!= 1)
492 PH
.Align
= static_cast<llvm::yaml::Hex64
>(Phdr
.p_align
);
494 // Here we match sections with segments.
495 // It is not possible to have a non-Section chunk, because
496 // obj2yaml does not create Fill chunks.
497 for (const std::unique_ptr
<ELFYAML::Chunk
> &C
: Chunks
) {
498 ELFYAML::Section
&S
= cast
<ELFYAML::Section
>(*C
);
499 if (isInSegment
<ELFT
>(S
, Sections
[S
.OriginalSecNdx
], Phdr
)) {
501 PH
.FirstSec
= S
.Name
;
503 PH
.Chunks
.push_back(C
.get());
513 template <class ELFT
>
514 std::optional
<DWARFYAML::Data
> ELFDumper
<ELFT
>::dumpDWARFSections(
515 std::vector
<std::unique_ptr
<ELFYAML::Chunk
>> &Sections
) {
516 DWARFYAML::Data DWARF
;
517 for (std::unique_ptr
<ELFYAML::Chunk
> &C
: Sections
) {
518 if (!C
->Name
.startswith(".debug_"))
521 if (ELFYAML::RawContentSection
*RawSec
=
522 dyn_cast
<ELFYAML::RawContentSection
>(C
.get())) {
523 // FIXME: The dumpDebug* functions should take the content as stored in
524 // RawSec. Currently, they just use the last section with the matching
525 // name, which defeats this attempt to skip reading a section header
526 // string table with the same name as a DWARF section.
527 if (ShStrTabIndex
&& RawSec
->OriginalSecNdx
== *ShStrTabIndex
)
529 Error Err
= Error::success();
530 cantFail(std::move(Err
));
532 if (RawSec
->Name
== ".debug_aranges")
533 Err
= dumpDebugARanges(*DWARFCtx
, DWARF
);
534 else if (RawSec
->Name
== ".debug_str")
535 Err
= dumpDebugStrings(*DWARFCtx
, DWARF
);
536 else if (RawSec
->Name
== ".debug_ranges")
537 Err
= dumpDebugRanges(*DWARFCtx
, DWARF
);
538 else if (RawSec
->Name
== ".debug_addr")
539 Err
= dumpDebugAddr(*DWARFCtx
, DWARF
);
543 // If the DWARF section cannot be successfully parsed, emit raw content
544 // instead of an entry in the DWARF section of the YAML.
546 consumeError(std::move(Err
));
548 RawSec
->Content
.reset();
552 if (DWARF
.getNonEmptySectionNames().empty())
557 template <class ELFT
>
558 Expected
<ELFYAML::RawContentSection
*>
559 ELFDumper
<ELFT
>::dumpPlaceholderSection(const Elf_Shdr
*Shdr
) {
560 auto S
= std::make_unique
<ELFYAML::RawContentSection
>();
561 if (Error E
= dumpCommonSection(Shdr
, *S
.get()))
564 // Normally symbol tables should not be empty. We dump the "Size"
565 // key when they are.
566 if ((Shdr
->sh_type
== ELF::SHT_SYMTAB
|| Shdr
->sh_type
== ELF::SHT_DYNSYM
) &&
573 template <class ELFT
>
574 Expected
<std::vector
<std::unique_ptr
<ELFYAML::Chunk
>>>
575 ELFDumper
<ELFT
>::dumpSections() {
576 std::vector
<std::unique_ptr
<ELFYAML::Chunk
>> Ret
;
577 auto Add
= [&](Expected
<ELFYAML::Chunk
*> SecOrErr
) -> Error
{
579 return SecOrErr
.takeError();
580 Ret
.emplace_back(*SecOrErr
);
581 return Error::success();
584 auto GetDumper
= [this](unsigned Type
)
585 -> std::function
<Expected
<ELFYAML::Chunk
*>(const Elf_Shdr
*)> {
586 if (Obj
.getHeader().e_machine
== ELF::EM_ARM
&& Type
== ELF::SHT_ARM_EXIDX
)
587 return [this](const Elf_Shdr
*S
) { return dumpARMIndexTableSection(S
); };
589 if (Obj
.getHeader().e_machine
== ELF::EM_MIPS
&&
590 Type
== ELF::SHT_MIPS_ABIFLAGS
)
591 return [this](const Elf_Shdr
*S
) { return dumpMipsABIFlags(S
); };
594 case ELF::SHT_DYNAMIC
:
595 return [this](const Elf_Shdr
*S
) { return dumpDynamicSection(S
); };
596 case ELF::SHT_SYMTAB_SHNDX
:
597 return [this](const Elf_Shdr
*S
) { return dumpSymtabShndxSection(S
); };
600 return [this](const Elf_Shdr
*S
) { return dumpRelocSection(S
); };
602 return [this](const Elf_Shdr
*S
) { return dumpRelrSection(S
); };
604 return [this](const Elf_Shdr
*S
) { return dumpGroupSection(S
); };
605 case ELF::SHT_NOBITS
:
606 return [this](const Elf_Shdr
*S
) { return dumpNoBitsSection(S
); };
608 return [this](const Elf_Shdr
*S
) { return dumpNoteSection(S
); };
610 return [this](const Elf_Shdr
*S
) { return dumpHashSection(S
); };
611 case ELF::SHT_GNU_HASH
:
612 return [this](const Elf_Shdr
*S
) { return dumpGnuHashSection(S
); };
613 case ELF::SHT_GNU_verdef
:
614 return [this](const Elf_Shdr
*S
) { return dumpVerdefSection(S
); };
615 case ELF::SHT_GNU_versym
:
616 return [this](const Elf_Shdr
*S
) { return dumpSymverSection(S
); };
617 case ELF::SHT_GNU_verneed
:
618 return [this](const Elf_Shdr
*S
) { return dumpVerneedSection(S
); };
619 case ELF::SHT_LLVM_ADDRSIG
:
620 return [this](const Elf_Shdr
*S
) { return dumpAddrsigSection(S
); };
621 case ELF::SHT_LLVM_LINKER_OPTIONS
:
622 return [this](const Elf_Shdr
*S
) { return dumpLinkerOptionsSection(S
); };
623 case ELF::SHT_LLVM_DEPENDENT_LIBRARIES
:
624 return [this](const Elf_Shdr
*S
) {
625 return dumpDependentLibrariesSection(S
);
627 case ELF::SHT_LLVM_CALL_GRAPH_PROFILE
:
629 [this](const Elf_Shdr
*S
) { return dumpCallGraphProfileSection(S
); };
630 case ELF::SHT_LLVM_BB_ADDR_MAP_V0
:
631 case ELF::SHT_LLVM_BB_ADDR_MAP
:
632 return [this](const Elf_Shdr
*S
) { return dumpBBAddrMapSection(S
); };
633 case ELF::SHT_STRTAB
:
634 case ELF::SHT_SYMTAB
:
635 case ELF::SHT_DYNSYM
:
636 // The contents of these sections are described by other parts of the YAML
637 // file. But we still want to dump them, because their properties can be
638 // important. See comments for 'shouldPrintSection()' for more details.
639 return [this](const Elf_Shdr
*S
) { return dumpPlaceholderSection(S
); };
645 for (const Elf_Shdr
&Sec
: Sections
) {
646 // We have dedicated dumping functions for most of the section types.
647 // Try to use one of them first.
648 if (std::function
<Expected
<ELFYAML::Chunk
*>(const Elf_Shdr
*)> DumpFn
=
649 GetDumper(Sec
.sh_type
)) {
650 if (Error E
= Add(DumpFn(&Sec
)))
655 // Recognize some special SHT_PROGBITS sections by name.
656 if (Sec
.sh_type
== ELF::SHT_PROGBITS
) {
657 auto NameOrErr
= Obj
.getSectionName(Sec
);
659 return NameOrErr
.takeError();
661 if (ELFYAML::StackSizesSection::nameMatches(*NameOrErr
)) {
662 if (Error E
= Add(dumpStackSizesSection(&Sec
)))
668 if (Error E
= Add(dumpContentSection(&Sec
)))
672 return std::move(Ret
);
675 template <class ELFT
>
676 Error ELFDumper
<ELFT
>::dumpSymbols(
677 const Elf_Shdr
*Symtab
,
678 std::optional
<std::vector
<ELFYAML::Symbol
>> &Symbols
) {
680 return Error::success();
682 auto SymtabOrErr
= Obj
.symbols(Symtab
);
684 return SymtabOrErr
.takeError();
686 if (SymtabOrErr
->empty())
687 return Error::success();
689 auto StrTableOrErr
= Obj
.getStringTableForSymtab(*Symtab
);
691 return StrTableOrErr
.takeError();
693 if (Symtab
->sh_type
== ELF::SHT_SYMTAB
) {
694 SymTable
= *SymtabOrErr
;
695 SymbolNames
.resize(SymTable
.size());
699 for (const auto &Sym
: (*SymtabOrErr
).drop_front()) {
701 if (auto EC
= dumpSymbol(&Sym
, Symtab
, *StrTableOrErr
, S
))
703 Symbols
->push_back(S
);
706 return Error::success();
709 template <class ELFT
>
710 Error ELFDumper
<ELFT
>::dumpSymbol(const Elf_Sym
*Sym
, const Elf_Shdr
*SymTab
,
711 StringRef StrTable
, ELFYAML::Symbol
&S
) {
712 S
.Type
= Sym
->getType();
714 S
.Value
= (yaml::Hex64
)Sym
->st_value
;
716 S
.Size
= (yaml::Hex64
)Sym
->st_size
;
717 S
.Other
= Sym
->st_other
;
718 S
.Binding
= Sym
->getBinding();
720 Expected
<StringRef
> SymbolNameOrErr
=
721 getUniquedSymbolName(Sym
, StrTable
, SymTab
);
722 if (!SymbolNameOrErr
)
723 return SymbolNameOrErr
.takeError();
724 S
.Name
= SymbolNameOrErr
.get();
726 if (Sym
->st_shndx
>= ELF::SHN_LORESERVE
) {
727 S
.Index
= (ELFYAML::ELF_SHN
)Sym
->st_shndx
;
728 return Error::success();
731 auto ShdrOrErr
= Obj
.getSection(*Sym
, SymTab
, ShndxTables
.lookup(SymTab
));
733 return ShdrOrErr
.takeError();
734 const Elf_Shdr
*Shdr
= *ShdrOrErr
;
736 return Error::success();
738 auto NameOrErr
= getUniquedSectionName(*Shdr
);
740 return NameOrErr
.takeError();
741 S
.Section
= NameOrErr
.get();
743 return Error::success();
746 template <class ELFT
>
747 template <class RelT
>
748 Error ELFDumper
<ELFT
>::dumpRelocation(const RelT
*Rel
, const Elf_Shdr
*SymTab
,
749 ELFYAML::Relocation
&R
) {
750 R
.Type
= Rel
->getType(Obj
.isMips64EL());
751 R
.Offset
= Rel
->r_offset
;
754 auto SymOrErr
= Obj
.getRelocationSymbol(*Rel
, SymTab
);
756 return SymOrErr
.takeError();
758 // We have might have a relocation with symbol index 0,
759 // e.g. R_X86_64_NONE or R_X86_64_GOTPC32.
760 const Elf_Sym
*Sym
= *SymOrErr
;
762 return Error::success();
764 auto StrTabSec
= Obj
.getSection(SymTab
->sh_link
);
766 return StrTabSec
.takeError();
767 auto StrTabOrErr
= Obj
.getStringTable(**StrTabSec
);
769 return StrTabOrErr
.takeError();
771 Expected
<StringRef
> NameOrErr
=
772 getUniquedSymbolName(Sym
, *StrTabOrErr
, SymTab
);
774 return NameOrErr
.takeError();
775 R
.Symbol
= NameOrErr
.get();
777 return Error::success();
780 template <class ELFT
>
781 Error ELFDumper
<ELFT
>::dumpCommonSection(const Elf_Shdr
*Shdr
,
782 ELFYAML::Section
&S
) {
783 // Dump fields. We do not dump the ShOffset field. When not explicitly
784 // set, the value is set by yaml2obj automatically.
785 S
.Type
= Shdr
->sh_type
;
787 S
.Flags
= static_cast<ELFYAML::ELF_SHF
>(Shdr
->sh_flags
);
789 S
.Address
= static_cast<uint64_t>(Shdr
->sh_addr
);
790 S
.AddressAlign
= Shdr
->sh_addralign
;
792 S
.OriginalSecNdx
= Shdr
- &Sections
[0];
794 Expected
<StringRef
> NameOrErr
= getUniquedSectionName(*Shdr
);
796 return NameOrErr
.takeError();
797 S
.Name
= NameOrErr
.get();
799 if (Shdr
->sh_entsize
!= ELFYAML::getDefaultShEntSize
<ELFT
>(
800 Obj
.getHeader().e_machine
, S
.Type
, S
.Name
))
801 S
.EntSize
= static_cast<llvm::yaml::Hex64
>(Shdr
->sh_entsize
);
803 if (Shdr
->sh_link
!= ELF::SHN_UNDEF
) {
804 Expected
<const Elf_Shdr
*> LinkSection
= Obj
.getSection(Shdr
->sh_link
);
806 return make_error
<StringError
>(
807 "unable to resolve sh_link reference in section '" + S
.Name
+
808 "': " + toString(LinkSection
.takeError()),
809 inconvertibleErrorCode());
811 NameOrErr
= getUniquedSectionName(**LinkSection
);
813 return NameOrErr
.takeError();
814 S
.Link
= NameOrErr
.get();
817 return Error::success();
820 template <class ELFT
>
821 Error ELFDumper
<ELFT
>::dumpCommonRelocationSection(
822 const Elf_Shdr
*Shdr
, ELFYAML::RelocationSection
&S
) {
823 if (Error E
= dumpCommonSection(Shdr
, S
))
826 // Having a zero sh_info field is normal: .rela.dyn is a dynamic
827 // relocation section that normally has no value in this field.
829 return Error::success();
831 auto InfoSection
= Obj
.getSection(Shdr
->sh_info
);
833 return InfoSection
.takeError();
835 Expected
<StringRef
> NameOrErr
= getUniquedSectionName(**InfoSection
);
837 return NameOrErr
.takeError();
838 S
.RelocatableSec
= NameOrErr
.get();
840 return Error::success();
843 template <class ELFT
>
844 Expected
<ELFYAML::StackSizesSection
*>
845 ELFDumper
<ELFT
>::dumpStackSizesSection(const Elf_Shdr
*Shdr
) {
846 auto S
= std::make_unique
<ELFYAML::StackSizesSection
>();
847 if (Error E
= dumpCommonSection(Shdr
, *S
))
850 auto ContentOrErr
= Obj
.getSectionContents(*Shdr
);
852 return ContentOrErr
.takeError();
854 ArrayRef
<uint8_t> Content
= *ContentOrErr
;
855 DataExtractor
Data(Content
, Obj
.isLE(), ELFT::Is64Bits
? 8 : 4);
857 std::vector
<ELFYAML::StackSizeEntry
> Entries
;
858 DataExtractor::Cursor
Cur(0);
859 while (Cur
&& Cur
.tell() < Content
.size()) {
860 uint64_t Address
= Data
.getAddress(Cur
);
861 uint64_t Size
= Data
.getULEB128(Cur
);
862 Entries
.push_back({Address
, Size
});
865 if (Content
.empty() || !Cur
) {
866 // If .stack_sizes cannot be decoded, we dump it as an array of bytes.
867 consumeError(Cur
.takeError());
868 S
->Content
= yaml::BinaryRef(Content
);
870 S
->Entries
= std::move(Entries
);
876 template <class ELFT
>
877 Expected
<ELFYAML::BBAddrMapSection
*>
878 ELFDumper
<ELFT
>::dumpBBAddrMapSection(const Elf_Shdr
*Shdr
) {
879 auto S
= std::make_unique
<ELFYAML::BBAddrMapSection
>();
880 if (Error E
= dumpCommonSection(Shdr
, *S
))
883 auto ContentOrErr
= Obj
.getSectionContents(*Shdr
);
885 return ContentOrErr
.takeError();
887 ArrayRef
<uint8_t> Content
= *ContentOrErr
;
891 DataExtractor
Data(Content
, Obj
.isLE(), ELFT::Is64Bits
? 8 : 4);
893 std::vector
<ELFYAML::BBAddrMapEntry
> Entries
;
894 DataExtractor::Cursor
Cur(0);
897 while (Cur
&& Cur
.tell() < Content
.size()) {
898 if (Shdr
->sh_type
== ELF::SHT_LLVM_BB_ADDR_MAP
) {
899 Version
= Data
.getU8(Cur
);
900 if (Cur
&& Version
> 2)
901 return createStringError(
902 errc::invalid_argument
,
903 "invalid SHT_LLVM_BB_ADDR_MAP section version: " +
904 Twine(static_cast<int>(Version
)));
905 Feature
= Data
.getU8(Cur
);
907 uint64_t Address
= Data
.getAddress(Cur
);
908 uint64_t NumBlocks
= Data
.getULEB128(Cur
);
909 std::vector
<ELFYAML::BBAddrMapEntry::BBEntry
> BBEntries
;
910 // Read the specified number of BB entries, or until decoding fails.
911 for (uint64_t BlockIndex
= 0; Cur
&& BlockIndex
< NumBlocks
; ++BlockIndex
) {
912 uint32_t ID
= Version
>= 2 ? Data
.getULEB128(Cur
) : BlockIndex
;
913 uint64_t Offset
= Data
.getULEB128(Cur
);
914 uint64_t Size
= Data
.getULEB128(Cur
);
915 uint64_t Metadata
= Data
.getULEB128(Cur
);
916 BBEntries
.push_back({ID
, Offset
, Size
, Metadata
});
919 {Version
, Feature
, Address
, /*NumBlocks=*/{}, std::move(BBEntries
)});
923 // If the section cannot be decoded, we dump it as an array of bytes.
924 consumeError(Cur
.takeError());
925 S
->Content
= yaml::BinaryRef(Content
);
927 S
->Entries
= std::move(Entries
);
933 template <class ELFT
>
934 Expected
<ELFYAML::AddrsigSection
*>
935 ELFDumper
<ELFT
>::dumpAddrsigSection(const Elf_Shdr
*Shdr
) {
936 auto S
= std::make_unique
<ELFYAML::AddrsigSection
>();
937 if (Error E
= dumpCommonSection(Shdr
, *S
))
940 auto ContentOrErr
= Obj
.getSectionContents(*Shdr
);
942 return ContentOrErr
.takeError();
944 ArrayRef
<uint8_t> Content
= *ContentOrErr
;
945 DataExtractor::Cursor
Cur(0);
946 DataExtractor
Data(Content
, Obj
.isLE(), /*AddressSize=*/0);
947 std::vector
<ELFYAML::YAMLFlowString
> Symbols
;
948 while (Cur
&& Cur
.tell() < Content
.size()) {
949 uint64_t SymNdx
= Data
.getULEB128(Cur
);
953 Expected
<StringRef
> SymbolName
= getSymbolName(Shdr
->sh_link
, SymNdx
);
954 if (!SymbolName
|| SymbolName
->empty()) {
955 consumeError(SymbolName
.takeError());
956 Symbols
.emplace_back(
957 StringRef(std::to_string(SymNdx
)).copy(StringAllocator
));
961 Symbols
.emplace_back(*SymbolName
);
965 S
->Symbols
= std::move(Symbols
);
969 consumeError(Cur
.takeError());
970 S
->Content
= yaml::BinaryRef(Content
);
974 template <class ELFT
>
975 Expected
<ELFYAML::LinkerOptionsSection
*>
976 ELFDumper
<ELFT
>::dumpLinkerOptionsSection(const Elf_Shdr
*Shdr
) {
977 auto S
= std::make_unique
<ELFYAML::LinkerOptionsSection
>();
978 if (Error E
= dumpCommonSection(Shdr
, *S
))
981 auto ContentOrErr
= Obj
.getSectionContents(*Shdr
);
983 return ContentOrErr
.takeError();
985 ArrayRef
<uint8_t> Content
= *ContentOrErr
;
986 if (Content
.empty() || Content
.back() != 0) {
987 S
->Content
= Content
;
991 SmallVector
<StringRef
, 16> Strings
;
992 toStringRef(Content
.drop_back()).split(Strings
, '\0');
993 if (Strings
.size() % 2 != 0) {
994 S
->Content
= Content
;
998 S
->Options
.emplace();
999 for (size_t I
= 0, E
= Strings
.size(); I
!= E
; I
+= 2)
1000 S
->Options
->push_back({Strings
[I
], Strings
[I
+ 1]});
1005 template <class ELFT
>
1006 Expected
<ELFYAML::DependentLibrariesSection
*>
1007 ELFDumper
<ELFT
>::dumpDependentLibrariesSection(const Elf_Shdr
*Shdr
) {
1008 auto DL
= std::make_unique
<ELFYAML::DependentLibrariesSection
>();
1009 if (Error E
= dumpCommonSection(Shdr
, *DL
))
1010 return std::move(E
);
1012 Expected
<ArrayRef
<uint8_t>> ContentOrErr
= Obj
.getSectionContents(*Shdr
);
1014 return ContentOrErr
.takeError();
1016 ArrayRef
<uint8_t> Content
= *ContentOrErr
;
1017 if (!Content
.empty() && Content
.back() != 0) {
1018 DL
->Content
= Content
;
1019 return DL
.release();
1023 for (const uint8_t *I
= Content
.begin(), *E
= Content
.end(); I
< E
;) {
1024 StringRef
Lib((const char *)I
);
1025 DL
->Libs
->emplace_back(Lib
);
1026 I
+= Lib
.size() + 1;
1029 return DL
.release();
1032 template <class ELFT
>
1033 Expected
<ELFYAML::CallGraphProfileSection
*>
1034 ELFDumper
<ELFT
>::dumpCallGraphProfileSection(const Elf_Shdr
*Shdr
) {
1035 auto S
= std::make_unique
<ELFYAML::CallGraphProfileSection
>();
1036 if (Error E
= dumpCommonSection(Shdr
, *S
))
1037 return std::move(E
);
1039 Expected
<ArrayRef
<uint8_t>> ContentOrErr
= Obj
.getSectionContents(*Shdr
);
1041 return ContentOrErr
.takeError();
1042 ArrayRef
<uint8_t> Content
= *ContentOrErr
;
1043 const uint32_t SizeOfEntry
= ELFYAML::getDefaultShEntSize
<ELFT
>(
1044 Obj
.getHeader().e_machine
, S
->Type
, S
->Name
);
1045 // Dump the section by using the Content key when it is truncated.
1046 // There is no need to create either "Content" or "Entries" fields when the
1047 // section is empty.
1048 if (Content
.empty() || Content
.size() % SizeOfEntry
!= 0) {
1049 if (!Content
.empty())
1050 S
->Content
= yaml::BinaryRef(Content
);
1054 std::vector
<ELFYAML::CallGraphEntryWeight
> Entries(Content
.size() /
1056 DataExtractor
Data(Content
, Obj
.isLE(), /*AddressSize=*/0);
1057 DataExtractor::Cursor
Cur(0);
1058 auto ReadEntry
= [&](ELFYAML::CallGraphEntryWeight
&E
) {
1059 E
.Weight
= Data
.getU64(Cur
);
1061 consumeError(Cur
.takeError());
1067 for (ELFYAML::CallGraphEntryWeight
&E
: Entries
) {
1070 S
->Content
= yaml::BinaryRef(Content
);
1074 S
->Entries
= std::move(Entries
);
1078 template <class ELFT
>
1079 Expected
<ELFYAML::DynamicSection
*>
1080 ELFDumper
<ELFT
>::dumpDynamicSection(const Elf_Shdr
*Shdr
) {
1081 auto S
= std::make_unique
<ELFYAML::DynamicSection
>();
1082 if (Error E
= dumpCommonSection(Shdr
, *S
))
1083 return std::move(E
);
1085 auto DynTagsOrErr
= Obj
.template getSectionContentsAsArray
<Elf_Dyn
>(*Shdr
);
1087 return DynTagsOrErr
.takeError();
1089 S
->Entries
.emplace();
1090 for (const Elf_Dyn
&Dyn
: *DynTagsOrErr
)
1091 S
->Entries
->push_back({(ELFYAML::ELF_DYNTAG
)Dyn
.getTag(), Dyn
.getVal()});
1096 template <class ELFT
>
1097 Expected
<ELFYAML::RelocationSection
*>
1098 ELFDumper
<ELFT
>::dumpRelocSection(const Elf_Shdr
*Shdr
) {
1099 auto S
= std::make_unique
<ELFYAML::RelocationSection
>();
1100 if (auto E
= dumpCommonRelocationSection(Shdr
, *S
))
1101 return std::move(E
);
1103 auto SymTabOrErr
= Obj
.getSection(Shdr
->sh_link
);
1105 return SymTabOrErr
.takeError();
1107 if (Shdr
->sh_size
!= 0)
1108 S
->Relocations
.emplace();
1110 if (Shdr
->sh_type
== ELF::SHT_REL
) {
1111 auto Rels
= Obj
.rels(*Shdr
);
1113 return Rels
.takeError();
1114 for (const Elf_Rel
&Rel
: *Rels
) {
1115 ELFYAML::Relocation R
;
1116 if (Error E
= dumpRelocation(&Rel
, *SymTabOrErr
, R
))
1117 return std::move(E
);
1118 S
->Relocations
->push_back(R
);
1121 auto Rels
= Obj
.relas(*Shdr
);
1123 return Rels
.takeError();
1124 for (const Elf_Rela
&Rel
: *Rels
) {
1125 ELFYAML::Relocation R
;
1126 if (Error E
= dumpRelocation(&Rel
, *SymTabOrErr
, R
))
1127 return std::move(E
);
1128 R
.Addend
= Rel
.r_addend
;
1129 S
->Relocations
->push_back(R
);
1136 template <class ELFT
>
1137 Expected
<ELFYAML::RelrSection
*>
1138 ELFDumper
<ELFT
>::dumpRelrSection(const Elf_Shdr
*Shdr
) {
1139 auto S
= std::make_unique
<ELFYAML::RelrSection
>();
1140 if (auto E
= dumpCommonSection(Shdr
, *S
))
1141 return std::move(E
);
1143 if (Expected
<ArrayRef
<Elf_Relr
>> Relrs
= Obj
.relrs(*Shdr
)) {
1144 S
->Entries
.emplace();
1145 for (Elf_Relr Rel
: *Relrs
)
1146 S
->Entries
->emplace_back(Rel
);
1149 // Ignore. We are going to dump the data as raw content below.
1150 consumeError(Relrs
.takeError());
1153 Expected
<ArrayRef
<uint8_t>> ContentOrErr
= Obj
.getSectionContents(*Shdr
);
1155 return ContentOrErr
.takeError();
1156 S
->Content
= *ContentOrErr
;
1160 template <class ELFT
>
1161 Expected
<ELFYAML::RawContentSection
*>
1162 ELFDumper
<ELFT
>::dumpContentSection(const Elf_Shdr
*Shdr
) {
1163 auto S
= std::make_unique
<ELFYAML::RawContentSection
>();
1164 if (Error E
= dumpCommonSection(Shdr
, *S
))
1165 return std::move(E
);
1167 unsigned SecIndex
= Shdr
- &Sections
[0];
1168 if (SecIndex
!= 0 || Shdr
->sh_type
!= ELF::SHT_NULL
) {
1169 auto ContentOrErr
= Obj
.getSectionContents(*Shdr
);
1171 return ContentOrErr
.takeError();
1172 ArrayRef
<uint8_t> Content
= *ContentOrErr
;
1173 if (!Content
.empty())
1174 S
->Content
= yaml::BinaryRef(Content
);
1176 S
->Size
= static_cast<llvm::yaml::Hex64
>(Shdr
->sh_size
);
1180 S
->Info
= static_cast<llvm::yaml::Hex64
>(Shdr
->sh_info
);
1184 template <class ELFT
>
1185 Expected
<ELFYAML::SymtabShndxSection
*>
1186 ELFDumper
<ELFT
>::dumpSymtabShndxSection(const Elf_Shdr
*Shdr
) {
1187 auto S
= std::make_unique
<ELFYAML::SymtabShndxSection
>();
1188 if (Error E
= dumpCommonSection(Shdr
, *S
))
1189 return std::move(E
);
1191 auto EntriesOrErr
= Obj
.template getSectionContentsAsArray
<Elf_Word
>(*Shdr
);
1193 return EntriesOrErr
.takeError();
1195 S
->Entries
.emplace();
1196 for (const Elf_Word
&E
: *EntriesOrErr
)
1197 S
->Entries
->push_back(E
);
1201 template <class ELFT
>
1202 Expected
<ELFYAML::NoBitsSection
*>
1203 ELFDumper
<ELFT
>::dumpNoBitsSection(const Elf_Shdr
*Shdr
) {
1204 auto S
= std::make_unique
<ELFYAML::NoBitsSection
>();
1205 if (Error E
= dumpCommonSection(Shdr
, *S
))
1206 return std::move(E
);
1208 S
->Size
= static_cast<llvm::yaml::Hex64
>(Shdr
->sh_size
);
1212 template <class ELFT
>
1213 Expected
<ELFYAML::NoteSection
*>
1214 ELFDumper
<ELFT
>::dumpNoteSection(const Elf_Shdr
*Shdr
) {
1215 auto S
= std::make_unique
<ELFYAML::NoteSection
>();
1216 if (Error E
= dumpCommonSection(Shdr
, *S
))
1217 return std::move(E
);
1219 auto ContentOrErr
= Obj
.getSectionContents(*Shdr
);
1221 return ContentOrErr
.takeError();
1223 std::vector
<ELFYAML::NoteEntry
> Entries
;
1224 ArrayRef
<uint8_t> Content
= *ContentOrErr
;
1225 size_t Align
= std::max
<size_t>(Shdr
->sh_addralign
, 4);
1226 while (!Content
.empty()) {
1227 if (Content
.size() < sizeof(Elf_Nhdr
)) {
1228 S
->Content
= yaml::BinaryRef(*ContentOrErr
);
1232 const Elf_Nhdr
*Header
= reinterpret_cast<const Elf_Nhdr
*>(Content
.data());
1233 if (Content
.size() < Header
->getSize(Align
)) {
1234 S
->Content
= yaml::BinaryRef(*ContentOrErr
);
1238 Elf_Note
Note(*Header
);
1240 {Note
.getName(), Note
.getDesc(Align
), (ELFYAML::ELF_NT
)Note
.getType()});
1242 Content
= Content
.drop_front(Header
->getSize(Align
));
1245 S
->Notes
= std::move(Entries
);
1249 template <class ELFT
>
1250 Expected
<ELFYAML::HashSection
*>
1251 ELFDumper
<ELFT
>::dumpHashSection(const Elf_Shdr
*Shdr
) {
1252 auto S
= std::make_unique
<ELFYAML::HashSection
>();
1253 if (Error E
= dumpCommonSection(Shdr
, *S
))
1254 return std::move(E
);
1256 auto ContentOrErr
= Obj
.getSectionContents(*Shdr
);
1258 return ContentOrErr
.takeError();
1260 ArrayRef
<uint8_t> Content
= *ContentOrErr
;
1261 if (Content
.size() % 4 != 0 || Content
.size() < 8) {
1262 S
->Content
= yaml::BinaryRef(Content
);
1266 DataExtractor::Cursor
Cur(0);
1267 DataExtractor
Data(Content
, Obj
.isLE(), /*AddressSize=*/0);
1268 uint64_t NBucket
= Data
.getU32(Cur
);
1269 uint64_t NChain
= Data
.getU32(Cur
);
1270 if (Content
.size() != (2 + NBucket
+ NChain
) * 4) {
1271 S
->Content
= yaml::BinaryRef(Content
);
1274 llvm_unreachable("entries were not read correctly");
1277 S
->Bucket
.emplace(NBucket
);
1278 for (uint32_t &V
: *S
->Bucket
)
1279 V
= Data
.getU32(Cur
);
1281 S
->Chain
.emplace(NChain
);
1282 for (uint32_t &V
: *S
->Chain
)
1283 V
= Data
.getU32(Cur
);
1287 llvm_unreachable("entries were not read correctly");
1290 template <class ELFT
>
1291 Expected
<ELFYAML::GnuHashSection
*>
1292 ELFDumper
<ELFT
>::dumpGnuHashSection(const Elf_Shdr
*Shdr
) {
1293 auto S
= std::make_unique
<ELFYAML::GnuHashSection
>();
1294 if (Error E
= dumpCommonSection(Shdr
, *S
))
1295 return std::move(E
);
1297 auto ContentOrErr
= Obj
.getSectionContents(*Shdr
);
1299 return ContentOrErr
.takeError();
1301 unsigned AddrSize
= ELFT::Is64Bits
? 8 : 4;
1302 ArrayRef
<uint8_t> Content
= *ContentOrErr
;
1303 DataExtractor
Data(Content
, Obj
.isLE(), AddrSize
);
1305 ELFYAML::GnuHashHeader Header
;
1306 DataExtractor::Cursor
Cur(0);
1307 uint64_t NBuckets
= Data
.getU32(Cur
);
1308 Header
.SymNdx
= Data
.getU32(Cur
);
1309 uint64_t MaskWords
= Data
.getU32(Cur
);
1310 Header
.Shift2
= Data
.getU32(Cur
);
1312 // Set just the raw binary content if we were unable to read the header
1313 // or when the section data is truncated or malformed.
1314 uint64_t Size
= Data
.getData().size() - Cur
.tell();
1315 if (!Cur
|| (Size
< MaskWords
* AddrSize
+ NBuckets
* 4) ||
1317 consumeError(Cur
.takeError());
1318 S
->Content
= yaml::BinaryRef(Content
);
1324 S
->BloomFilter
.emplace(MaskWords
);
1325 for (llvm::yaml::Hex64
&Val
: *S
->BloomFilter
)
1326 Val
= Data
.getAddress(Cur
);
1328 S
->HashBuckets
.emplace(NBuckets
);
1329 for (llvm::yaml::Hex32
&Val
: *S
->HashBuckets
)
1330 Val
= Data
.getU32(Cur
);
1332 S
->HashValues
.emplace((Data
.getData().size() - Cur
.tell()) / 4);
1333 for (llvm::yaml::Hex32
&Val
: *S
->HashValues
)
1334 Val
= Data
.getU32(Cur
);
1338 llvm_unreachable("GnuHashSection was not read correctly");
1341 template <class ELFT
>
1342 Expected
<ELFYAML::VerdefSection
*>
1343 ELFDumper
<ELFT
>::dumpVerdefSection(const Elf_Shdr
*Shdr
) {
1344 auto S
= std::make_unique
<ELFYAML::VerdefSection
>();
1345 if (Error E
= dumpCommonSection(Shdr
, *S
))
1346 return std::move(E
);
1348 auto StringTableShdrOrErr
= Obj
.getSection(Shdr
->sh_link
);
1349 if (!StringTableShdrOrErr
)
1350 return StringTableShdrOrErr
.takeError();
1352 auto StringTableOrErr
= Obj
.getStringTable(**StringTableShdrOrErr
);
1353 if (!StringTableOrErr
)
1354 return StringTableOrErr
.takeError();
1356 auto Contents
= Obj
.getSectionContents(*Shdr
);
1358 return Contents
.takeError();
1360 S
->Entries
.emplace();
1362 llvm::ArrayRef
<uint8_t> Data
= *Contents
;
1363 const uint8_t *Buf
= Data
.data();
1365 const Elf_Verdef
*Verdef
= reinterpret_cast<const Elf_Verdef
*>(Buf
);
1366 ELFYAML::VerdefEntry Entry
;
1367 if (Verdef
->vd_version
!= 1)
1368 return createStringError(errc::invalid_argument
,
1369 "invalid SHT_GNU_verdef section version: " +
1370 Twine(Verdef
->vd_version
));
1372 if (Verdef
->vd_flags
!= 0)
1373 Entry
.Flags
= Verdef
->vd_flags
;
1375 if (Verdef
->vd_ndx
!= 0)
1376 Entry
.VersionNdx
= Verdef
->vd_ndx
;
1378 if (Verdef
->vd_hash
!= 0)
1379 Entry
.Hash
= Verdef
->vd_hash
;
1381 const uint8_t *BufAux
= Buf
+ Verdef
->vd_aux
;
1383 const Elf_Verdaux
*Verdaux
=
1384 reinterpret_cast<const Elf_Verdaux
*>(BufAux
);
1385 Entry
.VerNames
.push_back(
1386 StringTableOrErr
->drop_front(Verdaux
->vda_name
).data());
1387 BufAux
= Verdaux
->vda_next
? BufAux
+ Verdaux
->vda_next
: nullptr;
1390 S
->Entries
->push_back(Entry
);
1391 Buf
= Verdef
->vd_next
? Buf
+ Verdef
->vd_next
: nullptr;
1394 if (Shdr
->sh_info
!= S
->Entries
->size())
1395 S
->Info
= (llvm::yaml::Hex64
)Shdr
->sh_info
;
1400 template <class ELFT
>
1401 Expected
<ELFYAML::SymverSection
*>
1402 ELFDumper
<ELFT
>::dumpSymverSection(const Elf_Shdr
*Shdr
) {
1403 auto S
= std::make_unique
<ELFYAML::SymverSection
>();
1404 if (Error E
= dumpCommonSection(Shdr
, *S
))
1405 return std::move(E
);
1407 auto VersionsOrErr
= Obj
.template getSectionContentsAsArray
<Elf_Half
>(*Shdr
);
1409 return VersionsOrErr
.takeError();
1411 S
->Entries
.emplace();
1412 for (const Elf_Half
&E
: *VersionsOrErr
)
1413 S
->Entries
->push_back(E
);
1418 template <class ELFT
>
1419 Expected
<ELFYAML::VerneedSection
*>
1420 ELFDumper
<ELFT
>::dumpVerneedSection(const Elf_Shdr
*Shdr
) {
1421 auto S
= std::make_unique
<ELFYAML::VerneedSection
>();
1422 if (Error E
= dumpCommonSection(Shdr
, *S
))
1423 return std::move(E
);
1425 auto Contents
= Obj
.getSectionContents(*Shdr
);
1427 return Contents
.takeError();
1429 auto StringTableShdrOrErr
= Obj
.getSection(Shdr
->sh_link
);
1430 if (!StringTableShdrOrErr
)
1431 return StringTableShdrOrErr
.takeError();
1433 auto StringTableOrErr
= Obj
.getStringTable(**StringTableShdrOrErr
);
1434 if (!StringTableOrErr
)
1435 return StringTableOrErr
.takeError();
1437 S
->VerneedV
.emplace();
1439 llvm::ArrayRef
<uint8_t> Data
= *Contents
;
1440 const uint8_t *Buf
= Data
.data();
1442 const Elf_Verneed
*Verneed
= reinterpret_cast<const Elf_Verneed
*>(Buf
);
1444 ELFYAML::VerneedEntry Entry
;
1445 Entry
.Version
= Verneed
->vn_version
;
1447 StringRef(StringTableOrErr
->drop_front(Verneed
->vn_file
).data());
1449 const uint8_t *BufAux
= Buf
+ Verneed
->vn_aux
;
1451 const Elf_Vernaux
*Vernaux
=
1452 reinterpret_cast<const Elf_Vernaux
*>(BufAux
);
1454 ELFYAML::VernauxEntry Aux
;
1455 Aux
.Hash
= Vernaux
->vna_hash
;
1456 Aux
.Flags
= Vernaux
->vna_flags
;
1457 Aux
.Other
= Vernaux
->vna_other
;
1459 StringRef(StringTableOrErr
->drop_front(Vernaux
->vna_name
).data());
1461 Entry
.AuxV
.push_back(Aux
);
1462 BufAux
= Vernaux
->vna_next
? BufAux
+ Vernaux
->vna_next
: nullptr;
1465 S
->VerneedV
->push_back(Entry
);
1466 Buf
= Verneed
->vn_next
? Buf
+ Verneed
->vn_next
: nullptr;
1469 if (Shdr
->sh_info
!= S
->VerneedV
->size())
1470 S
->Info
= (llvm::yaml::Hex64
)Shdr
->sh_info
;
1475 template <class ELFT
>
1476 Expected
<StringRef
> ELFDumper
<ELFT
>::getSymbolName(uint32_t SymtabNdx
,
1477 uint32_t SymbolNdx
) {
1478 auto SymtabOrErr
= Obj
.getSection(SymtabNdx
);
1480 return SymtabOrErr
.takeError();
1482 const Elf_Shdr
*Symtab
= *SymtabOrErr
;
1483 auto SymOrErr
= Obj
.getSymbol(Symtab
, SymbolNdx
);
1485 return SymOrErr
.takeError();
1487 auto StrTabOrErr
= Obj
.getStringTableForSymtab(*Symtab
);
1489 return StrTabOrErr
.takeError();
1490 return getUniquedSymbolName(*SymOrErr
, *StrTabOrErr
, Symtab
);
1493 template <class ELFT
>
1494 Expected
<ELFYAML::GroupSection
*>
1495 ELFDumper
<ELFT
>::dumpGroupSection(const Elf_Shdr
*Shdr
) {
1496 auto S
= std::make_unique
<ELFYAML::GroupSection
>();
1497 if (Error E
= dumpCommonSection(Shdr
, *S
))
1498 return std::move(E
);
1500 // Get symbol with index sh_info. This symbol's name is the signature of the group.
1501 Expected
<StringRef
> SymbolName
= getSymbolName(Shdr
->sh_link
, Shdr
->sh_info
);
1503 return SymbolName
.takeError();
1504 S
->Signature
= *SymbolName
;
1506 auto MembersOrErr
= Obj
.template getSectionContentsAsArray
<Elf_Word
>(*Shdr
);
1508 return MembersOrErr
.takeError();
1510 S
->Members
.emplace();
1511 for (Elf_Word Member
: *MembersOrErr
) {
1512 if (Member
== llvm::ELF::GRP_COMDAT
) {
1513 S
->Members
->push_back({"GRP_COMDAT"});
1517 Expected
<const Elf_Shdr
*> SHdrOrErr
= Obj
.getSection(Member
);
1519 return SHdrOrErr
.takeError();
1520 Expected
<StringRef
> NameOrErr
= getUniquedSectionName(**SHdrOrErr
);
1522 return NameOrErr
.takeError();
1523 S
->Members
->push_back({*NameOrErr
});
1528 template <class ELFT
>
1529 Expected
<ELFYAML::ARMIndexTableSection
*>
1530 ELFDumper
<ELFT
>::dumpARMIndexTableSection(const Elf_Shdr
*Shdr
) {
1531 auto S
= std::make_unique
<ELFYAML::ARMIndexTableSection
>();
1532 if (Error E
= dumpCommonSection(Shdr
, *S
))
1533 return std::move(E
);
1535 Expected
<ArrayRef
<uint8_t>> ContentOrErr
= Obj
.getSectionContents(*Shdr
);
1537 return ContentOrErr
.takeError();
1539 if (ContentOrErr
->size() % (sizeof(Elf_Word
) * 2) != 0) {
1540 S
->Content
= yaml::BinaryRef(*ContentOrErr
);
1544 ArrayRef
<Elf_Word
> Words(
1545 reinterpret_cast<const Elf_Word
*>(ContentOrErr
->data()),
1546 ContentOrErr
->size() / sizeof(Elf_Word
));
1548 S
->Entries
.emplace();
1549 for (size_t I
= 0, E
= Words
.size(); I
!= E
; I
+= 2)
1550 S
->Entries
->push_back({(yaml::Hex32
)Words
[I
], (yaml::Hex32
)Words
[I
+ 1]});
1555 template <class ELFT
>
1556 Expected
<ELFYAML::MipsABIFlags
*>
1557 ELFDumper
<ELFT
>::dumpMipsABIFlags(const Elf_Shdr
*Shdr
) {
1558 assert(Shdr
->sh_type
== ELF::SHT_MIPS_ABIFLAGS
&&
1559 "Section type is not SHT_MIPS_ABIFLAGS");
1560 auto S
= std::make_unique
<ELFYAML::MipsABIFlags
>();
1561 if (Error E
= dumpCommonSection(Shdr
, *S
))
1562 return std::move(E
);
1564 auto ContentOrErr
= Obj
.getSectionContents(*Shdr
);
1566 return ContentOrErr
.takeError();
1568 auto *Flags
= reinterpret_cast<const object::Elf_Mips_ABIFlags
<ELFT
> *>(
1569 ContentOrErr
.get().data());
1570 S
->Version
= Flags
->version
;
1571 S
->ISALevel
= Flags
->isa_level
;
1572 S
->ISARevision
= Flags
->isa_rev
;
1573 S
->GPRSize
= Flags
->gpr_size
;
1574 S
->CPR1Size
= Flags
->cpr1_size
;
1575 S
->CPR2Size
= Flags
->cpr2_size
;
1576 S
->FpABI
= Flags
->fp_abi
;
1577 S
->ISAExtension
= Flags
->isa_ext
;
1578 S
->ASEs
= Flags
->ases
;
1579 S
->Flags1
= Flags
->flags1
;
1580 S
->Flags2
= Flags
->flags2
;
1584 template <class ELFT
>
1585 static Error
elf2yaml(raw_ostream
&Out
, const object::ELFFile
<ELFT
> &Obj
,
1586 std::unique_ptr
<DWARFContext
> DWARFCtx
) {
1587 ELFDumper
<ELFT
> Dumper(Obj
, std::move(DWARFCtx
));
1588 Expected
<ELFYAML::Object
*> YAMLOrErr
= Dumper
.dump();
1590 return YAMLOrErr
.takeError();
1592 std::unique_ptr
<ELFYAML::Object
> YAML(YAMLOrErr
.get());
1593 yaml::Output
Yout(Out
);
1596 return Error::success();
1599 Error
elf2yaml(raw_ostream
&Out
, const object::ObjectFile
&Obj
) {
1600 std::unique_ptr
<DWARFContext
> DWARFCtx
= DWARFContext::create(Obj
);
1601 if (const auto *ELFObj
= dyn_cast
<object::ELF32LEObjectFile
>(&Obj
))
1602 return elf2yaml(Out
, ELFObj
->getELFFile(), std::move(DWARFCtx
));
1604 if (const auto *ELFObj
= dyn_cast
<object::ELF32BEObjectFile
>(&Obj
))
1605 return elf2yaml(Out
, ELFObj
->getELFFile(), std::move(DWARFCtx
));
1607 if (const auto *ELFObj
= dyn_cast
<object::ELF64LEObjectFile
>(&Obj
))
1608 return elf2yaml(Out
, ELFObj
->getELFFile(), std::move(DWARFCtx
));
1610 if (const auto *ELFObj
= dyn_cast
<object::ELF64BEObjectFile
>(&Obj
))
1611 return elf2yaml(Out
, ELFObj
->getELFFile(), std::move(DWARFCtx
));
1613 llvm_unreachable("unknown ELF file format");