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 "Error.h" 10 #include "llvm/ADT/DenseSet.h" 11 #include "llvm/ADT/STLExtras.h" 12 #include "llvm/Object/ELFObjectFile.h" 13 #include "llvm/ObjectYAML/ELFYAML.h" 14 #include "llvm/Support/DataExtractor.h" 15 #include "llvm/Support/ErrorHandling.h" 16 #include "llvm/Support/YAMLTraits.h" 17 18 using namespace llvm; 19 20 namespace { 21 22 template <class ELFT> 23 class ELFDumper { 24 typedef object::Elf_Sym_Impl<ELFT> Elf_Sym; 25 typedef typename ELFT::Dyn Elf_Dyn; 26 typedef typename ELFT::Shdr Elf_Shdr; 27 typedef typename ELFT::Word Elf_Word; 28 typedef typename ELFT::Rel Elf_Rel; 29 typedef typename ELFT::Rela Elf_Rela; 30 using Elf_Relr = typename ELFT::Relr; 31 using Elf_Nhdr = typename ELFT::Nhdr; 32 using Elf_Note = typename ELFT::Note; 33 34 ArrayRef<Elf_Shdr> Sections; 35 ArrayRef<Elf_Sym> SymTable; 36 37 DenseMap<StringRef, uint32_t> UsedSectionNames; 38 std::vector<std::string> SectionNames; 39 40 DenseMap<StringRef, uint32_t> UsedSymbolNames; 41 std::vector<std::string> SymbolNames; 42 43 BumpPtrAllocator StringAllocator; 44 45 Expected<StringRef> getUniquedSectionName(const Elf_Shdr *Sec); 46 Expected<StringRef> getUniquedSymbolName(const Elf_Sym *Sym, 47 StringRef StrTable, 48 const Elf_Shdr *SymTab); 49 Expected<StringRef> getSymbolName(uint32_t SymtabNdx, uint32_t SymbolNdx); 50 51 const object::ELFFile<ELFT> &Obj; 52 ArrayRef<Elf_Word> ShndxTable; 53 54 Expected<std::vector<ELFYAML::ProgramHeader>> 55 dumpProgramHeaders(ArrayRef<std::unique_ptr<ELFYAML::Chunk>> Sections); 56 57 Error dumpSymbols(const Elf_Shdr *Symtab, 58 std::vector<ELFYAML::Symbol> &Symbols); 59 Error dumpSymbol(const Elf_Sym *Sym, const Elf_Shdr *SymTab, 60 StringRef StrTable, ELFYAML::Symbol &S); 61 Expected<std::vector<std::unique_ptr<ELFYAML::Chunk>>> dumpSections(); 62 Error dumpCommonSection(const Elf_Shdr *Shdr, ELFYAML::Section &S); 63 Error dumpCommonRelocationSection(const Elf_Shdr *Shdr, 64 ELFYAML::RelocationSection &S); 65 template <class RelT> 66 Error dumpRelocation(const RelT *Rel, const Elf_Shdr *SymTab, 67 ELFYAML::Relocation &R); 68 69 Expected<ELFYAML::AddrsigSection *> dumpAddrsigSection(const Elf_Shdr *Shdr); 70 Expected<ELFYAML::LinkerOptionsSection *> 71 dumpLinkerOptionsSection(const Elf_Shdr *Shdr); 72 Expected<ELFYAML::DependentLibrariesSection *> 73 dumpDependentLibrariesSection(const Elf_Shdr *Shdr); 74 Expected<ELFYAML::CallGraphProfileSection *> 75 dumpCallGraphProfileSection(const Elf_Shdr *Shdr); 76 Expected<ELFYAML::DynamicSection *> dumpDynamicSection(const Elf_Shdr *Shdr); 77 Expected<ELFYAML::RelocationSection *> dumpRelocSection(const Elf_Shdr *Shdr); 78 Expected<ELFYAML::RelrSection *> dumpRelrSection(const Elf_Shdr *Shdr); 79 Expected<ELFYAML::RawContentSection *> 80 dumpContentSection(const Elf_Shdr *Shdr); 81 Expected<ELFYAML::SymtabShndxSection *> 82 dumpSymtabShndxSection(const Elf_Shdr *Shdr); 83 Expected<ELFYAML::NoBitsSection *> dumpNoBitsSection(const Elf_Shdr *Shdr); 84 Expected<ELFYAML::HashSection *> dumpHashSection(const Elf_Shdr *Shdr); 85 Expected<ELFYAML::NoteSection *> dumpNoteSection(const Elf_Shdr *Shdr); 86 Expected<ELFYAML::GnuHashSection *> dumpGnuHashSection(const Elf_Shdr *Shdr); 87 Expected<ELFYAML::VerdefSection *> dumpVerdefSection(const Elf_Shdr *Shdr); 88 Expected<ELFYAML::SymverSection *> dumpSymverSection(const Elf_Shdr *Shdr); 89 Expected<ELFYAML::VerneedSection *> dumpVerneedSection(const Elf_Shdr *Shdr); 90 Expected<ELFYAML::Group *> dumpGroup(const Elf_Shdr *Shdr); 91 Expected<ELFYAML::MipsABIFlags *> dumpMipsABIFlags(const Elf_Shdr *Shdr); 92 Expected<ELFYAML::StackSizesSection *> 93 dumpStackSizesSection(const Elf_Shdr *Shdr); 94 Expected<ELFYAML::RawContentSection *> 95 dumpPlaceholderSection(const Elf_Shdr *Shdr); 96 97 bool shouldPrintSection(const ELFYAML::Section &S, const Elf_Shdr &SHdr); 98 99 public: 100 ELFDumper(const object::ELFFile<ELFT> &O); 101 Expected<ELFYAML::Object *> dump(); 102 }; 103 104 } 105 106 template <class ELFT> 107 ELFDumper<ELFT>::ELFDumper(const object::ELFFile<ELFT> &O) 108 : Obj(O) {} 109 110 template <class ELFT> 111 Expected<StringRef> 112 ELFDumper<ELFT>::getUniquedSectionName(const Elf_Shdr *Sec) { 113 unsigned SecIndex = Sec - &Sections[0]; 114 assert(&Sections[SecIndex] == Sec); 115 if (!SectionNames[SecIndex].empty()) 116 return SectionNames[SecIndex]; 117 118 auto NameOrErr = Obj.getSectionName(Sec); 119 if (!NameOrErr) 120 return NameOrErr; 121 StringRef Name = *NameOrErr; 122 // In some specific cases we might have more than one section without a 123 // name (sh_name == 0). It normally doesn't happen, but when we have this case 124 // it doesn't make sense to uniquify their names and add noise to the output. 125 if (Name.empty()) 126 return ""; 127 128 std::string &Ret = SectionNames[SecIndex]; 129 130 auto It = UsedSectionNames.insert({Name, 0}); 131 if (!It.second) 132 Ret = ELFYAML::appendUniqueSuffix(Name, Twine(++It.first->second)); 133 else 134 Ret = std::string(Name); 135 return Ret; 136 } 137 138 template <class ELFT> 139 Expected<StringRef> 140 ELFDumper<ELFT>::getUniquedSymbolName(const Elf_Sym *Sym, StringRef StrTable, 141 const Elf_Shdr *SymTab) { 142 Expected<StringRef> SymbolNameOrErr = Sym->getName(StrTable); 143 if (!SymbolNameOrErr) 144 return SymbolNameOrErr; 145 StringRef Name = *SymbolNameOrErr; 146 if (Name.empty() && Sym->getType() == ELF::STT_SECTION) { 147 auto ShdrOrErr = Obj.getSection(Sym, SymTab, ShndxTable); 148 if (!ShdrOrErr) 149 return ShdrOrErr.takeError(); 150 return getUniquedSectionName(*ShdrOrErr); 151 } 152 153 // Symbols in .symtab can have duplicate names. For example, it is a common 154 // situation for local symbols in a relocatable object. Here we assign unique 155 // suffixes for such symbols so that we can differentiate them. 156 if (SymTab->sh_type == ELF::SHT_SYMTAB) { 157 unsigned Index = Sym - SymTable.data(); 158 if (!SymbolNames[Index].empty()) 159 return SymbolNames[Index]; 160 161 auto It = UsedSymbolNames.insert({Name, 0}); 162 if (!It.second) 163 SymbolNames[Index] = 164 ELFYAML::appendUniqueSuffix(Name, Twine(++It.first->second)); 165 else 166 SymbolNames[Index] = std::string(Name); 167 return SymbolNames[Index]; 168 } 169 170 return Name; 171 } 172 173 template <class ELFT> 174 bool ELFDumper<ELFT>::shouldPrintSection(const ELFYAML::Section &S, 175 const Elf_Shdr &SHdr) { 176 // We only print the SHT_NULL section at index 0 when it 177 // has at least one non-null field, because yaml2obj 178 // normally creates the zero section at index 0 implicitly. 179 if (S.Type == ELF::SHT_NULL && (&SHdr == &Sections[0])) { 180 const uint8_t *Begin = reinterpret_cast<const uint8_t *>(&SHdr); 181 const uint8_t *End = Begin + sizeof(Elf_Shdr); 182 return std::find_if(Begin, End, [](uint8_t V) { return V != 0; }) != End; 183 } 184 185 // Normally we use "Symbols:" and "DynamicSymbols:" to describe contents of 186 // symbol tables. We also build and emit corresponding string tables 187 // implicitly. But sometimes it is important to preserve positions and virtual 188 // addresses of allocatable sections, e.g. for creating program headers. 189 // Generally we are trying to reduce noise in the YAML output. Because 190 // of that we do not print non-allocatable versions of such sections and 191 // assume they are placed at the end. 192 if (S.Type == ELF::SHT_STRTAB || S.Type == ELF::SHT_SYMTAB || 193 S.Type == ELF::SHT_DYNSYM) 194 return S.Flags.getValueOr(ELFYAML::ELF_SHF(0)) & ELF::SHF_ALLOC; 195 196 return true; 197 } 198 199 template <class ELFT> Expected<ELFYAML::Object *> ELFDumper<ELFT>::dump() { 200 auto Y = std::make_unique<ELFYAML::Object>(); 201 202 // Dump header. We do not dump SHEntSize, SHOff, SHNum and SHStrNdx fields. 203 // When not explicitly set, the values are set by yaml2obj automatically 204 // and there is no need to dump them here. 205 Y->Header.Class = ELFYAML::ELF_ELFCLASS(Obj.getHeader()->getFileClass()); 206 Y->Header.Data = ELFYAML::ELF_ELFDATA(Obj.getHeader()->getDataEncoding()); 207 Y->Header.OSABI = Obj.getHeader()->e_ident[ELF::EI_OSABI]; 208 Y->Header.ABIVersion = Obj.getHeader()->e_ident[ELF::EI_ABIVERSION]; 209 Y->Header.Type = Obj.getHeader()->e_type; 210 Y->Header.Machine = Obj.getHeader()->e_machine; 211 Y->Header.Flags = Obj.getHeader()->e_flags; 212 Y->Header.Entry = Obj.getHeader()->e_entry; 213 214 // Dump sections 215 auto SectionsOrErr = Obj.sections(); 216 if (!SectionsOrErr) 217 return SectionsOrErr.takeError(); 218 Sections = *SectionsOrErr; 219 SectionNames.resize(Sections.size()); 220 221 // Dump symbols. We need to do this early because other sections might want 222 // to access the deduplicated symbol names that we also create here. 223 const Elf_Shdr *SymTab = nullptr; 224 const Elf_Shdr *SymTabShndx = nullptr; 225 const Elf_Shdr *DynSymTab = nullptr; 226 227 for (const Elf_Shdr &Sec : Sections) { 228 if (Sec.sh_type == ELF::SHT_SYMTAB) { 229 SymTab = &Sec; 230 } else if (Sec.sh_type == ELF::SHT_DYNSYM) { 231 DynSymTab = &Sec; 232 } else if (Sec.sh_type == ELF::SHT_SYMTAB_SHNDX) { 233 // ABI allows us to have one SHT_SYMTAB_SHNDX for each symbol table. 234 // We only support having the SHT_SYMTAB_SHNDX for SHT_SYMTAB now. 235 if (SymTabShndx) 236 return createStringError(obj2yaml_error::not_implemented, 237 "multiple SHT_SYMTAB_SHNDX sections are not supported"); 238 SymTabShndx = &Sec; 239 } 240 } 241 242 // We need to locate the SHT_SYMTAB_SHNDX section early, because it might be 243 // needed for dumping symbols. 244 if (SymTabShndx) { 245 if (!SymTab || 246 SymTabShndx->sh_link != (unsigned)(SymTab - Sections.begin())) 247 return createStringError( 248 obj2yaml_error::not_implemented, 249 "only SHT_SYMTAB_SHNDX associated with SHT_SYMTAB are supported"); 250 251 auto TableOrErr = Obj.getSHNDXTable(*SymTabShndx); 252 if (!TableOrErr) 253 return TableOrErr.takeError(); 254 ShndxTable = *TableOrErr; 255 } 256 257 if (SymTab) { 258 Y->Symbols.emplace(); 259 if (Error E = dumpSymbols(SymTab, *Y->Symbols)) 260 return std::move(E); 261 } 262 263 if (DynSymTab) { 264 Y->DynamicSymbols.emplace(); 265 if (Error E = dumpSymbols(DynSymTab, *Y->DynamicSymbols)) 266 return std::move(E); 267 } 268 269 // We dump all sections first. It is simple and allows us to verify that all 270 // sections are valid and also to generalize the code. But we are not going to 271 // keep all of them in the final output (see comments for 272 // 'shouldPrintSection()'). Undesired chunks will be removed later. 273 Expected<std::vector<std::unique_ptr<ELFYAML::Chunk>>> ChunksOrErr = 274 dumpSections(); 275 if (!ChunksOrErr) 276 return ChunksOrErr.takeError(); 277 std::vector<std::unique_ptr<ELFYAML::Chunk>> Chunks = std::move(*ChunksOrErr); 278 279 // Dump program headers. 280 Expected<std::vector<ELFYAML::ProgramHeader>> PhdrsOrErr = 281 dumpProgramHeaders(Chunks); 282 if (!PhdrsOrErr) 283 return PhdrsOrErr.takeError(); 284 Y->ProgramHeaders = std::move(*PhdrsOrErr); 285 286 llvm::erase_if(Chunks, [this](const std::unique_ptr<ELFYAML::Chunk> &C) { 287 const ELFYAML::Section &S = cast<ELFYAML::Section>(*C.get()); 288 return !shouldPrintSection(S, Sections[S.OriginalSecNdx]); 289 }); 290 291 Y->Chunks = std::move(Chunks); 292 return Y.release(); 293 } 294 295 template <class ELFT> 296 static bool isInSegment(const ELFYAML::Section &Sec, 297 const typename ELFT::Shdr &SHdr, 298 const typename ELFT::Phdr &Phdr) { 299 if (Sec.Type == ELF::SHT_NULL) 300 return false; 301 302 // A section is within a segment when its location in a file is within the 303 // [p_offset, p_offset + p_filesz] region. 304 bool FileOffsetsMatch = 305 SHdr.sh_offset >= Phdr.p_offset && 306 (SHdr.sh_offset + SHdr.sh_size <= Phdr.p_offset + Phdr.p_filesz); 307 308 bool VirtualAddressesMatch = SHdr.sh_addr >= Phdr.p_vaddr && 309 SHdr.sh_addr <= Phdr.p_vaddr + Phdr.p_memsz; 310 311 if (FileOffsetsMatch) { 312 // An empty section on the edges of a program header can be outside of the 313 // virtual address space of the segment. This means it is not included in 314 // the segment and we should ignore it. 315 if (SHdr.sh_size == 0 && (SHdr.sh_offset == Phdr.p_offset || 316 SHdr.sh_offset == Phdr.p_offset + Phdr.p_filesz)) 317 return VirtualAddressesMatch; 318 return true; 319 } 320 321 // SHT_NOBITS sections usually occupy no physical space in a file. Such 322 // sections belong to a segment when they reside in the segment's virtual 323 // address space. 324 if (Sec.Type != ELF::SHT_NOBITS) 325 return false; 326 return VirtualAddressesMatch; 327 } 328 329 template <class ELFT> 330 Expected<std::vector<ELFYAML::ProgramHeader>> 331 ELFDumper<ELFT>::dumpProgramHeaders( 332 ArrayRef<std::unique_ptr<ELFYAML::Chunk>> Chunks) { 333 std::vector<ELFYAML::ProgramHeader> Ret; 334 Expected<typename ELFT::PhdrRange> PhdrsOrErr = Obj.program_headers(); 335 if (!PhdrsOrErr) 336 return PhdrsOrErr.takeError(); 337 338 for (const typename ELFT::Phdr &Phdr : *PhdrsOrErr) { 339 ELFYAML::ProgramHeader PH; 340 PH.Type = Phdr.p_type; 341 PH.Flags = Phdr.p_flags; 342 PH.VAddr = Phdr.p_vaddr; 343 PH.PAddr = Phdr.p_paddr; 344 345 // yaml2obj sets the alignment of a segment to 1 by default. 346 // We do not print the default alignment to reduce noise in the output. 347 if (Phdr.p_align != 1) 348 PH.Align = static_cast<llvm::yaml::Hex64>(Phdr.p_align); 349 350 // Here we match sections with segments. 351 // It is not possible to have a non-Section chunk, because 352 // obj2yaml does not create Fill chunks. 353 for (const std::unique_ptr<ELFYAML::Chunk> &C : Chunks) { 354 ELFYAML::Section &S = cast<ELFYAML::Section>(*C.get()); 355 if (isInSegment<ELFT>(S, Sections[S.OriginalSecNdx], Phdr)) 356 PH.Sections.push_back({S.Name}); 357 } 358 359 Ret.push_back(PH); 360 } 361 362 return Ret; 363 } 364 365 template <class ELFT> 366 Expected<ELFYAML::RawContentSection *> 367 ELFDumper<ELFT>::dumpPlaceholderSection(const Elf_Shdr *Shdr) { 368 auto S = std::make_unique<ELFYAML::RawContentSection>(); 369 if (Error E = dumpCommonSection(Shdr, *S.get())) 370 return std::move(E); 371 return S.release(); 372 } 373 374 template <class ELFT> 375 Expected<std::vector<std::unique_ptr<ELFYAML::Chunk>>> 376 ELFDumper<ELFT>::dumpSections() { 377 std::vector<std::unique_ptr<ELFYAML::Chunk>> Ret; 378 auto Add = [&](Expected<ELFYAML::Chunk *> SecOrErr) -> Error { 379 if (!SecOrErr) 380 return SecOrErr.takeError(); 381 Ret.emplace_back(*SecOrErr); 382 return Error::success(); 383 }; 384 385 auto GetDumper = [this](unsigned Type) 386 -> std::function<Expected<ELFYAML::Chunk *>(const Elf_Shdr *)> { 387 switch (Type) { 388 case ELF::SHT_DYNAMIC: 389 return [this](const Elf_Shdr *S) { return dumpDynamicSection(S); }; 390 case ELF::SHT_SYMTAB_SHNDX: 391 return [this](const Elf_Shdr *S) { return dumpSymtabShndxSection(S); }; 392 case ELF::SHT_REL: 393 case ELF::SHT_RELA: 394 return [this](const Elf_Shdr *S) { return dumpRelocSection(S); }; 395 case ELF::SHT_RELR: 396 return [this](const Elf_Shdr *S) { return dumpRelrSection(S); }; 397 case ELF::SHT_GROUP: 398 return [this](const Elf_Shdr *S) { return dumpGroup(S); }; 399 case ELF::SHT_MIPS_ABIFLAGS: 400 return [this](const Elf_Shdr *S) { return dumpMipsABIFlags(S); }; 401 case ELF::SHT_NOBITS: 402 return [this](const Elf_Shdr *S) { return dumpNoBitsSection(S); }; 403 case ELF::SHT_NOTE: 404 return [this](const Elf_Shdr *S) { return dumpNoteSection(S); }; 405 case ELF::SHT_HASH: 406 return [this](const Elf_Shdr *S) { return dumpHashSection(S); }; 407 case ELF::SHT_GNU_HASH: 408 return [this](const Elf_Shdr *S) { return dumpGnuHashSection(S); }; 409 case ELF::SHT_GNU_verdef: 410 return [this](const Elf_Shdr *S) { return dumpVerdefSection(S); }; 411 case ELF::SHT_GNU_versym: 412 return [this](const Elf_Shdr *S) { return dumpSymverSection(S); }; 413 case ELF::SHT_GNU_verneed: 414 return [this](const Elf_Shdr *S) { return dumpVerneedSection(S); }; 415 case ELF::SHT_LLVM_ADDRSIG: 416 return [this](const Elf_Shdr *S) { return dumpAddrsigSection(S); }; 417 case ELF::SHT_LLVM_LINKER_OPTIONS: 418 return [this](const Elf_Shdr *S) { return dumpLinkerOptionsSection(S); }; 419 case ELF::SHT_LLVM_DEPENDENT_LIBRARIES: 420 return [this](const Elf_Shdr *S) { 421 return dumpDependentLibrariesSection(S); 422 }; 423 case ELF::SHT_LLVM_CALL_GRAPH_PROFILE: 424 return 425 [this](const Elf_Shdr *S) { return dumpCallGraphProfileSection(S); }; 426 case ELF::SHT_STRTAB: 427 case ELF::SHT_SYMTAB: 428 case ELF::SHT_DYNSYM: 429 // The contents of these sections are described by other parts of the YAML 430 // file. But we still want to dump them, because their properties can be 431 // important. See comments for 'shouldPrintSection()' for more details. 432 return [this](const Elf_Shdr *S) { return dumpPlaceholderSection(S); }; 433 default: 434 return nullptr; 435 } 436 }; 437 438 for (const Elf_Shdr &Sec : Sections) { 439 // We have dedicated dumping functions for most of the section types. 440 // Try to use one of them first. 441 if (std::function<Expected<ELFYAML::Chunk *>(const Elf_Shdr *)> DumpFn = 442 GetDumper(Sec.sh_type)) { 443 if (Error E = Add(DumpFn(&Sec))) 444 return std::move(E); 445 continue; 446 } 447 448 // Recognize some special SHT_PROGBITS sections by name. 449 if (Sec.sh_type == ELF::SHT_PROGBITS) { 450 auto NameOrErr = getUniquedSectionName(&Sec); 451 if (!NameOrErr) 452 return NameOrErr.takeError(); 453 454 if (ELFYAML::StackSizesSection::nameMatches(*NameOrErr)) { 455 if (Error E = Add(dumpStackSizesSection(&Sec))) 456 return std::move(E); 457 continue; 458 } 459 } 460 461 if (Error E = Add(dumpContentSection(&Sec))) 462 return std::move(E); 463 } 464 465 return std::move(Ret); 466 } 467 468 template <class ELFT> 469 Error ELFDumper<ELFT>::dumpSymbols(const Elf_Shdr *Symtab, 470 std::vector<ELFYAML::Symbol> &Symbols) { 471 if (!Symtab) 472 return Error::success(); 473 474 auto StrTableOrErr = Obj.getStringTableForSymtab(*Symtab); 475 if (!StrTableOrErr) 476 return StrTableOrErr.takeError(); 477 StringRef StrTable = *StrTableOrErr; 478 479 auto SymtabOrErr = Obj.symbols(Symtab); 480 if (!SymtabOrErr) 481 return SymtabOrErr.takeError(); 482 483 if (Symtab->sh_type == ELF::SHT_SYMTAB) { 484 SymTable = *SymtabOrErr; 485 SymbolNames.resize(SymTable.size()); 486 } 487 488 for (const auto &Sym : (*SymtabOrErr).drop_front()) { 489 ELFYAML::Symbol S; 490 if (auto EC = dumpSymbol(&Sym, Symtab, StrTable, S)) 491 return EC; 492 Symbols.push_back(S); 493 } 494 495 return Error::success(); 496 } 497 498 template <class ELFT> 499 Error ELFDumper<ELFT>::dumpSymbol(const Elf_Sym *Sym, const Elf_Shdr *SymTab, 500 StringRef StrTable, ELFYAML::Symbol &S) { 501 S.Type = Sym->getType(); 502 S.Value = Sym->st_value; 503 S.Size = Sym->st_size; 504 S.Other = Sym->st_other; 505 S.Binding = Sym->getBinding(); 506 507 Expected<StringRef> SymbolNameOrErr = 508 getUniquedSymbolName(Sym, StrTable, SymTab); 509 if (!SymbolNameOrErr) 510 return SymbolNameOrErr.takeError(); 511 S.Name = SymbolNameOrErr.get(); 512 513 if (Sym->st_shndx >= ELF::SHN_LORESERVE) { 514 S.Index = (ELFYAML::ELF_SHN)Sym->st_shndx; 515 return Error::success(); 516 } 517 518 auto ShdrOrErr = Obj.getSection(Sym, SymTab, ShndxTable); 519 if (!ShdrOrErr) 520 return ShdrOrErr.takeError(); 521 const Elf_Shdr *Shdr = *ShdrOrErr; 522 if (!Shdr) 523 return Error::success(); 524 525 auto NameOrErr = getUniquedSectionName(Shdr); 526 if (!NameOrErr) 527 return NameOrErr.takeError(); 528 S.Section = NameOrErr.get(); 529 530 return Error::success(); 531 } 532 533 template <class ELFT> 534 template <class RelT> 535 Error ELFDumper<ELFT>::dumpRelocation(const RelT *Rel, const Elf_Shdr *SymTab, 536 ELFYAML::Relocation &R) { 537 R.Type = Rel->getType(Obj.isMips64EL()); 538 R.Offset = Rel->r_offset; 539 R.Addend = 0; 540 541 auto SymOrErr = Obj.getRelocationSymbol(Rel, SymTab); 542 if (!SymOrErr) 543 return SymOrErr.takeError(); 544 545 // We have might have a relocation with symbol index 0, 546 // e.g. R_X86_64_NONE or R_X86_64_GOTPC32. 547 const Elf_Sym *Sym = *SymOrErr; 548 if (!Sym) 549 return Error::success(); 550 551 auto StrTabSec = Obj.getSection(SymTab->sh_link); 552 if (!StrTabSec) 553 return StrTabSec.takeError(); 554 auto StrTabOrErr = Obj.getStringTable(*StrTabSec); 555 if (!StrTabOrErr) 556 return StrTabOrErr.takeError(); 557 558 Expected<StringRef> NameOrErr = 559 getUniquedSymbolName(Sym, *StrTabOrErr, SymTab); 560 if (!NameOrErr) 561 return NameOrErr.takeError(); 562 R.Symbol = NameOrErr.get(); 563 564 return Error::success(); 565 } 566 567 template <class ELFT> 568 static unsigned getDefaultShEntSize(ELFYAML::ELF_SHT SecType) { 569 switch (SecType) { 570 case ELF::SHT_REL: 571 return sizeof(typename ELFT::Rel); 572 case ELF::SHT_RELA: 573 return sizeof(typename ELFT::Rela); 574 case ELF::SHT_RELR: 575 return sizeof(typename ELFT::Relr); 576 case ELF::SHT_DYNAMIC: 577 return sizeof(typename ELFT::Dyn); 578 default: 579 return 0; 580 } 581 } 582 583 template <class ELFT> 584 Error ELFDumper<ELFT>::dumpCommonSection(const Elf_Shdr *Shdr, 585 ELFYAML::Section &S) { 586 // Dump fields. We do not dump the ShOffset field. When not explicitly 587 // set, the value is set by yaml2obj automatically. 588 S.Type = Shdr->sh_type; 589 if (Shdr->sh_flags) 590 S.Flags = static_cast<ELFYAML::ELF_SHF>(Shdr->sh_flags); 591 if (Shdr->sh_addr) 592 S.Address = static_cast<uint64_t>(Shdr->sh_addr); 593 S.AddressAlign = Shdr->sh_addralign; 594 595 if (Shdr->sh_entsize != getDefaultShEntSize<ELFT>(S.Type)) 596 S.EntSize = static_cast<llvm::yaml::Hex64>(Shdr->sh_entsize); 597 598 S.OriginalSecNdx = Shdr - &Sections[0]; 599 600 auto NameOrErr = getUniquedSectionName(Shdr); 601 if (!NameOrErr) 602 return NameOrErr.takeError(); 603 S.Name = NameOrErr.get(); 604 605 if (Shdr->sh_link != ELF::SHN_UNDEF) { 606 auto LinkSection = Obj.getSection(Shdr->sh_link); 607 if (!LinkSection) 608 return make_error<StringError>( 609 "unable to resolve sh_link reference in section '" + S.Name + 610 "': " + toString(LinkSection.takeError()), 611 inconvertibleErrorCode()); 612 613 NameOrErr = getUniquedSectionName(*LinkSection); 614 if (!NameOrErr) 615 return NameOrErr.takeError(); 616 S.Link = NameOrErr.get(); 617 } 618 619 return Error::success(); 620 } 621 622 template <class ELFT> 623 Error ELFDumper<ELFT>::dumpCommonRelocationSection( 624 const Elf_Shdr *Shdr, ELFYAML::RelocationSection &S) { 625 if (Error E = dumpCommonSection(Shdr, S)) 626 return E; 627 628 // Having a zero sh_info field is normal: .rela.dyn is a dynamic 629 // relocation section that normally has no value in this field. 630 if (!Shdr->sh_info) 631 return Error::success(); 632 633 auto InfoSection = Obj.getSection(Shdr->sh_info); 634 if (!InfoSection) 635 return InfoSection.takeError(); 636 637 auto NameOrErr = getUniquedSectionName(*InfoSection); 638 if (!NameOrErr) 639 return NameOrErr.takeError(); 640 S.RelocatableSec = NameOrErr.get(); 641 642 return Error::success(); 643 } 644 645 template <class ELFT> 646 Expected<ELFYAML::StackSizesSection *> 647 ELFDumper<ELFT>::dumpStackSizesSection(const Elf_Shdr *Shdr) { 648 auto S = std::make_unique<ELFYAML::StackSizesSection>(); 649 if (Error E = dumpCommonSection(Shdr, *S)) 650 return std::move(E); 651 652 auto ContentOrErr = Obj.getSectionContents(Shdr); 653 if (!ContentOrErr) 654 return ContentOrErr.takeError(); 655 656 ArrayRef<uint8_t> Content = *ContentOrErr; 657 DataExtractor Data(Content, Obj.isLE(), ELFT::Is64Bits ? 8 : 4); 658 659 std::vector<ELFYAML::StackSizeEntry> Entries; 660 DataExtractor::Cursor Cur(0); 661 while (Cur && Cur.tell() < Content.size()) { 662 uint64_t Address = Data.getAddress(Cur); 663 uint64_t Size = Data.getULEB128(Cur); 664 Entries.push_back({Address, Size}); 665 } 666 667 if (Content.empty() || !Cur) { 668 // If .stack_sizes cannot be decoded, we dump it as an array of bytes. 669 consumeError(Cur.takeError()); 670 S->Content = yaml::BinaryRef(Content); 671 } else { 672 S->Entries = std::move(Entries); 673 } 674 675 return S.release(); 676 } 677 678 template <class ELFT> 679 Expected<ELFYAML::AddrsigSection *> 680 ELFDumper<ELFT>::dumpAddrsigSection(const Elf_Shdr *Shdr) { 681 auto S = std::make_unique<ELFYAML::AddrsigSection>(); 682 if (Error E = dumpCommonSection(Shdr, *S)) 683 return std::move(E); 684 685 auto ContentOrErr = Obj.getSectionContents(Shdr); 686 if (!ContentOrErr) 687 return ContentOrErr.takeError(); 688 689 ArrayRef<uint8_t> Content = *ContentOrErr; 690 DataExtractor::Cursor Cur(0); 691 DataExtractor Data(Content, Obj.isLE(), /*AddressSize=*/0); 692 std::vector<ELFYAML::YAMLFlowString> Symbols; 693 while (Cur && Cur.tell() < Content.size()) { 694 uint64_t SymNdx = Data.getULEB128(Cur); 695 if (!Cur) 696 break; 697 698 Expected<StringRef> SymbolName = getSymbolName(Shdr->sh_link, SymNdx); 699 if (!SymbolName || SymbolName->empty()) { 700 consumeError(SymbolName.takeError()); 701 Symbols.emplace_back( 702 StringRef(std::to_string(SymNdx)).copy(StringAllocator)); 703 continue; 704 } 705 706 Symbols.emplace_back(*SymbolName); 707 } 708 709 if (Cur) { 710 S->Symbols = std::move(Symbols); 711 return S.release(); 712 } 713 714 consumeError(Cur.takeError()); 715 S->Content = yaml::BinaryRef(Content); 716 return S.release(); 717 } 718 719 template <class ELFT> 720 Expected<ELFYAML::LinkerOptionsSection *> 721 ELFDumper<ELFT>::dumpLinkerOptionsSection(const Elf_Shdr *Shdr) { 722 auto S = std::make_unique<ELFYAML::LinkerOptionsSection>(); 723 if (Error E = dumpCommonSection(Shdr, *S)) 724 return std::move(E); 725 726 auto ContentOrErr = Obj.getSectionContents(Shdr); 727 if (!ContentOrErr) 728 return ContentOrErr.takeError(); 729 730 ArrayRef<uint8_t> Content = *ContentOrErr; 731 if (Content.empty() || Content.back() != 0) { 732 S->Content = Content; 733 return S.release(); 734 } 735 736 SmallVector<StringRef, 16> Strings; 737 toStringRef(Content.drop_back()).split(Strings, '\0'); 738 if (Strings.size() % 2 != 0) { 739 S->Content = Content; 740 return S.release(); 741 } 742 743 S->Options.emplace(); 744 for (size_t I = 0, E = Strings.size(); I != E; I += 2) 745 S->Options->push_back({Strings[I], Strings[I + 1]}); 746 747 return S.release(); 748 } 749 750 template <class ELFT> 751 Expected<ELFYAML::DependentLibrariesSection *> 752 ELFDumper<ELFT>::dumpDependentLibrariesSection(const Elf_Shdr *Shdr) { 753 auto DL = std::make_unique<ELFYAML::DependentLibrariesSection>(); 754 if (Error E = dumpCommonSection(Shdr, *DL)) 755 return std::move(E); 756 757 Expected<ArrayRef<uint8_t>> ContentOrErr = Obj.getSectionContents(Shdr); 758 if (!ContentOrErr) 759 return ContentOrErr.takeError(); 760 761 ArrayRef<uint8_t> Content = *ContentOrErr; 762 if (!Content.empty() && Content.back() != 0) { 763 DL->Content = Content; 764 return DL.release(); 765 } 766 767 DL->Libs.emplace(); 768 for (const uint8_t *I = Content.begin(), *E = Content.end(); I < E;) { 769 StringRef Lib((const char *)I); 770 DL->Libs->emplace_back(Lib); 771 I += Lib.size() + 1; 772 } 773 774 return DL.release(); 775 } 776 777 template <class ELFT> 778 Expected<ELFYAML::CallGraphProfileSection *> 779 ELFDumper<ELFT>::dumpCallGraphProfileSection(const Elf_Shdr *Shdr) { 780 auto S = std::make_unique<ELFYAML::CallGraphProfileSection>(); 781 if (Error E = dumpCommonSection(Shdr, *S)) 782 return std::move(E); 783 784 Expected<ArrayRef<uint8_t>> ContentOrErr = Obj.getSectionContents(Shdr); 785 if (!ContentOrErr) 786 return ContentOrErr.takeError(); 787 ArrayRef<uint8_t> Content = *ContentOrErr; 788 789 // Dump the section by using the Content key when it is truncated. 790 // There is no need to create either "Content" or "Entries" fields when the 791 // section is empty. 792 if (Content.empty() || Content.size() % 16 != 0) { 793 if (!Content.empty()) 794 S->Content = yaml::BinaryRef(Content); 795 return S.release(); 796 } 797 798 std::vector<ELFYAML::CallGraphEntry> Entries(Content.size() / 16); 799 DataExtractor Data(Content, Obj.isLE(), /*AddressSize=*/0); 800 DataExtractor::Cursor Cur(0); 801 auto ReadEntry = [&](ELFYAML::CallGraphEntry &E) { 802 uint32_t FromSymIndex = Data.getU32(Cur); 803 uint32_t ToSymIndex = Data.getU32(Cur); 804 E.Weight = Data.getU64(Cur); 805 if (!Cur) { 806 consumeError(Cur.takeError()); 807 return false; 808 } 809 810 Expected<StringRef> From = getSymbolName(Shdr->sh_link, FromSymIndex); 811 Expected<StringRef> To = getSymbolName(Shdr->sh_link, ToSymIndex); 812 if (From && To) { 813 E.From = *From; 814 E.To = *To; 815 return true; 816 } 817 consumeError(From.takeError()); 818 consumeError(To.takeError()); 819 return false; 820 }; 821 822 for (ELFYAML::CallGraphEntry &E : Entries) { 823 if (ReadEntry(E)) 824 continue; 825 S->Content = yaml::BinaryRef(Content); 826 return S.release(); 827 } 828 829 S->Entries = std::move(Entries); 830 return S.release(); 831 } 832 833 template <class ELFT> 834 Expected<ELFYAML::DynamicSection *> 835 ELFDumper<ELFT>::dumpDynamicSection(const Elf_Shdr *Shdr) { 836 auto S = std::make_unique<ELFYAML::DynamicSection>(); 837 if (Error E = dumpCommonSection(Shdr, *S)) 838 return std::move(E); 839 840 auto DynTagsOrErr = Obj.template getSectionContentsAsArray<Elf_Dyn>(Shdr); 841 if (!DynTagsOrErr) 842 return DynTagsOrErr.takeError(); 843 844 for (const Elf_Dyn &Dyn : *DynTagsOrErr) 845 S->Entries.push_back({(ELFYAML::ELF_DYNTAG)Dyn.getTag(), Dyn.getVal()}); 846 847 return S.release(); 848 } 849 850 template <class ELFT> 851 Expected<ELFYAML::RelocationSection *> 852 ELFDumper<ELFT>::dumpRelocSection(const Elf_Shdr *Shdr) { 853 auto S = std::make_unique<ELFYAML::RelocationSection>(); 854 if (auto E = dumpCommonRelocationSection(Shdr, *S)) 855 return std::move(E); 856 857 auto SymTabOrErr = Obj.getSection(Shdr->sh_link); 858 if (!SymTabOrErr) 859 return SymTabOrErr.takeError(); 860 const Elf_Shdr *SymTab = *SymTabOrErr; 861 862 if (Shdr->sh_type == ELF::SHT_REL) { 863 auto Rels = Obj.rels(Shdr); 864 if (!Rels) 865 return Rels.takeError(); 866 for (const Elf_Rel &Rel : *Rels) { 867 ELFYAML::Relocation R; 868 if (Error E = dumpRelocation(&Rel, SymTab, R)) 869 return std::move(E); 870 S->Relocations.push_back(R); 871 } 872 } else { 873 auto Rels = Obj.relas(Shdr); 874 if (!Rels) 875 return Rels.takeError(); 876 for (const Elf_Rela &Rel : *Rels) { 877 ELFYAML::Relocation R; 878 if (Error E = dumpRelocation(&Rel, SymTab, R)) 879 return std::move(E); 880 R.Addend = Rel.r_addend; 881 S->Relocations.push_back(R); 882 } 883 } 884 885 return S.release(); 886 } 887 888 template <class ELFT> 889 Expected<ELFYAML::RelrSection *> 890 ELFDumper<ELFT>::dumpRelrSection(const Elf_Shdr *Shdr) { 891 auto S = std::make_unique<ELFYAML::RelrSection>(); 892 if (auto E = dumpCommonSection(Shdr, *S)) 893 return std::move(E); 894 895 if (Expected<ArrayRef<Elf_Relr>> Relrs = Obj.relrs(Shdr)) { 896 S->Entries.emplace(); 897 for (Elf_Relr Rel : *Relrs) 898 S->Entries->emplace_back(Rel); 899 return S.release(); 900 } else { 901 // Ignore. We are going to dump the data as raw content below. 902 consumeError(Relrs.takeError()); 903 } 904 905 Expected<ArrayRef<uint8_t>> ContentOrErr = Obj.getSectionContents(Shdr); 906 if (!ContentOrErr) 907 return ContentOrErr.takeError(); 908 S->Content = *ContentOrErr; 909 return S.release(); 910 } 911 912 template <class ELFT> 913 Expected<ELFYAML::RawContentSection *> 914 ELFDumper<ELFT>::dumpContentSection(const Elf_Shdr *Shdr) { 915 auto S = std::make_unique<ELFYAML::RawContentSection>(); 916 if (Error E = dumpCommonSection(Shdr, *S)) 917 return std::move(E); 918 919 unsigned SecIndex = Shdr - &Sections[0]; 920 if (SecIndex != 0 || Shdr->sh_type != ELF::SHT_NULL) { 921 auto ContentOrErr = Obj.getSectionContents(Shdr); 922 if (!ContentOrErr) 923 return ContentOrErr.takeError(); 924 ArrayRef<uint8_t> Content = *ContentOrErr; 925 if (!Content.empty()) 926 S->Content = yaml::BinaryRef(Content); 927 } else { 928 S->Size = static_cast<llvm::yaml::Hex64>(Shdr->sh_size); 929 } 930 931 if (Shdr->sh_info) 932 S->Info = static_cast<llvm::yaml::Hex64>(Shdr->sh_info); 933 return S.release(); 934 } 935 936 template <class ELFT> 937 Expected<ELFYAML::SymtabShndxSection *> 938 ELFDumper<ELFT>::dumpSymtabShndxSection(const Elf_Shdr *Shdr) { 939 auto S = std::make_unique<ELFYAML::SymtabShndxSection>(); 940 if (Error E = dumpCommonSection(Shdr, *S)) 941 return std::move(E); 942 943 auto EntriesOrErr = Obj.template getSectionContentsAsArray<Elf_Word>(Shdr); 944 if (!EntriesOrErr) 945 return EntriesOrErr.takeError(); 946 for (const Elf_Word &E : *EntriesOrErr) 947 S->Entries.push_back(E); 948 return S.release(); 949 } 950 951 template <class ELFT> 952 Expected<ELFYAML::NoBitsSection *> 953 ELFDumper<ELFT>::dumpNoBitsSection(const Elf_Shdr *Shdr) { 954 auto S = std::make_unique<ELFYAML::NoBitsSection>(); 955 if (Error E = dumpCommonSection(Shdr, *S)) 956 return std::move(E); 957 S->Size = Shdr->sh_size; 958 959 return S.release(); 960 } 961 962 template <class ELFT> 963 Expected<ELFYAML::NoteSection *> 964 ELFDumper<ELFT>::dumpNoteSection(const Elf_Shdr *Shdr) { 965 auto S = std::make_unique<ELFYAML::NoteSection>(); 966 if (Error E = dumpCommonSection(Shdr, *S)) 967 return std::move(E); 968 969 auto ContentOrErr = Obj.getSectionContents(Shdr); 970 if (!ContentOrErr) 971 return ContentOrErr.takeError(); 972 973 std::vector<ELFYAML::NoteEntry> Entries; 974 ArrayRef<uint8_t> Content = *ContentOrErr; 975 while (!Content.empty()) { 976 if (Content.size() < sizeof(Elf_Nhdr)) { 977 S->Content = yaml::BinaryRef(*ContentOrErr); 978 return S.release(); 979 } 980 981 const Elf_Nhdr *Header = reinterpret_cast<const Elf_Nhdr *>(Content.data()); 982 if (Content.size() < Header->getSize()) { 983 S->Content = yaml::BinaryRef(*ContentOrErr); 984 return S.release(); 985 } 986 987 Elf_Note Note(*Header); 988 Entries.push_back( 989 {Note.getName(), Note.getDesc(), (llvm::yaml::Hex32)Note.getType()}); 990 991 Content = Content.drop_front(Header->getSize()); 992 } 993 994 S->Notes = std::move(Entries); 995 return S.release(); 996 } 997 998 template <class ELFT> 999 Expected<ELFYAML::HashSection *> 1000 ELFDumper<ELFT>::dumpHashSection(const Elf_Shdr *Shdr) { 1001 auto S = std::make_unique<ELFYAML::HashSection>(); 1002 if (Error E = dumpCommonSection(Shdr, *S)) 1003 return std::move(E); 1004 1005 auto ContentOrErr = Obj.getSectionContents(Shdr); 1006 if (!ContentOrErr) 1007 return ContentOrErr.takeError(); 1008 1009 ArrayRef<uint8_t> Content = *ContentOrErr; 1010 if (Content.size() % 4 != 0 || Content.size() < 8) { 1011 S->Content = yaml::BinaryRef(Content); 1012 return S.release(); 1013 } 1014 1015 DataExtractor::Cursor Cur(0); 1016 DataExtractor Data(Content, Obj.isLE(), /*AddressSize=*/0); 1017 uint32_t NBucket = Data.getU32(Cur); 1018 uint32_t NChain = Data.getU32(Cur); 1019 if (Content.size() != (2 + NBucket + NChain) * 4) { 1020 S->Content = yaml::BinaryRef(Content); 1021 if (Cur) 1022 return S.release(); 1023 llvm_unreachable("entries were not read correctly"); 1024 } 1025 1026 S->Bucket.emplace(NBucket); 1027 for (uint32_t &V : *S->Bucket) 1028 V = Data.getU32(Cur); 1029 1030 S->Chain.emplace(NChain); 1031 for (uint32_t &V : *S->Chain) 1032 V = Data.getU32(Cur); 1033 1034 if (Cur) 1035 return S.release(); 1036 llvm_unreachable("entries were not read correctly"); 1037 } 1038 1039 template <class ELFT> 1040 Expected<ELFYAML::GnuHashSection *> 1041 ELFDumper<ELFT>::dumpGnuHashSection(const Elf_Shdr *Shdr) { 1042 auto S = std::make_unique<ELFYAML::GnuHashSection>(); 1043 if (Error E = dumpCommonSection(Shdr, *S)) 1044 return std::move(E); 1045 1046 auto ContentOrErr = Obj.getSectionContents(Shdr); 1047 if (!ContentOrErr) 1048 return ContentOrErr.takeError(); 1049 1050 unsigned AddrSize = ELFT::Is64Bits ? 8 : 4; 1051 ArrayRef<uint8_t> Content = *ContentOrErr; 1052 DataExtractor Data(Content, Obj.isLE(), AddrSize); 1053 1054 ELFYAML::GnuHashHeader Header; 1055 DataExtractor::Cursor Cur(0); 1056 uint32_t NBuckets = Data.getU32(Cur); 1057 Header.SymNdx = Data.getU32(Cur); 1058 uint32_t MaskWords = Data.getU32(Cur); 1059 Header.Shift2 = Data.getU32(Cur); 1060 1061 // Set just the raw binary content if we were unable to read the header 1062 // or when the section data is truncated or malformed. 1063 uint64_t Size = Data.getData().size() - Cur.tell(); 1064 if (!Cur || (Size < MaskWords * AddrSize + NBuckets * 4) || 1065 (Size % 4 != 0)) { 1066 consumeError(Cur.takeError()); 1067 S->Content = yaml::BinaryRef(Content); 1068 return S.release(); 1069 } 1070 1071 S->Header = Header; 1072 1073 S->BloomFilter.emplace(MaskWords); 1074 for (llvm::yaml::Hex64 &Val : *S->BloomFilter) 1075 Val = Data.getAddress(Cur); 1076 1077 S->HashBuckets.emplace(NBuckets); 1078 for (llvm::yaml::Hex32 &Val : *S->HashBuckets) 1079 Val = Data.getU32(Cur); 1080 1081 S->HashValues.emplace((Data.getData().size() - Cur.tell()) / 4); 1082 for (llvm::yaml::Hex32 &Val : *S->HashValues) 1083 Val = Data.getU32(Cur); 1084 1085 if (Cur) 1086 return S.release(); 1087 llvm_unreachable("GnuHashSection was not read correctly"); 1088 } 1089 1090 template <class ELFT> 1091 Expected<ELFYAML::VerdefSection *> 1092 ELFDumper<ELFT>::dumpVerdefSection(const Elf_Shdr *Shdr) { 1093 typedef typename ELFT::Verdef Elf_Verdef; 1094 typedef typename ELFT::Verdaux Elf_Verdaux; 1095 1096 auto S = std::make_unique<ELFYAML::VerdefSection>(); 1097 if (Error E = dumpCommonSection(Shdr, *S)) 1098 return std::move(E); 1099 1100 S->Info = Shdr->sh_info; 1101 1102 auto StringTableShdrOrErr = Obj.getSection(Shdr->sh_link); 1103 if (!StringTableShdrOrErr) 1104 return StringTableShdrOrErr.takeError(); 1105 1106 auto StringTableOrErr = Obj.getStringTable(*StringTableShdrOrErr); 1107 if (!StringTableOrErr) 1108 return StringTableOrErr.takeError(); 1109 1110 auto Contents = Obj.getSectionContents(Shdr); 1111 if (!Contents) 1112 return Contents.takeError(); 1113 1114 S->Entries.emplace(); 1115 1116 llvm::ArrayRef<uint8_t> Data = *Contents; 1117 const uint8_t *Buf = Data.data(); 1118 while (Buf) { 1119 const Elf_Verdef *Verdef = reinterpret_cast<const Elf_Verdef *>(Buf); 1120 ELFYAML::VerdefEntry Entry; 1121 Entry.Version = Verdef->vd_version; 1122 Entry.Flags = Verdef->vd_flags; 1123 Entry.VersionNdx = Verdef->vd_ndx; 1124 Entry.Hash = Verdef->vd_hash; 1125 1126 const uint8_t *BufAux = Buf + Verdef->vd_aux; 1127 while (BufAux) { 1128 const Elf_Verdaux *Verdaux = 1129 reinterpret_cast<const Elf_Verdaux *>(BufAux); 1130 Entry.VerNames.push_back( 1131 StringTableOrErr->drop_front(Verdaux->vda_name).data()); 1132 BufAux = Verdaux->vda_next ? BufAux + Verdaux->vda_next : nullptr; 1133 } 1134 1135 S->Entries->push_back(Entry); 1136 Buf = Verdef->vd_next ? Buf + Verdef->vd_next : nullptr; 1137 } 1138 1139 return S.release(); 1140 } 1141 1142 template <class ELFT> 1143 Expected<ELFYAML::SymverSection *> 1144 ELFDumper<ELFT>::dumpSymverSection(const Elf_Shdr *Shdr) { 1145 typedef typename ELFT::Half Elf_Half; 1146 1147 auto S = std::make_unique<ELFYAML::SymverSection>(); 1148 if (Error E = dumpCommonSection(Shdr, *S)) 1149 return std::move(E); 1150 1151 auto VersionsOrErr = Obj.template getSectionContentsAsArray<Elf_Half>(Shdr); 1152 if (!VersionsOrErr) 1153 return VersionsOrErr.takeError(); 1154 for (const Elf_Half &E : *VersionsOrErr) 1155 S->Entries.push_back(E); 1156 1157 return S.release(); 1158 } 1159 1160 template <class ELFT> 1161 Expected<ELFYAML::VerneedSection *> 1162 ELFDumper<ELFT>::dumpVerneedSection(const Elf_Shdr *Shdr) { 1163 typedef typename ELFT::Verneed Elf_Verneed; 1164 typedef typename ELFT::Vernaux Elf_Vernaux; 1165 1166 auto S = std::make_unique<ELFYAML::VerneedSection>(); 1167 if (Error E = dumpCommonSection(Shdr, *S)) 1168 return std::move(E); 1169 1170 S->Info = Shdr->sh_info; 1171 1172 auto Contents = Obj.getSectionContents(Shdr); 1173 if (!Contents) 1174 return Contents.takeError(); 1175 1176 auto StringTableShdrOrErr = Obj.getSection(Shdr->sh_link); 1177 if (!StringTableShdrOrErr) 1178 return StringTableShdrOrErr.takeError(); 1179 1180 auto StringTableOrErr = Obj.getStringTable(*StringTableShdrOrErr); 1181 if (!StringTableOrErr) 1182 return StringTableOrErr.takeError(); 1183 1184 S->VerneedV.emplace(); 1185 1186 llvm::ArrayRef<uint8_t> Data = *Contents; 1187 const uint8_t *Buf = Data.data(); 1188 while (Buf) { 1189 const Elf_Verneed *Verneed = reinterpret_cast<const Elf_Verneed *>(Buf); 1190 1191 ELFYAML::VerneedEntry Entry; 1192 Entry.Version = Verneed->vn_version; 1193 Entry.File = 1194 StringRef(StringTableOrErr->drop_front(Verneed->vn_file).data()); 1195 1196 const uint8_t *BufAux = Buf + Verneed->vn_aux; 1197 while (BufAux) { 1198 const Elf_Vernaux *Vernaux = 1199 reinterpret_cast<const Elf_Vernaux *>(BufAux); 1200 1201 ELFYAML::VernauxEntry Aux; 1202 Aux.Hash = Vernaux->vna_hash; 1203 Aux.Flags = Vernaux->vna_flags; 1204 Aux.Other = Vernaux->vna_other; 1205 Aux.Name = 1206 StringRef(StringTableOrErr->drop_front(Vernaux->vna_name).data()); 1207 1208 Entry.AuxV.push_back(Aux); 1209 BufAux = Vernaux->vna_next ? BufAux + Vernaux->vna_next : nullptr; 1210 } 1211 1212 S->VerneedV->push_back(Entry); 1213 Buf = Verneed->vn_next ? Buf + Verneed->vn_next : nullptr; 1214 } 1215 1216 return S.release(); 1217 } 1218 1219 template <class ELFT> 1220 Expected<StringRef> ELFDumper<ELFT>::getSymbolName(uint32_t SymtabNdx, 1221 uint32_t SymbolNdx) { 1222 auto SymtabOrErr = Obj.getSection(SymtabNdx); 1223 if (!SymtabOrErr) 1224 return SymtabOrErr.takeError(); 1225 1226 const Elf_Shdr *Symtab = *SymtabOrErr; 1227 auto SymOrErr = Obj.getSymbol(Symtab, SymbolNdx); 1228 if (!SymOrErr) 1229 return SymOrErr.takeError(); 1230 1231 auto StrTabOrErr = Obj.getStringTableForSymtab(*Symtab); 1232 if (!StrTabOrErr) 1233 return StrTabOrErr.takeError(); 1234 return getUniquedSymbolName(*SymOrErr, *StrTabOrErr, Symtab); 1235 } 1236 1237 template <class ELFT> 1238 Expected<ELFYAML::Group *> ELFDumper<ELFT>::dumpGroup(const Elf_Shdr *Shdr) { 1239 auto S = std::make_unique<ELFYAML::Group>(); 1240 if (Error E = dumpCommonSection(Shdr, *S)) 1241 return std::move(E); 1242 1243 // Get symbol with index sh_info. This symbol's name is the signature of the group. 1244 Expected<StringRef> SymbolName = getSymbolName(Shdr->sh_link, Shdr->sh_info); 1245 if (!SymbolName) 1246 return SymbolName.takeError(); 1247 S->Signature = *SymbolName; 1248 1249 auto MembersOrErr = Obj.template getSectionContentsAsArray<Elf_Word>(Shdr); 1250 if (!MembersOrErr) 1251 return MembersOrErr.takeError(); 1252 1253 for (Elf_Word Member : *MembersOrErr) { 1254 if (Member == llvm::ELF::GRP_COMDAT) { 1255 S->Members.push_back({"GRP_COMDAT"}); 1256 continue; 1257 } 1258 1259 auto SHdrOrErr = Obj.getSection(Member); 1260 if (!SHdrOrErr) 1261 return SHdrOrErr.takeError(); 1262 auto NameOrErr = getUniquedSectionName(*SHdrOrErr); 1263 if (!NameOrErr) 1264 return NameOrErr.takeError(); 1265 S->Members.push_back({*NameOrErr}); 1266 } 1267 return S.release(); 1268 } 1269 1270 template <class ELFT> 1271 Expected<ELFYAML::MipsABIFlags *> 1272 ELFDumper<ELFT>::dumpMipsABIFlags(const Elf_Shdr *Shdr) { 1273 assert(Shdr->sh_type == ELF::SHT_MIPS_ABIFLAGS && 1274 "Section type is not SHT_MIPS_ABIFLAGS"); 1275 auto S = std::make_unique<ELFYAML::MipsABIFlags>(); 1276 if (Error E = dumpCommonSection(Shdr, *S)) 1277 return std::move(E); 1278 1279 auto ContentOrErr = Obj.getSectionContents(Shdr); 1280 if (!ContentOrErr) 1281 return ContentOrErr.takeError(); 1282 1283 auto *Flags = reinterpret_cast<const object::Elf_Mips_ABIFlags<ELFT> *>( 1284 ContentOrErr.get().data()); 1285 S->Version = Flags->version; 1286 S->ISALevel = Flags->isa_level; 1287 S->ISARevision = Flags->isa_rev; 1288 S->GPRSize = Flags->gpr_size; 1289 S->CPR1Size = Flags->cpr1_size; 1290 S->CPR2Size = Flags->cpr2_size; 1291 S->FpABI = Flags->fp_abi; 1292 S->ISAExtension = Flags->isa_ext; 1293 S->ASEs = Flags->ases; 1294 S->Flags1 = Flags->flags1; 1295 S->Flags2 = Flags->flags2; 1296 return S.release(); 1297 } 1298 1299 template <class ELFT> 1300 static Error elf2yaml(raw_ostream &Out, const object::ELFFile<ELFT> &Obj) { 1301 ELFDumper<ELFT> Dumper(Obj); 1302 Expected<ELFYAML::Object *> YAMLOrErr = Dumper.dump(); 1303 if (!YAMLOrErr) 1304 return YAMLOrErr.takeError(); 1305 1306 std::unique_ptr<ELFYAML::Object> YAML(YAMLOrErr.get()); 1307 yaml::Output Yout(Out); 1308 Yout << *YAML; 1309 1310 return Error::success(); 1311 } 1312 1313 Error elf2yaml(raw_ostream &Out, const object::ObjectFile &Obj) { 1314 if (const auto *ELFObj = dyn_cast<object::ELF32LEObjectFile>(&Obj)) 1315 return elf2yaml(Out, *ELFObj->getELFFile()); 1316 1317 if (const auto *ELFObj = dyn_cast<object::ELF32BEObjectFile>(&Obj)) 1318 return elf2yaml(Out, *ELFObj->getELFFile()); 1319 1320 if (const auto *ELFObj = dyn_cast<object::ELF64LEObjectFile>(&Obj)) 1321 return elf2yaml(Out, *ELFObj->getELFFile()); 1322 1323 if (const auto *ELFObj = dyn_cast<object::ELF64BEObjectFile>(&Obj)) 1324 return elf2yaml(Out, *ELFObj->getELFFile()); 1325 1326 llvm_unreachable("unknown ELF file format"); 1327 } 1328