1 //===------ utils/elf2yaml.cpp - obj2yaml conversion tool -------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "Error.h" 11 #include "llvm/ADT/DenseSet.h" 12 #include "llvm/ADT/STLExtras.h" 13 #include "llvm/Object/ELFObjectFile.h" 14 #include "llvm/ObjectYAML/ELFYAML.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::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 ELFYAML::LocalGlobalWeakSymbols &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::RelocationSection *> dumpRelSection(const Elf_Shdr *Shdr); 56 ErrorOr<ELFYAML::RelocationSection *> dumpRelaSection(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::Group *> dumpGroup(const Elf_Shdr *Shdr); 61 ErrorOr<ELFYAML::MipsABIFlags *> dumpMipsABIFlags(const Elf_Shdr *Shdr); 62 63 public: 64 ELFDumper(const object::ELFFile<ELFT> &O); 65 ErrorOr<ELFYAML::Object *> dump(); 66 }; 67 68 } 69 70 template <class ELFT> 71 ELFDumper<ELFT>::ELFDumper(const object::ELFFile<ELFT> &O) 72 : Obj(O) {} 73 74 template <class ELFT> 75 Expected<StringRef> 76 ELFDumper<ELFT>::getUniquedSectionName(const Elf_Shdr *Sec) { 77 unsigned SecIndex = Sec - &Sections[0]; 78 assert(&Sections[SecIndex] == Sec); 79 if (!SectionNames[SecIndex].empty()) 80 return SectionNames[SecIndex]; 81 82 auto NameOrErr = Obj.getSectionName(Sec); 83 if (!NameOrErr) 84 return NameOrErr; 85 StringRef Name = *NameOrErr; 86 std::string &Ret = SectionNames[SecIndex]; 87 Ret = Name; 88 while (!UsedSectionNames.insert(Ret).second) 89 Ret = (Name + to_string(++Suffix)).str(); 90 return Ret; 91 } 92 93 template <class ELFT> 94 Expected<StringRef> ELFDumper<ELFT>::getSymbolName(const Elf_Sym *Sym, 95 StringRef StrTable, 96 const Elf_Shdr *SymTab) { 97 Expected<StringRef> SymbolNameOrErr = Sym->getName(StrTable); 98 if (!SymbolNameOrErr) 99 return SymbolNameOrErr; 100 StringRef Name = *SymbolNameOrErr; 101 if (Name.empty() && Sym->getType() == ELF::STT_SECTION) { 102 auto ShdrOrErr = Obj.getSection(Sym, SymTab, ShndxTable); 103 if (!ShdrOrErr) 104 return ShdrOrErr.takeError(); 105 return getUniquedSectionName(*ShdrOrErr); 106 } 107 return Name; 108 } 109 110 template <class ELFT> ErrorOr<ELFYAML::Object *> ELFDumper<ELFT>::dump() { 111 auto Y = make_unique<ELFYAML::Object>(); 112 113 // Dump header 114 Y->Header.Class = ELFYAML::ELF_ELFCLASS(Obj.getHeader()->getFileClass()); 115 Y->Header.Data = ELFYAML::ELF_ELFDATA(Obj.getHeader()->getDataEncoding()); 116 Y->Header.OSABI = Obj.getHeader()->e_ident[ELF::EI_OSABI]; 117 Y->Header.ABIVersion = Obj.getHeader()->e_ident[ELF::EI_ABIVERSION]; 118 Y->Header.Type = Obj.getHeader()->e_type; 119 Y->Header.Machine = Obj.getHeader()->e_machine; 120 Y->Header.Flags = Obj.getHeader()->e_flags; 121 Y->Header.Entry = Obj.getHeader()->e_entry; 122 123 const Elf_Shdr *Symtab = nullptr; 124 const Elf_Shdr *DynSymtab = nullptr; 125 126 // Dump sections 127 auto SectionsOrErr = Obj.sections(); 128 if (!SectionsOrErr) 129 return errorToErrorCode(SectionsOrErr.takeError()); 130 Sections = *SectionsOrErr; 131 SectionNames.resize(Sections.size()); 132 for (const Elf_Shdr &Sec : Sections) { 133 switch (Sec.sh_type) { 134 case ELF::SHT_NULL: 135 case ELF::SHT_STRTAB: 136 // Do not dump these sections. 137 break; 138 case ELF::SHT_SYMTAB: 139 Symtab = &Sec; 140 break; 141 case ELF::SHT_DYNSYM: 142 DynSymtab = &Sec; 143 break; 144 case ELF::SHT_SYMTAB_SHNDX: { 145 auto TableOrErr = Obj.getSHNDXTable(Sec); 146 if (!TableOrErr) 147 return errorToErrorCode(TableOrErr.takeError()); 148 ShndxTable = *TableOrErr; 149 break; 150 } 151 case ELF::SHT_RELA: { 152 ErrorOr<ELFYAML::RelocationSection *> S = dumpRelaSection(&Sec); 153 if (std::error_code EC = S.getError()) 154 return EC; 155 Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get())); 156 break; 157 } 158 case ELF::SHT_REL: { 159 ErrorOr<ELFYAML::RelocationSection *> S = dumpRelSection(&Sec); 160 if (std::error_code EC = S.getError()) 161 return EC; 162 Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get())); 163 break; 164 } 165 case ELF::SHT_GROUP: { 166 ErrorOr<ELFYAML::Group *> G = dumpGroup(&Sec); 167 if (std::error_code EC = G.getError()) 168 return EC; 169 Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(G.get())); 170 break; 171 } 172 case ELF::SHT_MIPS_ABIFLAGS: { 173 ErrorOr<ELFYAML::MipsABIFlags *> G = dumpMipsABIFlags(&Sec); 174 if (std::error_code EC = G.getError()) 175 return EC; 176 Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(G.get())); 177 break; 178 } 179 case ELF::SHT_NOBITS: { 180 ErrorOr<ELFYAML::NoBitsSection *> S = dumpNoBitsSection(&Sec); 181 if (std::error_code EC = S.getError()) 182 return EC; 183 Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get())); 184 break; 185 } 186 default: { 187 ErrorOr<ELFYAML::RawContentSection *> S = dumpContentSection(&Sec); 188 if (std::error_code EC = S.getError()) 189 return EC; 190 Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get())); 191 } 192 } 193 } 194 195 if (auto EC = dumpSymbols(Symtab, Y->Symbols)) 196 return EC; 197 if (auto EC = dumpSymbols(DynSymtab, Y->DynamicSymbols)) 198 return EC; 199 200 return Y.release(); 201 } 202 203 template <class ELFT> 204 std::error_code 205 ELFDumper<ELFT>::dumpSymbols(const Elf_Shdr *Symtab, 206 ELFYAML::LocalGlobalWeakSymbols &Symbols) { 207 if (!Symtab) 208 return std::error_code(); 209 210 auto StrTableOrErr = Obj.getStringTableForSymtab(*Symtab); 211 if (!StrTableOrErr) 212 return errorToErrorCode(StrTableOrErr.takeError()); 213 StringRef StrTable = *StrTableOrErr; 214 215 auto SymtabOrErr = Obj.symbols(Symtab); 216 if (!SymtabOrErr) 217 return errorToErrorCode(SymtabOrErr.takeError()); 218 219 bool IsFirstSym = true; 220 for (const auto &Sym : *SymtabOrErr) { 221 if (IsFirstSym) { 222 IsFirstSym = false; 223 continue; 224 } 225 226 ELFYAML::Symbol S; 227 if (auto EC = dumpSymbol(&Sym, Symtab, StrTable, S)) 228 return EC; 229 230 switch (Sym.getBinding()) { 231 case ELF::STB_LOCAL: 232 Symbols.Local.push_back(S); 233 break; 234 case ELF::STB_GLOBAL: 235 Symbols.Global.push_back(S); 236 break; 237 case ELF::STB_WEAK: 238 Symbols.Weak.push_back(S); 239 break; 240 default: 241 llvm_unreachable("Unknown ELF symbol binding"); 242 } 243 } 244 245 return std::error_code(); 246 } 247 248 template <class ELFT> 249 std::error_code 250 ELFDumper<ELFT>::dumpSymbol(const Elf_Sym *Sym, const Elf_Shdr *SymTab, 251 StringRef StrTable, ELFYAML::Symbol &S) { 252 S.Type = Sym->getType(); 253 S.Value = Sym->st_value; 254 S.Size = Sym->st_size; 255 S.Other = Sym->st_other; 256 257 Expected<StringRef> SymbolNameOrErr = getSymbolName(Sym, StrTable, SymTab); 258 if (!SymbolNameOrErr) 259 return errorToErrorCode(SymbolNameOrErr.takeError()); 260 S.Name = SymbolNameOrErr.get(); 261 262 auto ShdrOrErr = Obj.getSection(Sym, SymTab, ShndxTable); 263 if (!ShdrOrErr) 264 return errorToErrorCode(ShdrOrErr.takeError()); 265 const Elf_Shdr *Shdr = *ShdrOrErr; 266 if (!Shdr) 267 return obj2yaml_error::success; 268 269 auto NameOrErr = getUniquedSectionName(Shdr); 270 if (!NameOrErr) 271 return errorToErrorCode(NameOrErr.takeError()); 272 S.Section = NameOrErr.get(); 273 274 return obj2yaml_error::success; 275 } 276 277 template <class ELFT> 278 template <class RelT> 279 std::error_code ELFDumper<ELFT>::dumpRelocation(const RelT *Rel, 280 const Elf_Shdr *SymTab, 281 ELFYAML::Relocation &R) { 282 R.Type = Rel->getType(Obj.isMips64EL()); 283 R.Offset = Rel->r_offset; 284 R.Addend = 0; 285 286 auto SymOrErr = Obj.getRelocationSymbol(Rel, SymTab); 287 if (!SymOrErr) 288 return errorToErrorCode(SymOrErr.takeError()); 289 const Elf_Sym *Sym = *SymOrErr; 290 auto StrTabSec = Obj.getSection(SymTab->sh_link); 291 if (!StrTabSec) 292 return errorToErrorCode(StrTabSec.takeError()); 293 auto StrTabOrErr = Obj.getStringTable(*StrTabSec); 294 if (!StrTabOrErr) 295 return errorToErrorCode(StrTabOrErr.takeError()); 296 StringRef StrTab = *StrTabOrErr; 297 298 if (Sym) { 299 Expected<StringRef> NameOrErr = getSymbolName(Sym, StrTab, SymTab); 300 if (!NameOrErr) 301 return errorToErrorCode(NameOrErr.takeError()); 302 R.Symbol = NameOrErr.get(); 303 } else { 304 // We have some edge cases of relocations without a symbol associated, 305 // e.g. an object containing the invalid (according to the System V 306 // ABI) R_X86_64_NONE reloc. Create a symbol with an empty name instead 307 // of crashing. 308 R.Symbol = ""; 309 } 310 311 return obj2yaml_error::success; 312 } 313 314 template <class ELFT> 315 std::error_code ELFDumper<ELFT>::dumpCommonSection(const Elf_Shdr *Shdr, 316 ELFYAML::Section &S) { 317 S.Type = Shdr->sh_type; 318 S.Flags = Shdr->sh_flags; 319 S.Address = Shdr->sh_addr; 320 S.AddressAlign = Shdr->sh_addralign; 321 322 auto NameOrErr = getUniquedSectionName(Shdr); 323 if (!NameOrErr) 324 return errorToErrorCode(NameOrErr.takeError()); 325 S.Name = NameOrErr.get(); 326 327 if (Shdr->sh_link != ELF::SHN_UNDEF) { 328 auto LinkSection = Obj.getSection(Shdr->sh_link); 329 if (LinkSection.takeError()) 330 return errorToErrorCode(LinkSection.takeError()); 331 NameOrErr = getUniquedSectionName(*LinkSection); 332 if (!NameOrErr) 333 return errorToErrorCode(NameOrErr.takeError()); 334 S.Link = NameOrErr.get(); 335 } 336 337 return obj2yaml_error::success; 338 } 339 340 template <class ELFT> 341 std::error_code 342 ELFDumper<ELFT>::dumpCommonRelocationSection(const Elf_Shdr *Shdr, 343 ELFYAML::RelocationSection &S) { 344 if (std::error_code EC = dumpCommonSection(Shdr, S)) 345 return EC; 346 347 auto InfoSection = Obj.getSection(Shdr->sh_info); 348 if (!InfoSection) 349 return errorToErrorCode(InfoSection.takeError()); 350 351 auto NameOrErr = getUniquedSectionName(*InfoSection); 352 if (!NameOrErr) 353 return errorToErrorCode(NameOrErr.takeError()); 354 S.Info = NameOrErr.get(); 355 356 return obj2yaml_error::success; 357 } 358 359 template <class ELFT> 360 ErrorOr<ELFYAML::RelocationSection *> 361 ELFDumper<ELFT>::dumpRelSection(const Elf_Shdr *Shdr) { 362 assert(Shdr->sh_type == ELF::SHT_REL && "Section type is not SHT_REL"); 363 auto S = make_unique<ELFYAML::RelocationSection>(); 364 365 if (std::error_code EC = dumpCommonRelocationSection(Shdr, *S)) 366 return EC; 367 368 auto SymTabOrErr = Obj.getSection(Shdr->sh_link); 369 if (!SymTabOrErr) 370 return errorToErrorCode(SymTabOrErr.takeError()); 371 const Elf_Shdr *SymTab = *SymTabOrErr; 372 373 auto Rels = Obj.rels(Shdr); 374 if (!Rels) 375 return errorToErrorCode(Rels.takeError()); 376 for (const Elf_Rel &Rel : *Rels) { 377 ELFYAML::Relocation R; 378 if (std::error_code EC = dumpRelocation(&Rel, SymTab, R)) 379 return EC; 380 S->Relocations.push_back(R); 381 } 382 383 return S.release(); 384 } 385 386 template <class ELFT> 387 ErrorOr<ELFYAML::RelocationSection *> 388 ELFDumper<ELFT>::dumpRelaSection(const Elf_Shdr *Shdr) { 389 assert(Shdr->sh_type == ELF::SHT_RELA && "Section type is not SHT_RELA"); 390 auto S = make_unique<ELFYAML::RelocationSection>(); 391 392 if (std::error_code EC = dumpCommonRelocationSection(Shdr, *S)) 393 return EC; 394 395 auto SymTabOrErr = Obj.getSection(Shdr->sh_link); 396 if (!SymTabOrErr) 397 return errorToErrorCode(SymTabOrErr.takeError()); 398 const Elf_Shdr *SymTab = *SymTabOrErr; 399 400 auto Rels = Obj.relas(Shdr); 401 if (!Rels) 402 return errorToErrorCode(Rels.takeError()); 403 for (const Elf_Rela &Rel : *Rels) { 404 ELFYAML::Relocation R; 405 if (std::error_code EC = dumpRelocation(&Rel, SymTab, R)) 406 return EC; 407 R.Addend = Rel.r_addend; 408 S->Relocations.push_back(R); 409 } 410 411 return S.release(); 412 } 413 414 template <class ELFT> 415 ErrorOr<ELFYAML::RawContentSection *> 416 ELFDumper<ELFT>::dumpContentSection(const Elf_Shdr *Shdr) { 417 auto S = make_unique<ELFYAML::RawContentSection>(); 418 419 if (std::error_code EC = dumpCommonSection(Shdr, *S)) 420 return EC; 421 422 auto ContentOrErr = Obj.getSectionContents(Shdr); 423 if (!ContentOrErr) 424 return errorToErrorCode(ContentOrErr.takeError()); 425 S->Content = yaml::BinaryRef(ContentOrErr.get()); 426 S->Size = S->Content.binary_size(); 427 428 return S.release(); 429 } 430 431 template <class ELFT> 432 ErrorOr<ELFYAML::NoBitsSection *> 433 ELFDumper<ELFT>::dumpNoBitsSection(const Elf_Shdr *Shdr) { 434 auto S = make_unique<ELFYAML::NoBitsSection>(); 435 436 if (std::error_code EC = dumpCommonSection(Shdr, *S)) 437 return EC; 438 S->Size = Shdr->sh_size; 439 440 return S.release(); 441 } 442 443 template <class ELFT> 444 ErrorOr<ELFYAML::Group *> ELFDumper<ELFT>::dumpGroup(const Elf_Shdr *Shdr) { 445 auto S = make_unique<ELFYAML::Group>(); 446 447 if (std::error_code EC = dumpCommonSection(Shdr, *S)) 448 return EC; 449 // Get sh_info which is the signature. 450 auto SymtabOrErr = Obj.getSection(Shdr->sh_link); 451 if (!SymtabOrErr) 452 return errorToErrorCode(SymtabOrErr.takeError()); 453 const Elf_Shdr *Symtab = *SymtabOrErr; 454 auto SymOrErr = Obj.getSymbol(Symtab, Shdr->sh_info); 455 if (!SymOrErr) 456 return errorToErrorCode(SymOrErr.takeError()); 457 const Elf_Sym *symbol = *SymOrErr; 458 auto StrTabOrErr = Obj.getStringTableForSymtab(*Symtab); 459 if (!StrTabOrErr) 460 return errorToErrorCode(StrTabOrErr.takeError()); 461 StringRef StrTab = *StrTabOrErr; 462 auto sectionContents = Obj.getSectionContents(Shdr); 463 if (!sectionContents) 464 return errorToErrorCode(sectionContents.takeError()); 465 Expected<StringRef> symbolName = getSymbolName(symbol, StrTab, Symtab); 466 if (!symbolName) 467 return errorToErrorCode(symbolName.takeError()); 468 S->Info = *symbolName; 469 const Elf_Word *groupMembers = 470 reinterpret_cast<const Elf_Word *>(sectionContents->data()); 471 const long count = (Shdr->sh_size) / sizeof(Elf_Word); 472 ELFYAML::SectionOrType s; 473 for (int i = 0; i < count; i++) { 474 if (groupMembers[i] == llvm::ELF::GRP_COMDAT) { 475 s.sectionNameOrType = "GRP_COMDAT"; 476 } else { 477 auto sHdr = Obj.getSection(groupMembers[i]); 478 if (!sHdr) 479 return errorToErrorCode(sHdr.takeError()); 480 auto sectionName = getUniquedSectionName(*sHdr); 481 if (!sectionName) 482 return errorToErrorCode(sectionName.takeError()); 483 s.sectionNameOrType = *sectionName; 484 } 485 S->Members.push_back(s); 486 } 487 return S.release(); 488 } 489 490 template <class ELFT> 491 ErrorOr<ELFYAML::MipsABIFlags *> 492 ELFDumper<ELFT>::dumpMipsABIFlags(const Elf_Shdr *Shdr) { 493 assert(Shdr->sh_type == ELF::SHT_MIPS_ABIFLAGS && 494 "Section type is not SHT_MIPS_ABIFLAGS"); 495 auto S = make_unique<ELFYAML::MipsABIFlags>(); 496 if (std::error_code EC = dumpCommonSection(Shdr, *S)) 497 return EC; 498 499 auto ContentOrErr = Obj.getSectionContents(Shdr); 500 if (!ContentOrErr) 501 return errorToErrorCode(ContentOrErr.takeError()); 502 503 auto *Flags = reinterpret_cast<const object::Elf_Mips_ABIFlags<ELFT> *>( 504 ContentOrErr.get().data()); 505 S->Version = Flags->version; 506 S->ISALevel = Flags->isa_level; 507 S->ISARevision = Flags->isa_rev; 508 S->GPRSize = Flags->gpr_size; 509 S->CPR1Size = Flags->cpr1_size; 510 S->CPR2Size = Flags->cpr2_size; 511 S->FpABI = Flags->fp_abi; 512 S->ISAExtension = Flags->isa_ext; 513 S->ASEs = Flags->ases; 514 S->Flags1 = Flags->flags1; 515 S->Flags2 = Flags->flags2; 516 return S.release(); 517 } 518 519 template <class ELFT> 520 static std::error_code elf2yaml(raw_ostream &Out, 521 const object::ELFFile<ELFT> &Obj) { 522 ELFDumper<ELFT> Dumper(Obj); 523 ErrorOr<ELFYAML::Object *> YAMLOrErr = Dumper.dump(); 524 if (std::error_code EC = YAMLOrErr.getError()) 525 return EC; 526 527 std::unique_ptr<ELFYAML::Object> YAML(YAMLOrErr.get()); 528 yaml::Output Yout(Out); 529 Yout << *YAML; 530 531 return std::error_code(); 532 } 533 534 std::error_code elf2yaml(raw_ostream &Out, const object::ObjectFile &Obj) { 535 if (const auto *ELFObj = dyn_cast<object::ELF32LEObjectFile>(&Obj)) 536 return elf2yaml(Out, *ELFObj->getELFFile()); 537 538 if (const auto *ELFObj = dyn_cast<object::ELF32BEObjectFile>(&Obj)) 539 return elf2yaml(Out, *ELFObj->getELFFile()); 540 541 if (const auto *ELFObj = dyn_cast<object::ELF64LEObjectFile>(&Obj)) 542 return elf2yaml(Out, *ELFObj->getELFFile()); 543 544 if (const auto *ELFObj = dyn_cast<object::ELF64BEObjectFile>(&Obj)) 545 return elf2yaml(Out, *ELFObj->getELFFile()); 546 547 return obj2yaml_error::unsupported_obj_file_format; 548 } 549