Bug Summary

File:build/llvm-toolchain-snapshot-16~++20220904122748+c444af1c20b3/llvm/tools/obj2yaml/elf2yaml.cpp
Warning:line 1045, 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/llvm-toolchain-snapshot-16~++20220904122748+c444af1c20b3/build-llvm/tools/clang/stage2-bins -resource-dir /usr/lib/llvm-16/lib/clang/16.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I tools/obj2yaml -I /build/llvm-toolchain-snapshot-16~++20220904122748+c444af1c20b3/llvm/tools/obj2yaml -I include -I /build/llvm-toolchain-snapshot-16~++20220904122748+c444af1c20b3/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-16/lib/clang/16.0.0/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/llvm-toolchain-snapshot-16~++20220904122748+c444af1c20b3/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fmacro-prefix-map=/build/llvm-toolchain-snapshot-16~++20220904122748+c444af1c20b3/= -fcoverage-prefix-map=/build/llvm-toolchain-snapshot-16~++20220904122748+c444af1c20b3/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fcoverage-prefix-map=/build/llvm-toolchain-snapshot-16~++20220904122748+c444af1c20b3/= -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/llvm-toolchain-snapshot-16~++20220904122748+c444af1c20b3/build-llvm/tools/clang/stage2-bins -fdebug-prefix-map=/build/llvm-toolchain-snapshot-16~++20220904122748+c444af1c20b3/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fdebug-prefix-map=/build/llvm-toolchain-snapshot-16~++20220904122748+c444af1c20b3/= -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-2022-09-04-125545-48738-1 -x c++ /build/llvm-toolchain-snapshot-16~++20220904122748+c444af1c20b3/llvm/tools/obj2yaml/elf2yaml.cpp

/build/llvm-toolchain-snapshot-16~++20220904122748+c444af1c20b3/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
22using namespace llvm;
23
24namespace {
25
26template <class ELFT>
27class ELFDumper {
28 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_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;
29
30 ArrayRef<Elf_Shdr> Sections;
31 ArrayRef<Elf_Sym> SymTable;
32
33 DenseMap<StringRef, uint32_t> UsedSectionNames;
34 std::vector<std::string> SectionNames;
35 Optional<uint32_t> ShStrTabIndex;
36
37 DenseMap<StringRef, uint32_t> UsedSymbolNames;
38 std::vector<std::string> SymbolNames;
39
40 BumpPtrAllocator StringAllocator;
41
42 Expected<StringRef> getUniquedSectionName(const Elf_Shdr &Sec);
43 Expected<StringRef> getUniquedSymbolName(const Elf_Sym *Sym,
44 StringRef StrTable,
45 const Elf_Shdr *SymTab);
46 Expected<StringRef> getSymbolName(uint32_t SymtabNdx, uint32_t SymbolNdx);
47
48 const object::ELFFile<ELFT> &Obj;
49 std::unique_ptr<DWARFContext> DWARFCtx;
50
51 DenseMap<const Elf_Shdr *, ArrayRef<Elf_Word>> ShndxTables;
52
53 Expected<std::vector<ELFYAML::ProgramHeader>>
54 dumpProgramHeaders(ArrayRef<std::unique_ptr<ELFYAML::Chunk>> Sections);
55
56 Optional<DWARFYAML::Data>
57 dumpDWARFSections(std::vector<std::unique_ptr<ELFYAML::Chunk>> &Sections);
58
59 Error dumpSymbols(const Elf_Shdr *Symtab,
60 Optional<std::vector<ELFYAML::Symbol>> &Symbols);
61 Error dumpSymbol(const Elf_Sym *Sym, const Elf_Shdr *SymTab,
62 StringRef StrTable, ELFYAML::Symbol &S);
63 Expected<std::vector<std::unique_ptr<ELFYAML::Chunk>>> dumpSections();
64 Error dumpCommonSection(const Elf_Shdr *Shdr, ELFYAML::Section &S);
65 Error dumpCommonRelocationSection(const Elf_Shdr *Shdr,
66 ELFYAML::RelocationSection &S);
67 template <class RelT>
68 Error dumpRelocation(const RelT *Rel, const Elf_Shdr *SymTab,
69 ELFYAML::Relocation &R);
70
71 Expected<ELFYAML::AddrsigSection *> dumpAddrsigSection(const Elf_Shdr *Shdr);
72 Expected<ELFYAML::LinkerOptionsSection *>
73 dumpLinkerOptionsSection(const Elf_Shdr *Shdr);
74 Expected<ELFYAML::DependentLibrariesSection *>
75 dumpDependentLibrariesSection(const Elf_Shdr *Shdr);
76 Expected<ELFYAML::CallGraphProfileSection *>
77 dumpCallGraphProfileSection(const Elf_Shdr *Shdr);
78 Expected<ELFYAML::DynamicSection *> dumpDynamicSection(const Elf_Shdr *Shdr);
79 Expected<ELFYAML::RelocationSection *> dumpRelocSection(const Elf_Shdr *Shdr);
80 Expected<ELFYAML::RelrSection *> dumpRelrSection(const Elf_Shdr *Shdr);
81 Expected<ELFYAML::RawContentSection *>
82 dumpContentSection(const Elf_Shdr *Shdr);
83 Expected<ELFYAML::SymtabShndxSection *>
84 dumpSymtabShndxSection(const Elf_Shdr *Shdr);
85 Expected<ELFYAML::NoBitsSection *> dumpNoBitsSection(const Elf_Shdr *Shdr);
86 Expected<ELFYAML::HashSection *> dumpHashSection(const Elf_Shdr *Shdr);
87 Expected<ELFYAML::NoteSection *> dumpNoteSection(const Elf_Shdr *Shdr);
88 Expected<ELFYAML::GnuHashSection *> dumpGnuHashSection(const Elf_Shdr *Shdr);
89 Expected<ELFYAML::VerdefSection *> dumpVerdefSection(const Elf_Shdr *Shdr);
90 Expected<ELFYAML::SymverSection *> dumpSymverSection(const Elf_Shdr *Shdr);
91 Expected<ELFYAML::VerneedSection *> dumpVerneedSection(const Elf_Shdr *Shdr);
92 Expected<ELFYAML::GroupSection *> dumpGroupSection(const Elf_Shdr *Shdr);
93 Expected<ELFYAML::ARMIndexTableSection *>
94 dumpARMIndexTableSection(const Elf_Shdr *Shdr);
95 Expected<ELFYAML::MipsABIFlags *> dumpMipsABIFlags(const Elf_Shdr *Shdr);
96 Expected<ELFYAML::StackSizesSection *>
97 dumpStackSizesSection(const Elf_Shdr *Shdr);
98 Expected<ELFYAML::BBAddrMapSection *>
99 dumpBBAddrMapSection(const Elf_Shdr *Shdr);
100 Expected<ELFYAML::RawContentSection *>
101 dumpPlaceholderSection(const Elf_Shdr *Shdr);
102
103 bool shouldPrintSection(const ELFYAML::Section &S, const Elf_Shdr &SHdr,
104 Optional<DWARFYAML::Data> DWARF);
105
106public:
107 ELFDumper(const object::ELFFile<ELFT> &O, std::unique_ptr<DWARFContext> DCtx);
108 Expected<ELFYAML::Object *> dump();
109};
110
111}
112
113template <class ELFT>
114ELFDumper<ELFT>::ELFDumper(const object::ELFFile<ELFT> &O,
115 std::unique_ptr<DWARFContext> DCtx)
116 : Obj(O), DWARFCtx(std::move(DCtx)) {}
117
118template <class ELFT>
119Expected<StringRef>
120ELFDumper<ELFT>::getUniquedSectionName(const Elf_Shdr &Sec) {
121 unsigned SecIndex = &Sec - &Sections[0];
122 if (!SectionNames[SecIndex].empty())
123 return SectionNames[SecIndex];
124
125 auto NameOrErr = Obj.getSectionName(Sec);
126 if (!NameOrErr)
127 return NameOrErr;
128 StringRef Name = *NameOrErr;
129 // In some specific cases we might have more than one section without a
130 // name (sh_name == 0). It normally doesn't happen, but when we have this case
131 // it doesn't make sense to uniquify their names and add noise to the output.
132 if (Name.empty())
133 return "";
134
135 std::string &Ret = SectionNames[SecIndex];
136
137 auto It = UsedSectionNames.insert({Name, 0});
138 if (!It.second)
139 Ret = ELFYAML::appendUniqueSuffix(Name, Twine(++It.first->second));
140 else
141 Ret = std::string(Name);
142 return Ret;
143}
144
145template <class ELFT>
146Expected<StringRef>
147ELFDumper<ELFT>::getUniquedSymbolName(const Elf_Sym *Sym, StringRef StrTable,
148 const Elf_Shdr *SymTab) {
149 Expected<StringRef> SymbolNameOrErr = Sym->getName(StrTable);
150 if (!SymbolNameOrErr)
151 return SymbolNameOrErr;
152 StringRef Name = *SymbolNameOrErr;
153 if (Name.empty() && Sym->getType() == ELF::STT_SECTION) {
154 Expected<const Elf_Shdr *> ShdrOrErr =
155 Obj.getSection(*Sym, SymTab, ShndxTables.lookup(SymTab));
156 if (!ShdrOrErr)
157 return ShdrOrErr.takeError();
158 // The null section has no name.
159 return (*ShdrOrErr == nullptr) ? "" : getUniquedSectionName(**ShdrOrErr);
160 }
161
162 // Symbols in .symtab can have duplicate names. For example, it is a common
163 // situation for local symbols in a relocatable object. Here we assign unique
164 // suffixes for such symbols so that we can differentiate them.
165 if (SymTab->sh_type == ELF::SHT_SYMTAB) {
166 unsigned Index = Sym - SymTable.data();
167 if (!SymbolNames[Index].empty())
168 return SymbolNames[Index];
169
170 auto It = UsedSymbolNames.insert({Name, 0});
171 if (!It.second)
172 SymbolNames[Index] =
173 ELFYAML::appendUniqueSuffix(Name, Twine(++It.first->second));
174 else
175 SymbolNames[Index] = std::string(Name);
176 return SymbolNames[Index];
177 }
178
179 return Name;
180}
181
182template <class ELFT>
183bool ELFDumper<ELFT>::shouldPrintSection(const ELFYAML::Section &S,
184 const Elf_Shdr &SHdr,
185 Optional<DWARFYAML::Data> DWARF) {
186 // We only print the SHT_NULL section at index 0 when it
187 // has at least one non-null field, because yaml2obj
188 // normally creates the zero section at index 0 implicitly.
189 if (S.Type == ELF::SHT_NULL && (&SHdr == &Sections[0])) {
190 const uint8_t *Begin = reinterpret_cast<const uint8_t *>(&SHdr);
191 const uint8_t *End = Begin + sizeof(Elf_Shdr);
192 return std::any_of(Begin, End, [](uint8_t V) { return V != 0; });
193 }
194
195 // Normally we use "DWARF:" to describe contents of DWARF sections. Sometimes
196 // the content of DWARF sections can be successfully parsed into the "DWARF:"
197 // entry but their section headers may have special flags, entry size, address
198 // alignment, etc. We will preserve the header for them under such
199 // circumstances.
200 StringRef SecName = S.Name.substr(1);
201 if (DWARF && DWARF->getNonEmptySectionNames().count(SecName)) {
202 if (const ELFYAML::RawContentSection *RawSec =
203 dyn_cast<const ELFYAML::RawContentSection>(&S)) {
204 if (RawSec->Type != ELF::SHT_PROGBITS || RawSec->Link || RawSec->Info ||
205 RawSec->AddressAlign != yaml::Hex64{1} || RawSec->Address ||
206 RawSec->EntSize)
207 return true;
208
209 ELFYAML::ELF_SHF ShFlags = RawSec->Flags.value_or(ELFYAML::ELF_SHF(0));
210
211 if (SecName == "debug_str")
212 return ShFlags != ELFYAML::ELF_SHF(ELF::SHF_MERGE | ELF::SHF_STRINGS);
213
214 return ShFlags != ELFYAML::ELF_SHF{0};
215 }
216 }
217
218 // Normally we use "Symbols:" and "DynamicSymbols:" to describe contents of
219 // symbol tables. We also build and emit corresponding string tables
220 // implicitly. But sometimes it is important to preserve positions and virtual
221 // addresses of allocatable sections, e.g. for creating program headers.
222 // Generally we are trying to reduce noise in the YAML output. Because
223 // of that we do not print non-allocatable versions of such sections and
224 // assume they are placed at the end.
225 // We also dump symbol tables when the Size field is set. It happens when they
226 // are empty, which should not normally happen.
227 if (S.Type == ELF::SHT_STRTAB || S.Type == ELF::SHT_SYMTAB ||
228 S.Type == ELF::SHT_DYNSYM) {
229 return S.Size || S.Flags.value_or(ELFYAML::ELF_SHF(0)) & ELF::SHF_ALLOC;
230 }
231
232 return true;
233}
234
235template <class ELFT>
236static void dumpSectionOffsets(const typename ELFT::Ehdr &Header,
237 ArrayRef<ELFYAML::ProgramHeader> Phdrs,
238 std::vector<std::unique_ptr<ELFYAML::Chunk>> &V,
239 ArrayRef<typename ELFT::Shdr> S) {
240 if (V.empty())
241 return;
242
243 uint64_t ExpectedOffset;
244 if (Header.e_phoff > 0)
245 ExpectedOffset = Header.e_phoff + Header.e_phentsize * Header.e_phnum;
246 else
247 ExpectedOffset = sizeof(typename ELFT::Ehdr);
248
249 for (const std::unique_ptr<ELFYAML::Chunk> &C :
250 makeArrayRef(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 makeArrayRef(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.get()))
405 return false;
406
407 const ELFYAML::Section &S = cast<ELFYAML::Section>(*C.get());
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.get());
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>
513Optional<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.get(), DWARF);
533 else if (RawSec->Name == ".debug_str")
534 Err = dumpDebugStrings(*DWARFCtx.get(), DWARF);
535 else if (RawSec->Name == ".debug_ranges")
536 Err = dumpDebugRanges(*DWARFCtx.get(), DWARF);
537 else if (RawSec->Name == ".debug_addr")
538 Err = dumpDebugAddr(*DWARFCtx.get(), 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 None;
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, Optional<std::vector<ELFYAML::Symbol>> &Symbols) {
677 if (!Symtab)
678 return Error::success();
679
680 auto SymtabOrErr = Obj.symbols(Symtab);
681 if (!SymtabOrErr)
682 return SymtabOrErr.takeError();
683
684 if (SymtabOrErr->empty())
685 return Error::success();
686
687 auto StrTableOrErr = Obj.getStringTableForSymtab(*Symtab);
688 if (!StrTableOrErr)
689 return StrTableOrErr.takeError();
690
691 if (Symtab->sh_type == ELF::SHT_SYMTAB) {
692 SymTable = *SymtabOrErr;
693 SymbolNames.resize(SymTable.size());
694 }
695
696 Symbols.emplace();
697 for (const auto &Sym : (*SymtabOrErr).drop_front()) {
698 ELFYAML::Symbol S;
699 if (auto EC = dumpSymbol(&Sym, Symtab, *StrTableOrErr, S))
700 return EC;
701 Symbols->push_back(S);
702 }
703
704 return Error::success();
705}
706
707template <class ELFT>
708Error ELFDumper<ELFT>::dumpSymbol(const Elf_Sym *Sym, const Elf_Shdr *SymTab,
709 StringRef StrTable, ELFYAML::Symbol &S) {
710 S.Type = Sym->getType();
711 if (Sym->st_value)
712 S.Value = (yaml::Hex64)Sym->st_value;
713 if (Sym->st_size)
714 S.Size = (yaml::Hex64)Sym->st_size;
715 S.Other = Sym->st_other;
716 S.Binding = Sym->getBinding();
717
718 Expected<StringRef> SymbolNameOrErr =
719 getUniquedSymbolName(Sym, StrTable, SymTab);
720 if (!SymbolNameOrErr)
721 return SymbolNameOrErr.takeError();
722 S.Name = SymbolNameOrErr.get();
723
724 if (Sym->st_shndx >= ELF::SHN_LORESERVE) {
725 S.Index = (ELFYAML::ELF_SHN)Sym->st_shndx;
726 return Error::success();
727 }
728
729 auto ShdrOrErr = Obj.getSection(*Sym, SymTab, ShndxTables.lookup(SymTab));
730 if (!ShdrOrErr)
731 return ShdrOrErr.takeError();
732 const Elf_Shdr *Shdr = *ShdrOrErr;
733 if (!Shdr)
734 return Error::success();
735
736 auto NameOrErr = getUniquedSectionName(*Shdr);
737 if (!NameOrErr)
738 return NameOrErr.takeError();
739 S.Section = NameOrErr.get();
740
741 return Error::success();
742}
743
744template <class ELFT>
745template <class RelT>
746Error ELFDumper<ELFT>::dumpRelocation(const RelT *Rel, const Elf_Shdr *SymTab,
747 ELFYAML::Relocation &R) {
748 R.Type = Rel->getType(Obj.isMips64EL());
749 R.Offset = Rel->r_offset;
750 R.Addend = 0;
751
752 auto SymOrErr = Obj.getRelocationSymbol(*Rel, SymTab);
753 if (!SymOrErr)
754 return SymOrErr.takeError();
755
756 // We have might have a relocation with symbol index 0,
757 // e.g. R_X86_64_NONE or R_X86_64_GOTPC32.
758 const Elf_Sym *Sym = *SymOrErr;
759 if (!Sym)
760 return Error::success();
761
762 auto StrTabSec = Obj.getSection(SymTab->sh_link);
763 if (!StrTabSec)
764 return StrTabSec.takeError();
765 auto StrTabOrErr = Obj.getStringTable(**StrTabSec);
766 if (!StrTabOrErr)
767 return StrTabOrErr.takeError();
768
769 Expected<StringRef> NameOrErr =
770 getUniquedSymbolName(Sym, *StrTabOrErr, SymTab);
771 if (!NameOrErr)
772 return NameOrErr.takeError();
773 R.Symbol = NameOrErr.get();
774
775 return Error::success();
776}
777
778template <class ELFT>
779Error ELFDumper<ELFT>::dumpCommonSection(const Elf_Shdr *Shdr,
780 ELFYAML::Section &S) {
781 // Dump fields. We do not dump the ShOffset field. When not explicitly
782 // set, the value is set by yaml2obj automatically.
783 S.Type = Shdr->sh_type;
784 if (Shdr->sh_flags)
785 S.Flags = static_cast<ELFYAML::ELF_SHF>(Shdr->sh_flags);
786 if (Shdr->sh_addr)
787 S.Address = static_cast<uint64_t>(Shdr->sh_addr);
788 S.AddressAlign = Shdr->sh_addralign;
789
790 S.OriginalSecNdx = Shdr - &Sections[0];
791
792 Expected<StringRef> NameOrErr = getUniquedSectionName(*Shdr);
793 if (!NameOrErr)
794 return NameOrErr.takeError();
795 S.Name = NameOrErr.get();
796
797 if (Shdr->sh_entsize != ELFYAML::getDefaultShEntSize<ELFT>(
798 Obj.getHeader().e_machine, S.Type, S.Name))
799 S.EntSize = static_cast<llvm::yaml::Hex64>(Shdr->sh_entsize);
800
801 if (Shdr->sh_link != ELF::SHN_UNDEF) {
802 Expected<const Elf_Shdr *> LinkSection = Obj.getSection(Shdr->sh_link);
803 if (!LinkSection)
804 return make_error<StringError>(
805 "unable to resolve sh_link reference in section '" + S.Name +
806 "': " + toString(LinkSection.takeError()),
807 inconvertibleErrorCode());
808
809 NameOrErr = getUniquedSectionName(**LinkSection);
810 if (!NameOrErr)
811 return NameOrErr.takeError();
812 S.Link = NameOrErr.get();
813 }
814
815 return Error::success();
816}
817
818template <class ELFT>
819Error ELFDumper<ELFT>::dumpCommonRelocationSection(
820 const Elf_Shdr *Shdr, ELFYAML::RelocationSection &S) {
821 if (Error E = dumpCommonSection(Shdr, S))
822 return E;
823
824 // Having a zero sh_info field is normal: .rela.dyn is a dynamic
825 // relocation section that normally has no value in this field.
826 if (!Shdr->sh_info)
827 return Error::success();
828
829 auto InfoSection = Obj.getSection(Shdr->sh_info);
830 if (!InfoSection)
831 return InfoSection.takeError();
832
833 Expected<StringRef> NameOrErr = getUniquedSectionName(**InfoSection);
834 if (!NameOrErr)
835 return NameOrErr.takeError();
836 S.RelocatableSec = NameOrErr.get();
837
838 return Error::success();
839}
840
841template <class ELFT>
842Expected<ELFYAML::StackSizesSection *>
843ELFDumper<ELFT>::dumpStackSizesSection(const Elf_Shdr *Shdr) {
844 auto S = std::make_unique<ELFYAML::StackSizesSection>();
845 if (Error E = dumpCommonSection(Shdr, *S))
846 return std::move(E);
847
848 auto ContentOrErr = Obj.getSectionContents(*Shdr);
849 if (!ContentOrErr)
850 return ContentOrErr.takeError();
851
852 ArrayRef<uint8_t> Content = *ContentOrErr;
853 DataExtractor Data(Content, Obj.isLE(), ELFT::Is64Bits ? 8 : 4);
854
855 std::vector<ELFYAML::StackSizeEntry> Entries;
856 DataExtractor::Cursor Cur(0);
857 while (Cur && Cur.tell() < Content.size()) {
858 uint64_t Address = Data.getAddress(Cur);
859 uint64_t Size = Data.getULEB128(Cur);
860 Entries.push_back({Address, Size});
861 }
862
863 if (Content.empty() || !Cur) {
864 // If .stack_sizes cannot be decoded, we dump it as an array of bytes.
865 consumeError(Cur.takeError());
866 S->Content = yaml::BinaryRef(Content);
867 } else {
868 S->Entries = std::move(Entries);
869 }
870
871 return S.release();
872}
873
874template <class ELFT>
875Expected<ELFYAML::BBAddrMapSection *>
876ELFDumper<ELFT>::dumpBBAddrMapSection(const Elf_Shdr *Shdr) {
877 auto S = std::make_unique<ELFYAML::BBAddrMapSection>();
878 if (Error E = dumpCommonSection(Shdr, *S))
879 return std::move(E);
880
881 auto ContentOrErr = Obj.getSectionContents(*Shdr);
882 if (!ContentOrErr)
883 return ContentOrErr.takeError();
884
885 ArrayRef<uint8_t> Content = *ContentOrErr;
886 if (Content.empty())
887 return S.release();
888
889 DataExtractor Data(Content, Obj.isLE(), ELFT::Is64Bits ? 8 : 4);
890
891 std::vector<ELFYAML::BBAddrMapEntry> Entries;
892 DataExtractor::Cursor Cur(0);
893 uint8_t Version = 0;
894 uint8_t Feature = 0;
895 while (Cur && Cur.tell() < Content.size()) {
896 if (Shdr->sh_type == ELF::SHT_LLVM_BB_ADDR_MAP) {
897 Version = Data.getU8(Cur);
898 if (Cur && Version > 1)
899 return createStringError(
900 errc::invalid_argument,
901 "invalid SHT_LLVM_BB_ADDR_MAP section version: " +
902 Twine(static_cast<int>(Version)));
903 Feature = Data.getU8(Cur);
904 }
905 uint64_t Address = Data.getAddress(Cur);
906 uint64_t NumBlocks = Data.getULEB128(Cur);
907 std::vector<ELFYAML::BBAddrMapEntry::BBEntry> BBEntries;
908 // Read the specified number of BB entries, or until decoding fails.
909 for (uint64_t BlockID = 0; Cur && BlockID < NumBlocks; ++BlockID) {
910 uint64_t Offset = Data.getULEB128(Cur);
911 uint64_t Size = Data.getULEB128(Cur);
912 uint64_t Metadata = Data.getULEB128(Cur);
913 BBEntries.push_back({Offset, Size, Metadata});
914 }
915 Entries.push_back(
916 {Version, Feature, Address, /*NumBlocks=*/{}, std::move(BBEntries)});
917 }
918
919 if (!Cur) {
920 // If the section cannot be decoded, we dump it as an array of bytes.
921 consumeError(Cur.takeError());
922 S->Content = yaml::BinaryRef(Content);
923 } else {
924 S->Entries = std::move(Entries);
925 }
926
927 return S.release();
928}
929
930template <class ELFT>
931Expected<ELFYAML::AddrsigSection *>
932ELFDumper<ELFT>::dumpAddrsigSection(const Elf_Shdr *Shdr) {
933 auto S = std::make_unique<ELFYAML::AddrsigSection>();
934 if (Error E = dumpCommonSection(Shdr, *S))
935 return std::move(E);
936
937 auto ContentOrErr = Obj.getSectionContents(*Shdr);
938 if (!ContentOrErr)
939 return ContentOrErr.takeError();
940
941 ArrayRef<uint8_t> Content = *ContentOrErr;
942 DataExtractor::Cursor Cur(0);
943 DataExtractor Data(Content, Obj.isLE(), /*AddressSize=*/0);
944 std::vector<ELFYAML::YAMLFlowString> Symbols;
945 while (Cur && Cur.tell() < Content.size()) {
946 uint64_t SymNdx = Data.getULEB128(Cur);
947 if (!Cur)
948 break;
949
950 Expected<StringRef> SymbolName = getSymbolName(Shdr->sh_link, SymNdx);
951 if (!SymbolName || SymbolName->empty()) {
952 consumeError(SymbolName.takeError());
953 Symbols.emplace_back(
954 StringRef(std::to_string(SymNdx)).copy(StringAllocator));
955 continue;
956 }
957
958 Symbols.emplace_back(*SymbolName);
959 }
960
961 if (Cur) {
962 S->Symbols = std::move(Symbols);
963 return S.release();
964 }
965
966 consumeError(Cur.takeError());
967 S->Content = yaml::BinaryRef(Content);
968 return S.release();
969}
970
971template <class ELFT>
972Expected<ELFYAML::LinkerOptionsSection *>
973ELFDumper<ELFT>::dumpLinkerOptionsSection(const Elf_Shdr *Shdr) {
974 auto S = std::make_unique<ELFYAML::LinkerOptionsSection>();
975 if (Error E = dumpCommonSection(Shdr, *S))
976 return std::move(E);
977
978 auto ContentOrErr = Obj.getSectionContents(*Shdr);
979 if (!ContentOrErr)
980 return ContentOrErr.takeError();
981
982 ArrayRef<uint8_t> Content = *ContentOrErr;
983 if (Content.empty() || Content.back() != 0) {
984 S->Content = Content;
985 return S.release();
986 }
987
988 SmallVector<StringRef, 16> Strings;
989 toStringRef(Content.drop_back()).split(Strings, '\0');
990 if (Strings.size() % 2 != 0) {
991 S->Content = Content;
992 return S.release();
993 }
994
995 S->Options.emplace();
996 for (size_t I = 0, E = Strings.size(); I != E; I += 2)
997 S->Options->push_back({Strings[I], Strings[I + 1]});
998
999 return S.release();
1000}
1001
1002template <class ELFT>
1003Expected<ELFYAML::DependentLibrariesSection *>
1004ELFDumper<ELFT>::dumpDependentLibrariesSection(const Elf_Shdr *Shdr) {
1005 auto DL = std::make_unique<ELFYAML::DependentLibrariesSection>();
1006 if (Error E = dumpCommonSection(Shdr, *DL))
1007 return std::move(E);
1008
1009 Expected<ArrayRef<uint8_t>> ContentOrErr = Obj.getSectionContents(*Shdr);
1010 if (!ContentOrErr)
1011 return ContentOrErr.takeError();
1012
1013 ArrayRef<uint8_t> Content = *ContentOrErr;
1014 if (!Content.empty() && Content.back() != 0) {
1015 DL->Content = Content;
1016 return DL.release();
1017 }
1018
1019 DL->Libs.emplace();
1020 for (const uint8_t *I = Content.begin(), *E = Content.end(); I < E;) {
1021 StringRef Lib((const char *)I);
1022 DL->Libs->emplace_back(Lib);
1023 I += Lib.size() + 1;
1024 }
1025
1026 return DL.release();
1027}
1028
1029template <class ELFT>
1030Expected<ELFYAML::CallGraphProfileSection *>
1031ELFDumper<ELFT>::dumpCallGraphProfileSection(const Elf_Shdr *Shdr) {
1032 auto S = std::make_unique<ELFYAML::CallGraphProfileSection>();
1033 if (Error E = dumpCommonSection(Shdr, *S))
2
Assuming the condition is false
3
Taking false branch
1034 return std::move(E);
1035
1036 Expected<ArrayRef<uint8_t>> ContentOrErr = Obj.getSectionContents(*Shdr);
1037 if (!ContentOrErr)
4
Taking false branch
1038 return ContentOrErr.takeError();
1039 ArrayRef<uint8_t> Content = *ContentOrErr;
1040 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
1041 Obj.getHeader().e_machine, S->Type, S->Name);
1042 // Dump the section by using the Content key when it is truncated.
1043 // There is no need to create either "Content" or "Entries" fields when the
1044 // section is empty.
1045 if (Content.empty() || Content.size() % SizeOfEntry != 0) {
14
Assuming the condition is false
15
Division by zero
1046 if (!Content.empty())
1047 S->Content = yaml::BinaryRef(Content);
1048 return S.release();
1049 }
1050
1051 std::vector<ELFYAML::CallGraphEntryWeight> Entries(Content.size() /
1052 SizeOfEntry);
1053 DataExtractor Data(Content, Obj.isLE(), /*AddressSize=*/0);
1054 DataExtractor::Cursor Cur(0);
1055 auto ReadEntry = [&](ELFYAML::CallGraphEntryWeight &E) {
1056 E.Weight = Data.getU64(Cur);
1057 if (!Cur) {
1058 consumeError(Cur.takeError());
1059 return false;
1060 }
1061 return true;
1062 };
1063
1064 for (ELFYAML::CallGraphEntryWeight &E : Entries) {
1065 if (ReadEntry(E))
1066 continue;
1067 S->Content = yaml::BinaryRef(Content);
1068 return S.release();
1069 }
1070
1071 S->Entries = std::move(Entries);
1072 return S.release();
1073}
1074
1075template <class ELFT>
1076Expected<ELFYAML::DynamicSection *>
1077ELFDumper<ELFT>::dumpDynamicSection(const Elf_Shdr *Shdr) {
1078 auto S = std::make_unique<ELFYAML::DynamicSection>();
1079 if (Error E = dumpCommonSection(Shdr, *S))
1080 return std::move(E);
1081
1082 auto DynTagsOrErr = Obj.template getSectionContentsAsArray<Elf_Dyn>(*Shdr);
1083 if (!DynTagsOrErr)
1084 return DynTagsOrErr.takeError();
1085
1086 S->Entries.emplace();
1087 for (const Elf_Dyn &Dyn : *DynTagsOrErr)
1088 S->Entries->push_back({(ELFYAML::ELF_DYNTAG)Dyn.getTag(), Dyn.getVal()});
1089
1090 return S.release();
1091}
1092
1093template <class ELFT>
1094Expected<ELFYAML::RelocationSection *>
1095ELFDumper<ELFT>::dumpRelocSection(const Elf_Shdr *Shdr) {
1096 auto S = std::make_unique<ELFYAML::RelocationSection>();
1097 if (auto E = dumpCommonRelocationSection(Shdr, *S))
1098 return std::move(E);
1099
1100 auto SymTabOrErr = Obj.getSection(Shdr->sh_link);
1101 if (!SymTabOrErr)
1102 return SymTabOrErr.takeError();
1103
1104 if (Shdr->sh_size != 0)
1105 S->Relocations.emplace();
1106
1107 if (Shdr->sh_type == ELF::SHT_REL) {
1108 auto Rels = Obj.rels(*Shdr);
1109 if (!Rels)
1110 return Rels.takeError();
1111 for (const Elf_Rel &Rel : *Rels) {
1112 ELFYAML::Relocation R;
1113 if (Error E = dumpRelocation(&Rel, *SymTabOrErr, R))
1114 return std::move(E);
1115 S->Relocations->push_back(R);
1116 }
1117 } else {
1118 auto Rels = Obj.relas(*Shdr);
1119 if (!Rels)
1120 return Rels.takeError();
1121 for (const Elf_Rela &Rel : *Rels) {
1122 ELFYAML::Relocation R;
1123 if (Error E = dumpRelocation(&Rel, *SymTabOrErr, R))
1124 return std::move(E);
1125 R.Addend = Rel.r_addend;
1126 S->Relocations->push_back(R);
1127 }
1128 }
1129
1130 return S.release();
1131}
1132
1133template <class ELFT>
1134Expected<ELFYAML::RelrSection *>
1135ELFDumper<ELFT>::dumpRelrSection(const Elf_Shdr *Shdr) {
1136 auto S = std::make_unique<ELFYAML::RelrSection>();
1137 if (auto E = dumpCommonSection(Shdr, *S))
1138 return std::move(E);
1139
1140 if (Expected<ArrayRef<Elf_Relr>> Relrs = Obj.relrs(*Shdr)) {
1141 S->Entries.emplace();
1142 for (Elf_Relr Rel : *Relrs)
1143 S->Entries->emplace_back(Rel);
1144 return S.release();
1145 } else {
1146 // Ignore. We are going to dump the data as raw content below.
1147 consumeError(Relrs.takeError());
1148 }
1149
1150 Expected<ArrayRef<uint8_t>> ContentOrErr = Obj.getSectionContents(*Shdr);
1151 if (!ContentOrErr)
1152 return ContentOrErr.takeError();
1153 S->Content = *ContentOrErr;
1154 return S.release();
1155}
1156
1157template <class ELFT>
1158Expected<ELFYAML::RawContentSection *>
1159ELFDumper<ELFT>::dumpContentSection(const Elf_Shdr *Shdr) {
1160 auto S = std::make_unique<ELFYAML::RawContentSection>();
1161 if (Error E = dumpCommonSection(Shdr, *S))
1162 return std::move(E);
1163
1164 unsigned SecIndex = Shdr - &Sections[0];
1165 if (SecIndex != 0 || Shdr->sh_type != ELF::SHT_NULL) {
1166 auto ContentOrErr = Obj.getSectionContents(*Shdr);
1167 if (!ContentOrErr)
1168 return ContentOrErr.takeError();
1169 ArrayRef<uint8_t> Content = *ContentOrErr;
1170 if (!Content.empty())
1171 S->Content = yaml::BinaryRef(Content);
1172 } else {
1173 S->Size = static_cast<llvm::yaml::Hex64>(Shdr->sh_size);
1174 }
1175
1176 if (Shdr->sh_info)
1177 S->Info = static_cast<llvm::yaml::Hex64>(Shdr->sh_info);
1178 return S.release();
1179}
1180
1181template <class ELFT>
1182Expected<ELFYAML::SymtabShndxSection *>
1183ELFDumper<ELFT>::dumpSymtabShndxSection(const Elf_Shdr *Shdr) {
1184 auto S = std::make_unique<ELFYAML::SymtabShndxSection>();
1185 if (Error E = dumpCommonSection(Shdr, *S))
1186 return std::move(E);
1187
1188 auto EntriesOrErr = Obj.template getSectionContentsAsArray<Elf_Word>(*Shdr);
1189 if (!EntriesOrErr)
1190 return EntriesOrErr.takeError();
1191
1192 S->Entries.emplace();
1193 for (const Elf_Word &E : *EntriesOrErr)
1194 S->Entries->push_back(E);
1195 return S.release();
1196}
1197
1198template <class ELFT>
1199Expected<ELFYAML::NoBitsSection *>
1200ELFDumper<ELFT>::dumpNoBitsSection(const Elf_Shdr *Shdr) {
1201 auto S = std::make_unique<ELFYAML::NoBitsSection>();
1202 if (Error E = dumpCommonSection(Shdr, *S))
1203 return std::move(E);
1204 if (Shdr->sh_size)
1205 S->Size = static_cast<llvm::yaml::Hex64>(Shdr->sh_size);
1206 return S.release();
1207}
1208
1209template <class ELFT>
1210Expected<ELFYAML::NoteSection *>
1211ELFDumper<ELFT>::dumpNoteSection(const Elf_Shdr *Shdr) {
1212 auto S = std::make_unique<ELFYAML::NoteSection>();
1213 if (Error E = dumpCommonSection(Shdr, *S))
1214 return std::move(E);
1215
1216 auto ContentOrErr = Obj.getSectionContents(*Shdr);
1217 if (!ContentOrErr)
1218 return ContentOrErr.takeError();
1219
1220 std::vector<ELFYAML::NoteEntry> Entries;
1221 ArrayRef<uint8_t> Content = *ContentOrErr;
1222 while (!Content.empty()) {
1223 if (Content.size() < sizeof(Elf_Nhdr)) {
1224 S->Content = yaml::BinaryRef(*ContentOrErr);
1225 return S.release();
1226 }
1227
1228 const Elf_Nhdr *Header = reinterpret_cast<const Elf_Nhdr *>(Content.data());
1229 if (Content.size() < Header->getSize()) {
1230 S->Content = yaml::BinaryRef(*ContentOrErr);
1231 return S.release();
1232 }
1233
1234 Elf_Note Note(*Header);
1235 Entries.push_back(
1236 {Note.getName(), Note.getDesc(), (ELFYAML::ELF_NT)Note.getType()});
1237
1238 Content = Content.drop_front(Header->getSize());
1239 }
1240
1241 S->Notes = std::move(Entries);
1242 return S.release();
1243}
1244
1245template <class ELFT>
1246Expected<ELFYAML::HashSection *>
1247ELFDumper<ELFT>::dumpHashSection(const Elf_Shdr *Shdr) {
1248 auto S = std::make_unique<ELFYAML::HashSection>();
1249 if (Error E = dumpCommonSection(Shdr, *S))
1250 return std::move(E);
1251
1252 auto ContentOrErr = Obj.getSectionContents(*Shdr);
1253 if (!ContentOrErr)
1254 return ContentOrErr.takeError();
1255
1256 ArrayRef<uint8_t> Content = *ContentOrErr;
1257 if (Content.size() % 4 != 0 || Content.size() < 8) {
1258 S->Content = yaml::BinaryRef(Content);
1259 return S.release();
1260 }
1261
1262 DataExtractor::Cursor Cur(0);
1263 DataExtractor Data(Content, Obj.isLE(), /*AddressSize=*/0);
1264 uint64_t NBucket = Data.getU32(Cur);
1265 uint64_t NChain = Data.getU32(Cur);
1266 if (Content.size() != (2 + NBucket + NChain) * 4) {
1267 S->Content = yaml::BinaryRef(Content);
1268 if (Cur)
1269 return S.release();
1270 llvm_unreachable("entries were not read correctly")::llvm::llvm_unreachable_internal("entries were not read correctly"
, "llvm/tools/obj2yaml/elf2yaml.cpp", 1270)
;
1271 }
1272
1273 S->Bucket.emplace(NBucket);
1274 for (uint32_t &V : *S->Bucket)
1275 V = Data.getU32(Cur);
1276
1277 S->Chain.emplace(NChain);
1278 for (uint32_t &V : *S->Chain)
1279 V = Data.getU32(Cur);
1280
1281 if (Cur)
1282 return S.release();
1283 llvm_unreachable("entries were not read correctly")::llvm::llvm_unreachable_internal("entries were not read correctly"
, "llvm/tools/obj2yaml/elf2yaml.cpp", 1283)
;
1284}
1285
1286template <class ELFT>
1287Expected<ELFYAML::GnuHashSection *>
1288ELFDumper<ELFT>::dumpGnuHashSection(const Elf_Shdr *Shdr) {
1289 auto S = std::make_unique<ELFYAML::GnuHashSection>();
1290 if (Error E = dumpCommonSection(Shdr, *S))
1291 return std::move(E);
1292
1293 auto ContentOrErr = Obj.getSectionContents(*Shdr);
1294 if (!ContentOrErr)
1295 return ContentOrErr.takeError();
1296
1297 unsigned AddrSize = ELFT::Is64Bits ? 8 : 4;
1298 ArrayRef<uint8_t> Content = *ContentOrErr;
1299 DataExtractor Data(Content, Obj.isLE(), AddrSize);
1300
1301 ELFYAML::GnuHashHeader Header;
1302 DataExtractor::Cursor Cur(0);
1303 uint64_t NBuckets = Data.getU32(Cur);
1304 Header.SymNdx = Data.getU32(Cur);
1305 uint64_t MaskWords = Data.getU32(Cur);
1306 Header.Shift2 = Data.getU32(Cur);
1307
1308 // Set just the raw binary content if we were unable to read the header
1309 // or when the section data is truncated or malformed.
1310 uint64_t Size = Data.getData().size() - Cur.tell();
1311 if (!Cur || (Size < MaskWords * AddrSize + NBuckets * 4) ||
1312 (Size % 4 != 0)) {
1313 consumeError(Cur.takeError());
1314 S->Content = yaml::BinaryRef(Content);
1315 return S.release();
1316 }
1317
1318 S->Header = Header;
1319
1320 S->BloomFilter.emplace(MaskWords);
1321 for (llvm::yaml::Hex64 &Val : *S->BloomFilter)
1322 Val = Data.getAddress(Cur);
1323
1324 S->HashBuckets.emplace(NBuckets);
1325 for (llvm::yaml::Hex32 &Val : *S->HashBuckets)
1326 Val = Data.getU32(Cur);
1327
1328 S->HashValues.emplace((Data.getData().size() - Cur.tell()) / 4);
1329 for (llvm::yaml::Hex32 &Val : *S->HashValues)
1330 Val = Data.getU32(Cur);
1331
1332 if (Cur)
1333 return S.release();
1334 llvm_unreachable("GnuHashSection was not read correctly")::llvm::llvm_unreachable_internal("GnuHashSection was not read correctly"
, "llvm/tools/obj2yaml/elf2yaml.cpp", 1334)
;
1335}
1336
1337template <class ELFT>
1338Expected<ELFYAML::VerdefSection *>
1339ELFDumper<ELFT>::dumpVerdefSection(const Elf_Shdr *Shdr) {
1340 auto S = std::make_unique<ELFYAML::VerdefSection>();
1341 if (Error E = dumpCommonSection(Shdr, *S))
1342 return std::move(E);
1343
1344 auto StringTableShdrOrErr = Obj.getSection(Shdr->sh_link);
1345 if (!StringTableShdrOrErr)
1346 return StringTableShdrOrErr.takeError();
1347
1348 auto StringTableOrErr = Obj.getStringTable(**StringTableShdrOrErr);
1349 if (!StringTableOrErr)
1350 return StringTableOrErr.takeError();
1351
1352 auto Contents = Obj.getSectionContents(*Shdr);
1353 if (!Contents)
1354 return Contents.takeError();
1355
1356 S->Entries.emplace();
1357
1358 llvm::ArrayRef<uint8_t> Data = *Contents;
1359 const uint8_t *Buf = Data.data();
1360 while (Buf) {
1361 const Elf_Verdef *Verdef = reinterpret_cast<const Elf_Verdef *>(Buf);
1362 ELFYAML::VerdefEntry Entry;
1363 if (Verdef->vd_version != 1)
1364 return createStringError(errc::invalid_argument,
1365 "invalid SHT_GNU_verdef section version: " +
1366 Twine(Verdef->vd_version));
1367
1368 if (Verdef->vd_flags != 0)
1369 Entry.Flags = Verdef->vd_flags;
1370
1371 if (Verdef->vd_ndx != 0)
1372 Entry.VersionNdx = Verdef->vd_ndx;
1373
1374 if (Verdef->vd_hash != 0)
1375 Entry.Hash = Verdef->vd_hash;
1376
1377 const uint8_t *BufAux = Buf + Verdef->vd_aux;
1378 while (BufAux) {
1379 const Elf_Verdaux *Verdaux =
1380 reinterpret_cast<const Elf_Verdaux *>(BufAux);
1381 Entry.VerNames.push_back(
1382 StringTableOrErr->drop_front(Verdaux->vda_name).data());
1383 BufAux = Verdaux->vda_next ? BufAux + Verdaux->vda_next : nullptr;
1384 }
1385
1386 S->Entries->push_back(Entry);
1387 Buf = Verdef->vd_next ? Buf + Verdef->vd_next : nullptr;
1388 }
1389
1390 if (Shdr->sh_info != S->Entries->size())
1391 S->Info = (llvm::yaml::Hex64)Shdr->sh_info;
1392
1393 return S.release();
1394}
1395
1396template <class ELFT>
1397Expected<ELFYAML::SymverSection *>
1398ELFDumper<ELFT>::dumpSymverSection(const Elf_Shdr *Shdr) {
1399 auto S = std::make_unique<ELFYAML::SymverSection>();
1400 if (Error E = dumpCommonSection(Shdr, *S))
1401 return std::move(E);
1402
1403 auto VersionsOrErr = Obj.template getSectionContentsAsArray<Elf_Half>(*Shdr);
1404 if (!VersionsOrErr)
1405 return VersionsOrErr.takeError();
1406
1407 S->Entries.emplace();
1408 for (const Elf_Half &E : *VersionsOrErr)
1409 S->Entries->push_back(E);
1410
1411 return S.release();
1412}
1413
1414template <class ELFT>
1415Expected<ELFYAML::VerneedSection *>
1416ELFDumper<ELFT>::dumpVerneedSection(const Elf_Shdr *Shdr) {
1417 auto S = std::make_unique<ELFYAML::VerneedSection>();
1418 if (Error E = dumpCommonSection(Shdr, *S))
1419 return std::move(E);
1420
1421 auto Contents = Obj.getSectionContents(*Shdr);
1422 if (!Contents)
1423 return Contents.takeError();
1424
1425 auto StringTableShdrOrErr = Obj.getSection(Shdr->sh_link);
1426 if (!StringTableShdrOrErr)
1427 return StringTableShdrOrErr.takeError();
1428
1429 auto StringTableOrErr = Obj.getStringTable(**StringTableShdrOrErr);
1430 if (!StringTableOrErr)
1431 return StringTableOrErr.takeError();
1432
1433 S->VerneedV.emplace();
1434
1435 llvm::ArrayRef<uint8_t> Data = *Contents;
1436 const uint8_t *Buf = Data.data();
1437 while (Buf) {
1438 const Elf_Verneed *Verneed = reinterpret_cast<const Elf_Verneed *>(Buf);
1439
1440 ELFYAML::VerneedEntry Entry;
1441 Entry.Version = Verneed->vn_version;
1442 Entry.File =
1443 StringRef(StringTableOrErr->drop_front(Verneed->vn_file).data());
1444
1445 const uint8_t *BufAux = Buf + Verneed->vn_aux;
1446 while (BufAux) {
1447 const Elf_Vernaux *Vernaux =
1448 reinterpret_cast<const Elf_Vernaux *>(BufAux);
1449
1450 ELFYAML::VernauxEntry Aux;
1451 Aux.Hash = Vernaux->vna_hash;
1452 Aux.Flags = Vernaux->vna_flags;
1453 Aux.Other = Vernaux->vna_other;
1454 Aux.Name =
1455 StringRef(StringTableOrErr->drop_front(Vernaux->vna_name).data());
1456
1457 Entry.AuxV.push_back(Aux);
1458 BufAux = Vernaux->vna_next ? BufAux + Vernaux->vna_next : nullptr;
1459 }
1460
1461 S->VerneedV->push_back(Entry);
1462 Buf = Verneed->vn_next ? Buf + Verneed->vn_next : nullptr;
1463 }
1464
1465 if (Shdr->sh_info != S->VerneedV->size())
1466 S->Info = (llvm::yaml::Hex64)Shdr->sh_info;
1467
1468 return S.release();
1469}
1470
1471template <class ELFT>
1472Expected<StringRef> ELFDumper<ELFT>::getSymbolName(uint32_t SymtabNdx,
1473 uint32_t SymbolNdx) {
1474 auto SymtabOrErr = Obj.getSection(SymtabNdx);
1475 if (!SymtabOrErr)
1476 return SymtabOrErr.takeError();
1477
1478 const Elf_Shdr *Symtab = *SymtabOrErr;
1479 auto SymOrErr = Obj.getSymbol(Symtab, SymbolNdx);
1480 if (!SymOrErr)
1481 return SymOrErr.takeError();
1482
1483 auto StrTabOrErr = Obj.getStringTableForSymtab(*Symtab);
1484 if (!StrTabOrErr)
1485 return StrTabOrErr.takeError();
1486 return getUniquedSymbolName(*SymOrErr, *StrTabOrErr, Symtab);
1487}
1488
1489template <class ELFT>
1490Expected<ELFYAML::GroupSection *>
1491ELFDumper<ELFT>::dumpGroupSection(const Elf_Shdr *Shdr) {
1492 auto S = std::make_unique<ELFYAML::GroupSection>();
1493 if (Error E = dumpCommonSection(Shdr, *S))
1494 return std::move(E);
1495
1496 // Get symbol with index sh_info. This symbol's name is the signature of the group.
1497 Expected<StringRef> SymbolName = getSymbolName(Shdr->sh_link, Shdr->sh_info);
1498 if (!SymbolName)
1499 return SymbolName.takeError();
1500 S->Signature = *SymbolName;
1501
1502 auto MembersOrErr = Obj.template getSectionContentsAsArray<Elf_Word>(*Shdr);
1503 if (!MembersOrErr)
1504 return MembersOrErr.takeError();
1505
1506 S->Members.emplace();
1507 for (Elf_Word Member : *MembersOrErr) {
1508 if (Member == llvm::ELF::GRP_COMDAT) {
1509 S->Members->push_back({"GRP_COMDAT"});
1510 continue;
1511 }
1512
1513 Expected<const Elf_Shdr *> SHdrOrErr = Obj.getSection(Member);
1514 if (!SHdrOrErr)
1515 return SHdrOrErr.takeError();
1516 Expected<StringRef> NameOrErr = getUniquedSectionName(**SHdrOrErr);
1517 if (!NameOrErr)
1518 return NameOrErr.takeError();
1519 S->Members->push_back({*NameOrErr});
1520 }
1521 return S.release();
1522}
1523
1524template <class ELFT>
1525Expected<ELFYAML::ARMIndexTableSection *>
1526ELFDumper<ELFT>::dumpARMIndexTableSection(const Elf_Shdr *Shdr) {
1527 auto S = std::make_unique<ELFYAML::ARMIndexTableSection>();
1528 if (Error E = dumpCommonSection(Shdr, *S))
1529 return std::move(E);
1530
1531 Expected<ArrayRef<uint8_t>> ContentOrErr = Obj.getSectionContents(*Shdr);
1532 if (!ContentOrErr)
1533 return ContentOrErr.takeError();
1534
1535 if (ContentOrErr->size() % (sizeof(Elf_Word) * 2) != 0) {
1536 S->Content = yaml::BinaryRef(*ContentOrErr);
1537 return S.release();
1538 }
1539
1540 ArrayRef<Elf_Word> Words(
1541 reinterpret_cast<const Elf_Word *>(ContentOrErr->data()),
1542 ContentOrErr->size() / sizeof(Elf_Word));
1543
1544 S->Entries.emplace();
1545 for (size_t I = 0, E = Words.size(); I != E; I += 2)
1546 S->Entries->push_back({(yaml::Hex32)Words[I], (yaml::Hex32)Words[I + 1]});
1547
1548 return S.release();
1549}
1550
1551template <class ELFT>
1552Expected<ELFYAML::MipsABIFlags *>
1553ELFDumper<ELFT>::dumpMipsABIFlags(const Elf_Shdr *Shdr) {
1554 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", 1555, __extension__ __PRETTY_FUNCTION__
))
1555 "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", 1555, __extension__ __PRETTY_FUNCTION__
))
;
1556 auto S = std::make_unique<ELFYAML::MipsABIFlags>();
1557 if (Error E = dumpCommonSection(Shdr, *S))
1558 return std::move(E);
1559
1560 auto ContentOrErr = Obj.getSectionContents(*Shdr);
1561 if (!ContentOrErr)
1562 return ContentOrErr.takeError();
1563
1564 auto *Flags = reinterpret_cast<const object::Elf_Mips_ABIFlags<ELFT> *>(
1565 ContentOrErr.get().data());
1566 S->Version = Flags->version;
1567 S->ISALevel = Flags->isa_level;
1568 S->ISARevision = Flags->isa_rev;
1569 S->GPRSize = Flags->gpr_size;
1570 S->CPR1Size = Flags->cpr1_size;
1571 S->CPR2Size = Flags->cpr2_size;
1572 S->FpABI = Flags->fp_abi;
1573 S->ISAExtension = Flags->isa_ext;
1574 S->ASEs = Flags->ases;
1575 S->Flags1 = Flags->flags1;
1576 S->Flags2 = Flags->flags2;
1577 return S.release();
1578}
1579
1580template <class ELFT>
1581static Error elf2yaml(raw_ostream &Out, const object::ELFFile<ELFT> &Obj,
1582 std::unique_ptr<DWARFContext> DWARFCtx) {
1583 ELFDumper<ELFT> Dumper(Obj, std::move(DWARFCtx));
1584 Expected<ELFYAML::Object *> YAMLOrErr = Dumper.dump();
1585 if (!YAMLOrErr)
1586 return YAMLOrErr.takeError();
1587
1588 std::unique_ptr<ELFYAML::Object> YAML(YAMLOrErr.get());
1589 yaml::Output Yout(Out);
1590 Yout << *YAML;
1591
1592 return Error::success();
1593}
1594
1595Error elf2yaml(raw_ostream &Out, const object::ObjectFile &Obj) {
1596 std::unique_ptr<DWARFContext> DWARFCtx = DWARFContext::create(Obj);
1597 if (const auto *ELFObj = dyn_cast<object::ELF32LEObjectFile>(&Obj))
1598 return elf2yaml(Out, ELFObj->getELFFile(), std::move(DWARFCtx));
1599
1600 if (const auto *ELFObj = dyn_cast<object::ELF32BEObjectFile>(&Obj))
1601 return elf2yaml(Out, ELFObj->getELFFile(), std::move(DWARFCtx));
1602
1603 if (const auto *ELFObj = dyn_cast<object::ELF64LEObjectFile>(&Obj))
1604 return elf2yaml(Out, ELFObj->getELFFile(), std::move(DWARFCtx));
1605
1606 if (const auto *ELFObj = dyn_cast<object::ELF64BEObjectFile>(&Obj))
1607 return elf2yaml(Out, ELFObj->getELFFile(), std::move(DWARFCtx));
1608
1609 llvm_unreachable("unknown ELF file format")::llvm::llvm_unreachable_internal("unknown ELF file format", "llvm/tools/obj2yaml/elf2yaml.cpp"
, 1609)
;
1610}

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