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/ErrorHandling.h" 15 #include "llvm/Support/YAMLTraits.h" 16 17 using namespace llvm; 18 19 namespace { 20 21 template <class ELFT> 22 class ELFDumper { 23 typedef object::Elf_Sym_Impl<ELFT> Elf_Sym; 24 typedef typename ELFT::Dyn Elf_Dyn; 25 typedef typename ELFT::Shdr Elf_Shdr; 26 typedef typename ELFT::Word Elf_Word; 27 typedef typename ELFT::Rel Elf_Rel; 28 typedef typename ELFT::Rela Elf_Rela; 29 30 ArrayRef<Elf_Shdr> Sections; 31 32 // If the file has multiple sections with the same name, we add a 33 // suffix to make them unique. 34 unsigned Suffix = 0; 35 DenseSet<StringRef> UsedSectionNames; 36 std::vector<std::string> SectionNames; 37 Expected<StringRef> getUniquedSectionName(const Elf_Shdr *Sec); 38 Expected<StringRef> getSymbolName(const Elf_Sym *Sym, StringRef StrTable, 39 const Elf_Shdr *SymTab); 40 41 const object::ELFFile<ELFT> &Obj; 42 ArrayRef<Elf_Word> ShndxTable; 43 44 std::error_code dumpSymbols(const Elf_Shdr *Symtab, 45 std::vector<ELFYAML::Symbol> &Symbols); 46 std::error_code dumpSymbol(const Elf_Sym *Sym, const Elf_Shdr *SymTab, 47 StringRef StrTable, ELFYAML::Symbol &S); 48 std::error_code dumpCommonSection(const Elf_Shdr *Shdr, ELFYAML::Section &S); 49 std::error_code dumpCommonRelocationSection(const Elf_Shdr *Shdr, 50 ELFYAML::RelocationSection &S); 51 template <class RelT> 52 std::error_code dumpRelocation(const RelT *Rel, const Elf_Shdr *SymTab, 53 ELFYAML::Relocation &R); 54 55 ErrorOr<ELFYAML::DynamicSection *> dumpDynamicSection(const Elf_Shdr *Shdr); 56 ErrorOr<ELFYAML::RelocationSection *> dumpRelocSection(const Elf_Shdr *Shdr); 57 ErrorOr<ELFYAML::RawContentSection *> 58 dumpContentSection(const Elf_Shdr *Shdr); 59 ErrorOr<ELFYAML::NoBitsSection *> dumpNoBitsSection(const Elf_Shdr *Shdr); 60 ErrorOr<ELFYAML::VerdefSection *> dumpVerdefSection(const Elf_Shdr *Shdr); 61 ErrorOr<ELFYAML::SymverSection *> dumpSymverSection(const Elf_Shdr *Shdr); 62 ErrorOr<ELFYAML::VerneedSection *> dumpVerneedSection(const Elf_Shdr *Shdr); 63 ErrorOr<ELFYAML::Group *> dumpGroup(const Elf_Shdr *Shdr); 64 ErrorOr<ELFYAML::MipsABIFlags *> dumpMipsABIFlags(const Elf_Shdr *Shdr); 65 66 public: 67 ELFDumper(const object::ELFFile<ELFT> &O); 68 ErrorOr<ELFYAML::Object *> dump(); 69 }; 70 71 } 72 73 template <class ELFT> 74 ELFDumper<ELFT>::ELFDumper(const object::ELFFile<ELFT> &O) 75 : Obj(O) {} 76 77 template <class ELFT> 78 Expected<StringRef> 79 ELFDumper<ELFT>::getUniquedSectionName(const Elf_Shdr *Sec) { 80 unsigned SecIndex = Sec - &Sections[0]; 81 assert(&Sections[SecIndex] == Sec); 82 if (!SectionNames[SecIndex].empty()) 83 return SectionNames[SecIndex]; 84 85 auto NameOrErr = Obj.getSectionName(Sec); 86 if (!NameOrErr) 87 return NameOrErr; 88 StringRef Name = *NameOrErr; 89 std::string &Ret = SectionNames[SecIndex]; 90 Ret = Name; 91 while (!UsedSectionNames.insert(Ret).second) 92 Ret = (Name + to_string(++Suffix)).str(); 93 return Ret; 94 } 95 96 template <class ELFT> 97 Expected<StringRef> ELFDumper<ELFT>::getSymbolName(const Elf_Sym *Sym, 98 StringRef StrTable, 99 const Elf_Shdr *SymTab) { 100 Expected<StringRef> SymbolNameOrErr = Sym->getName(StrTable); 101 if (!SymbolNameOrErr) 102 return SymbolNameOrErr; 103 StringRef Name = *SymbolNameOrErr; 104 if (Name.empty() && Sym->getType() == ELF::STT_SECTION) { 105 auto ShdrOrErr = Obj.getSection(Sym, SymTab, ShndxTable); 106 if (!ShdrOrErr) 107 return ShdrOrErr.takeError(); 108 return getUniquedSectionName(*ShdrOrErr); 109 } 110 return Name; 111 } 112 113 template <class ELFT> ErrorOr<ELFYAML::Object *> ELFDumper<ELFT>::dump() { 114 auto Y = make_unique<ELFYAML::Object>(); 115 116 // Dump header 117 Y->Header.Class = ELFYAML::ELF_ELFCLASS(Obj.getHeader()->getFileClass()); 118 Y->Header.Data = ELFYAML::ELF_ELFDATA(Obj.getHeader()->getDataEncoding()); 119 Y->Header.OSABI = Obj.getHeader()->e_ident[ELF::EI_OSABI]; 120 Y->Header.ABIVersion = Obj.getHeader()->e_ident[ELF::EI_ABIVERSION]; 121 Y->Header.Type = Obj.getHeader()->e_type; 122 Y->Header.Machine = Obj.getHeader()->e_machine; 123 Y->Header.Flags = Obj.getHeader()->e_flags; 124 Y->Header.Entry = Obj.getHeader()->e_entry; 125 126 const Elf_Shdr *Symtab = nullptr; 127 const Elf_Shdr *DynSymtab = nullptr; 128 129 // Dump sections 130 auto SectionsOrErr = Obj.sections(); 131 if (!SectionsOrErr) 132 return errorToErrorCode(SectionsOrErr.takeError()); 133 Sections = *SectionsOrErr; 134 SectionNames.resize(Sections.size()); 135 for (const Elf_Shdr &Sec : Sections) { 136 switch (Sec.sh_type) { 137 case ELF::SHT_DYNAMIC: { 138 ErrorOr<ELFYAML::DynamicSection *> S = dumpDynamicSection(&Sec); 139 if (std::error_code EC = S.getError()) 140 return EC; 141 Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get())); 142 break; 143 } 144 case ELF::SHT_NULL: 145 case ELF::SHT_STRTAB: 146 // Do not dump these sections. 147 break; 148 case ELF::SHT_SYMTAB: 149 Symtab = &Sec; 150 break; 151 case ELF::SHT_DYNSYM: 152 DynSymtab = &Sec; 153 break; 154 case ELF::SHT_SYMTAB_SHNDX: { 155 auto TableOrErr = Obj.getSHNDXTable(Sec); 156 if (!TableOrErr) 157 return errorToErrorCode(TableOrErr.takeError()); 158 ShndxTable = *TableOrErr; 159 break; 160 } 161 case ELF::SHT_REL: 162 case ELF::SHT_RELA: { 163 ErrorOr<ELFYAML::RelocationSection *> S = dumpRelocSection(&Sec); 164 if (std::error_code EC = S.getError()) 165 return EC; 166 Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get())); 167 break; 168 } 169 case ELF::SHT_GROUP: { 170 ErrorOr<ELFYAML::Group *> G = dumpGroup(&Sec); 171 if (std::error_code EC = G.getError()) 172 return EC; 173 Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(G.get())); 174 break; 175 } 176 case ELF::SHT_MIPS_ABIFLAGS: { 177 ErrorOr<ELFYAML::MipsABIFlags *> G = dumpMipsABIFlags(&Sec); 178 if (std::error_code EC = G.getError()) 179 return EC; 180 Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(G.get())); 181 break; 182 } 183 case ELF::SHT_NOBITS: { 184 ErrorOr<ELFYAML::NoBitsSection *> S = dumpNoBitsSection(&Sec); 185 if (std::error_code EC = S.getError()) 186 return EC; 187 Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get())); 188 break; 189 } 190 case ELF::SHT_GNU_verdef: { 191 ErrorOr<ELFYAML::VerdefSection *> S = dumpVerdefSection(&Sec); 192 if (std::error_code EC = S.getError()) 193 return EC; 194 Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get())); 195 break; 196 } 197 case ELF::SHT_GNU_versym: { 198 ErrorOr<ELFYAML::SymverSection *> S = dumpSymverSection(&Sec); 199 if (std::error_code EC = S.getError()) 200 return EC; 201 Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get())); 202 break; 203 } 204 case ELF::SHT_GNU_verneed: { 205 ErrorOr<ELFYAML::VerneedSection *> S = dumpVerneedSection(&Sec); 206 if (std::error_code EC = S.getError()) 207 return EC; 208 Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get())); 209 break; 210 } 211 default: { 212 ErrorOr<ELFYAML::RawContentSection *> S = dumpContentSection(&Sec); 213 if (std::error_code EC = S.getError()) 214 return EC; 215 Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get())); 216 } 217 } 218 } 219 220 if (auto EC = dumpSymbols(Symtab, Y->Symbols)) 221 return EC; 222 if (auto EC = dumpSymbols(DynSymtab, Y->DynamicSymbols)) 223 return EC; 224 225 return Y.release(); 226 } 227 228 template <class ELFT> 229 std::error_code 230 ELFDumper<ELFT>::dumpSymbols(const Elf_Shdr *Symtab, 231 std::vector<ELFYAML::Symbol> &Symbols) { 232 if (!Symtab) 233 return std::error_code(); 234 235 auto StrTableOrErr = Obj.getStringTableForSymtab(*Symtab); 236 if (!StrTableOrErr) 237 return errorToErrorCode(StrTableOrErr.takeError()); 238 StringRef StrTable = *StrTableOrErr; 239 240 auto SymtabOrErr = Obj.symbols(Symtab); 241 if (!SymtabOrErr) 242 return errorToErrorCode(SymtabOrErr.takeError()); 243 244 for (const auto &Sym : (*SymtabOrErr).drop_front()) { 245 ELFYAML::Symbol S; 246 if (auto EC = dumpSymbol(&Sym, Symtab, StrTable, S)) 247 return EC; 248 Symbols.push_back(S); 249 } 250 251 return std::error_code(); 252 } 253 254 template <class ELFT> 255 std::error_code 256 ELFDumper<ELFT>::dumpSymbol(const Elf_Sym *Sym, const Elf_Shdr *SymTab, 257 StringRef StrTable, ELFYAML::Symbol &S) { 258 S.Type = Sym->getType(); 259 S.Value = Sym->st_value; 260 S.Size = Sym->st_size; 261 S.Other = Sym->st_other; 262 S.Binding = Sym->getBinding(); 263 264 Expected<StringRef> SymbolNameOrErr = getSymbolName(Sym, StrTable, SymTab); 265 if (!SymbolNameOrErr) 266 return errorToErrorCode(SymbolNameOrErr.takeError()); 267 S.Name = SymbolNameOrErr.get(); 268 269 if (Sym->st_shndx >= ELF::SHN_LORESERVE) { 270 if (Sym->st_shndx == ELF::SHN_XINDEX) 271 return obj2yaml_error::not_implemented; 272 S.Index = (ELFYAML::ELF_SHN)Sym->st_shndx; 273 return obj2yaml_error::success; 274 } 275 276 auto ShdrOrErr = Obj.getSection(Sym, SymTab, ShndxTable); 277 if (!ShdrOrErr) 278 return errorToErrorCode(ShdrOrErr.takeError()); 279 const Elf_Shdr *Shdr = *ShdrOrErr; 280 if (!Shdr) 281 return obj2yaml_error::success; 282 283 auto NameOrErr = getUniquedSectionName(Shdr); 284 if (!NameOrErr) 285 return errorToErrorCode(NameOrErr.takeError()); 286 S.Section = NameOrErr.get(); 287 288 return obj2yaml_error::success; 289 } 290 291 template <class ELFT> 292 template <class RelT> 293 std::error_code ELFDumper<ELFT>::dumpRelocation(const RelT *Rel, 294 const Elf_Shdr *SymTab, 295 ELFYAML::Relocation &R) { 296 R.Type = Rel->getType(Obj.isMips64EL()); 297 R.Offset = Rel->r_offset; 298 R.Addend = 0; 299 300 auto SymOrErr = Obj.getRelocationSymbol(Rel, SymTab); 301 if (!SymOrErr) 302 return errorToErrorCode(SymOrErr.takeError()); 303 const Elf_Sym *Sym = *SymOrErr; 304 auto StrTabSec = Obj.getSection(SymTab->sh_link); 305 if (!StrTabSec) 306 return errorToErrorCode(StrTabSec.takeError()); 307 auto StrTabOrErr = Obj.getStringTable(*StrTabSec); 308 if (!StrTabOrErr) 309 return errorToErrorCode(StrTabOrErr.takeError()); 310 StringRef StrTab = *StrTabOrErr; 311 312 if (Sym) { 313 Expected<StringRef> NameOrErr = getSymbolName(Sym, StrTab, SymTab); 314 if (!NameOrErr) 315 return errorToErrorCode(NameOrErr.takeError()); 316 R.Symbol = NameOrErr.get(); 317 } else { 318 // We have some edge cases of relocations without a symbol associated, 319 // e.g. an object containing the invalid (according to the System V 320 // ABI) R_X86_64_NONE reloc. Create a symbol with an empty name instead 321 // of crashing. 322 R.Symbol = ""; 323 } 324 325 return obj2yaml_error::success; 326 } 327 328 template <class ELFT> 329 std::error_code ELFDumper<ELFT>::dumpCommonSection(const Elf_Shdr *Shdr, 330 ELFYAML::Section &S) { 331 S.Type = Shdr->sh_type; 332 S.Flags = Shdr->sh_flags; 333 S.Address = Shdr->sh_addr; 334 S.AddressAlign = Shdr->sh_addralign; 335 if (Shdr->sh_entsize) 336 S.EntSize = static_cast<llvm::yaml::Hex64>(Shdr->sh_entsize); 337 338 auto NameOrErr = getUniquedSectionName(Shdr); 339 if (!NameOrErr) 340 return errorToErrorCode(NameOrErr.takeError()); 341 S.Name = NameOrErr.get(); 342 343 if (Shdr->sh_link != ELF::SHN_UNDEF) { 344 auto LinkSection = Obj.getSection(Shdr->sh_link); 345 if (LinkSection.takeError()) 346 return errorToErrorCode(LinkSection.takeError()); 347 NameOrErr = getUniquedSectionName(*LinkSection); 348 if (!NameOrErr) 349 return errorToErrorCode(NameOrErr.takeError()); 350 S.Link = NameOrErr.get(); 351 } 352 353 return obj2yaml_error::success; 354 } 355 356 template <class ELFT> 357 std::error_code 358 ELFDumper<ELFT>::dumpCommonRelocationSection(const Elf_Shdr *Shdr, 359 ELFYAML::RelocationSection &S) { 360 if (std::error_code EC = dumpCommonSection(Shdr, S)) 361 return EC; 362 363 auto InfoSection = Obj.getSection(Shdr->sh_info); 364 if (!InfoSection) 365 return errorToErrorCode(InfoSection.takeError()); 366 367 auto NameOrErr = getUniquedSectionName(*InfoSection); 368 if (!NameOrErr) 369 return errorToErrorCode(NameOrErr.takeError()); 370 S.RelocatableSec = NameOrErr.get(); 371 372 return obj2yaml_error::success; 373 } 374 375 template <class ELFT> 376 ErrorOr<ELFYAML::DynamicSection *> 377 ELFDumper<ELFT>::dumpDynamicSection(const Elf_Shdr *Shdr) { 378 auto S = make_unique<ELFYAML::DynamicSection>(); 379 if (std::error_code EC = dumpCommonSection(Shdr, *S)) 380 return EC; 381 382 auto DynTagsOrErr = Obj.template getSectionContentsAsArray<Elf_Dyn>(Shdr); 383 if (!DynTagsOrErr) 384 return errorToErrorCode(DynTagsOrErr.takeError()); 385 386 for (const Elf_Dyn &Dyn : *DynTagsOrErr) 387 S->Entries.push_back({(ELFYAML::ELF_DYNTAG)Dyn.getTag(), Dyn.getVal()}); 388 389 return S.release(); 390 } 391 392 template <class ELFT> 393 ErrorOr<ELFYAML::RelocationSection *> 394 ELFDumper<ELFT>::dumpRelocSection(const Elf_Shdr *Shdr) { 395 auto S = make_unique<ELFYAML::RelocationSection>(); 396 if (std::error_code EC = dumpCommonRelocationSection(Shdr, *S)) 397 return EC; 398 399 auto SymTabOrErr = Obj.getSection(Shdr->sh_link); 400 if (!SymTabOrErr) 401 return errorToErrorCode(SymTabOrErr.takeError()); 402 const Elf_Shdr *SymTab = *SymTabOrErr; 403 404 if (Shdr->sh_type == ELF::SHT_REL) { 405 auto Rels = Obj.rels(Shdr); 406 if (!Rels) 407 return errorToErrorCode(Rels.takeError()); 408 for (const Elf_Rel &Rel : *Rels) { 409 ELFYAML::Relocation R; 410 if (std::error_code EC = dumpRelocation(&Rel, SymTab, R)) 411 return EC; 412 S->Relocations.push_back(R); 413 } 414 } else { 415 auto Rels = Obj.relas(Shdr); 416 if (!Rels) 417 return errorToErrorCode(Rels.takeError()); 418 for (const Elf_Rela &Rel : *Rels) { 419 ELFYAML::Relocation R; 420 if (std::error_code EC = dumpRelocation(&Rel, SymTab, R)) 421 return EC; 422 R.Addend = Rel.r_addend; 423 S->Relocations.push_back(R); 424 } 425 } 426 427 return S.release(); 428 } 429 430 template <class ELFT> 431 ErrorOr<ELFYAML::RawContentSection *> 432 ELFDumper<ELFT>::dumpContentSection(const Elf_Shdr *Shdr) { 433 auto S = make_unique<ELFYAML::RawContentSection>(); 434 435 if (std::error_code EC = dumpCommonSection(Shdr, *S)) 436 return EC; 437 438 auto ContentOrErr = Obj.getSectionContents(Shdr); 439 if (!ContentOrErr) 440 return errorToErrorCode(ContentOrErr.takeError()); 441 S->Content = yaml::BinaryRef(ContentOrErr.get()); 442 S->Size = S->Content.binary_size(); 443 S->Info = Shdr->sh_info; 444 445 return S.release(); 446 } 447 448 template <class ELFT> 449 ErrorOr<ELFYAML::NoBitsSection *> 450 ELFDumper<ELFT>::dumpNoBitsSection(const Elf_Shdr *Shdr) { 451 auto S = make_unique<ELFYAML::NoBitsSection>(); 452 453 if (std::error_code EC = dumpCommonSection(Shdr, *S)) 454 return EC; 455 S->Size = Shdr->sh_size; 456 457 return S.release(); 458 } 459 460 template <class ELFT> 461 ErrorOr<ELFYAML::VerdefSection *> 462 ELFDumper<ELFT>::dumpVerdefSection(const Elf_Shdr *Shdr) { 463 typedef typename ELFT::Verdef Elf_Verdef; 464 typedef typename ELFT::Verdaux Elf_Verdaux; 465 466 auto S = make_unique<ELFYAML::VerdefSection>(); 467 if (std::error_code EC = dumpCommonSection(Shdr, *S)) 468 return EC; 469 470 S->Info = Shdr->sh_info; 471 472 auto StringTableShdrOrErr = Obj.getSection(Shdr->sh_link); 473 if (!StringTableShdrOrErr) 474 return errorToErrorCode(StringTableShdrOrErr.takeError()); 475 476 auto StringTableOrErr = Obj.getStringTable(*StringTableShdrOrErr); 477 if (!StringTableOrErr) 478 return errorToErrorCode(StringTableOrErr.takeError()); 479 480 auto Contents = Obj.getSectionContents(Shdr); 481 if (!Contents) 482 return errorToErrorCode(Contents.takeError()); 483 484 llvm::ArrayRef<uint8_t> Data = *Contents; 485 const uint8_t *Buf = Data.data(); 486 while (Buf) { 487 const Elf_Verdef *Verdef = reinterpret_cast<const Elf_Verdef *>(Buf); 488 ELFYAML::VerdefEntry Entry; 489 Entry.Version = Verdef->vd_version; 490 Entry.Flags = Verdef->vd_flags; 491 Entry.VersionNdx = Verdef->vd_ndx; 492 Entry.Hash = Verdef->vd_hash; 493 494 const uint8_t *BufAux = Buf + Verdef->vd_aux; 495 while (BufAux) { 496 const Elf_Verdaux *Verdaux = 497 reinterpret_cast<const Elf_Verdaux *>(BufAux); 498 Entry.VerNames.push_back( 499 StringTableOrErr->drop_front(Verdaux->vda_name).data()); 500 BufAux = Verdaux->vda_next ? BufAux + Verdaux->vda_next : nullptr; 501 } 502 503 S->Entries.push_back(Entry); 504 Buf = Verdef->vd_next ? Buf + Verdef->vd_next : nullptr; 505 } 506 507 return S.release(); 508 } 509 510 template <class ELFT> 511 ErrorOr<ELFYAML::SymverSection *> 512 ELFDumper<ELFT>::dumpSymverSection(const Elf_Shdr *Shdr) { 513 typedef typename ELFT::Half Elf_Half; 514 515 auto S = make_unique<ELFYAML::SymverSection>(); 516 if (std::error_code EC = dumpCommonSection(Shdr, *S)) 517 return EC; 518 519 auto VersionsOrErr = Obj.template getSectionContentsAsArray<Elf_Half>(Shdr); 520 if (!VersionsOrErr) 521 return errorToErrorCode(VersionsOrErr.takeError()); 522 for (const Elf_Half &E : *VersionsOrErr) 523 S->Entries.push_back(E); 524 525 return S.release(); 526 } 527 528 template <class ELFT> 529 ErrorOr<ELFYAML::VerneedSection *> 530 ELFDumper<ELFT>::dumpVerneedSection(const Elf_Shdr *Shdr) { 531 typedef typename ELFT::Verneed Elf_Verneed; 532 typedef typename ELFT::Vernaux Elf_Vernaux; 533 534 auto S = make_unique<ELFYAML::VerneedSection>(); 535 if (std::error_code EC = dumpCommonSection(Shdr, *S)) 536 return EC; 537 538 S->Info = Shdr->sh_info; 539 540 auto Contents = Obj.getSectionContents(Shdr); 541 if (!Contents) 542 return errorToErrorCode(Contents.takeError()); 543 544 auto StringTableShdrOrErr = Obj.getSection(Shdr->sh_link); 545 if (!StringTableShdrOrErr) 546 return errorToErrorCode(StringTableShdrOrErr.takeError()); 547 548 auto StringTableOrErr = Obj.getStringTable(*StringTableShdrOrErr); 549 if (!StringTableOrErr) 550 return errorToErrorCode(StringTableOrErr.takeError()); 551 552 llvm::ArrayRef<uint8_t> Data = *Contents; 553 const uint8_t *Buf = Data.data(); 554 while (Buf) { 555 const Elf_Verneed *Verneed = reinterpret_cast<const Elf_Verneed *>(Buf); 556 557 ELFYAML::VerneedEntry Entry; 558 Entry.Version = Verneed->vn_version; 559 Entry.File = 560 StringRef(StringTableOrErr->drop_front(Verneed->vn_file).data()); 561 562 const uint8_t *BufAux = Buf + Verneed->vn_aux; 563 while (BufAux) { 564 const Elf_Vernaux *Vernaux = 565 reinterpret_cast<const Elf_Vernaux *>(BufAux); 566 567 ELFYAML::VernauxEntry Aux; 568 Aux.Hash = Vernaux->vna_hash; 569 Aux.Flags = Vernaux->vna_flags; 570 Aux.Other = Vernaux->vna_other; 571 Aux.Name = 572 StringRef(StringTableOrErr->drop_front(Vernaux->vna_name).data()); 573 574 Entry.AuxV.push_back(Aux); 575 BufAux = Vernaux->vna_next ? BufAux + Vernaux->vna_next : nullptr; 576 } 577 578 S->VerneedV.push_back(Entry); 579 Buf = Verneed->vn_next ? Buf + Verneed->vn_next : nullptr; 580 } 581 582 return S.release(); 583 } 584 585 template <class ELFT> 586 ErrorOr<ELFYAML::Group *> ELFDumper<ELFT>::dumpGroup(const Elf_Shdr *Shdr) { 587 auto S = make_unique<ELFYAML::Group>(); 588 if (std::error_code EC = dumpCommonSection(Shdr, *S)) 589 return EC; 590 591 auto SymtabOrErr = Obj.getSection(Shdr->sh_link); 592 if (!SymtabOrErr) 593 return errorToErrorCode(SymtabOrErr.takeError()); 594 // Get symbol with index sh_info which name is the signature of the group. 595 const Elf_Shdr *Symtab = *SymtabOrErr; 596 auto SymOrErr = Obj.getSymbol(Symtab, Shdr->sh_info); 597 if (!SymOrErr) 598 return errorToErrorCode(SymOrErr.takeError()); 599 auto StrTabOrErr = Obj.getStringTableForSymtab(*Symtab); 600 if (!StrTabOrErr) 601 return errorToErrorCode(StrTabOrErr.takeError()); 602 603 Expected<StringRef> SymbolName = 604 getSymbolName(*SymOrErr, *StrTabOrErr, Symtab); 605 if (!SymbolName) 606 return errorToErrorCode(SymbolName.takeError()); 607 S->Signature = *SymbolName; 608 609 auto MembersOrErr = Obj.template getSectionContentsAsArray<Elf_Word>(Shdr); 610 if (!MembersOrErr) 611 return errorToErrorCode(MembersOrErr.takeError()); 612 613 for (Elf_Word Member : *MembersOrErr) { 614 if (Member == llvm::ELF::GRP_COMDAT) { 615 S->Members.push_back({"GRP_COMDAT"}); 616 continue; 617 } 618 619 auto SHdrOrErr = Obj.getSection(Member); 620 if (!SHdrOrErr) 621 return errorToErrorCode(SHdrOrErr.takeError()); 622 auto NameOrErr = getUniquedSectionName(*SHdrOrErr); 623 if (!NameOrErr) 624 return errorToErrorCode(NameOrErr.takeError()); 625 S->Members.push_back({*NameOrErr}); 626 } 627 return S.release(); 628 } 629 630 template <class ELFT> 631 ErrorOr<ELFYAML::MipsABIFlags *> 632 ELFDumper<ELFT>::dumpMipsABIFlags(const Elf_Shdr *Shdr) { 633 assert(Shdr->sh_type == ELF::SHT_MIPS_ABIFLAGS && 634 "Section type is not SHT_MIPS_ABIFLAGS"); 635 auto S = make_unique<ELFYAML::MipsABIFlags>(); 636 if (std::error_code EC = dumpCommonSection(Shdr, *S)) 637 return EC; 638 639 auto ContentOrErr = Obj.getSectionContents(Shdr); 640 if (!ContentOrErr) 641 return errorToErrorCode(ContentOrErr.takeError()); 642 643 auto *Flags = reinterpret_cast<const object::Elf_Mips_ABIFlags<ELFT> *>( 644 ContentOrErr.get().data()); 645 S->Version = Flags->version; 646 S->ISALevel = Flags->isa_level; 647 S->ISARevision = Flags->isa_rev; 648 S->GPRSize = Flags->gpr_size; 649 S->CPR1Size = Flags->cpr1_size; 650 S->CPR2Size = Flags->cpr2_size; 651 S->FpABI = Flags->fp_abi; 652 S->ISAExtension = Flags->isa_ext; 653 S->ASEs = Flags->ases; 654 S->Flags1 = Flags->flags1; 655 S->Flags2 = Flags->flags2; 656 return S.release(); 657 } 658 659 template <class ELFT> 660 static std::error_code elf2yaml(raw_ostream &Out, 661 const object::ELFFile<ELFT> &Obj) { 662 ELFDumper<ELFT> Dumper(Obj); 663 ErrorOr<ELFYAML::Object *> YAMLOrErr = Dumper.dump(); 664 if (std::error_code EC = YAMLOrErr.getError()) 665 return EC; 666 667 std::unique_ptr<ELFYAML::Object> YAML(YAMLOrErr.get()); 668 yaml::Output Yout(Out); 669 Yout << *YAML; 670 671 return std::error_code(); 672 } 673 674 std::error_code elf2yaml(raw_ostream &Out, const object::ObjectFile &Obj) { 675 if (const auto *ELFObj = dyn_cast<object::ELF32LEObjectFile>(&Obj)) 676 return elf2yaml(Out, *ELFObj->getELFFile()); 677 678 if (const auto *ELFObj = dyn_cast<object::ELF32BEObjectFile>(&Obj)) 679 return elf2yaml(Out, *ELFObj->getELFFile()); 680 681 if (const auto *ELFObj = dyn_cast<object::ELF64LEObjectFile>(&Obj)) 682 return elf2yaml(Out, *ELFObj->getELFFile()); 683 684 if (const auto *ELFObj = dyn_cast<object::ELF64BEObjectFile>(&Obj)) 685 return elf2yaml(Out, *ELFObj->getELFFile()); 686 687 return obj2yaml_error::unsupported_obj_file_format; 688 } 689