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 "obj2yaml.h" 12 #include "llvm/ADT/STLExtras.h" 13 #include "llvm/Object/ELFObjectFile.h" 14 #include "llvm/Object/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 object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr; 26 typedef typename object::ELFFile<ELFT>::Elf_Word Elf_Word; 27 28 const object::ELFFile<ELFT> &Obj; 29 ArrayRef<Elf_Word> ShndxTable; 30 31 std::error_code dumpSymbol(const Elf_Sym *Sym, const Elf_Shdr *SymTab, 32 StringRef StrTable, ELFYAML::Symbol &S); 33 std::error_code dumpCommonSection(const Elf_Shdr *Shdr, ELFYAML::Section &S); 34 std::error_code dumpCommonRelocationSection(const Elf_Shdr *Shdr, 35 ELFYAML::RelocationSection &S); 36 template <class RelT> 37 std::error_code dumpRelocation(const RelT *Rel, const Elf_Shdr *SymTab, 38 ELFYAML::Relocation &R); 39 40 ErrorOr<ELFYAML::RelocationSection *> dumpRelSection(const Elf_Shdr *Shdr); 41 ErrorOr<ELFYAML::RelocationSection *> dumpRelaSection(const Elf_Shdr *Shdr); 42 ErrorOr<ELFYAML::RawContentSection *> 43 dumpContentSection(const Elf_Shdr *Shdr); 44 ErrorOr<ELFYAML::NoBitsSection *> dumpNoBitsSection(const Elf_Shdr *Shdr); 45 ErrorOr<ELFYAML::Group *> dumpGroup(const Elf_Shdr *Shdr); 46 ErrorOr<ELFYAML::MipsABIFlags *> dumpMipsABIFlags(const Elf_Shdr *Shdr); 47 48 public: 49 ELFDumper(const object::ELFFile<ELFT> &O); 50 ErrorOr<ELFYAML::Object *> dump(); 51 }; 52 53 } 54 55 template <class ELFT> 56 ELFDumper<ELFT>::ELFDumper(const object::ELFFile<ELFT> &O) 57 : Obj(O) {} 58 59 template <class ELFT> 60 ErrorOr<ELFYAML::Object *> ELFDumper<ELFT>::dump() { 61 auto Y = make_unique<ELFYAML::Object>(); 62 63 // Dump header 64 Y->Header.Class = ELFYAML::ELF_ELFCLASS(Obj.getHeader()->getFileClass()); 65 Y->Header.Data = ELFYAML::ELF_ELFDATA(Obj.getHeader()->getDataEncoding()); 66 Y->Header.OSABI = Obj.getHeader()->e_ident[ELF::EI_OSABI]; 67 Y->Header.Type = Obj.getHeader()->e_type; 68 Y->Header.Machine = Obj.getHeader()->e_machine; 69 Y->Header.Flags = Obj.getHeader()->e_flags; 70 Y->Header.Entry = Obj.getHeader()->e_entry; 71 72 const Elf_Shdr *Symtab = nullptr; 73 74 // Dump sections 75 for (const Elf_Shdr &Sec : Obj.sections()) { 76 switch (Sec.sh_type) { 77 case ELF::SHT_NULL: 78 case ELF::SHT_DYNSYM: 79 case ELF::SHT_STRTAB: 80 // Do not dump these sections. 81 break; 82 case ELF::SHT_SYMTAB: 83 Symtab = &Sec; 84 break; 85 case ELF::SHT_SYMTAB_SHNDX: { 86 ErrorOr<ArrayRef<Elf_Word>> TableOrErr = Obj.getSHNDXTable(Sec); 87 if (std::error_code EC = TableOrErr.getError()) 88 return EC; 89 ShndxTable = *TableOrErr; 90 break; 91 } 92 case ELF::SHT_RELA: { 93 ErrorOr<ELFYAML::RelocationSection *> S = dumpRelaSection(&Sec); 94 if (std::error_code EC = S.getError()) 95 return EC; 96 Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get())); 97 break; 98 } 99 case ELF::SHT_REL: { 100 ErrorOr<ELFYAML::RelocationSection *> S = dumpRelSection(&Sec); 101 if (std::error_code EC = S.getError()) 102 return EC; 103 Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get())); 104 break; 105 } 106 case ELF::SHT_GROUP: { 107 ErrorOr<ELFYAML::Group *> G = dumpGroup(&Sec); 108 if (std::error_code EC = G.getError()) 109 return EC; 110 Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(G.get())); 111 break; 112 } 113 case ELF::SHT_MIPS_ABIFLAGS: { 114 ErrorOr<ELFYAML::MipsABIFlags *> G = dumpMipsABIFlags(&Sec); 115 if (std::error_code EC = G.getError()) 116 return EC; 117 Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(G.get())); 118 break; 119 } 120 case ELF::SHT_NOBITS: { 121 ErrorOr<ELFYAML::NoBitsSection *> S = dumpNoBitsSection(&Sec); 122 if (std::error_code EC = S.getError()) 123 return EC; 124 Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get())); 125 break; 126 } 127 default: { 128 ErrorOr<ELFYAML::RawContentSection *> S = dumpContentSection(&Sec); 129 if (std::error_code EC = S.getError()) 130 return EC; 131 Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get())); 132 } 133 } 134 } 135 136 // Dump symbols 137 ErrorOr<StringRef> StrTableOrErr = Obj.getStringTableForSymtab(*Symtab); 138 if (std::error_code EC = StrTableOrErr.getError()) 139 return EC; 140 StringRef StrTable = *StrTableOrErr; 141 142 bool IsFirstSym = true; 143 for (const Elf_Sym &Sym : Obj.symbols(Symtab)) { 144 if (IsFirstSym) { 145 IsFirstSym = false; 146 continue; 147 } 148 149 ELFYAML::Symbol S; 150 if (std::error_code EC = 151 ELFDumper<ELFT>::dumpSymbol(&Sym, Symtab, StrTable, S)) 152 return EC; 153 154 switch (Sym.getBinding()) 155 { 156 case ELF::STB_LOCAL: 157 Y->Symbols.Local.push_back(S); 158 break; 159 case ELF::STB_GLOBAL: 160 Y->Symbols.Global.push_back(S); 161 break; 162 case ELF::STB_WEAK: 163 Y->Symbols.Weak.push_back(S); 164 break; 165 default: 166 llvm_unreachable("Unknown ELF symbol binding"); 167 } 168 } 169 170 return Y.release(); 171 } 172 173 template <class ELFT> 174 std::error_code 175 ELFDumper<ELFT>::dumpSymbol(const Elf_Sym *Sym, const Elf_Shdr *SymTab, 176 StringRef StrTable, ELFYAML::Symbol &S) { 177 S.Type = Sym->getType(); 178 S.Value = Sym->st_value; 179 S.Size = Sym->st_size; 180 S.Other = Sym->st_other; 181 182 ErrorOr<StringRef> NameOrErr = Sym->getName(StrTable); 183 if (std::error_code EC = NameOrErr.getError()) 184 return EC; 185 S.Name = NameOrErr.get(); 186 187 ErrorOr<const Elf_Shdr *> ShdrOrErr = Obj.getSection(Sym, SymTab, ShndxTable); 188 if (std::error_code EC = ShdrOrErr.getError()) 189 return EC; 190 const Elf_Shdr *Shdr = *ShdrOrErr; 191 if (!Shdr) 192 return obj2yaml_error::success; 193 194 NameOrErr = Obj.getSectionName(Shdr); 195 if (std::error_code EC = NameOrErr.getError()) 196 return EC; 197 S.Section = NameOrErr.get(); 198 199 return obj2yaml_error::success; 200 } 201 202 template <class ELFT> 203 template <class RelT> 204 std::error_code ELFDumper<ELFT>::dumpRelocation(const RelT *Rel, 205 const Elf_Shdr *SymTab, 206 ELFYAML::Relocation &R) { 207 R.Type = Rel->getType(Obj.isMips64EL()); 208 R.Offset = Rel->r_offset; 209 R.Addend = 0; 210 211 const Elf_Sym *Sym = Obj.getRelocationSymbol(Rel, SymTab); 212 ErrorOr<const Elf_Shdr *> StrTabSec = Obj.getSection(SymTab->sh_link); 213 if (std::error_code EC = StrTabSec.getError()) 214 return EC; 215 ErrorOr<StringRef> StrTabOrErr = Obj.getStringTable(*StrTabSec); 216 if (std::error_code EC = StrTabOrErr.getError()) 217 return EC; 218 StringRef StrTab = *StrTabOrErr; 219 220 ErrorOr<StringRef> NameOrErr = Sym->getName(StrTab); 221 if (std::error_code EC = NameOrErr.getError()) 222 return EC; 223 R.Symbol = NameOrErr.get(); 224 225 return obj2yaml_error::success; 226 } 227 228 template <class ELFT> 229 std::error_code ELFDumper<ELFT>::dumpCommonSection(const Elf_Shdr *Shdr, 230 ELFYAML::Section &S) { 231 S.Type = Shdr->sh_type; 232 S.Flags = Shdr->sh_flags; 233 S.Address = Shdr->sh_addr; 234 S.AddressAlign = Shdr->sh_addralign; 235 236 ErrorOr<StringRef> NameOrErr = Obj.getSectionName(Shdr); 237 if (std::error_code EC = NameOrErr.getError()) 238 return EC; 239 S.Name = NameOrErr.get(); 240 241 if (Shdr->sh_link != ELF::SHN_UNDEF) { 242 ErrorOr<const Elf_Shdr *> LinkSection = Obj.getSection(Shdr->sh_link); 243 if (std::error_code EC = LinkSection.getError()) 244 return EC; 245 NameOrErr = Obj.getSectionName(*LinkSection); 246 if (std::error_code EC = NameOrErr.getError()) 247 return EC; 248 S.Link = NameOrErr.get(); 249 } 250 251 return obj2yaml_error::success; 252 } 253 254 template <class ELFT> 255 std::error_code 256 ELFDumper<ELFT>::dumpCommonRelocationSection(const Elf_Shdr *Shdr, 257 ELFYAML::RelocationSection &S) { 258 if (std::error_code EC = dumpCommonSection(Shdr, S)) 259 return EC; 260 261 ErrorOr<const Elf_Shdr *> InfoSection = Obj.getSection(Shdr->sh_info); 262 if (std::error_code EC = InfoSection.getError()) 263 return EC; 264 265 ErrorOr<StringRef> NameOrErr = Obj.getSectionName(*InfoSection); 266 if (std::error_code EC = NameOrErr.getError()) 267 return EC; 268 S.Info = NameOrErr.get(); 269 270 return obj2yaml_error::success; 271 } 272 273 template <class ELFT> 274 ErrorOr<ELFYAML::RelocationSection *> 275 ELFDumper<ELFT>::dumpRelSection(const Elf_Shdr *Shdr) { 276 assert(Shdr->sh_type == ELF::SHT_REL && "Section type is not SHT_REL"); 277 auto S = make_unique<ELFYAML::RelocationSection>(); 278 279 if (std::error_code EC = dumpCommonRelocationSection(Shdr, *S)) 280 return EC; 281 282 ErrorOr<const Elf_Shdr *> SymTabOrErr = Obj.getSection(Shdr->sh_link); 283 if (std::error_code EC = SymTabOrErr.getError()) 284 return EC; 285 const Elf_Shdr *SymTab = *SymTabOrErr; 286 287 for (auto RI = Obj.rel_begin(Shdr), RE = Obj.rel_end(Shdr); RI != RE; ++RI) { 288 ELFYAML::Relocation R; 289 if (std::error_code EC = dumpRelocation(&*RI, SymTab, R)) 290 return EC; 291 S->Relocations.push_back(R); 292 } 293 294 return S.release(); 295 } 296 297 template <class ELFT> 298 ErrorOr<ELFYAML::RelocationSection *> 299 ELFDumper<ELFT>::dumpRelaSection(const Elf_Shdr *Shdr) { 300 assert(Shdr->sh_type == ELF::SHT_RELA && "Section type is not SHT_RELA"); 301 auto S = make_unique<ELFYAML::RelocationSection>(); 302 303 if (std::error_code EC = dumpCommonRelocationSection(Shdr, *S)) 304 return EC; 305 306 ErrorOr<const Elf_Shdr *> SymTabOrErr = Obj.getSection(Shdr->sh_link); 307 if (std::error_code EC = SymTabOrErr.getError()) 308 return EC; 309 const Elf_Shdr *SymTab = *SymTabOrErr; 310 311 for (auto RI = Obj.rela_begin(Shdr), RE = Obj.rela_end(Shdr); RI != RE; 312 ++RI) { 313 ELFYAML::Relocation R; 314 if (std::error_code EC = dumpRelocation(&*RI, SymTab, R)) 315 return EC; 316 R.Addend = RI->r_addend; 317 S->Relocations.push_back(R); 318 } 319 320 return S.release(); 321 } 322 323 template <class ELFT> 324 ErrorOr<ELFYAML::RawContentSection *> 325 ELFDumper<ELFT>::dumpContentSection(const Elf_Shdr *Shdr) { 326 auto S = make_unique<ELFYAML::RawContentSection>(); 327 328 if (std::error_code EC = dumpCommonSection(Shdr, *S)) 329 return EC; 330 331 ErrorOr<ArrayRef<uint8_t>> ContentOrErr = Obj.getSectionContents(Shdr); 332 if (std::error_code EC = ContentOrErr.getError()) 333 return EC; 334 S->Content = yaml::BinaryRef(ContentOrErr.get()); 335 S->Size = S->Content.binary_size(); 336 337 return S.release(); 338 } 339 340 template <class ELFT> 341 ErrorOr<ELFYAML::NoBitsSection *> 342 ELFDumper<ELFT>::dumpNoBitsSection(const Elf_Shdr *Shdr) { 343 auto S = make_unique<ELFYAML::NoBitsSection>(); 344 345 if (std::error_code EC = dumpCommonSection(Shdr, *S)) 346 return EC; 347 S->Size = Shdr->sh_size; 348 349 return S.release(); 350 } 351 352 template <class ELFT> 353 ErrorOr<ELFYAML::Group *> ELFDumper<ELFT>::dumpGroup(const Elf_Shdr *Shdr) { 354 auto S = make_unique<ELFYAML::Group>(); 355 356 if (std::error_code EC = dumpCommonSection(Shdr, *S)) 357 return EC; 358 // Get sh_info which is the signature. 359 ErrorOr<const Elf_Shdr *> SymtabOrErr = Obj.getSection(Shdr->sh_link); 360 if (std::error_code EC = SymtabOrErr.getError()) 361 return EC; 362 const Elf_Shdr *Symtab = *SymtabOrErr; 363 const Elf_Sym *symbol = Obj.getSymbol(Symtab, Shdr->sh_info); 364 ErrorOr<StringRef> StrTabOrErr = Obj.getStringTableForSymtab(*Symtab); 365 if (std::error_code EC = StrTabOrErr.getError()) 366 return EC; 367 StringRef StrTab = *StrTabOrErr; 368 auto sectionContents = Obj.getSectionContents(Shdr); 369 if (std::error_code ec = sectionContents.getError()) 370 return ec; 371 ErrorOr<StringRef> symbolName = symbol->getName(StrTab); 372 if (std::error_code EC = symbolName.getError()) 373 return EC; 374 S->Info = *symbolName; 375 const Elf_Word *groupMembers = 376 reinterpret_cast<const Elf_Word *>(sectionContents->data()); 377 const long count = (Shdr->sh_size) / sizeof(Elf_Word); 378 ELFYAML::SectionOrType s; 379 for (int i = 0; i < count; i++) { 380 if (groupMembers[i] == llvm::ELF::GRP_COMDAT) { 381 s.sectionNameOrType = "GRP_COMDAT"; 382 } else { 383 ErrorOr<const Elf_Shdr *> sHdr = Obj.getSection(groupMembers[i]); 384 if (std::error_code EC = sHdr.getError()) 385 return EC; 386 ErrorOr<StringRef> sectionName = Obj.getSectionName(*sHdr); 387 if (std::error_code ec = sectionName.getError()) 388 return ec; 389 s.sectionNameOrType = *sectionName; 390 } 391 S->Members.push_back(s); 392 } 393 return S.release(); 394 } 395 396 template <class ELFT> 397 ErrorOr<ELFYAML::MipsABIFlags *> 398 ELFDumper<ELFT>::dumpMipsABIFlags(const Elf_Shdr *Shdr) { 399 assert(Shdr->sh_type == ELF::SHT_MIPS_ABIFLAGS && 400 "Section type is not SHT_MIPS_ABIFLAGS"); 401 auto S = make_unique<ELFYAML::MipsABIFlags>(); 402 if (std::error_code EC = dumpCommonSection(Shdr, *S)) 403 return EC; 404 405 ErrorOr<ArrayRef<uint8_t>> ContentOrErr = Obj.getSectionContents(Shdr); 406 if (std::error_code EC = ContentOrErr.getError()) 407 return EC; 408 409 auto *Flags = reinterpret_cast<const object::Elf_Mips_ABIFlags<ELFT> *>( 410 ContentOrErr.get().data()); 411 S->Version = Flags->version; 412 S->ISALevel = Flags->isa_level; 413 S->ISARevision = Flags->isa_rev; 414 S->GPRSize = Flags->gpr_size; 415 S->CPR1Size = Flags->cpr1_size; 416 S->CPR2Size = Flags->cpr2_size; 417 S->FpABI = Flags->fp_abi; 418 S->ISAExtension = Flags->isa_ext; 419 S->ASEs = Flags->ases; 420 S->Flags1 = Flags->flags1; 421 S->Flags2 = Flags->flags2; 422 return S.release(); 423 } 424 425 template <class ELFT> 426 static std::error_code elf2yaml(raw_ostream &Out, 427 const object::ELFFile<ELFT> &Obj) { 428 ELFDumper<ELFT> Dumper(Obj); 429 ErrorOr<ELFYAML::Object *> YAMLOrErr = Dumper.dump(); 430 if (std::error_code EC = YAMLOrErr.getError()) 431 return EC; 432 433 std::unique_ptr<ELFYAML::Object> YAML(YAMLOrErr.get()); 434 yaml::Output Yout(Out); 435 Yout << *YAML; 436 437 return std::error_code(); 438 } 439 440 std::error_code elf2yaml(raw_ostream &Out, const object::ObjectFile &Obj) { 441 if (const auto *ELFObj = dyn_cast<object::ELF32LEObjectFile>(&Obj)) 442 return elf2yaml(Out, *ELFObj->getELFFile()); 443 444 if (const auto *ELFObj = dyn_cast<object::ELF32BEObjectFile>(&Obj)) 445 return elf2yaml(Out, *ELFObj->getELFFile()); 446 447 if (const auto *ELFObj = dyn_cast<object::ELF64LEObjectFile>(&Obj)) 448 return elf2yaml(Out, *ELFObj->getELFFile()); 449 450 if (const auto *ELFObj = dyn_cast<object::ELF64BEObjectFile>(&Obj)) 451 return elf2yaml(Out, *ELFObj->getELFFile()); 452 453 return obj2yaml_error::unsupported_obj_file_format; 454 } 455