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