Bug Summary

File:build/source/llvm/tools/obj2yaml/elf2yaml.cpp
Warning:line 1047, column 41
Division by zero

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name elf2yaml.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/source/build-llvm/tools/clang/stage2-bins -resource-dir /usr/lib/llvm-17/lib/clang/17 -D _DEBUG -D _GLIBCXX_ASSERTIONS -D _GNU_SOURCE -D _LIBCPP_ENABLE_ASSERTIONS -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I tools/obj2yaml -I /build/source/llvm/tools/obj2yaml -I include -I /build/source/llvm/include -D _FORTIFY_SOURCE=2 -D NDEBUG -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/x86_64-linux-gnu/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/backward -internal-isystem /usr/lib/llvm-17/lib/clang/17/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/build/source/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fmacro-prefix-map=/build/source/= -fcoverage-prefix-map=/build/source/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fcoverage-prefix-map=/build/source/= -source-date-epoch 1683717183 -O2 -Wno-unused-command-line-argument -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wno-comment -Wno-misleading-indentation -std=c++17 -fdeprecated-macro -fdebug-compilation-dir=/build/source/build-llvm/tools/clang/stage2-bins -fdebug-prefix-map=/build/source/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fdebug-prefix-map=/build/source/= -ferror-limit 19 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2023-05-10-133810-16478-1 -x c++ /build/source/llvm/tools/obj2yaml/elf2yaml.cpp

/build/source/llvm/tools/obj2yaml/elf2yaml.cpp

1//===------ utils/elf2yaml.cpp - obj2yaml conversion tool -------*- C++ -*-===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
9#include "obj2yaml.h"
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"
21#include <optional>
22
23using namespace llvm;
24
25namespace {
26
27template <class ELFT>
28class ELFDumper {
29 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)using Elf_Addr = typename ELFT::Addr; using Elf_Off = typename
ELFT::Off; using Elf_Half = typename ELFT::Half; using Elf_Word
= typename ELFT::Word; using Elf_Sword = typename ELFT::Sword
; using Elf_Xword = typename ELFT::Xword; using Elf_Sxword = typename
ELFT::Sxword; using uintX_t = typename ELFT::uint; using Elf_Ehdr
= typename ELFT::Ehdr; using Elf_Shdr = typename ELFT::Shdr;
using Elf_Sym = typename ELFT::Sym; using Elf_Dyn = typename
ELFT::Dyn; using Elf_Phdr = typename ELFT::Phdr; using Elf_Rel
= typename ELFT::Rel; using Elf_Rela = typename ELFT::Rela; using
Elf_Relr = typename ELFT::Relr; using Elf_Verdef = typename ELFT
::Verdef; using Elf_Verdaux = typename ELFT::Verdaux; using Elf_Verneed
= typename ELFT::Verneed; using Elf_Vernaux = typename ELFT::
Vernaux; using Elf_Versym = typename ELFT::Versym; using Elf_Hash
= typename ELFT::Hash; using Elf_GnuHash = typename ELFT::GnuHash
; using Elf_Chdr = typename ELFT::Chdr; using Elf_Nhdr = typename
ELFT::Nhdr; using Elf_Note = typename ELFT::Note; using Elf_Note_Iterator
= typename ELFT::NoteIterator; using Elf_CGProfile = typename
ELFT::CGProfile; using Elf_Dyn_Range = typename ELFT::DynRange
; using Elf_Shdr_Range = typename ELFT::ShdrRange; using Elf_Sym_Range
= typename ELFT::SymRange; using Elf_Rel_Range = typename ELFT
::RelRange; using Elf_Rela_Range = typename ELFT::RelaRange; using
Elf_Relr_Range = typename ELFT::RelrRange; using Elf_Phdr_Range
= typename ELFT::PhdrRange;
30
31 ArrayRef<Elf_Shdr> Sections;
32 ArrayRef<Elf_Sym> SymTable;
33
34 DenseMap<StringRef, uint32_t> UsedSectionNames;
35 std::vector<std::string> SectionNames;
36 std::optional<uint32_t> ShStrTabIndex;
37
38 DenseMap<StringRef, uint32_t> UsedSymbolNames;
39 std::vector<std::string> SymbolNames;
40
41 BumpPtrAllocator StringAllocator;
42
43 Expected<StringRef> getUniquedSectionName(const Elf_Shdr &Sec);
44 Expected<StringRef> getUniquedSymbolName(const Elf_Sym *Sym,
45 StringRef StrTable,
46 const Elf_Shdr *SymTab);
47 Expected<StringRef> getSymbolName(uint32_t SymtabNdx, uint32_t SymbolNdx);
48
49 const object::ELFFile<ELFT> &Obj;
50 std::unique_ptr<DWARFContext> DWARFCtx;
51
52 DenseMap<const Elf_Shdr *, ArrayRef<Elf_Word>> ShndxTables;
53
54 Expected<std::vector<ELFYAML::ProgramHeader>>
55 dumpProgramHeaders(ArrayRef<std::unique_ptr<ELFYAML::Chunk>> Sections);
56
57 std::optional<DWARFYAML::Data>
58 dumpDWARFSections(std::vector<std::unique_ptr<ELFYAML::Chunk>> &Sections);
59
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);
68 template <class RelT>
69 Error dumpRelocation(const RelT *Rel, const Elf_Shdr *SymTab,
70 ELFYAML::Relocation &R);
71
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);
103
104 bool shouldPrintSection(const ELFYAML::Section &S, const Elf_Shdr &SHdr,
105 std::optional<DWARFYAML::Data> DWARF);
106
107public:
108 ELFDumper(const object::ELFFile<ELFT> &O, std::unique_ptr<DWARFContext> DCtx);
109 Expected<ELFYAML::Object *> dump();
110};
111
112}
113
114template <class ELFT>
115ELFDumper<ELFT>::ELFDumper(const object::ELFFile<ELFT> &O,
116 std::unique_ptr<DWARFContext> DCtx)
117 : Obj(O), DWARFCtx(std::move(DCtx)) {}
118
119template <class ELFT>
120Expected<StringRef>
121ELFDumper<ELFT>::getUniquedSectionName(const Elf_Shdr &Sec) {
122 unsigned SecIndex = &Sec - &Sections[0];
123 if (!SectionNames[SecIndex].empty())
124 return SectionNames[SecIndex];
125
126 auto NameOrErr = Obj.getSectionName(Sec);
127 if (!NameOrErr)
128 return NameOrErr;
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.
133 if (Name.empty())
134 return "";
135
136 std::string &Ret = SectionNames[SecIndex];
137
138 auto It = UsedSectionNames.insert({Name, 0});
139 if (!It.second)
140 Ret = ELFYAML::appendUniqueSuffix(Name, Twine(++It.first->second));
141 else
142 Ret = std::string(Name);
143 return Ret;
144}
145
146template <class ELFT>
147Expected<StringRef>
148ELFDumper<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));
157 if (!ShdrOrErr)
158 return ShdrOrErr.takeError();
159 // The null section has no name.
160 return (*ShdrOrErr == nullptr) ? "" : getUniquedSectionName(**ShdrOrErr);
161 }
162
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];
170
171 auto It = UsedSymbolNames.insert({Name, 0});
172 if (!It.second)
173 SymbolNames[Index] =
174 ELFYAML::appendUniqueSuffix(Name, Twine(++It.first->second));
175 else
176 SymbolNames[Index] = std::string(Name);
177 return SymbolNames[Index];
178 }
179
180 return Name;
181}
182
183template <class ELFT>
184bool 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; });
194 }
195
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
200 // circumstances.
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 ||
207 RawSec->EntSize)
208 return true;
209
210 ELFYAML::ELF_SHF ShFlags = RawSec->Flags.value_or(ELFYAML::ELF_SHF(0));
211
212 if (SecName == "debug_str")
213 return ShFlags != ELFYAML::ELF_SHF(ELF::SHF_MERGE | ELF::SHF_STRINGS);
214
215 return ShFlags != ELFYAML::ELF_SHF{0};
216 }
217 }
218
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;
231 }
232
233 return true;
234}
235
236template <class ELFT>
237static 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) {
241 if (V.empty())
242 return;
243
244 uint64_t ExpectedOffset;
245 if (Header.e_phoff > 0)
246 ExpectedOffset = Header.e_phoff + Header.e_phentsize * Header.e_phnum;
247 else
248 ExpectedOffset = sizeof(typename ELFT::Ehdr);
249
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];
253
254 ExpectedOffset = alignTo(ExpectedOffset,
255 SecHdr.sh_addralign ? SecHdr.sh_addralign : 1uLL);
256
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;
262
263 if (Sec.Type == ELF::SHT_NOBITS &&
264 !ELFYAML::shouldAllocateFileSpace(Phdrs,
265 *cast<ELFYAML::NoBitsSection>(&Sec)))
266 ExpectedOffset = SecHdr.sh_offset;
267 else
268 ExpectedOffset = SecHdr.sh_offset + SecHdr.sh_size;
269 }
270}
271
272template <class ELFT> Expected<ELFYAML::Object *> ELFDumper<ELFT>::dump() {
273 auto Y = std::make_unique<ELFYAML::Object>();
274
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
277 // them here.
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;
287
288 // Dump sections
289 auto SectionsOrErr = Obj.sections();
290 if (!SectionsOrErr)
291 return SectionsOrErr.takeError();
292 Sections = *SectionsOrErr;
293 SectionNames.resize(Sections.size());
294
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.
300 }
301
302 // Normally an object that does not have sections has e_shnum == 0.
303 // Also, e_shnum might be 0, when the 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;
309
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;
314
315 for (const Elf_Shdr &Sec : Sections) {
316 if (Sec.sh_type == ELF::SHT_SYMTAB) {
317 SymTab = &Sec;
318 } else if (Sec.sh_type == ELF::SHT_DYNSYM) {
319 DynSymTab = &Sec;
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 " +
332 Twine(Sec.sh_link));
333 } else {
334 return createStringError(errc::invalid_argument,
335 "unable to read extended section indexes: " +
336 toString(TableOrErr.takeError()));
337 }
338 }
339 }
340
341 if (SymTab)
342 if (Error E = dumpSymbols(SymTab, Y->Symbols))
343 return std::move(E);
344
345 if (DynSymTab)
346 if (Error E = dumpSymbols(DynSymTab, Y->DynamicSymbols))
347 return std::move(E);
348
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 =
354 dumpSections();
355 if (!ChunksOrErr)
356 return ChunksOrErr.takeError();
357 std::vector<std::unique_ptr<ELFYAML::Chunk>> Chunks = std::move(*ChunksOrErr);
358
359 std::vector<ELFYAML::Section *> OriginalOrder;
360 if (!Chunks.empty())
361 for (const std::unique_ptr<ELFYAML::Chunk> &C :
362 ArrayRef(Chunks).drop_front())
363 OriginalOrder.push_back(cast<ELFYAML::Section>(C.get()));
364
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;
371 });
372
373 // Dump program headers.
374 Expected<std::vector<ELFYAML::ProgramHeader>> PhdrsOrErr =
375 dumpProgramHeaders(Chunks);
376 if (!PhdrsOrErr)
377 return PhdrsOrErr.takeError();
378 Y->ProgramHeaders = std::move(*PhdrsOrErr);
379
380 dumpSectionOffsets<ELFT>(Obj.getHeader(), Y->ProgramHeaders, Chunks,
381 Sections);
382
383 // Dump DWARF sections.
384 Y->DWARF = dumpDWARFSections(Chunks);
385
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;
393 });
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));
401 }
402
403 llvm::erase_if(Chunks, [this, &Y](const std::unique_ptr<ELFYAML::Chunk> &C) {
404 if (isa<ELFYAML::SectionHeaderTable>(*C))
405 return false;
406
407 const ELFYAML::Section &S = cast<ELFYAML::Section>(*C);
408 return !shouldPrintSection(S, Sections[S.OriginalSecNdx], Y->DWARF);
409 });
410
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]));
426 } else {
427 // Otherwise, the section name potentially needs uniquifying.
428 ShStrtabName = cantFail(getUniquedSectionName(Sections[*ShStrTabIndex]));
429 }
430 if (ShStrtabName != ".shstrtab")
431 Y->Header.SectionHeaderStringTable = ShStrtabName;
432 }
433
434 Y->Chunks = std::move(Chunks);
435 return Y.release();
436}
437
438template <class ELFT>
439static 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)
443 return false;
444
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);
450
451 bool VirtualAddressesMatch = SHdr.sh_addr >= Phdr.p_vaddr &&
452 SHdr.sh_addr <= Phdr.p_vaddr + Phdr.p_memsz;
453
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;
461 return true;
462 }
463
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
466 // address space.
467 if (Sec.Type != ELF::SHT_NOBITS)
468 return false;
469 return VirtualAddressesMatch;
470}
471
472template <class ELFT>
473Expected<std::vector<ELFYAML::ProgramHeader>>
474ELFDumper<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();
478 if (!PhdrsOrErr)
479 return PhdrsOrErr.takeError();
480
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
488 // yaml2obj sets the alignment of a segment to 1 by default.
489 // We do not print the default alignment to reduce noise in the output.
490 if (Phdr.p_align != 1)
491 PH.Align = static_cast<llvm::yaml::Hex64>(Phdr.p_align);
492
493 // Here we match sections with segments.
494 // It is not possible to have a non-Section chunk, because
495 // obj2yaml does not create Fill chunks.
496 for (const std::unique_ptr<ELFYAML::Chunk> &C : Chunks) {
497 ELFYAML::Section &S = cast<ELFYAML::Section>(*C);
498 if (isInSegment<ELFT>(S, Sections[S.OriginalSecNdx], Phdr)) {
499 if (!PH.FirstSec)
500 PH.FirstSec = S.Name;
501 PH.LastSec = S.Name;
502 PH.Chunks.push_back(C.get());
503 }
504 }
505
506 Ret.push_back(PH);
507 }
508
509 return Ret;
510}
511
512template <class ELFT>
513std::optional<DWARFYAML::Data> ELFDumper<ELFT>::dumpDWARFSections(
514 std::vector<std::unique_ptr<ELFYAML::Chunk>> &Sections) {
515 DWARFYAML::Data DWARF;
516 for (std::unique_ptr<ELFYAML::Chunk> &C : Sections) {
517 if (!C->Name.startswith(".debug_"))
518 continue;
519
520 if (ELFYAML::RawContentSection *RawSec =
521 dyn_cast<ELFYAML::RawContentSection>(C.get())) {
522 // FIXME: The dumpDebug* functions should take the content as stored in
523 // RawSec. Currently, they just use the last section with the matching
524 // name, which defeats this attempt to skip reading a section header
525 // string table with the same name as a DWARF section.
526 if (ShStrTabIndex && RawSec->OriginalSecNdx == *ShStrTabIndex)
527 continue;
528 Error Err = Error::success();
529 cantFail(std::move(Err));
530
531 if (RawSec->Name == ".debug_aranges")
532 Err = dumpDebugARanges(*DWARFCtx, DWARF);
533 else if (RawSec->Name == ".debug_str")
534 Err = dumpDebugStrings(*DWARFCtx, DWARF);
535 else if (RawSec->Name == ".debug_ranges")
536 Err = dumpDebugRanges(*DWARFCtx, DWARF);
537 else if (RawSec->Name == ".debug_addr")
538 Err = dumpDebugAddr(*DWARFCtx, DWARF);
539 else
540 continue;
541
542 // If the DWARF section cannot be successfully parsed, emit raw content
543 // instead of an entry in the DWARF section of the YAML.
544 if (Err)
545 consumeError(std::move(Err));
546 else
547 RawSec->Content.reset();
548 }
549 }
550
551 if (DWARF.getNonEmptySectionNames().empty())
552 return std::nullopt;
553 return DWARF;
554}
555
556template <class ELFT>
557Expected<ELFYAML::RawContentSection *>
558ELFDumper<ELFT>::dumpPlaceholderSection(const Elf_Shdr *Shdr) {
559 auto S = std::make_unique<ELFYAML::RawContentSection>();
560 if (Error E = dumpCommonSection(Shdr, *S.get()))
561 return std::move(E);
562
563 // Normally symbol tables should not be empty. We dump the "Size"
564 // key when they are.
565 if ((Shdr->sh_type == ELF::SHT_SYMTAB || Shdr->sh_type == ELF::SHT_DYNSYM) &&
566 !Shdr->sh_size)
567 S->Size.emplace();
568
569 return S.release();
570}
571
572template <class ELFT>
573Expected<std::vector<std::unique_ptr<ELFYAML::Chunk>>>
574ELFDumper<ELFT>::dumpSections() {
575 std::vector<std::unique_ptr<ELFYAML::Chunk>> Ret;
576 auto Add = [&](Expected<ELFYAML::Chunk *> SecOrErr) -> Error {
577 if (!SecOrErr)
578 return SecOrErr.takeError();
579 Ret.emplace_back(*SecOrErr);
580 return Error::success();
581 };
582
583 auto GetDumper = [this](unsigned Type)
584 -> std::function<Expected<ELFYAML::Chunk *>(const Elf_Shdr *)> {
585 if (Obj.getHeader().e_machine == ELF::EM_ARM && Type == ELF::SHT_ARM_EXIDX)
586 return [this](const Elf_Shdr *S) { return dumpARMIndexTableSection(S); };
587
588 if (Obj.getHeader().e_machine == ELF::EM_MIPS &&
589 Type == ELF::SHT_MIPS_ABIFLAGS)
590 return [this](const Elf_Shdr *S) { return dumpMipsABIFlags(S); };
591
592 switch (Type) {
593 case ELF::SHT_DYNAMIC:
594 return [this](const Elf_Shdr *S) { return dumpDynamicSection(S); };
595 case ELF::SHT_SYMTAB_SHNDX:
596 return [this](const Elf_Shdr *S) { return dumpSymtabShndxSection(S); };
597 case ELF::SHT_REL:
598 case ELF::SHT_RELA:
599 return [this](const Elf_Shdr *S) { return dumpRelocSection(S); };
600 case ELF::SHT_RELR:
601 return [this](const Elf_Shdr *S) { return dumpRelrSection(S); };
602 case ELF::SHT_GROUP:
603 return [this](const Elf_Shdr *S) { return dumpGroupSection(S); };
604 case ELF::SHT_NOBITS:
605 return [this](const Elf_Shdr *S) { return dumpNoBitsSection(S); };
606 case ELF::SHT_NOTE:
607 return [this](const Elf_Shdr *S) { return dumpNoteSection(S); };
608 case ELF::SHT_HASH:
609 return [this](const Elf_Shdr *S) { return dumpHashSection(S); };
610 case ELF::SHT_GNU_HASH:
611 return [this](const Elf_Shdr *S) { return dumpGnuHashSection(S); };
612 case ELF::SHT_GNU_verdef:
613 return [this](const Elf_Shdr *S) { return dumpVerdefSection(S); };
614 case ELF::SHT_GNU_versym:
615 return [this](const Elf_Shdr *S) { return dumpSymverSection(S); };
616 case ELF::SHT_GNU_verneed:
617 return [this](const Elf_Shdr *S) { return dumpVerneedSection(S); };
618 case ELF::SHT_LLVM_ADDRSIG:
619 return [this](const Elf_Shdr *S) { return dumpAddrsigSection(S); };
620 case ELF::SHT_LLVM_LINKER_OPTIONS:
621 return [this](const Elf_Shdr *S) { return dumpLinkerOptionsSection(S); };
622 case ELF::SHT_LLVM_DEPENDENT_LIBRARIES:
623 return [this](const Elf_Shdr *S) {
624 return dumpDependentLibrariesSection(S);
625 };
626 case ELF::SHT_LLVM_CALL_GRAPH_PROFILE:
627 return
628 [this](const Elf_Shdr *S) { return dumpCallGraphProfileSection(S); };
1
Calling 'ELFDumper::dumpCallGraphProfileSection'
629 case ELF::SHT_LLVM_BB_ADDR_MAP_V0:
630 case ELF::SHT_LLVM_BB_ADDR_MAP:
631 return [this](const Elf_Shdr *S) { return dumpBBAddrMapSection(S); };
632 case ELF::SHT_STRTAB:
633 case ELF::SHT_SYMTAB:
634 case ELF::SHT_DYNSYM:
635 // The contents of these sections are described by other parts of the YAML
636 // file. But we still want to dump them, because their properties can be
637 // important. See comments for 'shouldPrintSection()' for more details.
638 return [this](const Elf_Shdr *S) { return dumpPlaceholderSection(S); };
639 default:
640 return nullptr;
641 }
642 };
643
644 for (const Elf_Shdr &Sec : Sections) {
645 // We have dedicated dumping functions for most of the section types.
646 // Try to use one of them first.
647 if (std::function<Expected<ELFYAML::Chunk *>(const Elf_Shdr *)> DumpFn =
648 GetDumper(Sec.sh_type)) {
649 if (Error E = Add(DumpFn(&Sec)))
650 return std::move(E);
651 continue;
652 }
653
654 // Recognize some special SHT_PROGBITS sections by name.
655 if (Sec.sh_type == ELF::SHT_PROGBITS) {
656 auto NameOrErr = Obj.getSectionName(Sec);
657 if (!NameOrErr)
658 return NameOrErr.takeError();
659
660 if (ELFYAML::StackSizesSection::nameMatches(*NameOrErr)) {
661 if (Error E = Add(dumpStackSizesSection(&Sec)))
662 return std::move(E);
663 continue;
664 }
665 }
666
667 if (Error E = Add(dumpContentSection(&Sec)))
668 return std::move(E);
669 }
670
671 return std::move(Ret);
672}
673
674template <class ELFT>
675Error ELFDumper<ELFT>::dumpSymbols(
676 const Elf_Shdr *Symtab,
677 std::optional<std::vector<ELFYAML::Symbol>> &Symbols) {
678 if (!Symtab)
679 return Error::success();
680
681 auto SymtabOrErr = Obj.symbols(Symtab);
682 if (!SymtabOrErr)
683 return SymtabOrErr.takeError();
684
685 if (SymtabOrErr->empty())
686 return Error::success();
687
688 auto StrTableOrErr = Obj.getStringTableForSymtab(*Symtab);
689 if (!StrTableOrErr)
690 return StrTableOrErr.takeError();
691
692 if (Symtab->sh_type == ELF::SHT_SYMTAB) {
693 SymTable = *SymtabOrErr;
694 SymbolNames.resize(SymTable.size());
695 }
696
697 Symbols.emplace();
698 for (const auto &Sym : (*SymtabOrErr).drop_front()) {
699 ELFYAML::Symbol S;
700 if (auto EC = dumpSymbol(&Sym, Symtab, *StrTableOrErr, S))
701 return EC;
702 Symbols->push_back(S);
703 }
704
705 return Error::success();
706}
707
708template <class ELFT>
709Error ELFDumper<ELFT>::dumpSymbol(const Elf_Sym *Sym, const Elf_Shdr *SymTab,
710 StringRef StrTable, ELFYAML::Symbol &S) {
711 S.Type = Sym->getType();
712 if (Sym->st_value)
713 S.Value = (yaml::Hex64)Sym->st_value;
714 if (Sym->st_size)
715 S.Size = (yaml::Hex64)Sym->st_size;
716 S.Other = Sym->st_other;
717 S.Binding = Sym->getBinding();
718
719 Expected<StringRef> SymbolNameOrErr =
720 getUniquedSymbolName(Sym, StrTable, SymTab);
721 if (!SymbolNameOrErr)
722 return SymbolNameOrErr.takeError();
723 S.Name = SymbolNameOrErr.get();
724
725 if (Sym->st_shndx >= ELF::SHN_LORESERVE) {
726 S.Index = (ELFYAML::ELF_SHN)Sym->st_shndx;
727 return Error::success();
728 }
729
730 auto ShdrOrErr = Obj.getSection(*Sym, SymTab, ShndxTables.lookup(SymTab));
731 if (!ShdrOrErr)
732 return ShdrOrErr.takeError();
733 const Elf_Shdr *Shdr = *ShdrOrErr;
734 if (!Shdr)
735 return Error::success();
736
737 auto NameOrErr = getUniquedSectionName(*Shdr);
738 if (!NameOrErr)
739 return NameOrErr.takeError();
740 S.Section = NameOrErr.get();
741
742 return Error::success();
743}
744
745template <class ELFT>
746template <class RelT>
747Error ELFDumper<ELFT>::dumpRelocation(const RelT *Rel, const Elf_Shdr *SymTab,
748 ELFYAML::Relocation &R) {
749 R.Type = Rel->getType(Obj.isMips64EL());
750 R.Offset = Rel->r_offset;
751 R.Addend = 0;
752
753 auto SymOrErr = Obj.getRelocationSymbol(*Rel, SymTab);
754 if (!SymOrErr)
755 return SymOrErr.takeError();
756
757 // We have might have a relocation with symbol index 0,
758 // e.g. R_X86_64_NONE or R_X86_64_GOTPC32.
759 const Elf_Sym *Sym = *SymOrErr;
760 if (!Sym)
761 return Error::success();
762
763 auto StrTabSec = Obj.getSection(SymTab->sh_link);
764 if (!StrTabSec)
765 return StrTabSec.takeError();
766 auto StrTabOrErr = Obj.getStringTable(**StrTabSec);
767 if (!StrTabOrErr)
768 return StrTabOrErr.takeError();
769
770 Expected<StringRef> NameOrErr =
771 getUniquedSymbolName(Sym, *StrTabOrErr, SymTab);
772 if (!NameOrErr)
773 return NameOrErr.takeError();
774 R.Symbol = NameOrErr.get();
775
776 return Error::success();
777}
778
779template <class ELFT>
780Error ELFDumper<ELFT>::dumpCommonSection(const Elf_Shdr *Shdr,
781 ELFYAML::Section &S) {
782 // Dump fields. We do not dump the ShOffset field. When not explicitly
783 // set, the value is set by yaml2obj automatically.
784 S.Type = Shdr->sh_type;
785 if (Shdr->sh_flags)
786 S.Flags = static_cast<ELFYAML::ELF_SHF>(Shdr->sh_flags);
787 if (Shdr->sh_addr)
788 S.Address = static_cast<uint64_t>(Shdr->sh_addr);
789 S.AddressAlign = Shdr->sh_addralign;
790
791 S.OriginalSecNdx = Shdr - &Sections[0];
792
793 Expected<StringRef> NameOrErr = getUniquedSectionName(*Shdr);
794 if (!NameOrErr)
795 return NameOrErr.takeError();
796 S.Name = NameOrErr.get();
797
798 if (Shdr->sh_entsize != ELFYAML::getDefaultShEntSize<ELFT>(
799 Obj.getHeader().e_machine, S.Type, S.Name))
800 S.EntSize = static_cast<llvm::yaml::Hex64>(Shdr->sh_entsize);
801
802 if (Shdr->sh_link != ELF::SHN_UNDEF) {
803 Expected<const Elf_Shdr *> LinkSection = Obj.getSection(Shdr->sh_link);
804 if (!LinkSection)
805 return make_error<StringError>(
806 "unable to resolve sh_link reference in section '" + S.Name +
807 "': " + toString(LinkSection.takeError()),
808 inconvertibleErrorCode());
809
810 NameOrErr = getUniquedSectionName(**LinkSection);
811 if (!NameOrErr)
812 return NameOrErr.takeError();
813 S.Link = NameOrErr.get();
814 }
815
816 return Error::success();
817}
818
819template <class ELFT>
820Error ELFDumper<ELFT>::dumpCommonRelocationSection(
821 const Elf_Shdr *Shdr, ELFYAML::RelocationSection &S) {
822 if (Error E = dumpCommonSection(Shdr, S))
823 return E;
824
825 // Having a zero sh_info field is normal: .rela.dyn is a dynamic
826 // relocation section that normally has no value in this field.
827 if (!Shdr->sh_info)
828 return Error::success();
829
830 auto InfoSection = Obj.getSection(Shdr->sh_info);
831 if (!InfoSection)
832 return InfoSection.takeError();
833
834 Expected<StringRef> NameOrErr = getUniquedSectionName(**InfoSection);
835 if (!NameOrErr)
836 return NameOrErr.takeError();
837 S.RelocatableSec = NameOrErr.get();
838
839 return Error::success();
840}
841
842template <class ELFT>
843Expected<ELFYAML::StackSizesSection *>
844ELFDumper<ELFT>::dumpStackSizesSection(const Elf_Shdr *Shdr) {
845 auto S = std::make_unique<ELFYAML::StackSizesSection>();
846 if (Error E = dumpCommonSection(Shdr, *S))
847 return std::move(E);
848
849 auto ContentOrErr = Obj.getSectionContents(*Shdr);
850 if (!ContentOrErr)
851 return ContentOrErr.takeError();
852
853 ArrayRef<uint8_t> Content = *ContentOrErr;
854 DataExtractor Data(Content, Obj.isLE(), ELFT::Is64Bits ? 8 : 4);
855
856 std::vector<ELFYAML::StackSizeEntry> Entries;
857 DataExtractor::Cursor Cur(0);
858 while (Cur && Cur.tell() < Content.size()) {
859 uint64_t Address = Data.getAddress(Cur);
860 uint64_t Size = Data.getULEB128(Cur);
861 Entries.push_back({Address, Size});
862 }
863
864 if (Content.empty() || !Cur) {
865 // If .stack_sizes cannot be decoded, we dump it as an array of bytes.
866 consumeError(Cur.takeError());
867 S->Content = yaml::BinaryRef(Content);
868 } else {
869 S->Entries = std::move(Entries);
870 }
871
872 return S.release();
873}
874
875template <class ELFT>
876Expected<ELFYAML::BBAddrMapSection *>
877ELFDumper<ELFT>::dumpBBAddrMapSection(const Elf_Shdr *Shdr) {
878 auto S = std::make_unique<ELFYAML::BBAddrMapSection>();
879 if (Error E = dumpCommonSection(Shdr, *S))
880 return std::move(E);
881
882 auto ContentOrErr = Obj.getSectionContents(*Shdr);
883 if (!ContentOrErr)
884 return ContentOrErr.takeError();
885
886 ArrayRef<uint8_t> Content = *ContentOrErr;
887 if (Content.empty())
888 return S.release();
889
890 DataExtractor Data(Content, Obj.isLE(), ELFT::Is64Bits ? 8 : 4);
891
892 std::vector<ELFYAML::BBAddrMapEntry> Entries;
893 DataExtractor::Cursor Cur(0);
894 uint8_t Version = 0;
895 uint8_t Feature = 0;
896 while (Cur && Cur.tell() < Content.size()) {
897 if (Shdr->sh_type == ELF::SHT_LLVM_BB_ADDR_MAP) {
898 Version = Data.getU8(Cur);
899 if (Cur && Version > 2)
900 return createStringError(
901 errc::invalid_argument,
902 "invalid SHT_LLVM_BB_ADDR_MAP section version: " +
903 Twine(static_cast<int>(Version)));
904 Feature = Data.getU8(Cur);
905 }
906 uint64_t Address = Data.getAddress(Cur);
907 uint64_t NumBlocks = Data.getULEB128(Cur);
908 std::vector<ELFYAML::BBAddrMapEntry::BBEntry> BBEntries;
909 // Read the specified number of BB entries, or until decoding fails.
910 for (uint64_t BlockIndex = 0; Cur && BlockIndex < NumBlocks; ++BlockIndex) {
911 uint32_t ID = Version >= 2 ? Data.getULEB128(Cur) : BlockIndex;
912 uint64_t Offset = Data.getULEB128(Cur);
913 uint64_t Size = Data.getULEB128(Cur);
914 uint64_t Metadata = Data.getULEB128(Cur);
915 BBEntries.push_back({ID, Offset, Size, Metadata});
916 }
917 Entries.push_back(
918 {Version, Feature, Address, /*NumBlocks=*/{}, std::move(BBEntries)});
919 }
920
921 if (!Cur) {
922 // If the section cannot be decoded, we dump it as an array of bytes.
923 consumeError(Cur.takeError());
924 S->Content = yaml::BinaryRef(Content);
925 } else {
926 S->Entries = std::move(Entries);
927 }
928
929 return S.release();
930}
931
932template <class ELFT>
933Expected<ELFYAML::AddrsigSection *>
934ELFDumper<ELFT>::dumpAddrsigSection(const Elf_Shdr *Shdr) {
935 auto S = std::make_unique<ELFYAML::AddrsigSection>();
936 if (Error E = dumpCommonSection(Shdr, *S))
937 return std::move(E);
938
939 auto ContentOrErr = Obj.getSectionContents(*Shdr);
940 if (!ContentOrErr)
941 return ContentOrErr.takeError();
942
943 ArrayRef<uint8_t> Content = *ContentOrErr;
944 DataExtractor::Cursor Cur(0);
945 DataExtractor Data(Content, Obj.isLE(), /*AddressSize=*/0);
946 std::vector<ELFYAML::YAMLFlowString> Symbols;
947 while (Cur && Cur.tell() < Content.size()) {
948 uint64_t SymNdx = Data.getULEB128(Cur);
949 if (!Cur)
950 break;
951
952 Expected<StringRef> SymbolName = getSymbolName(Shdr->sh_link, SymNdx);
953 if (!SymbolName || SymbolName->empty()) {
954 consumeError(SymbolName.takeError());
955 Symbols.emplace_back(
956 StringRef(std::to_string(SymNdx)).copy(StringAllocator));
957 continue;
958 }
959
960 Symbols.emplace_back(*SymbolName);
961 }
962
963 if (Cur) {
964 S->Symbols = std::move(Symbols);
965 return S.release();
966 }
967
968 consumeError(Cur.takeError());
969 S->Content = yaml::BinaryRef(Content);
970 return S.release();
971}
972
973template <class ELFT>
974Expected<ELFYAML::LinkerOptionsSection *>
975ELFDumper<ELFT>::dumpLinkerOptionsSection(const Elf_Shdr *Shdr) {
976 auto S = std::make_unique<ELFYAML::LinkerOptionsSection>();
977 if (Error E = dumpCommonSection(Shdr, *S))
978 return std::move(E);
979
980 auto ContentOrErr = Obj.getSectionContents(*Shdr);
981 if (!ContentOrErr)
982 return ContentOrErr.takeError();
983
984 ArrayRef<uint8_t> Content = *ContentOrErr;
985 if (Content.empty() || Content.back() != 0) {
986 S->Content = Content;
987 return S.release();
988 }
989
990 SmallVector<StringRef, 16> Strings;
991 toStringRef(Content.drop_back()).split(Strings, '\0');
992 if (Strings.size() % 2 != 0) {
993 S->Content = Content;
994 return S.release();
995 }
996
997 S->Options.emplace();
998 for (size_t I = 0, E = Strings.size(); I != E; I += 2)
999 S->Options->push_back({Strings[I], Strings[I + 1]});
1000
1001 return S.release();
1002}
1003
1004template <class ELFT>
1005Expected<ELFYAML::DependentLibrariesSection *>
1006ELFDumper<ELFT>::dumpDependentLibrariesSection(const Elf_Shdr *Shdr) {
1007 auto DL = std::make_unique<ELFYAML::DependentLibrariesSection>();
1008 if (Error E = dumpCommonSection(Shdr, *DL))
1009 return std::move(E);
1010
1011 Expected<ArrayRef<uint8_t>> ContentOrErr = Obj.getSectionContents(*Shdr);
1012 if (!ContentOrErr)
1013 return ContentOrErr.takeError();
1014
1015 ArrayRef<uint8_t> Content = *ContentOrErr;
1016 if (!Content.empty() && Content.back() != 0) {
1017 DL->Content = Content;
1018 return DL.release();
1019 }
1020
1021 DL->Libs.emplace();
1022 for (const uint8_t *I = Content.begin(), *E = Content.end(); I < E;) {
1023 StringRef Lib((const char *)I);
1024 DL->Libs->emplace_back(Lib);
1025 I += Lib.size() + 1;
1026 }
1027
1028 return DL.release();
1029}
1030
1031template <class ELFT>
1032Expected<ELFYAML::CallGraphProfileSection *>
1033ELFDumper<ELFT>::dumpCallGraphProfileSection(const Elf_Shdr *Shdr) {
1034 auto S = std::make_unique<ELFYAML::CallGraphProfileSection>();
1035 if (Error E = dumpCommonSection(Shdr, *S))
2
Assuming the condition is false
3
Taking false branch
1036 return std::move(E);
1037
1038 Expected<ArrayRef<uint8_t>> ContentOrErr = Obj.getSectionContents(*Shdr);
1039 if (!ContentOrErr)
4
Taking false branch
1040 return ContentOrErr.takeError();
1041 ArrayRef<uint8_t> Content = *ContentOrErr;
1042 const uint32_t SizeOfEntry = ELFYAML::getDefaultShEntSize<ELFT>(
5
Calling 'getDefaultShEntSize<llvm::object::ELFType<llvm::support::big, true>>'
12
Returning from 'getDefaultShEntSize<llvm::object::ELFType<llvm::support::big, true>>'
13
'SizeOfEntry' initialized to 0
1043 Obj.getHeader().e_machine, S->Type, S->Name);
1044 // Dump the section by using the Content key when it is truncated.
1045 // There is no need to create either "Content" or "Entries" fields when the
1046 // section is empty.
1047 if (Content.empty() || Content.size() % SizeOfEntry != 0) {
14
Assuming the condition is false
15
Division by zero
1048 if (!Content.empty())
1049 S->Content = yaml::BinaryRef(Content);
1050 return S.release();
1051 }
1052
1053 std::vector<ELFYAML::CallGraphEntryWeight> Entries(Content.size() /
1054 SizeOfEntry);
1055 DataExtractor Data(Content, Obj.isLE(), /*AddressSize=*/0);
1056 DataExtractor::Cursor Cur(0);
1057 auto ReadEntry = [&](ELFYAML::CallGraphEntryWeight &E) {
1058 E.Weight = Data.getU64(Cur);
1059 if (!Cur) {
1060 consumeError(Cur.takeError());
1061 return false;
1062 }
1063 return true;
1064 };
1065
1066 for (ELFYAML::CallGraphEntryWeight &E : Entries) {
1067 if (ReadEntry(E))
1068 continue;
1069 S->Content = yaml::BinaryRef(Content);
1070 return S.release();
1071 }
1072
1073 S->Entries = std::move(Entries);
1074 return S.release();
1075}
1076
1077template <class ELFT>
1078Expected<ELFYAML::DynamicSection *>
1079ELFDumper<ELFT>::dumpDynamicSection(const Elf_Shdr *Shdr) {
1080 auto S = std::make_unique<ELFYAML::DynamicSection>();
1081 if (Error E = dumpCommonSection(Shdr, *S))
1082 return std::move(E);
1083
1084 auto DynTagsOrErr = Obj.template getSectionContentsAsArray<Elf_Dyn>(*Shdr);
1085 if (!DynTagsOrErr)
1086 return DynTagsOrErr.takeError();
1087
1088 S->Entries.emplace();
1089 for (const Elf_Dyn &Dyn : *DynTagsOrErr)
1090 S->Entries->push_back({(ELFYAML::ELF_DYNTAG)Dyn.getTag(), Dyn.getVal()});
1091
1092 return S.release();
1093}
1094
1095template <class ELFT>
1096Expected<ELFYAML::RelocationSection *>
1097ELFDumper<ELFT>::dumpRelocSection(const Elf_Shdr *Shdr) {
1098 auto S = std::make_unique<ELFYAML::RelocationSection>();
1099 if (auto E = dumpCommonRelocationSection(Shdr, *S))
1100 return std::move(E);
1101
1102 auto SymTabOrErr = Obj.getSection(Shdr->sh_link);
1103 if (!SymTabOrErr)
1104 return SymTabOrErr.takeError();
1105
1106 if (Shdr->sh_size != 0)
1107 S->Relocations.emplace();
1108
1109 if (Shdr->sh_type == ELF::SHT_REL) {
1110 auto Rels = Obj.rels(*Shdr);
1111 if (!Rels)
1112 return Rels.takeError();
1113 for (const Elf_Rel &Rel : *Rels) {
1114 ELFYAML::Relocation R;
1115 if (Error E = dumpRelocation(&Rel, *SymTabOrErr, R))
1116 return std::move(E);
1117 S->Relocations->push_back(R);
1118 }
1119 } else {
1120 auto Rels = Obj.relas(*Shdr);
1121 if (!Rels)
1122 return Rels.takeError();
1123 for (const Elf_Rela &Rel : *Rels) {
1124 ELFYAML::Relocation R;
1125 if (Error E = dumpRelocation(&Rel, *SymTabOrErr, R))
1126 return std::move(E);
1127 R.Addend = Rel.r_addend;
1128 S->Relocations->push_back(R);
1129 }
1130 }
1131
1132 return S.release();
1133}
1134
1135template <class ELFT>
1136Expected<ELFYAML::RelrSection *>
1137ELFDumper<ELFT>::dumpRelrSection(const Elf_Shdr *Shdr) {
1138 auto S = std::make_unique<ELFYAML::RelrSection>();
1139 if (auto E = dumpCommonSection(Shdr, *S))
1140 return std::move(E);
1141
1142 if (Expected<ArrayRef<Elf_Relr>> Relrs = Obj.relrs(*Shdr)) {
1143 S->Entries.emplace();
1144 for (Elf_Relr Rel : *Relrs)
1145 S->Entries->emplace_back(Rel);
1146 return S.release();
1147 } else {
1148 // Ignore. We are going to dump the data as raw content below.
1149 consumeError(Relrs.takeError());
1150 }
1151
1152 Expected<ArrayRef<uint8_t>> ContentOrErr = Obj.getSectionContents(*Shdr);
1153 if (!ContentOrErr)
1154 return ContentOrErr.takeError();
1155 S->Content = *ContentOrErr;
1156 return S.release();
1157}
1158
1159template <class ELFT>
1160Expected<ELFYAML::RawContentSection *>
1161ELFDumper<ELFT>::dumpContentSection(const Elf_Shdr *Shdr) {
1162 auto S = std::make_unique<ELFYAML::RawContentSection>();
1163 if (Error E = dumpCommonSection(Shdr, *S))
1164 return std::move(E);
1165
1166 unsigned SecIndex = Shdr - &Sections[0];
1167 if (SecIndex != 0 || Shdr->sh_type != ELF::SHT_NULL) {
1168 auto ContentOrErr = Obj.getSectionContents(*Shdr);
1169 if (!ContentOrErr)
1170 return ContentOrErr.takeError();
1171 ArrayRef<uint8_t> Content = *ContentOrErr;
1172 if (!Content.empty())
1173 S->Content = yaml::BinaryRef(Content);
1174 } else {
1175 S->Size = static_cast<llvm::yaml::Hex64>(Shdr->sh_size);
1176 }
1177
1178 if (Shdr->sh_info)
1179 S->Info = static_cast<llvm::yaml::Hex64>(Shdr->sh_info);
1180 return S.release();
1181}
1182
1183template <class ELFT>
1184Expected<ELFYAML::SymtabShndxSection *>
1185ELFDumper<ELFT>::dumpSymtabShndxSection(const Elf_Shdr *Shdr) {
1186 auto S = std::make_unique<ELFYAML::SymtabShndxSection>();
1187 if (Error E = dumpCommonSection(Shdr, *S))
1188 return std::move(E);
1189
1190 auto EntriesOrErr = Obj.template getSectionContentsAsArray<Elf_Word>(*Shdr);
1191 if (!EntriesOrErr)
1192 return EntriesOrErr.takeError();
1193
1194 S->Entries.emplace();
1195 for (const Elf_Word &E : *EntriesOrErr)
1196 S->Entries->push_back(E);
1197 return S.release();
1198}
1199
1200template <class ELFT>
1201Expected<ELFYAML::NoBitsSection *>
1202ELFDumper<ELFT>::dumpNoBitsSection(const Elf_Shdr *Shdr) {
1203 auto S = std::make_unique<ELFYAML::NoBitsSection>();
1204 if (Error E = dumpCommonSection(Shdr, *S))
1205 return std::move(E);
1206 if (Shdr->sh_size)
1207 S->Size = static_cast<llvm::yaml::Hex64>(Shdr->sh_size);
1208 return S.release();
1209}
1210
1211template <class ELFT>
1212Expected<ELFYAML::NoteSection *>
1213ELFDumper<ELFT>::dumpNoteSection(const Elf_Shdr *Shdr) {
1214 auto S = std::make_unique<ELFYAML::NoteSection>();
1215 if (Error E = dumpCommonSection(Shdr, *S))
1216 return std::move(E);
1217
1218 auto ContentOrErr = Obj.getSectionContents(*Shdr);
1219 if (!ContentOrErr)
1220 return ContentOrErr.takeError();
1221
1222 std::vector<ELFYAML::NoteEntry> Entries;
1223 ArrayRef<uint8_t> Content = *ContentOrErr;
1224 while (!Content.empty()) {
1225 if (Content.size() < sizeof(Elf_Nhdr)) {
1226 S->Content = yaml::BinaryRef(*ContentOrErr);
1227 return S.release();
1228 }
1229
1230 const Elf_Nhdr *Header = reinterpret_cast<const Elf_Nhdr *>(Content.data());
1231 if (Content.size() < Header->getSize()) {
1232 S->Content = yaml::BinaryRef(*ContentOrErr);
1233 return S.release();
1234 }
1235
1236 Elf_Note Note(*Header);
1237 Entries.push_back(
1238 {Note.getName(), Note.getDesc(), (ELFYAML::ELF_NT)Note.getType()});
1239
1240 Content = Content.drop_front(Header->getSize());
1241 }
1242
1243 S->Notes = std::move(Entries);
1244 return S.release();
1245}
1246
1247template <class ELFT>
1248Expected<ELFYAML::HashSection *>
1249ELFDumper<ELFT>::dumpHashSection(const Elf_Shdr *Shdr) {
1250 auto S = std::make_unique<ELFYAML::HashSection>();
1251 if (Error E = dumpCommonSection(Shdr, *S))
1252 return std::move(E);
1253
1254 auto ContentOrErr = Obj.getSectionContents(*Shdr);
1255 if (!ContentOrErr)
1256 return ContentOrErr.takeError();
1257
1258 ArrayRef<uint8_t> Content = *ContentOrErr;
1259 if (Content.size() % 4 != 0 || Content.size() < 8) {
1260 S->Content = yaml::BinaryRef(Content);
1261 return S.release();
1262 }
1263
1264 DataExtractor::Cursor Cur(0);
1265 DataExtractor Data(Content, Obj.isLE(), /*AddressSize=*/0);
1266 uint64_t NBucket = Data.getU32(Cur);
1267 uint64_t NChain = Data.getU32(Cur);
1268 if (Content.size() != (2 + NBucket + NChain) * 4) {
1269 S->Content = yaml::BinaryRef(Content);
1270 if (Cur)
1271 return S.release();
1272 llvm_unreachable("entries were not read correctly")::llvm::llvm_unreachable_internal("entries were not read correctly"
, "llvm/tools/obj2yaml/elf2yaml.cpp", 1272)
;
1273 }
1274
1275 S->Bucket.emplace(NBucket);
1276 for (uint32_t &V : *S->Bucket)
1277 V = Data.getU32(Cur);
1278
1279 S->Chain.emplace(NChain);
1280 for (uint32_t &V : *S->Chain)
1281 V = Data.getU32(Cur);
1282
1283 if (Cur)
1284 return S.release();
1285 llvm_unreachable("entries were not read correctly")::llvm::llvm_unreachable_internal("entries were not read correctly"
, "llvm/tools/obj2yaml/elf2yaml.cpp", 1285)
;
1286}
1287
1288template <class ELFT>
1289Expected<ELFYAML::GnuHashSection *>
1290ELFDumper<ELFT>::dumpGnuHashSection(const Elf_Shdr *Shdr) {
1291 auto S = std::make_unique<ELFYAML::GnuHashSection>();
1292 if (Error E = dumpCommonSection(Shdr, *S))
1293 return std::move(E);
1294
1295 auto ContentOrErr = Obj.getSectionContents(*Shdr);
1296 if (!ContentOrErr)
1297 return ContentOrErr.takeError();
1298
1299 unsigned AddrSize = ELFT::Is64Bits ? 8 : 4;
1300 ArrayRef<uint8_t> Content = *ContentOrErr;
1301 DataExtractor Data(Content, Obj.isLE(), AddrSize);
1302
1303 ELFYAML::GnuHashHeader Header;
1304 DataExtractor::Cursor Cur(0);
1305 uint64_t NBuckets = Data.getU32(Cur);
1306 Header.SymNdx = Data.getU32(Cur);
1307 uint64_t MaskWords = Data.getU32(Cur);
1308 Header.Shift2 = Data.getU32(Cur);
1309
1310 // Set just the raw binary content if we were unable to read the header
1311 // or when the section data is truncated or malformed.
1312 uint64_t Size = Data.getData().size() - Cur.tell();
1313 if (!Cur || (Size < MaskWords * AddrSize + NBuckets * 4) ||
1314 (Size % 4 != 0)) {
1315 consumeError(Cur.takeError());
1316 S->Content = yaml::BinaryRef(Content);
1317 return S.release();
1318 }
1319
1320 S->Header = Header;
1321
1322 S->BloomFilter.emplace(MaskWords);
1323 for (llvm::yaml::Hex64 &Val : *S->BloomFilter)
1324 Val = Data.getAddress(Cur);
1325
1326 S->HashBuckets.emplace(NBuckets);
1327 for (llvm::yaml::Hex32 &Val : *S->HashBuckets)
1328 Val = Data.getU32(Cur);
1329
1330 S->HashValues.emplace((Data.getData().size() - Cur.tell()) / 4);
1331 for (llvm::yaml::Hex32 &Val : *S->HashValues)
1332 Val = Data.getU32(Cur);
1333
1334 if (Cur)
1335 return S.release();
1336 llvm_unreachable("GnuHashSection was not read correctly")::llvm::llvm_unreachable_internal("GnuHashSection was not read correctly"
, "llvm/tools/obj2yaml/elf2yaml.cpp", 1336)
;
1337}
1338
1339template <class ELFT>
1340Expected<ELFYAML::VerdefSection *>
1341ELFDumper<ELFT>::dumpVerdefSection(const Elf_Shdr *Shdr) {
1342 auto S = std::make_unique<ELFYAML::VerdefSection>();
1343 if (Error E = dumpCommonSection(Shdr, *S))
1344 return std::move(E);
1345
1346 auto StringTableShdrOrErr = Obj.getSection(Shdr->sh_link);
1347 if (!StringTableShdrOrErr)
1348 return StringTableShdrOrErr.takeError();
1349
1350 auto StringTableOrErr = Obj.getStringTable(**StringTableShdrOrErr);
1351 if (!StringTableOrErr)
1352 return StringTableOrErr.takeError();
1353
1354 auto Contents = Obj.getSectionContents(*Shdr);
1355 if (!Contents)
1356 return Contents.takeError();
1357
1358 S->Entries.emplace();
1359
1360 llvm::ArrayRef<uint8_t> Data = *Contents;
1361 const uint8_t *Buf = Data.data();
1362 while (Buf) {
1363 const Elf_Verdef *Verdef = reinterpret_cast<const Elf_Verdef *>(Buf);
1364 ELFYAML::VerdefEntry Entry;
1365 if (Verdef->vd_version != 1)
1366 return createStringError(errc::invalid_argument,
1367 "invalid SHT_GNU_verdef section version: " +
1368 Twine(Verdef->vd_version));
1369
1370 if (Verdef->vd_flags != 0)
1371 Entry.Flags = Verdef->vd_flags;
1372
1373 if (Verdef->vd_ndx != 0)
1374 Entry.VersionNdx = Verdef->vd_ndx;
1375
1376 if (Verdef->vd_hash != 0)
1377 Entry.Hash = Verdef->vd_hash;
1378
1379 const uint8_t *BufAux = Buf + Verdef->vd_aux;
1380 while (BufAux) {
1381 const Elf_Verdaux *Verdaux =
1382 reinterpret_cast<const Elf_Verdaux *>(BufAux);
1383 Entry.VerNames.push_back(
1384 StringTableOrErr->drop_front(Verdaux->vda_name).data());
1385 BufAux = Verdaux->vda_next ? BufAux + Verdaux->vda_next : nullptr;
1386 }
1387
1388 S->Entries->push_back(Entry);
1389 Buf = Verdef->vd_next ? Buf + Verdef->vd_next : nullptr;
1390 }
1391
1392 if (Shdr->sh_info != S->Entries->size())
1393 S->Info = (llvm::yaml::Hex64)Shdr->sh_info;
1394
1395 return S.release();
1396}
1397
1398template <class ELFT>
1399Expected<ELFYAML::SymverSection *>
1400ELFDumper<ELFT>::dumpSymverSection(const Elf_Shdr *Shdr) {
1401 auto S = std::make_unique<ELFYAML::SymverSection>();
1402 if (Error E = dumpCommonSection(Shdr, *S))
1403 return std::move(E);
1404
1405 auto VersionsOrErr = Obj.template getSectionContentsAsArray<Elf_Half>(*Shdr);
1406 if (!VersionsOrErr)
1407 return VersionsOrErr.takeError();
1408
1409 S->Entries.emplace();
1410 for (const Elf_Half &E : *VersionsOrErr)
1411 S->Entries->push_back(E);
1412
1413 return S.release();
1414}
1415
1416template <class ELFT>
1417Expected<ELFYAML::VerneedSection *>
1418ELFDumper<ELFT>::dumpVerneedSection(const Elf_Shdr *Shdr) {
1419 auto S = std::make_unique<ELFYAML::VerneedSection>();
1420 if (Error E = dumpCommonSection(Shdr, *S))
1421 return std::move(E);
1422
1423 auto Contents = Obj.getSectionContents(*Shdr);
1424 if (!Contents)
1425 return Contents.takeError();
1426
1427 auto StringTableShdrOrErr = Obj.getSection(Shdr->sh_link);
1428 if (!StringTableShdrOrErr)
1429 return StringTableShdrOrErr.takeError();
1430
1431 auto StringTableOrErr = Obj.getStringTable(**StringTableShdrOrErr);
1432 if (!StringTableOrErr)
1433 return StringTableOrErr.takeError();
1434
1435 S->VerneedV.emplace();
1436
1437 llvm::ArrayRef<uint8_t> Data = *Contents;
1438 const uint8_t *Buf = Data.data();
1439 while (Buf) {
1440 const Elf_Verneed *Verneed = reinterpret_cast<const Elf_Verneed *>(Buf);
1441
1442 ELFYAML::VerneedEntry Entry;
1443 Entry.Version = Verneed->vn_version;
1444 Entry.File =
1445 StringRef(StringTableOrErr->drop_front(Verneed->vn_file).data());
1446
1447 const uint8_t *BufAux = Buf + Verneed->vn_aux;
1448 while (BufAux) {
1449 const Elf_Vernaux *Vernaux =
1450 reinterpret_cast<const Elf_Vernaux *>(BufAux);
1451
1452 ELFYAML::VernauxEntry Aux;
1453 Aux.Hash = Vernaux->vna_hash;
1454 Aux.Flags = Vernaux->vna_flags;
1455 Aux.Other = Vernaux->vna_other;
1456 Aux.Name =
1457 StringRef(StringTableOrErr->drop_front(Vernaux->vna_name).data());
1458
1459 Entry.AuxV.push_back(Aux);
1460 BufAux = Vernaux->vna_next ? BufAux + Vernaux->vna_next : nullptr;
1461 }
1462
1463 S->VerneedV->push_back(Entry);
1464 Buf = Verneed->vn_next ? Buf + Verneed->vn_next : nullptr;
1465 }
1466
1467 if (Shdr->sh_info != S->VerneedV->size())
1468 S->Info = (llvm::yaml::Hex64)Shdr->sh_info;
1469
1470 return S.release();
1471}
1472
1473template <class ELFT>
1474Expected<StringRef> ELFDumper<ELFT>::getSymbolName(uint32_t SymtabNdx,
1475 uint32_t SymbolNdx) {
1476 auto SymtabOrErr = Obj.getSection(SymtabNdx);
1477 if (!SymtabOrErr)
1478 return SymtabOrErr.takeError();
1479
1480 const Elf_Shdr *Symtab = *SymtabOrErr;
1481 auto SymOrErr = Obj.getSymbol(Symtab, SymbolNdx);
1482 if (!SymOrErr)
1483 return SymOrErr.takeError();
1484
1485 auto StrTabOrErr = Obj.getStringTableForSymtab(*Symtab);
1486 if (!StrTabOrErr)
1487 return StrTabOrErr.takeError();
1488 return getUniquedSymbolName(*SymOrErr, *StrTabOrErr, Symtab);
1489}
1490
1491template <class ELFT>
1492Expected<ELFYAML::GroupSection *>
1493ELFDumper<ELFT>::dumpGroupSection(const Elf_Shdr *Shdr) {
1494 auto S = std::make_unique<ELFYAML::GroupSection>();
1495 if (Error E = dumpCommonSection(Shdr, *S))
1496 return std::move(E);
1497
1498 // Get symbol with index sh_info. This symbol's name is the signature of the group.
1499 Expected<StringRef> SymbolName = getSymbolName(Shdr->sh_link, Shdr->sh_info);
1500 if (!SymbolName)
1501 return SymbolName.takeError();
1502 S->Signature = *SymbolName;
1503
1504 auto MembersOrErr = Obj.template getSectionContentsAsArray<Elf_Word>(*Shdr);
1505 if (!MembersOrErr)
1506 return MembersOrErr.takeError();
1507
1508 S->Members.emplace();
1509 for (Elf_Word Member : *MembersOrErr) {
1510 if (Member == llvm::ELF::GRP_COMDAT) {
1511 S->Members->push_back({"GRP_COMDAT"});
1512 continue;
1513 }
1514
1515 Expected<const Elf_Shdr *> SHdrOrErr = Obj.getSection(Member);
1516 if (!SHdrOrErr)
1517 return SHdrOrErr.takeError();
1518 Expected<StringRef> NameOrErr = getUniquedSectionName(**SHdrOrErr);
1519 if (!NameOrErr)
1520 return NameOrErr.takeError();
1521 S->Members->push_back({*NameOrErr});
1522 }
1523 return S.release();
1524}
1525
1526template <class ELFT>
1527Expected<ELFYAML::ARMIndexTableSection *>
1528ELFDumper<ELFT>::dumpARMIndexTableSection(const Elf_Shdr *Shdr) {
1529 auto S = std::make_unique<ELFYAML::ARMIndexTableSection>();
1530 if (Error E = dumpCommonSection(Shdr, *S))
1531 return std::move(E);
1532
1533 Expected<ArrayRef<uint8_t>> ContentOrErr = Obj.getSectionContents(*Shdr);
1534 if (!ContentOrErr)
1535 return ContentOrErr.takeError();
1536
1537 if (ContentOrErr->size() % (sizeof(Elf_Word) * 2) != 0) {
1538 S->Content = yaml::BinaryRef(*ContentOrErr);
1539 return S.release();
1540 }
1541
1542 ArrayRef<Elf_Word> Words(
1543 reinterpret_cast<const Elf_Word *>(ContentOrErr->data()),
1544 ContentOrErr->size() / sizeof(Elf_Word));
1545
1546 S->Entries.emplace();
1547 for (size_t I = 0, E = Words.size(); I != E; I += 2)
1548 S->Entries->push_back({(yaml::Hex32)Words[I], (yaml::Hex32)Words[I + 1]});
1549
1550 return S.release();
1551}
1552
1553template <class ELFT>
1554Expected<ELFYAML::MipsABIFlags *>
1555ELFDumper<ELFT>::dumpMipsABIFlags(const Elf_Shdr *Shdr) {
1556 assert(Shdr->sh_type == ELF::SHT_MIPS_ABIFLAGS &&(static_cast <bool> (Shdr->sh_type == ELF::SHT_MIPS_ABIFLAGS
&& "Section type is not SHT_MIPS_ABIFLAGS") ? void (
0) : __assert_fail ("Shdr->sh_type == ELF::SHT_MIPS_ABIFLAGS && \"Section type is not SHT_MIPS_ABIFLAGS\""
, "llvm/tools/obj2yaml/elf2yaml.cpp", 1557, __extension__ __PRETTY_FUNCTION__
))
1557 "Section type is not SHT_MIPS_ABIFLAGS")(static_cast <bool> (Shdr->sh_type == ELF::SHT_MIPS_ABIFLAGS
&& "Section type is not SHT_MIPS_ABIFLAGS") ? void (
0) : __assert_fail ("Shdr->sh_type == ELF::SHT_MIPS_ABIFLAGS && \"Section type is not SHT_MIPS_ABIFLAGS\""
, "llvm/tools/obj2yaml/elf2yaml.cpp", 1557, __extension__ __PRETTY_FUNCTION__
))
;
1558 auto S = std::make_unique<ELFYAML::MipsABIFlags>();
1559 if (Error E = dumpCommonSection(Shdr, *S))
1560 return std::move(E);
1561
1562 auto ContentOrErr = Obj.getSectionContents(*Shdr);
1563 if (!ContentOrErr)
1564 return ContentOrErr.takeError();
1565
1566 auto *Flags = reinterpret_cast<const object::Elf_Mips_ABIFlags<ELFT> *>(
1567 ContentOrErr.get().data());
1568 S->Version = Flags->version;
1569 S->ISALevel = Flags->isa_level;
1570 S->ISARevision = Flags->isa_rev;
1571 S->GPRSize = Flags->gpr_size;
1572 S->CPR1Size = Flags->cpr1_size;
1573 S->CPR2Size = Flags->cpr2_size;
1574 S->FpABI = Flags->fp_abi;
1575 S->ISAExtension = Flags->isa_ext;
1576 S->ASEs = Flags->ases;
1577 S->Flags1 = Flags->flags1;
1578 S->Flags2 = Flags->flags2;
1579 return S.release();
1580}
1581
1582template <class ELFT>
1583static Error elf2yaml(raw_ostream &Out, const object::ELFFile<ELFT> &Obj,
1584 std::unique_ptr<DWARFContext> DWARFCtx) {
1585 ELFDumper<ELFT> Dumper(Obj, std::move(DWARFCtx));
1586 Expected<ELFYAML::Object *> YAMLOrErr = Dumper.dump();
1587 if (!YAMLOrErr)
1588 return YAMLOrErr.takeError();
1589
1590 std::unique_ptr<ELFYAML::Object> YAML(YAMLOrErr.get());
1591 yaml::Output Yout(Out);
1592 Yout << *YAML;
1593
1594 return Error::success();
1595}
1596
1597Error elf2yaml(raw_ostream &Out, const object::ObjectFile &Obj) {
1598 std::unique_ptr<DWARFContext> DWARFCtx = DWARFContext::create(Obj);
1599 if (const auto *ELFObj = dyn_cast<object::ELF32LEObjectFile>(&Obj))
1600 return elf2yaml(Out, ELFObj->getELFFile(), std::move(DWARFCtx));
1601
1602 if (const auto *ELFObj = dyn_cast<object::ELF32BEObjectFile>(&Obj))
1603 return elf2yaml(Out, ELFObj->getELFFile(), std::move(DWARFCtx));
1604
1605 if (const auto *ELFObj = dyn_cast<object::ELF64LEObjectFile>(&Obj))
1606 return elf2yaml(Out, ELFObj->getELFFile(), std::move(DWARFCtx));
1607
1608 if (const auto *ELFObj = dyn_cast<object::ELF64BEObjectFile>(&Obj))
1609 return elf2yaml(Out, ELFObj->getELFFile(), std::move(DWARFCtx));
1610
1611 llvm_unreachable("unknown ELF file format")::llvm::llvm_unreachable_internal("unknown ELF file format", "llvm/tools/obj2yaml/elf2yaml.cpp"
, 1611)
;
1612}

/build/source/llvm/include/llvm/ObjectYAML/ELFYAML.h

1//===- ELFYAML.h - ELF YAMLIO implementation --------------------*- C++ -*-===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8///
9/// \file
10/// This file declares classes for handling the YAML representation
11/// of ELF.
12///
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_OBJECTYAML_ELFYAML_H
16#define LLVM_OBJECTYAML_ELFYAML_H
17
18#include "llvm/ADT/StringRef.h"
19#include "llvm/BinaryFormat/ELF.h"
20#include "llvm/Object/ELFTypes.h"
21#include "llvm/ObjectYAML/DWARFYAML.h"
22#include "llvm/ObjectYAML/YAML.h"
23#include "llvm/Support/YAMLTraits.h"
24#include <cstdint>
25#include <memory>
26#include <optional>
27#include <vector>
28
29namespace llvm {
30namespace ELFYAML {
31
32StringRef dropUniqueSuffix(StringRef S);
33std::string appendUniqueSuffix(StringRef Name, const Twine& Msg);
34
35// These types are invariant across 32/64-bit ELF, so for simplicity just
36// directly give them their exact sizes. We don't need to worry about
37// endianness because these are just the types in the YAMLIO structures,
38// and are appropriately converted to the necessary endianness when
39// reading/generating binary object files.
40// The naming of these types is intended to be ELF_PREFIX, where PREFIX is
41// the common prefix of the respective constants. E.g. ELF_EM corresponds
42// to the `e_machine` constants, like `EM_X86_64`.
43// In the future, these would probably be better suited by C++11 enum
44// class's with appropriate fixed underlying type.
45LLVM_YAML_STRONG_TYPEDEF(uint16_t, ELF_ET)struct ELF_ET { ELF_ET() = default; ELF_ET(const uint16_t v) :
value(v) {} ELF_ET(const ELF_ET &v) = default; ELF_ET &
operator=(const ELF_ET &rhs) = default; ELF_ET &operator
=(const uint16_t &rhs) { value = rhs; return *this; } operator
const uint16_t & () const { return value; } bool operator
==(const ELF_ET &rhs) const { return value == rhs.value; }
bool operator==(const uint16_t &rhs) const { return value
== rhs; } bool operator<(const ELF_ET &rhs) const { return
value < rhs.value; } uint16_t value; using BaseType = uint16_t
; };
46LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_PT)struct ELF_PT { ELF_PT() = default; ELF_PT(const uint32_t v) :
value(v) {} ELF_PT(const ELF_PT &v) = default; ELF_PT &
operator=(const ELF_PT &rhs) = default; ELF_PT &operator
=(const uint32_t &rhs) { value = rhs; return *this; } operator
const uint32_t & () const { return value; } bool operator
==(const ELF_PT &rhs) const { return value == rhs.value; }
bool operator==(const uint32_t &rhs) const { return value
== rhs; } bool operator<(const ELF_PT &rhs) const { return
value < rhs.value; } uint32_t value; using BaseType = uint32_t
; };
47LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_EM)struct ELF_EM { ELF_EM() = default; ELF_EM(const uint32_t v) :
value(v) {} ELF_EM(const ELF_EM &v) = default; ELF_EM &
operator=(const ELF_EM &rhs) = default; ELF_EM &operator
=(const uint32_t &rhs) { value = rhs; return *this; } operator
const uint32_t & () const { return value; } bool operator
==(const ELF_EM &rhs) const { return value == rhs.value; }
bool operator==(const uint32_t &rhs) const { return value
== rhs; } bool operator<(const ELF_EM &rhs) const { return
value < rhs.value; } uint32_t value; using BaseType = uint32_t
; };
48LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFCLASS)struct ELF_ELFCLASS { ELF_ELFCLASS() = default; ELF_ELFCLASS(
const uint8_t v) : value(v) {} ELF_ELFCLASS(const ELF_ELFCLASS
&v) = default; ELF_ELFCLASS &operator=(const ELF_ELFCLASS
&rhs) = default; ELF_ELFCLASS &operator=(const uint8_t
&rhs) { value = rhs; return *this; } operator const uint8_t
& () const { return value; } bool operator==(const ELF_ELFCLASS
&rhs) const { return value == rhs.value; } bool operator
==(const uint8_t &rhs) const { return value == rhs; } bool
operator<(const ELF_ELFCLASS &rhs) const { return value
< rhs.value; } uint8_t value; using BaseType = uint8_t; }
;
49LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFDATA)struct ELF_ELFDATA { ELF_ELFDATA() = default; ELF_ELFDATA(const
uint8_t v) : value(v) {} ELF_ELFDATA(const ELF_ELFDATA &
v) = default; ELF_ELFDATA &operator=(const ELF_ELFDATA &
rhs) = default; ELF_ELFDATA &operator=(const uint8_t &
rhs) { value = rhs; return *this; } operator const uint8_t &
() const { return value; } bool operator==(const ELF_ELFDATA
&rhs) const { return value == rhs.value; } bool operator
==(const uint8_t &rhs) const { return value == rhs; } bool
operator<(const ELF_ELFDATA &rhs) const { return value
< rhs.value; } uint8_t value; using BaseType = uint8_t; }
;
50LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFOSABI)struct ELF_ELFOSABI { ELF_ELFOSABI() = default; ELF_ELFOSABI(
const uint8_t v) : value(v) {} ELF_ELFOSABI(const ELF_ELFOSABI
&v) = default; ELF_ELFOSABI &operator=(const ELF_ELFOSABI
&rhs) = default; ELF_ELFOSABI &operator=(const uint8_t
&rhs) { value = rhs; return *this; } operator const uint8_t
& () const { return value; } bool operator==(const ELF_ELFOSABI
&rhs) const { return value == rhs.value; } bool operator
==(const uint8_t &rhs) const { return value == rhs; } bool
operator<(const ELF_ELFOSABI &rhs) const { return value
< rhs.value; } uint8_t value; using BaseType = uint8_t; }
;
51// Just use 64, since it can hold 32-bit values too.
52LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_EF)struct ELF_EF { ELF_EF() = default; ELF_EF(const uint64_t v) :
value(v) {} ELF_EF(const ELF_EF &v) = default; ELF_EF &
operator=(const ELF_EF &rhs) = default; ELF_EF &operator
=(const uint64_t &rhs) { value = rhs; return *this; } operator
const uint64_t & () const { return value; } bool operator
==(const ELF_EF &rhs) const { return value == rhs.value; }
bool operator==(const uint64_t &rhs) const { return value
== rhs; } bool operator<(const ELF_EF &rhs) const { return
value < rhs.value; } uint64_t value; using BaseType = uint64_t
; };
53// Just use 64, since it can hold 32-bit values too.
54LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_DYNTAG)struct ELF_DYNTAG { ELF_DYNTAG() = default; ELF_DYNTAG(const uint64_t
v) : value(v) {} ELF_DYNTAG(const ELF_DYNTAG &v) = default
; ELF_DYNTAG &operator=(const ELF_DYNTAG &rhs) = default
; ELF_DYNTAG &operator=(const uint64_t &rhs) { value =
rhs; return *this; } operator const uint64_t & () const {
return value; } bool operator==(const ELF_DYNTAG &rhs) const
{ return value == rhs.value; } bool operator==(const uint64_t
&rhs) const { return value == rhs; } bool operator<(const
ELF_DYNTAG &rhs) const { return value < rhs.value; } uint64_t
value; using BaseType = uint64_t; };
55LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_PF)struct ELF_PF { ELF_PF() = default; ELF_PF(const uint32_t v) :
value(v) {} ELF_PF(const ELF_PF &v) = default; ELF_PF &
operator=(const ELF_PF &rhs) = default; ELF_PF &operator
=(const uint32_t &rhs) { value = rhs; return *this; } operator
const uint32_t & () const { return value; } bool operator
==(const ELF_PF &rhs) const { return value == rhs.value; }
bool operator==(const uint32_t &rhs) const { return value
== rhs; } bool operator<(const ELF_PF &rhs) const { return
value < rhs.value; } uint32_t value; using BaseType = uint32_t
; };
56LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_SHT)struct ELF_SHT { ELF_SHT() = default; ELF_SHT(const uint32_t v
) : value(v) {} ELF_SHT(const ELF_SHT &v) = default; ELF_SHT
&operator=(const ELF_SHT &rhs) = default; ELF_SHT &
operator=(const uint32_t &rhs) { value = rhs; return *this
; } operator const uint32_t & () const { return value; } bool
operator==(const ELF_SHT &rhs) const { return value == rhs
.value; } bool operator==(const uint32_t &rhs) const { return
value == rhs; } bool operator<(const ELF_SHT &rhs) const
{ return value < rhs.value; } uint32_t value; using BaseType
= uint32_t; };
57LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_REL)struct ELF_REL { ELF_REL() = default; ELF_REL(const uint32_t v
) : value(v) {} ELF_REL(const ELF_REL &v) = default; ELF_REL
&operator=(const ELF_REL &rhs) = default; ELF_REL &
operator=(const uint32_t &rhs) { value = rhs; return *this
; } operator const uint32_t & () const { return value; } bool
operator==(const ELF_REL &rhs) const { return value == rhs
.value; } bool operator==(const uint32_t &rhs) const { return
value == rhs; } bool operator<(const ELF_REL &rhs) const
{ return value < rhs.value; } uint32_t value; using BaseType
= uint32_t; };
58LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_RSS)struct ELF_RSS { ELF_RSS() = default; ELF_RSS(const uint8_t v
) : value(v) {} ELF_RSS(const ELF_RSS &v) = default; ELF_RSS
&operator=(const ELF_RSS &rhs) = default; ELF_RSS &
operator=(const uint8_t &rhs) { value = rhs; return *this
; } operator const uint8_t & () const { return value; } bool
operator==(const ELF_RSS &rhs) const { return value == rhs
.value; } bool operator==(const uint8_t &rhs) const { return
value == rhs; } bool operator<(const ELF_RSS &rhs) const
{ return value < rhs.value; } uint8_t value; using BaseType
= uint8_t; };
59// Just use 64, since it can hold 32-bit values too.
60LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_SHF)struct ELF_SHF { ELF_SHF() = default; ELF_SHF(const uint64_t v
) : value(v) {} ELF_SHF(const ELF_SHF &v) = default; ELF_SHF
&operator=(const ELF_SHF &rhs) = default; ELF_SHF &
operator=(const uint64_t &rhs) { value = rhs; return *this
; } operator const uint64_t & () const { return value; } bool
operator==(const ELF_SHF &rhs) const { return value == rhs
.value; } bool operator==(const uint64_t &rhs) const { return
value == rhs; } bool operator<(const ELF_SHF &rhs) const
{ return value < rhs.value; } uint64_t value; using BaseType
= uint64_t; };
61LLVM_YAML_STRONG_TYPEDEF(uint16_t, ELF_SHN)struct ELF_SHN { ELF_SHN() = default; ELF_SHN(const uint16_t v
) : value(v) {} ELF_SHN(const ELF_SHN &v) = default; ELF_SHN
&operator=(const ELF_SHN &rhs) = default; ELF_SHN &
operator=(const uint16_t &rhs) { value = rhs; return *this
; } operator const uint16_t & () const { return value; } bool
operator==(const ELF_SHN &rhs) const { return value == rhs
.value; } bool operator==(const uint16_t &rhs) const { return
value == rhs; } bool operator<(const ELF_SHN &rhs) const
{ return value < rhs.value; } uint16_t value; using BaseType
= uint16_t; };
62LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STB)struct ELF_STB { ELF_STB() = default; ELF_STB(const uint8_t v
) : value(v) {} ELF_STB(const ELF_STB &v) = default; ELF_STB
&operator=(const ELF_STB &rhs) = default; ELF_STB &
operator=(const uint8_t &rhs) { value = rhs; return *this
; } operator const uint8_t & () const { return value; } bool
operator==(const ELF_STB &rhs) const { return value == rhs
.value; } bool operator==(const uint8_t &rhs) const { return
value == rhs; } bool operator<(const ELF_STB &rhs) const
{ return value < rhs.value; } uint8_t value; using BaseType
= uint8_t; };
63LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STT)struct ELF_STT { ELF_STT() = default; ELF_STT(const uint8_t v
) : value(v) {} ELF_STT(const ELF_STT &v) = default; ELF_STT
&operator=(const ELF_STT &rhs) = default; ELF_STT &
operator=(const uint8_t &rhs) { value = rhs; return *this
; } operator const uint8_t & () const { return value; } bool
operator==(const ELF_STT &rhs) const { return value == rhs
.value; } bool operator==(const uint8_t &rhs) const { return
value == rhs; } bool operator<(const ELF_STT &rhs) const
{ return value < rhs.value; } uint8_t value; using BaseType
= uint8_t; };
64LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_NT)struct ELF_NT { ELF_NT() = default; ELF_NT(const uint32_t v) :
value(v) {} ELF_NT(const ELF_NT &v) = default; ELF_NT &
operator=(const ELF_NT &rhs) = default; ELF_NT &operator
=(const uint32_t &rhs) { value = rhs; return *this; } operator
const uint32_t & () const { return value; } bool operator
==(const ELF_NT &rhs) const { return value == rhs.value; }
bool operator==(const uint32_t &rhs) const { return value
== rhs; } bool operator<(const ELF_NT &rhs) const { return
value < rhs.value; } uint32_t value; using BaseType = uint32_t
; };
65
66LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_AFL_REG)struct MIPS_AFL_REG { MIPS_AFL_REG() = default; MIPS_AFL_REG(
const uint8_t v) : value(v) {} MIPS_AFL_REG(const MIPS_AFL_REG
&v) = default; MIPS_AFL_REG &operator=(const MIPS_AFL_REG
&rhs) = default; MIPS_AFL_REG &operator=(const uint8_t
&rhs) { value = rhs; return *this; } operator const uint8_t
& () const { return value; } bool operator==(const MIPS_AFL_REG
&rhs) const { return value == rhs.value; } bool operator
==(const uint8_t &rhs) const { return value == rhs; } bool
operator<(const MIPS_AFL_REG &rhs) const { return value
< rhs.value; } uint8_t value; using BaseType = uint8_t; }
;
67LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_ABI_FP)struct MIPS_ABI_FP { MIPS_ABI_FP() = default; MIPS_ABI_FP(const
uint8_t v) : value(v) {} MIPS_ABI_FP(const MIPS_ABI_FP &
v) = default; MIPS_ABI_FP &operator=(const MIPS_ABI_FP &
rhs) = default; MIPS_ABI_FP &operator=(const uint8_t &
rhs) { value = rhs; return *this; } operator const uint8_t &
() const { return value; } bool operator==(const MIPS_ABI_FP
&rhs) const { return value == rhs.value; } bool operator
==(const uint8_t &rhs) const { return value == rhs; } bool
operator<(const MIPS_ABI_FP &rhs) const { return value
< rhs.value; } uint8_t value; using BaseType = uint8_t; }
;
68LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_EXT)struct MIPS_AFL_EXT { MIPS_AFL_EXT() = default; MIPS_AFL_EXT(
const uint32_t v) : value(v) {} MIPS_AFL_EXT(const MIPS_AFL_EXT
&v) = default; MIPS_AFL_EXT &operator=(const MIPS_AFL_EXT
&rhs) = default; MIPS_AFL_EXT &operator=(const uint32_t
&rhs) { value = rhs; return *this; } operator const uint32_t
& () const { return value; } bool operator==(const MIPS_AFL_EXT
&rhs) const { return value == rhs.value; } bool operator
==(const uint32_t &rhs) const { return value == rhs; } bool
operator<(const MIPS_AFL_EXT &rhs) const { return value
< rhs.value; } uint32_t value; using BaseType = uint32_t;
};
69LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_ASE)struct MIPS_AFL_ASE { MIPS_AFL_ASE() = default; MIPS_AFL_ASE(
const uint32_t v) : value(v) {} MIPS_AFL_ASE(const MIPS_AFL_ASE
&v) = default; MIPS_AFL_ASE &operator=(const MIPS_AFL_ASE
&rhs) = default; MIPS_AFL_ASE &operator=(const uint32_t
&rhs) { value = rhs; return *this; } operator const uint32_t
& () const { return value; } bool operator==(const MIPS_AFL_ASE
&rhs) const { return value == rhs.value; } bool operator
==(const uint32_t &rhs) const { return value == rhs; } bool
operator<(const MIPS_AFL_ASE &rhs) const { return value
< rhs.value; } uint32_t value; using BaseType = uint32_t;
};
70LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_FLAGS1)struct MIPS_AFL_FLAGS1 { MIPS_AFL_FLAGS1() = default; MIPS_AFL_FLAGS1
(const uint32_t v) : value(v) {} MIPS_AFL_FLAGS1(const MIPS_AFL_FLAGS1
&v) = default; MIPS_AFL_FLAGS1 &operator=(const MIPS_AFL_FLAGS1
&rhs) = default; MIPS_AFL_FLAGS1 &operator=(const uint32_t
&rhs) { value = rhs; return *this; } operator const uint32_t
& () const { return value; } bool operator==(const MIPS_AFL_FLAGS1
&rhs) const { return value == rhs.value; } bool operator
==(const uint32_t &rhs) const { return value == rhs; } bool
operator<(const MIPS_AFL_FLAGS1 &rhs) const { return value
< rhs.value; } uint32_t value; using BaseType = uint32_t;
};
71LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_ISA)struct MIPS_ISA { MIPS_ISA() = default; MIPS_ISA(const uint32_t
v) : value(v) {} MIPS_ISA(const MIPS_ISA &v) = default; MIPS_ISA
&operator=(const MIPS_ISA &rhs) = default; MIPS_ISA &
operator=(const uint32_t &rhs) { value = rhs; return *this
; } operator const uint32_t & () const { return value; } bool
operator==(const MIPS_ISA &rhs) const { return value == rhs
.value; } bool operator==(const uint32_t &rhs) const { return
value == rhs; } bool operator<(const MIPS_ISA &rhs) const
{ return value < rhs.value; } uint32_t value; using BaseType
= uint32_t; };
72
73LLVM_YAML_STRONG_TYPEDEF(StringRef, YAMLFlowString)struct YAMLFlowString { YAMLFlowString() = default; YAMLFlowString
(const StringRef v) : value(v) {} YAMLFlowString(const YAMLFlowString
&v) = default; YAMLFlowString &operator=(const YAMLFlowString
&rhs) = default; YAMLFlowString &operator=(const StringRef
&rhs) { value = rhs; return *this; } operator const StringRef
& () const { return value; } bool operator==(const YAMLFlowString
&rhs) const { return value == rhs.value; } bool operator
==(const StringRef &rhs) const { return value == rhs; } bool
operator<(const YAMLFlowString &rhs) const { return value
< rhs.value; } StringRef value; using BaseType = StringRef
; };
74LLVM_YAML_STRONG_TYPEDEF(int64_t, YAMLIntUInt)struct YAMLIntUInt { YAMLIntUInt() = default; YAMLIntUInt(const
int64_t v) : value(v) {} YAMLIntUInt(const YAMLIntUInt &
v) = default; YAMLIntUInt &operator=(const YAMLIntUInt &
rhs) = default; YAMLIntUInt &operator=(const int64_t &
rhs) { value = rhs; return *this; } operator const int64_t &
() const { return value; } bool operator==(const YAMLIntUInt
&rhs) const { return value == rhs.value; } bool operator
==(const int64_t &rhs) const { return value == rhs; } bool
operator<(const YAMLIntUInt &rhs) const { return value
< rhs.value; } int64_t value; using BaseType = int64_t; }
;
75
76template <class ELFT>
77unsigned getDefaultShEntSize(unsigned EMachine, ELF_SHT SecType,
78 StringRef SecName) {
79 if (EMachine == ELF::EM_MIPS && SecType == ELF::SHT_MIPS_ABIFLAGS)
6
Assuming 'EMachine' is not equal to EM_MIPS
7
Taking false branch
80 return sizeof(object::Elf_Mips_ABIFlags<ELFT>);
81
82 switch (SecType) {
8
Control jumps to the 'default' case at line 104
83 case ELF::SHT_SYMTAB:
84 case ELF::SHT_DYNSYM:
85 return sizeof(typename ELFT::Sym);
86 case ELF::SHT_GROUP:
87 return sizeof(typename ELFT::Word);
88 case ELF::SHT_REL:
89 return sizeof(typename ELFT::Rel);
90 case ELF::SHT_RELA:
91 return sizeof(typename ELFT::Rela);
92 case ELF::SHT_RELR:
93 return sizeof(typename ELFT::Relr);
94 case ELF::SHT_DYNAMIC:
95 return sizeof(typename ELFT::Dyn);
96 case ELF::SHT_HASH:
97 return sizeof(typename ELFT::Word);
98 case ELF::SHT_SYMTAB_SHNDX:
99 return sizeof(typename ELFT::Word);
100 case ELF::SHT_GNU_versym:
101 return sizeof(typename ELFT::Half);
102 case ELF::SHT_LLVM_CALL_GRAPH_PROFILE:
103 return sizeof(object::Elf_CGProfile_Impl<ELFT>);
104 default:
105 if (SecName == ".debug_str")
9
Assuming the condition is false
10
Taking false branch
106 return 1;
107 return 0;
11
Returning zero
108 }
109}
110
111// For now, hardcode 64 bits everywhere that 32 or 64 would be needed
112// since 64-bit can hold 32-bit values too.
113struct FileHeader {
114 ELF_ELFCLASS Class;
115 ELF_ELFDATA Data;
116 ELF_ELFOSABI OSABI;
117 llvm::yaml::Hex8 ABIVersion;
118 ELF_ET Type;
119 std::optional<ELF_EM> Machine;
120 ELF_EF Flags;
121 llvm::yaml::Hex64 Entry;
122 std::optional<StringRef> SectionHeaderStringTable;
123
124 std::optional<llvm::yaml::Hex64> EPhOff;
125 std::optional<llvm::yaml::Hex16> EPhEntSize;
126 std::optional<llvm::yaml::Hex16> EPhNum;
127 std::optional<llvm::yaml::Hex16> EShEntSize;
128 std::optional<llvm::yaml::Hex64> EShOff;
129 std::optional<llvm::yaml::Hex16> EShNum;
130 std::optional<llvm::yaml::Hex16> EShStrNdx;
131};
132
133struct SectionHeader {
134 StringRef Name;
135};
136
137struct Symbol {
138 StringRef Name;
139 ELF_STT Type;
140 std::optional<StringRef> Section;
141 std::optional<ELF_SHN> Index;
142 ELF_STB Binding;
143 std::optional<llvm::yaml::Hex64> Value;
144 std::optional<llvm::yaml::Hex64> Size;
145 std::optional<uint8_t> Other;
146
147 std::optional<uint32_t> StName;
148};
149
150struct SectionOrType {
151 StringRef sectionNameOrType;
152};
153
154struct DynamicEntry {
155 ELF_DYNTAG Tag;
156 llvm::yaml::Hex64 Val;
157};
158
159struct BBAddrMapEntry {
160 struct BBEntry {
161 uint32_t ID;
162 llvm::yaml::Hex64 AddressOffset;
163 llvm::yaml::Hex64 Size;
164 llvm::yaml::Hex64 Metadata;
165 };
166 uint8_t Version;
167 llvm::yaml::Hex8 Feature;
168 llvm::yaml::Hex64 Address;
169 std::optional<uint64_t> NumBlocks;
170 std::optional<std::vector<BBEntry>> BBEntries;
171};
172
173struct StackSizeEntry {
174 llvm::yaml::Hex64 Address;
175 llvm::yaml::Hex64 Size;
176};
177
178struct NoteEntry {
179 StringRef Name;
180 yaml::BinaryRef Desc;
181 ELF_NT Type;
182};
183
184struct Chunk {
185 enum class ChunkKind {
186 Dynamic,
187 Group,
188 RawContent,
189 Relocation,
190 Relr,
191 NoBits,
192 Note,
193 Hash,
194 GnuHash,
195 Verdef,
196 Verneed,
197 StackSizes,
198 SymtabShndxSection,
199 Symver,
200 ARMIndexTable,
201 MipsABIFlags,
202 Addrsig,
203 LinkerOptions,
204 DependentLibraries,
205 CallGraphProfile,
206 BBAddrMap,
207
208 // Special chunks.
209 SpecialChunksStart,
210 Fill = SpecialChunksStart,
211 SectionHeaderTable,
212 };
213
214 ChunkKind Kind;
215 StringRef Name;
216 std::optional<llvm::yaml::Hex64> Offset;
217
218 // Usually chunks are not created implicitly, but rather loaded from YAML.
219 // This flag is used to signal whether this is the case or not.
220 bool IsImplicit;
221
222 Chunk(ChunkKind K, bool Implicit) : Kind(K), IsImplicit(Implicit) {}
223 virtual ~Chunk();
224};
225
226struct Section : public Chunk {
227 ELF_SHT Type;
228 std::optional<ELF_SHF> Flags;
229 std::optional<llvm::yaml::Hex64> Address;
230 std::optional<StringRef> Link;
231 llvm::yaml::Hex64 AddressAlign;
232 std::optional<llvm::yaml::Hex64> EntSize;
233
234 std::optional<yaml::BinaryRef> Content;
235 std::optional<llvm::yaml::Hex64> Size;
236
237 // Holds the original section index.
238 unsigned OriginalSecNdx;
239
240 Section(ChunkKind Kind, bool IsImplicit = false) : Chunk(Kind, IsImplicit) {}
241
242 static bool classof(const Chunk *S) {
243 return S->Kind < ChunkKind::SpecialChunksStart;
244 }
245
246 // Some derived sections might have their own special entries. This method
247 // returns a vector of <entry name, is used> pairs. It is used for section
248 // validation.
249 virtual std::vector<std::pair<StringRef, bool>> getEntries() const {
250 return {};
251 };
252
253 // The following members are used to override section fields which is
254 // useful for creating invalid objects.
255
256 // This can be used to override the sh_addralign field.
257 std::optional<llvm::yaml::Hex64> ShAddrAlign;
258
259 // This can be used to override the offset stored in the sh_name field.
260 // It does not affect the name stored in the string table.
261 std::optional<llvm::yaml::Hex64> ShName;
262
263 // This can be used to override the sh_offset field. It does not place the
264 // section data at the offset specified.
265 std::optional<llvm::yaml::Hex64> ShOffset;
266
267 // This can be used to override the sh_size field. It does not affect the
268 // content written.
269 std::optional<llvm::yaml::Hex64> ShSize;
270
271 // This can be used to override the sh_flags field.
272 std::optional<llvm::yaml::Hex64> ShFlags;
273
274 // This can be used to override the sh_type field. It is useful when we
275 // want to use specific YAML keys for a section of a particular type to
276 // describe the content, but still want to have a different final type
277 // for the section.
278 std::optional<ELF_SHT> ShType;
279};
280
281// Fill is a block of data which is placed outside of sections. It is
282// not present in the sections header table, but it might affect the output file
283// size and program headers produced.
284struct Fill : Chunk {
285 std::optional<yaml::BinaryRef> Pattern;
286 llvm::yaml::Hex64 Size;
287
288 Fill() : Chunk(ChunkKind::Fill, /*Implicit=*/false) {}
289
290 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Fill; }
291};
292
293struct SectionHeaderTable : Chunk {
294 SectionHeaderTable(bool IsImplicit)
295 : Chunk(ChunkKind::SectionHeaderTable, IsImplicit) {}
296
297 static bool classof(const Chunk *S) {
298 return S->Kind == ChunkKind::SectionHeaderTable;
299 }
300
301 std::optional<std::vector<SectionHeader>> Sections;
302 std::optional<std::vector<SectionHeader>> Excluded;
303 std::optional<bool> NoHeaders;
304
305 size_t getNumHeaders(size_t SectionsNum) const {
306 if (IsImplicit || isDefault())
307 return SectionsNum;
308 if (NoHeaders)
309 return (*NoHeaders) ? 0 : SectionsNum;
310 return (Sections ? Sections->size() : 0) + /*Null section*/ 1;
311 }
312
313 bool isDefault() const { return !Sections && !Excluded && !NoHeaders; }
314
315 static constexpr StringRef TypeStr = "SectionHeaderTable";
316};
317
318struct BBAddrMapSection : Section {
319 std::optional<std::vector<BBAddrMapEntry>> Entries;
320
321 BBAddrMapSection() : Section(ChunkKind::BBAddrMap) {}
322
323 std::vector<std::pair<StringRef, bool>> getEntries() const override {
324 return {{"Entries", Entries.has_value()}};
325 };
326
327 static bool classof(const Chunk *S) {
328 return S->Kind == ChunkKind::BBAddrMap;
329 }
330};
331
332struct StackSizesSection : Section {
333 std::optional<std::vector<StackSizeEntry>> Entries;
334
335 StackSizesSection() : Section(ChunkKind::StackSizes) {}
336
337 std::vector<std::pair<StringRef, bool>> getEntries() const override {
338 return {{"Entries", Entries.has_value()}};
339 };
340
341 static bool classof(const Chunk *S) {
342 return S->Kind == ChunkKind::StackSizes;
343 }
344
345 static bool nameMatches(StringRef Name) {
346 return Name == ".stack_sizes";
347 }
348};
349
350struct DynamicSection : Section {
351 std::optional<std::vector<DynamicEntry>> Entries;
352
353 DynamicSection() : Section(ChunkKind::Dynamic) {}
354
355 std::vector<std::pair<StringRef, bool>> getEntries() const override {
356 return {{"Entries", Entries.has_value()}};
357 };
358
359 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Dynamic; }
360};
361
362struct RawContentSection : Section {
363 std::optional<llvm::yaml::Hex64> Info;
364
365 RawContentSection() : Section(ChunkKind::RawContent) {}
366
367 static bool classof(const Chunk *S) {
368 return S->Kind == ChunkKind::RawContent;
369 }
370
371 // Is used when a content is read as an array of bytes.
372 std::optional<std::vector<uint8_t>> ContentBuf;
373};
374
375struct NoBitsSection : Section {
376 NoBitsSection() : Section(ChunkKind::NoBits) {}
377
378 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::NoBits; }
379};
380
381struct NoteSection : Section {
382 std::optional<std::vector<ELFYAML::NoteEntry>> Notes;
383
384 NoteSection() : Section(ChunkKind::Note) {}
385
386 std::vector<std::pair<StringRef, bool>> getEntries() const override {
387 return {{"Notes", Notes.has_value()}};
388 };
389
390 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Note; }
391};
392
393struct HashSection : Section {
394 std::optional<std::vector<uint32_t>> Bucket;
395 std::optional<std::vector<uint32_t>> Chain;
396
397 std::vector<std::pair<StringRef, bool>> getEntries() const override {
398 return {{"Bucket", Bucket.has_value()}, {"Chain", Chain.has_value()}};
399 };
400
401 // The following members are used to override section fields.
402 // This is useful for creating invalid objects.
403 std::optional<llvm::yaml::Hex64> NBucket;
404 std::optional<llvm::yaml::Hex64> NChain;
405
406 HashSection() : Section(ChunkKind::Hash) {}
407
408 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Hash; }
409};
410
411struct GnuHashHeader {
412 // The number of hash buckets.
413 // Not used when dumping the object, but can be used to override
414 // the real number of buckets when emiting an object from a YAML document.
415 std::optional<llvm::yaml::Hex32> NBuckets;
416
417 // Index of the first symbol in the dynamic symbol table
418 // included in the hash table.
419 llvm::yaml::Hex32 SymNdx;
420
421 // The number of words in the Bloom filter.
422 // Not used when dumping the object, but can be used to override the real
423 // number of words in the Bloom filter when emiting an object from a YAML
424 // document.
425 std::optional<llvm::yaml::Hex32> MaskWords;
426
427 // A shift constant used by the Bloom filter.
428 llvm::yaml::Hex32 Shift2;
429};
430
431struct GnuHashSection : Section {
432 std::optional<GnuHashHeader> Header;
433 std::optional<std::vector<llvm::yaml::Hex64>> BloomFilter;
434 std::optional<std::vector<llvm::yaml::Hex32>> HashBuckets;
435 std::optional<std::vector<llvm::yaml::Hex32>> HashValues;
436
437 GnuHashSection() : Section(ChunkKind::GnuHash) {}
438
439 std::vector<std::pair<StringRef, bool>> getEntries() const override {
440 return {{"Header", Header.has_value()},
441 {"BloomFilter", BloomFilter.has_value()},
442 {"HashBuckets", HashBuckets.has_value()},
443 {"HashValues", HashValues.has_value()}};
444 };
445
446 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::GnuHash; }
447};
448
449struct VernauxEntry {
450 uint32_t Hash;
451 uint16_t Flags;
452 uint16_t Other;
453 StringRef Name;
454};
455
456struct VerneedEntry {
457 uint16_t Version;
458 StringRef File;
459 std::vector<VernauxEntry> AuxV;
460};
461
462struct VerneedSection : Section {
463 std::optional<std::vector<VerneedEntry>> VerneedV;
464 std::optional<llvm::yaml::Hex64> Info;
465
466 VerneedSection() : Section(ChunkKind::Verneed) {}
467
468 std::vector<std::pair<StringRef, bool>> getEntries() const override {
469 return {{"Dependencies", VerneedV.has_value()}};
470 };
471
472 static bool classof(const Chunk *S) {
473 return S->Kind == ChunkKind::Verneed;
474 }
475};
476
477struct AddrsigSection : Section {
478 std::optional<std::vector<YAMLFlowString>> Symbols;
479
480 AddrsigSection() : Section(ChunkKind::Addrsig) {}
481
482 std::vector<std::pair<StringRef, bool>> getEntries() const override {
483 return {{"Symbols", Symbols.has_value()}};
484 };
485
486 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Addrsig; }
487};
488
489struct LinkerOption {
490 StringRef Key;
491 StringRef Value;
492};
493
494struct LinkerOptionsSection : Section {
495 std::optional<std::vector<LinkerOption>> Options;
496
497 LinkerOptionsSection() : Section(ChunkKind::LinkerOptions) {}
498
499 std::vector<std::pair<StringRef, bool>> getEntries() const override {
500 return {{"Options", Options.has_value()}};
501 };
502
503 static bool classof(const Chunk *S) {
504 return S->Kind == ChunkKind::LinkerOptions;
505 }
506};
507
508struct DependentLibrariesSection : Section {
509 std::optional<std::vector<YAMLFlowString>> Libs;
510
511 DependentLibrariesSection() : Section(ChunkKind::DependentLibraries) {}
512
513 std::vector<std::pair<StringRef, bool>> getEntries() const override {
514 return {{"Libraries", Libs.has_value()}};
515 };
516
517 static bool classof(const Chunk *S) {
518 return S->Kind == ChunkKind::DependentLibraries;
519 }
520};
521
522// Represents the call graph profile section entry.
523struct CallGraphEntryWeight {
524 // The weight of the edge.
525 uint64_t Weight;
526};
527
528struct CallGraphProfileSection : Section {
529 std::optional<std::vector<CallGraphEntryWeight>> Entries;
530
531 CallGraphProfileSection() : Section(ChunkKind::CallGraphProfile) {}
532
533 std::vector<std::pair<StringRef, bool>> getEntries() const override {
534 return {{"Entries", Entries.has_value()}};
535 };
536
537 static bool classof(const Chunk *S) {
538 return S->Kind == ChunkKind::CallGraphProfile;
539 }
540};
541
542struct SymverSection : Section {
543 std::optional<std::vector<uint16_t>> Entries;
544
545 SymverSection() : Section(ChunkKind::Symver) {}
546
547 std::vector<std::pair<StringRef, bool>> getEntries() const override {
548 return {{"Entries", Entries.has_value()}};
549 };
550
551 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Symver; }
552};
553
554struct VerdefEntry {
555 std::optional<uint16_t> Version;
556 std::optional<uint16_t> Flags;
557 std::optional<uint16_t> VersionNdx;
558 std::optional<uint32_t> Hash;
559 std::vector<StringRef> VerNames;
560};
561
562struct VerdefSection : Section {
563 std::optional<std::vector<VerdefEntry>> Entries;
564 std::optional<llvm::yaml::Hex64> Info;
565
566 VerdefSection() : Section(ChunkKind::Verdef) {}
567
568 std::vector<std::pair<StringRef, bool>> getEntries() const override {
569 return {{"Entries", Entries.has_value()}};
570 };
571
572 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Verdef; }
573};
574
575struct GroupSection : Section {
576 // Members of a group contain a flag and a list of section indices
577 // that are part of the group.
578 std::optional<std::vector<SectionOrType>> Members;
579 std::optional<StringRef> Signature; /* Info */
580
581 GroupSection() : Section(ChunkKind::Group) {}
582
583 std::vector<std::pair<StringRef, bool>> getEntries() const override {
584 return {{"Members", Members.has_value()}};
585 };
586
587 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Group; }
588};
589
590struct Relocation {
591 llvm::yaml::Hex64 Offset;
592 YAMLIntUInt Addend;
593 ELF_REL Type;
594 std::optional<StringRef> Symbol;
595};
596
597struct RelocationSection : Section {
598 std::optional<std::vector<Relocation>> Relocations;
599 StringRef RelocatableSec; /* Info */
600
601 RelocationSection() : Section(ChunkKind::Relocation) {}
602
603 std::vector<std::pair<StringRef, bool>> getEntries() const override {
604 return {{"Relocations", Relocations.has_value()}};
605 };
606
607 static bool classof(const Chunk *S) {
608 return S->Kind == ChunkKind::Relocation;
609 }
610};
611
612struct RelrSection : Section {
613 std::optional<std::vector<llvm::yaml::Hex64>> Entries;
614
615 RelrSection() : Section(ChunkKind::Relr) {}
616
617 std::vector<std::pair<StringRef, bool>> getEntries() const override {
618 return {{"Entries", Entries.has_value()}};
619 };
620
621 static bool classof(const Chunk *S) {
622 return S->Kind == ChunkKind::Relr;
623 }
624};
625
626struct SymtabShndxSection : Section {
627 std::optional<std::vector<uint32_t>> Entries;
628
629 SymtabShndxSection() : Section(ChunkKind::SymtabShndxSection) {}
630
631 std::vector<std::pair<StringRef, bool>> getEntries() const override {
632 return {{"Entries", Entries.has_value()}};
633 };
634
635 static bool classof(const Chunk *S) {
636 return S->Kind == ChunkKind::SymtabShndxSection;
637 }
638};
639
640struct ARMIndexTableEntry {
641 llvm::yaml::Hex32 Offset;
642 llvm::yaml::Hex32 Value;
643};
644
645struct ARMIndexTableSection : Section {
646 std::optional<std::vector<ARMIndexTableEntry>> Entries;
647
648 ARMIndexTableSection() : Section(ChunkKind::ARMIndexTable) {}
649
650 std::vector<std::pair<StringRef, bool>> getEntries() const override {
651 return {{"Entries", Entries.has_value()}};
652 };
653
654 static bool classof(const Chunk *S) {
655 return S->Kind == ChunkKind::ARMIndexTable;
656 }
657};
658
659// Represents .MIPS.abiflags section
660struct MipsABIFlags : Section {
661 llvm::yaml::Hex16 Version;
662 MIPS_ISA ISALevel;
663 llvm::yaml::Hex8 ISARevision;
664 MIPS_AFL_REG GPRSize;
665 MIPS_AFL_REG CPR1Size;
666 MIPS_AFL_REG CPR2Size;
667 MIPS_ABI_FP FpABI;
668 MIPS_AFL_EXT ISAExtension;
669 MIPS_AFL_ASE ASEs;
670 MIPS_AFL_FLAGS1 Flags1;
671 llvm::yaml::Hex32 Flags2;
672
673 MipsABIFlags() : Section(ChunkKind::MipsABIFlags) {}
674
675 static bool classof(const Chunk *S) {
676 return S->Kind == ChunkKind::MipsABIFlags;
677 }
678};
679
680struct ProgramHeader {
681 ELF_PT Type;
682 ELF_PF Flags;
683 llvm::yaml::Hex64 VAddr;
684 llvm::yaml::Hex64 PAddr;
685 std::optional<llvm::yaml::Hex64> Align;
686 std::optional<llvm::yaml::Hex64> FileSize;
687 std::optional<llvm::yaml::Hex64> MemSize;
688 std::optional<llvm::yaml::Hex64> Offset;
689 std::optional<StringRef> FirstSec;
690 std::optional<StringRef> LastSec;
691
692 // This vector contains all chunks from [FirstSec, LastSec].
693 std::vector<Chunk *> Chunks;
694};
695
696struct Object {
697 FileHeader Header;
698 std::vector<ProgramHeader> ProgramHeaders;
699
700 // An object might contain output section descriptions as well as
701 // custom data that does not belong to any section.
702 std::vector<std::unique_ptr<Chunk>> Chunks;
703
704 // Although in reality the symbols reside in a section, it is a lot
705 // cleaner and nicer if we read them from the YAML as a separate
706 // top-level key, which automatically ensures that invariants like there
707 // being a single SHT_SYMTAB section are upheld.
708 std::optional<std::vector<Symbol>> Symbols;
709 std::optional<std::vector<Symbol>> DynamicSymbols;
710 std::optional<DWARFYAML::Data> DWARF;
711
712 std::vector<Section *> getSections() {
713 std::vector<Section *> Ret;
714 for (const std::unique_ptr<Chunk> &Sec : Chunks)
715 if (auto S = dyn_cast<ELFYAML::Section>(Sec.get()))
716 Ret.push_back(S);
717 return Ret;
718 }
719
720 const SectionHeaderTable &getSectionHeaderTable() const {
721 for (const std::unique_ptr<Chunk> &C : Chunks)
722 if (auto *S = dyn_cast<ELFYAML::SectionHeaderTable>(C.get()))
723 return *S;
724 llvm_unreachable("the section header table chunk must always be present")::llvm::llvm_unreachable_internal("the section header table chunk must always be present"
, "llvm/include/llvm/ObjectYAML/ELFYAML.h", 724)
;
725 }
726
727 ELF_ELFOSABI getOSAbi() const;
728 unsigned getMachine() const;
729};
730
731bool shouldAllocateFileSpace(ArrayRef<ProgramHeader> Phdrs,
732 const NoBitsSection &S);
733
734} // end namespace ELFYAML
735} // end namespace llvm
736
737LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::StackSizeEntry)namespace llvm { namespace yaml { static_assert( !std::is_fundamental_v
<llvm::ELFYAML::StackSizeEntry> && !std::is_same_v
<llvm::ELFYAML::StackSizeEntry, std::string> &&
!std::is_same_v<llvm::ELFYAML::StackSizeEntry, llvm::StringRef
>, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::StackSizeEntry> { static const bool flow = false; }; } }
738LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry)namespace llvm { namespace yaml { static_assert( !std::is_fundamental_v
<llvm::ELFYAML::BBAddrMapEntry> && !std::is_same_v
<llvm::ELFYAML::BBAddrMapEntry, std::string> &&
!std::is_same_v<llvm::ELFYAML::BBAddrMapEntry, llvm::StringRef
>, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::BBAddrMapEntry> { static const bool flow = false; }; } }
739LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry::BBEntry)namespace llvm { namespace yaml { static_assert( !std::is_fundamental_v
<llvm::ELFYAML::BBAddrMapEntry::BBEntry> && !std
::is_same_v<llvm::ELFYAML::BBAddrMapEntry::BBEntry, std::string
> && !std::is_same_v<llvm::ELFYAML::BBAddrMapEntry
::BBEntry, llvm::StringRef>, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::BBAddrMapEntry::BBEntry> { static const bool flow = false
; }; } }
740LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::DynamicEntry)namespace llvm { namespace yaml { static_assert( !std::is_fundamental_v
<llvm::ELFYAML::DynamicEntry> && !std::is_same_v
<llvm::ELFYAML::DynamicEntry, std::string> && !
std::is_same_v<llvm::ELFYAML::DynamicEntry, llvm::StringRef
>, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::DynamicEntry> { static const bool flow = false; }; } }
741LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::LinkerOption)namespace llvm { namespace yaml { static_assert( !std::is_fundamental_v
<llvm::ELFYAML::LinkerOption> && !std::is_same_v
<llvm::ELFYAML::LinkerOption, std::string> && !
std::is_same_v<llvm::ELFYAML::LinkerOption, llvm::StringRef
>, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::LinkerOption> { static const bool flow = false; }; } }
742LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::CallGraphEntryWeight)namespace llvm { namespace yaml { static_assert( !std::is_fundamental_v
<llvm::ELFYAML::CallGraphEntryWeight> && !std::
is_same_v<llvm::ELFYAML::CallGraphEntryWeight, std::string
> && !std::is_same_v<llvm::ELFYAML::CallGraphEntryWeight
, llvm::StringRef>, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::CallGraphEntryWeight> { static const bool flow = false; }
; } }
743LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::NoteEntry)namespace llvm { namespace yaml { static_assert( !std::is_fundamental_v
<llvm::ELFYAML::NoteEntry> && !std::is_same_v<
llvm::ELFYAML::NoteEntry, std::string> && !std::is_same_v
<llvm::ELFYAML::NoteEntry, llvm::StringRef>, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::NoteEntry> { static const bool flow = false; }; } }
744LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ProgramHeader)namespace llvm { namespace yaml { static_assert( !std::is_fundamental_v
<llvm::ELFYAML::ProgramHeader> && !std::is_same_v
<llvm::ELFYAML::ProgramHeader, std::string> && !
std::is_same_v<llvm::ELFYAML::ProgramHeader, llvm::StringRef
>, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::ProgramHeader> { static const bool flow = false; }; } }
745LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionHeader)namespace llvm { namespace yaml { static_assert( !std::is_fundamental_v
<llvm::ELFYAML::SectionHeader> && !std::is_same_v
<llvm::ELFYAML::SectionHeader, std::string> && !
std::is_same_v<llvm::ELFYAML::SectionHeader, llvm::StringRef
>, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::SectionHeader> { static const bool flow = false; }; } }
746LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::ELFYAML::Chunk>)namespace llvm { namespace yaml { static_assert( !std::is_fundamental_v
<std::unique_ptr<llvm::ELFYAML::Chunk> > &&
!std::is_same_v<std::unique_ptr<llvm::ELFYAML::Chunk>
, std::string> && !std::is_same_v<std::unique_ptr
<llvm::ELFYAML::Chunk>, llvm::StringRef>, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<std::unique_ptr
<llvm::ELFYAML::Chunk> > { static const bool flow = false
; }; } }
747LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Symbol)namespace llvm { namespace yaml { static_assert( !std::is_fundamental_v
<llvm::ELFYAML::Symbol> && !std::is_same_v<llvm
::ELFYAML::Symbol, std::string> && !std::is_same_v
<llvm::ELFYAML::Symbol, llvm::StringRef>, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::Symbol> { static const bool flow = false; }; } }
748LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerdefEntry)namespace llvm { namespace yaml { static_assert( !std::is_fundamental_v
<llvm::ELFYAML::VerdefEntry> && !std::is_same_v
<llvm::ELFYAML::VerdefEntry, std::string> && !std
::is_same_v<llvm::ELFYAML::VerdefEntry, llvm::StringRef>
, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::VerdefEntry> { static const bool flow = false; }; } }
749LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VernauxEntry)namespace llvm { namespace yaml { static_assert( !std::is_fundamental_v
<llvm::ELFYAML::VernauxEntry> && !std::is_same_v
<llvm::ELFYAML::VernauxEntry, std::string> && !
std::is_same_v<llvm::ELFYAML::VernauxEntry, llvm::StringRef
>, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::VernauxEntry> { static const bool flow = false; }; } }
750LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerneedEntry)namespace llvm { namespace yaml { static_assert( !std::is_fundamental_v
<llvm::ELFYAML::VerneedEntry> && !std::is_same_v
<llvm::ELFYAML::VerneedEntry, std::string> && !
std::is_same_v<llvm::ELFYAML::VerneedEntry, llvm::StringRef
>, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::VerneedEntry> { static const bool flow = false; }; } }
751LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Relocation)namespace llvm { namespace yaml { static_assert( !std::is_fundamental_v
<llvm::ELFYAML::Relocation> && !std::is_same_v<
llvm::ELFYAML::Relocation, std::string> && !std::is_same_v
<llvm::ELFYAML::Relocation, llvm::StringRef>, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::Relocation> { static const bool flow = false; }; } }
752LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionOrType)namespace llvm { namespace yaml { static_assert( !std::is_fundamental_v
<llvm::ELFYAML::SectionOrType> && !std::is_same_v
<llvm::ELFYAML::SectionOrType, std::string> && !
std::is_same_v<llvm::ELFYAML::SectionOrType, llvm::StringRef
>, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::SectionOrType> { static const bool flow = false; }; } }
753LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ARMIndexTableEntry)namespace llvm { namespace yaml { static_assert( !std::is_fundamental_v
<llvm::ELFYAML::ARMIndexTableEntry> && !std::is_same_v
<llvm::ELFYAML::ARMIndexTableEntry, std::string> &&
!std::is_same_v<llvm::ELFYAML::ARMIndexTableEntry, llvm::
StringRef>, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::ARMIndexTableEntry> { static const bool flow = false; };
} }
754
755namespace llvm {
756namespace yaml {
757
758template <> struct ScalarTraits<ELFYAML::YAMLIntUInt> {
759 static void output(const ELFYAML::YAMLIntUInt &Val, void *Ctx,
760 raw_ostream &Out);
761 static StringRef input(StringRef Scalar, void *Ctx,
762 ELFYAML::YAMLIntUInt &Val);
763 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
764};
765
766template <>
767struct ScalarEnumerationTraits<ELFYAML::ELF_ET> {
768 static void enumeration(IO &IO, ELFYAML::ELF_ET &Value);
769};
770
771template <> struct ScalarEnumerationTraits<ELFYAML::ELF_PT> {
772 static void enumeration(IO &IO, ELFYAML::ELF_PT &Value);
773};
774
775template <> struct ScalarEnumerationTraits<ELFYAML::ELF_NT> {
776 static void enumeration(IO &IO, ELFYAML::ELF_NT &Value);
777};
778
779template <>
780struct ScalarEnumerationTraits<ELFYAML::ELF_EM> {
781 static void enumeration(IO &IO, ELFYAML::ELF_EM &Value);
782};
783
784template <>
785struct ScalarEnumerationTraits<ELFYAML::ELF_ELFCLASS> {
786 static void enumeration(IO &IO, ELFYAML::ELF_ELFCLASS &Value);
787};
788
789template <>
790struct ScalarEnumerationTraits<ELFYAML::ELF_ELFDATA> {
791 static void enumeration(IO &IO, ELFYAML::ELF_ELFDATA &Value);
792};
793
794template <>
795struct ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI> {
796 static void enumeration(IO &IO, ELFYAML::ELF_ELFOSABI &Value);
797};
798
799template <>
800struct ScalarBitSetTraits<ELFYAML::ELF_EF> {
801 static void bitset(IO &IO, ELFYAML::ELF_EF &Value);
802};
803
804template <> struct ScalarBitSetTraits<ELFYAML::ELF_PF> {
805 static void bitset(IO &IO, ELFYAML::ELF_PF &Value);
806};
807
808template <>
809struct ScalarEnumerationTraits<ELFYAML::ELF_SHT> {
810 static void enumeration(IO &IO, ELFYAML::ELF_SHT &Value);
811};
812
813template <>
814struct ScalarBitSetTraits<ELFYAML::ELF_SHF> {
815 static void bitset(IO &IO, ELFYAML::ELF_SHF &Value);
816};
817
818template <> struct ScalarEnumerationTraits<ELFYAML::ELF_SHN> {
819 static void enumeration(IO &IO, ELFYAML::ELF_SHN &Value);
820};
821
822template <> struct ScalarEnumerationTraits<ELFYAML::ELF_STB> {
823 static void enumeration(IO &IO, ELFYAML::ELF_STB &Value);
824};
825
826template <>
827struct ScalarEnumerationTraits<ELFYAML::ELF_STT> {
828 static void enumeration(IO &IO, ELFYAML::ELF_STT &Value);
829};
830
831template <>
832struct ScalarEnumerationTraits<ELFYAML::ELF_REL> {
833 static void enumeration(IO &IO, ELFYAML::ELF_REL &Value);
834};
835
836template <>
837struct ScalarEnumerationTraits<ELFYAML::ELF_DYNTAG> {
838 static void enumeration(IO &IO, ELFYAML::ELF_DYNTAG &Value);
839};
840
841template <>
842struct ScalarEnumerationTraits<ELFYAML::ELF_RSS> {
843 static void enumeration(IO &IO, ELFYAML::ELF_RSS &Value);
844};
845
846template <>
847struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_REG> {
848 static void enumeration(IO &IO, ELFYAML::MIPS_AFL_REG &Value);
849};
850
851template <>
852struct ScalarEnumerationTraits<ELFYAML::MIPS_ABI_FP> {
853 static void enumeration(IO &IO, ELFYAML::MIPS_ABI_FP &Value);
854};
855
856template <>
857struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_EXT> {
858 static void enumeration(IO &IO, ELFYAML::MIPS_AFL_EXT &Value);
859};
860
861template <>
862struct ScalarEnumerationTraits<ELFYAML::MIPS_ISA> {
863 static void enumeration(IO &IO, ELFYAML::MIPS_ISA &Value);
864};
865
866template <>
867struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_ASE> {
868 static void bitset(IO &IO, ELFYAML::MIPS_AFL_ASE &Value);
869};
870
871template <>
872struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_FLAGS1> {
873 static void bitset(IO &IO, ELFYAML::MIPS_AFL_FLAGS1 &Value);
874};
875
876template <>
877struct MappingTraits<ELFYAML::FileHeader> {
878 static void mapping(IO &IO, ELFYAML::FileHeader &FileHdr);
879};
880
881template <> struct MappingTraits<ELFYAML::SectionHeader> {
882 static void mapping(IO &IO, ELFYAML::SectionHeader &SHdr);
883};
884
885template <> struct MappingTraits<ELFYAML::ProgramHeader> {
886 static void mapping(IO &IO, ELFYAML::ProgramHeader &FileHdr);
887 static std::string validate(IO &IO, ELFYAML::ProgramHeader &FileHdr);
888};
889
890template <>
891struct MappingTraits<ELFYAML::Symbol> {
892 static void mapping(IO &IO, ELFYAML::Symbol &Symbol);
893 static std::string validate(IO &IO, ELFYAML::Symbol &Symbol);
894};
895
896template <> struct MappingTraits<ELFYAML::StackSizeEntry> {
897 static void mapping(IO &IO, ELFYAML::StackSizeEntry &Rel);
898};
899
900template <> struct MappingTraits<ELFYAML::BBAddrMapEntry> {
901 static void mapping(IO &IO, ELFYAML::BBAddrMapEntry &Rel);
902};
903
904template <> struct MappingTraits<ELFYAML::BBAddrMapEntry::BBEntry> {
905 static void mapping(IO &IO, ELFYAML::BBAddrMapEntry::BBEntry &Rel);
906};
907
908template <> struct MappingTraits<ELFYAML::GnuHashHeader> {
909 static void mapping(IO &IO, ELFYAML::GnuHashHeader &Rel);
910};
911
912template <> struct MappingTraits<ELFYAML::DynamicEntry> {
913 static void mapping(IO &IO, ELFYAML::DynamicEntry &Rel);
914};
915
916template <> struct MappingTraits<ELFYAML::NoteEntry> {
917 static void mapping(IO &IO, ELFYAML::NoteEntry &N);
918};
919
920template <> struct MappingTraits<ELFYAML::VerdefEntry> {
921 static void mapping(IO &IO, ELFYAML::VerdefEntry &E);
922};
923
924template <> struct MappingTraits<ELFYAML::VerneedEntry> {
925 static void mapping(IO &IO, ELFYAML::VerneedEntry &E);
926};
927
928template <> struct MappingTraits<ELFYAML::VernauxEntry> {
929 static void mapping(IO &IO, ELFYAML::VernauxEntry &E);
930};
931
932template <> struct MappingTraits<ELFYAML::LinkerOption> {
933 static void mapping(IO &IO, ELFYAML::LinkerOption &Sym);
934};
935
936template <> struct MappingTraits<ELFYAML::CallGraphEntryWeight> {
937 static void mapping(IO &IO, ELFYAML::CallGraphEntryWeight &E);
938};
939
940template <> struct MappingTraits<ELFYAML::Relocation> {
941 static void mapping(IO &IO, ELFYAML::Relocation &Rel);
942};
943
944template <> struct MappingTraits<ELFYAML::ARMIndexTableEntry> {
945 static void mapping(IO &IO, ELFYAML::ARMIndexTableEntry &E);
946};
947
948template <> struct MappingTraits<std::unique_ptr<ELFYAML::Chunk>> {
949 static void mapping(IO &IO, std::unique_ptr<ELFYAML::Chunk> &C);
950 static std::string validate(IO &io, std::unique_ptr<ELFYAML::Chunk> &C);
951};
952
953template <>
954struct MappingTraits<ELFYAML::Object> {
955 static void mapping(IO &IO, ELFYAML::Object &Object);
956};
957
958template <> struct MappingTraits<ELFYAML::SectionOrType> {
959 static void mapping(IO &IO, ELFYAML::SectionOrType &sectionOrType);
960};
961
962} // end namespace yaml
963} // end namespace llvm
964
965#endif // LLVM_OBJECTYAML_ELFYAML_H