1 //===-- llvm-objdump.cpp - Object file dumping utility for llvm -----------===// 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 // This program is a utility that works like binutils "objdump", that is, it 11 // dumps out a plethora of information about an object file depending on the 12 // flags. 13 // 14 // The flags and output of this program should be near identical to those of 15 // binutils objdump. 16 // 17 //===----------------------------------------------------------------------===// 18 19 #include "llvm-objdump.h" 20 #include "llvm/ADT/STLExtras.h" 21 #include "llvm/ADT/StringExtras.h" 22 #include "llvm/ADT/Triple.h" 23 #include "llvm/MC/MCAsmInfo.h" 24 #include "llvm/MC/MCContext.h" 25 #include "llvm/MC/MCDisassembler.h" 26 #include "llvm/MC/MCInst.h" 27 #include "llvm/MC/MCInstPrinter.h" 28 #include "llvm/MC/MCInstrAnalysis.h" 29 #include "llvm/MC/MCInstrInfo.h" 30 #include "llvm/MC/MCObjectFileInfo.h" 31 #include "llvm/MC/MCRegisterInfo.h" 32 #include "llvm/MC/MCRelocationInfo.h" 33 #include "llvm/MC/MCSubtargetInfo.h" 34 #include "llvm/Object/Archive.h" 35 #include "llvm/Object/COFF.h" 36 #include "llvm/Object/MachO.h" 37 #include "llvm/Object/ObjectFile.h" 38 #include "llvm/Support/Casting.h" 39 #include "llvm/Support/CommandLine.h" 40 #include "llvm/Support/Debug.h" 41 #include "llvm/Support/FileSystem.h" 42 #include "llvm/Support/Format.h" 43 #include "llvm/Support/GraphWriter.h" 44 #include "llvm/Support/Host.h" 45 #include "llvm/Support/ManagedStatic.h" 46 #include "llvm/Support/MemoryBuffer.h" 47 #include "llvm/Support/MemoryObject.h" 48 #include "llvm/Support/PrettyStackTrace.h" 49 #include "llvm/Support/Signals.h" 50 #include "llvm/Support/SourceMgr.h" 51 #include "llvm/Support/TargetRegistry.h" 52 #include "llvm/Support/TargetSelect.h" 53 #include "llvm/Support/raw_ostream.h" 54 #include <algorithm> 55 #include <cctype> 56 #include <cstring> 57 #include <system_error> 58 59 using namespace llvm; 60 using namespace object; 61 62 static cl::list<std::string> 63 InputFilenames(cl::Positional, cl::desc("<input object files>"),cl::ZeroOrMore); 64 65 static cl::opt<bool> 66 Disassemble("disassemble", 67 cl::desc("Display assembler mnemonics for the machine instructions")); 68 static cl::alias 69 Disassembled("d", cl::desc("Alias for --disassemble"), 70 cl::aliasopt(Disassemble)); 71 72 static cl::opt<bool> 73 Relocations("r", cl::desc("Display the relocation entries in the file")); 74 75 static cl::opt<bool> 76 SectionContents("s", cl::desc("Display the content of each section")); 77 78 static cl::opt<bool> 79 SymbolTable("t", cl::desc("Display the symbol table")); 80 81 static cl::opt<bool> 82 ExportsTrie("exports-trie", cl::desc("Display mach-o exported symbols")); 83 84 static cl::opt<bool> 85 Rebase("rebase", cl::desc("Display mach-o rebasing info")); 86 87 static cl::opt<bool> 88 MachOOpt("macho", cl::desc("Use MachO specific object file parser")); 89 static cl::alias 90 MachOm("m", cl::desc("Alias for --macho"), cl::aliasopt(MachOOpt)); 91 92 cl::opt<std::string> 93 llvm::TripleName("triple", cl::desc("Target triple to disassemble for, " 94 "see -version for available targets")); 95 96 cl::opt<std::string> 97 llvm::MCPU("mcpu", 98 cl::desc("Target a specific cpu type (-mcpu=help for details)"), 99 cl::value_desc("cpu-name"), 100 cl::init("")); 101 102 cl::opt<std::string> 103 llvm::ArchName("arch", cl::desc("Target arch to disassemble for, " 104 "see -version for available targets")); 105 106 static cl::opt<bool> 107 SectionHeaders("section-headers", cl::desc("Display summaries of the headers " 108 "for each section.")); 109 static cl::alias 110 SectionHeadersShort("headers", cl::desc("Alias for --section-headers"), 111 cl::aliasopt(SectionHeaders)); 112 static cl::alias 113 SectionHeadersShorter("h", cl::desc("Alias for --section-headers"), 114 cl::aliasopt(SectionHeaders)); 115 116 cl::list<std::string> 117 llvm::MAttrs("mattr", 118 cl::CommaSeparated, 119 cl::desc("Target specific attributes"), 120 cl::value_desc("a1,+a2,-a3,...")); 121 122 static cl::opt<bool> 123 NoShowRawInsn("no-show-raw-insn", cl::desc("When disassembling instructions, " 124 "do not print the instruction bytes.")); 125 126 static cl::opt<bool> 127 UnwindInfo("unwind-info", cl::desc("Display unwind information")); 128 129 static cl::alias 130 UnwindInfoShort("u", cl::desc("Alias for --unwind-info"), 131 cl::aliasopt(UnwindInfo)); 132 133 static cl::opt<bool> 134 PrivateHeaders("private-headers", 135 cl::desc("Display format specific file headers")); 136 137 static cl::alias 138 PrivateHeadersShort("p", cl::desc("Alias for --private-headers"), 139 cl::aliasopt(PrivateHeaders)); 140 141 static StringRef ToolName; 142 143 bool llvm::error(std::error_code EC) { 144 if (!EC) 145 return false; 146 147 outs() << ToolName << ": error reading file: " << EC.message() << ".\n"; 148 outs().flush(); 149 return true; 150 } 151 152 static const Target *getTarget(const ObjectFile *Obj = nullptr) { 153 // Figure out the target triple. 154 llvm::Triple TheTriple("unknown-unknown-unknown"); 155 if (TripleName.empty()) { 156 if (Obj) { 157 TheTriple.setArch(Triple::ArchType(Obj->getArch())); 158 // TheTriple defaults to ELF, and COFF doesn't have an environment: 159 // the best we can do here is indicate that it is mach-o. 160 if (Obj->isMachO()) 161 TheTriple.setObjectFormat(Triple::MachO); 162 163 if (Obj->isCOFF()) { 164 const auto COFFObj = dyn_cast<COFFObjectFile>(Obj); 165 if (COFFObj->getArch() == Triple::thumb) 166 TheTriple.setTriple("thumbv7-windows"); 167 } 168 } 169 } else 170 TheTriple.setTriple(Triple::normalize(TripleName)); 171 172 // Get the target specific parser. 173 std::string Error; 174 const Target *TheTarget = TargetRegistry::lookupTarget(ArchName, TheTriple, 175 Error); 176 if (!TheTarget) { 177 errs() << ToolName << ": " << Error; 178 return nullptr; 179 } 180 181 // Update the triple name and return the found target. 182 TripleName = TheTriple.getTriple(); 183 return TheTarget; 184 } 185 186 void llvm::DumpBytes(StringRef bytes) { 187 static const char hex_rep[] = "0123456789abcdef"; 188 // FIXME: The real way to do this is to figure out the longest instruction 189 // and align to that size before printing. I'll fix this when I get 190 // around to outputting relocations. 191 // 15 is the longest x86 instruction 192 // 3 is for the hex rep of a byte + a space. 193 // 1 is for the null terminator. 194 enum { OutputSize = (15 * 3) + 1 }; 195 char output[OutputSize]; 196 197 assert(bytes.size() <= 15 198 && "DumpBytes only supports instructions of up to 15 bytes"); 199 memset(output, ' ', sizeof(output)); 200 unsigned index = 0; 201 for (StringRef::iterator i = bytes.begin(), 202 e = bytes.end(); i != e; ++i) { 203 output[index] = hex_rep[(*i & 0xF0) >> 4]; 204 output[index + 1] = hex_rep[*i & 0xF]; 205 index += 3; 206 } 207 208 output[sizeof(output) - 1] = 0; 209 outs() << output; 210 } 211 212 bool llvm::RelocAddressLess(RelocationRef a, RelocationRef b) { 213 uint64_t a_addr, b_addr; 214 if (error(a.getOffset(a_addr))) return false; 215 if (error(b.getOffset(b_addr))) return false; 216 return a_addr < b_addr; 217 } 218 219 static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) { 220 const Target *TheTarget = getTarget(Obj); 221 // getTarget() will have already issued a diagnostic if necessary, so 222 // just bail here if it failed. 223 if (!TheTarget) 224 return; 225 226 // Package up features to be passed to target/subtarget 227 std::string FeaturesStr; 228 if (MAttrs.size()) { 229 SubtargetFeatures Features; 230 for (unsigned i = 0; i != MAttrs.size(); ++i) 231 Features.AddFeature(MAttrs[i]); 232 FeaturesStr = Features.getString(); 233 } 234 235 std::unique_ptr<const MCRegisterInfo> MRI( 236 TheTarget->createMCRegInfo(TripleName)); 237 if (!MRI) { 238 errs() << "error: no register info for target " << TripleName << "\n"; 239 return; 240 } 241 242 // Set up disassembler. 243 std::unique_ptr<const MCAsmInfo> AsmInfo( 244 TheTarget->createMCAsmInfo(*MRI, TripleName)); 245 if (!AsmInfo) { 246 errs() << "error: no assembly info for target " << TripleName << "\n"; 247 return; 248 } 249 250 std::unique_ptr<const MCSubtargetInfo> STI( 251 TheTarget->createMCSubtargetInfo(TripleName, MCPU, FeaturesStr)); 252 if (!STI) { 253 errs() << "error: no subtarget info for target " << TripleName << "\n"; 254 return; 255 } 256 257 std::unique_ptr<const MCInstrInfo> MII(TheTarget->createMCInstrInfo()); 258 if (!MII) { 259 errs() << "error: no instruction info for target " << TripleName << "\n"; 260 return; 261 } 262 263 std::unique_ptr<const MCObjectFileInfo> MOFI(new MCObjectFileInfo); 264 MCContext Ctx(AsmInfo.get(), MRI.get(), MOFI.get()); 265 266 std::unique_ptr<MCDisassembler> DisAsm( 267 TheTarget->createMCDisassembler(*STI, Ctx)); 268 269 if (!DisAsm) { 270 errs() << "error: no disassembler for target " << TripleName << "\n"; 271 return; 272 } 273 274 std::unique_ptr<const MCInstrAnalysis> MIA( 275 TheTarget->createMCInstrAnalysis(MII.get())); 276 277 int AsmPrinterVariant = AsmInfo->getAssemblerDialect(); 278 std::unique_ptr<MCInstPrinter> IP(TheTarget->createMCInstPrinter( 279 AsmPrinterVariant, *AsmInfo, *MII, *MRI, *STI)); 280 if (!IP) { 281 errs() << "error: no instruction printer for target " << TripleName 282 << '\n'; 283 return; 284 } 285 286 StringRef Fmt = Obj->getBytesInAddress() > 4 ? "\t\t%016" PRIx64 ": " : 287 "\t\t\t%08" PRIx64 ": "; 288 289 // Create a mapping, RelocSecs = SectionRelocMap[S], where sections 290 // in RelocSecs contain the relocations for section S. 291 std::error_code EC; 292 std::map<SectionRef, SmallVector<SectionRef, 1>> SectionRelocMap; 293 for (const SectionRef &Section : Obj->sections()) { 294 section_iterator Sec2 = Section.getRelocatedSection(); 295 if (Sec2 != Obj->section_end()) 296 SectionRelocMap[*Sec2].push_back(Section); 297 } 298 299 for (const SectionRef &Section : Obj->sections()) { 300 bool Text; 301 if (error(Section.isText(Text))) 302 break; 303 if (!Text) 304 continue; 305 306 uint64_t SectionAddr; 307 if (error(Section.getAddress(SectionAddr))) 308 break; 309 310 uint64_t SectSize; 311 if (error(Section.getSize(SectSize))) 312 break; 313 314 // Make a list of all the symbols in this section. 315 std::vector<std::pair<uint64_t, StringRef>> Symbols; 316 for (const SymbolRef &Symbol : Obj->symbols()) { 317 bool contains; 318 if (!error(Section.containsSymbol(Symbol, contains)) && contains) { 319 uint64_t Address; 320 if (error(Symbol.getAddress(Address))) 321 break; 322 if (Address == UnknownAddressOrSize) 323 continue; 324 Address -= SectionAddr; 325 if (Address >= SectSize) 326 continue; 327 328 StringRef Name; 329 if (error(Symbol.getName(Name))) 330 break; 331 Symbols.push_back(std::make_pair(Address, Name)); 332 } 333 } 334 335 // Sort the symbols by address, just in case they didn't come in that way. 336 array_pod_sort(Symbols.begin(), Symbols.end()); 337 338 // Make a list of all the relocations for this section. 339 std::vector<RelocationRef> Rels; 340 if (InlineRelocs) { 341 for (const SectionRef &RelocSec : SectionRelocMap[Section]) { 342 for (const RelocationRef &Reloc : RelocSec.relocations()) { 343 Rels.push_back(Reloc); 344 } 345 } 346 } 347 348 // Sort relocations by address. 349 std::sort(Rels.begin(), Rels.end(), RelocAddressLess); 350 351 StringRef SegmentName = ""; 352 if (const MachOObjectFile *MachO = dyn_cast<const MachOObjectFile>(Obj)) { 353 DataRefImpl DR = Section.getRawDataRefImpl(); 354 SegmentName = MachO->getSectionFinalSegmentName(DR); 355 } 356 StringRef name; 357 if (error(Section.getName(name))) 358 break; 359 outs() << "Disassembly of section "; 360 if (!SegmentName.empty()) 361 outs() << SegmentName << ","; 362 outs() << name << ':'; 363 364 // If the section has no symbols just insert a dummy one and disassemble 365 // the whole section. 366 if (Symbols.empty()) 367 Symbols.push_back(std::make_pair(0, name)); 368 369 370 SmallString<40> Comments; 371 raw_svector_ostream CommentStream(Comments); 372 373 StringRef Bytes; 374 if (error(Section.getContents(Bytes))) 375 break; 376 StringRefMemoryObject memoryObject(Bytes, SectionAddr); 377 uint64_t Size; 378 uint64_t Index; 379 380 std::vector<RelocationRef>::const_iterator rel_cur = Rels.begin(); 381 std::vector<RelocationRef>::const_iterator rel_end = Rels.end(); 382 // Disassemble symbol by symbol. 383 for (unsigned si = 0, se = Symbols.size(); si != se; ++si) { 384 385 uint64_t Start = Symbols[si].first; 386 // The end is either the section end or the beginning of the next symbol. 387 uint64_t End = (si == se - 1) ? SectSize : Symbols[si + 1].first; 388 // If this symbol has the same address as the next symbol, then skip it. 389 if (Start == End) 390 continue; 391 392 outs() << '\n' << Symbols[si].second << ":\n"; 393 394 #ifndef NDEBUG 395 raw_ostream &DebugOut = DebugFlag ? dbgs() : nulls(); 396 #else 397 raw_ostream &DebugOut = nulls(); 398 #endif 399 400 for (Index = Start; Index < End; Index += Size) { 401 MCInst Inst; 402 403 if (DisAsm->getInstruction(Inst, Size, memoryObject, 404 SectionAddr + Index, 405 DebugOut, CommentStream)) { 406 outs() << format("%8" PRIx64 ":", SectionAddr + Index); 407 if (!NoShowRawInsn) { 408 outs() << "\t"; 409 DumpBytes(StringRef(Bytes.data() + Index, Size)); 410 } 411 IP->printInst(&Inst, outs(), ""); 412 outs() << CommentStream.str(); 413 Comments.clear(); 414 outs() << "\n"; 415 } else { 416 errs() << ToolName << ": warning: invalid instruction encoding\n"; 417 if (Size == 0) 418 Size = 1; // skip illegible bytes 419 } 420 421 // Print relocation for instruction. 422 while (rel_cur != rel_end) { 423 bool hidden = false; 424 uint64_t addr; 425 SmallString<16> name; 426 SmallString<32> val; 427 428 // If this relocation is hidden, skip it. 429 if (error(rel_cur->getHidden(hidden))) goto skip_print_rel; 430 if (hidden) goto skip_print_rel; 431 432 if (error(rel_cur->getOffset(addr))) goto skip_print_rel; 433 // Stop when rel_cur's address is past the current instruction. 434 if (addr >= Index + Size) break; 435 if (error(rel_cur->getTypeName(name))) goto skip_print_rel; 436 if (error(rel_cur->getValueString(val))) goto skip_print_rel; 437 438 outs() << format(Fmt.data(), SectionAddr + addr) << name 439 << "\t" << val << "\n"; 440 441 skip_print_rel: 442 ++rel_cur; 443 } 444 } 445 } 446 } 447 } 448 449 static void PrintRelocations(const ObjectFile *Obj) { 450 StringRef Fmt = Obj->getBytesInAddress() > 4 ? "%016" PRIx64 : 451 "%08" PRIx64; 452 // Regular objdump doesn't print relocations in non-relocatable object 453 // files. 454 if (!Obj->isRelocatableObject()) 455 return; 456 457 for (const SectionRef &Section : Obj->sections()) { 458 if (Section.relocation_begin() == Section.relocation_end()) 459 continue; 460 StringRef secname; 461 if (error(Section.getName(secname))) 462 continue; 463 outs() << "RELOCATION RECORDS FOR [" << secname << "]:\n"; 464 for (const RelocationRef &Reloc : Section.relocations()) { 465 bool hidden; 466 uint64_t address; 467 SmallString<32> relocname; 468 SmallString<32> valuestr; 469 if (error(Reloc.getHidden(hidden))) 470 continue; 471 if (hidden) 472 continue; 473 if (error(Reloc.getTypeName(relocname))) 474 continue; 475 if (error(Reloc.getOffset(address))) 476 continue; 477 if (error(Reloc.getValueString(valuestr))) 478 continue; 479 outs() << format(Fmt.data(), address) << " " << relocname << " " 480 << valuestr << "\n"; 481 } 482 outs() << "\n"; 483 } 484 } 485 486 static void PrintSectionHeaders(const ObjectFile *Obj) { 487 outs() << "Sections:\n" 488 "Idx Name Size Address Type\n"; 489 unsigned i = 0; 490 for (const SectionRef &Section : Obj->sections()) { 491 StringRef Name; 492 if (error(Section.getName(Name))) 493 return; 494 uint64_t Address; 495 if (error(Section.getAddress(Address))) 496 return; 497 uint64_t Size; 498 if (error(Section.getSize(Size))) 499 return; 500 bool Text, Data, BSS; 501 if (error(Section.isText(Text))) 502 return; 503 if (error(Section.isData(Data))) 504 return; 505 if (error(Section.isBSS(BSS))) 506 return; 507 std::string Type = (std::string(Text ? "TEXT " : "") + 508 (Data ? "DATA " : "") + (BSS ? "BSS" : "")); 509 outs() << format("%3d %-13s %08" PRIx64 " %016" PRIx64 " %s\n", i, 510 Name.str().c_str(), Size, Address, Type.c_str()); 511 ++i; 512 } 513 } 514 515 static void PrintSectionContents(const ObjectFile *Obj) { 516 std::error_code EC; 517 for (const SectionRef &Section : Obj->sections()) { 518 StringRef Name; 519 StringRef Contents; 520 uint64_t BaseAddr; 521 bool BSS; 522 if (error(Section.getName(Name))) 523 continue; 524 if (error(Section.getAddress(BaseAddr))) 525 continue; 526 if (error(Section.isBSS(BSS))) 527 continue; 528 529 outs() << "Contents of section " << Name << ":\n"; 530 if (BSS) { 531 uint64_t Size; 532 if (error(Section.getSize(Size))) 533 continue; 534 outs() << format("<skipping contents of bss section at [%04" PRIx64 535 ", %04" PRIx64 ")>\n", 536 BaseAddr, BaseAddr + Size); 537 continue; 538 } 539 540 if (error(Section.getContents(Contents))) 541 continue; 542 543 // Dump out the content as hex and printable ascii characters. 544 for (std::size_t addr = 0, end = Contents.size(); addr < end; addr += 16) { 545 outs() << format(" %04" PRIx64 " ", BaseAddr + addr); 546 // Dump line of hex. 547 for (std::size_t i = 0; i < 16; ++i) { 548 if (i != 0 && i % 4 == 0) 549 outs() << ' '; 550 if (addr + i < end) 551 outs() << hexdigit((Contents[addr + i] >> 4) & 0xF, true) 552 << hexdigit(Contents[addr + i] & 0xF, true); 553 else 554 outs() << " "; 555 } 556 // Print ascii. 557 outs() << " "; 558 for (std::size_t i = 0; i < 16 && addr + i < end; ++i) { 559 if (std::isprint(static_cast<unsigned char>(Contents[addr + i]) & 0xFF)) 560 outs() << Contents[addr + i]; 561 else 562 outs() << "."; 563 } 564 outs() << "\n"; 565 } 566 } 567 } 568 569 static void PrintCOFFSymbolTable(const COFFObjectFile *coff) { 570 for (unsigned SI = 0, SE = coff->getNumberOfSymbols(); SI != SE; ++SI) { 571 ErrorOr<COFFSymbolRef> Symbol = coff->getSymbol(SI); 572 StringRef Name; 573 if (error(Symbol.getError())) 574 return; 575 576 if (error(coff->getSymbolName(*Symbol, Name))) 577 return; 578 579 outs() << "[" << format("%2d", SI) << "]" 580 << "(sec " << format("%2d", int(Symbol->getSectionNumber())) << ")" 581 << "(fl 0x00)" // Flag bits, which COFF doesn't have. 582 << "(ty " << format("%3x", unsigned(Symbol->getType())) << ")" 583 << "(scl " << format("%3x", unsigned(Symbol->getStorageClass())) << ") " 584 << "(nx " << unsigned(Symbol->getNumberOfAuxSymbols()) << ") " 585 << "0x" << format("%08x", unsigned(Symbol->getValue())) << " " 586 << Name << "\n"; 587 588 for (unsigned AI = 0, AE = Symbol->getNumberOfAuxSymbols(); AI < AE; ++AI, ++SI) { 589 if (Symbol->isSectionDefinition()) { 590 const coff_aux_section_definition *asd; 591 if (error(coff->getAuxSymbol<coff_aux_section_definition>(SI + 1, asd))) 592 return; 593 594 outs() << "AUX " 595 << format("scnlen 0x%x nreloc %d nlnno %d checksum 0x%x " 596 , unsigned(asd->Length) 597 , unsigned(asd->NumberOfRelocations) 598 , unsigned(asd->NumberOfLinenumbers) 599 , unsigned(asd->CheckSum)) 600 << format("assoc %d comdat %d\n" 601 , unsigned(asd->Number) 602 , unsigned(asd->Selection)); 603 } else if (Symbol->isFileRecord()) { 604 const char *FileName; 605 if (error(coff->getAuxSymbol<char>(SI + 1, FileName))) 606 return; 607 608 StringRef Name(FileName, Symbol->getNumberOfAuxSymbols() * 609 coff->getSymbolTableEntrySize()); 610 outs() << "AUX " << Name.rtrim(StringRef("\0", 1)) << '\n'; 611 612 SI = SI + Symbol->getNumberOfAuxSymbols(); 613 break; 614 } else { 615 outs() << "AUX Unknown\n"; 616 } 617 } 618 } 619 } 620 621 static void PrintSymbolTable(const ObjectFile *o) { 622 outs() << "SYMBOL TABLE:\n"; 623 624 if (const COFFObjectFile *coff = dyn_cast<const COFFObjectFile>(o)) { 625 PrintCOFFSymbolTable(coff); 626 return; 627 } 628 for (const SymbolRef &Symbol : o->symbols()) { 629 StringRef Name; 630 uint64_t Address; 631 SymbolRef::Type Type; 632 uint64_t Size; 633 uint32_t Flags = Symbol.getFlags(); 634 section_iterator Section = o->section_end(); 635 if (error(Symbol.getName(Name))) 636 continue; 637 if (error(Symbol.getAddress(Address))) 638 continue; 639 if (error(Symbol.getType(Type))) 640 continue; 641 if (error(Symbol.getSize(Size))) 642 continue; 643 if (error(Symbol.getSection(Section))) 644 continue; 645 646 bool Global = Flags & SymbolRef::SF_Global; 647 bool Weak = Flags & SymbolRef::SF_Weak; 648 bool Absolute = Flags & SymbolRef::SF_Absolute; 649 650 if (Address == UnknownAddressOrSize) 651 Address = 0; 652 if (Size == UnknownAddressOrSize) 653 Size = 0; 654 char GlobLoc = ' '; 655 if (Type != SymbolRef::ST_Unknown) 656 GlobLoc = Global ? 'g' : 'l'; 657 char Debug = (Type == SymbolRef::ST_Debug || Type == SymbolRef::ST_File) 658 ? 'd' : ' '; 659 char FileFunc = ' '; 660 if (Type == SymbolRef::ST_File) 661 FileFunc = 'f'; 662 else if (Type == SymbolRef::ST_Function) 663 FileFunc = 'F'; 664 665 const char *Fmt = o->getBytesInAddress() > 4 ? "%016" PRIx64 : 666 "%08" PRIx64; 667 668 outs() << format(Fmt, Address) << " " 669 << GlobLoc // Local -> 'l', Global -> 'g', Neither -> ' ' 670 << (Weak ? 'w' : ' ') // Weak? 671 << ' ' // Constructor. Not supported yet. 672 << ' ' // Warning. Not supported yet. 673 << ' ' // Indirect reference to another symbol. 674 << Debug // Debugging (d) or dynamic (D) symbol. 675 << FileFunc // Name of function (F), file (f) or object (O). 676 << ' '; 677 if (Absolute) { 678 outs() << "*ABS*"; 679 } else if (Section == o->section_end()) { 680 outs() << "*UND*"; 681 } else { 682 if (const MachOObjectFile *MachO = 683 dyn_cast<const MachOObjectFile>(o)) { 684 DataRefImpl DR = Section->getRawDataRefImpl(); 685 StringRef SegmentName = MachO->getSectionFinalSegmentName(DR); 686 outs() << SegmentName << ","; 687 } 688 StringRef SectionName; 689 if (error(Section->getName(SectionName))) 690 SectionName = ""; 691 outs() << SectionName; 692 } 693 outs() << '\t' 694 << format("%08" PRIx64 " ", Size) 695 << Name 696 << '\n'; 697 } 698 } 699 700 static void PrintUnwindInfo(const ObjectFile *o) { 701 outs() << "Unwind info:\n\n"; 702 703 if (const COFFObjectFile *coff = dyn_cast<COFFObjectFile>(o)) { 704 printCOFFUnwindInfo(coff); 705 } else if (const MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o)) 706 printMachOUnwindInfo(MachO); 707 else { 708 // TODO: Extract DWARF dump tool to objdump. 709 errs() << "This operation is only currently supported " 710 "for COFF and MachO object files.\n"; 711 return; 712 } 713 } 714 715 static void printExportsTrie(const ObjectFile *o) { 716 outs() << "Exports trie:\n"; 717 if (const MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o)) 718 printMachOExportsTrie(MachO); 719 else { 720 errs() << "This operation is only currently supported " 721 "for Mach-O executable files.\n"; 722 return; 723 } 724 } 725 726 static void printRebaseTable(const ObjectFile *o) { 727 outs() << "Rebase table:\n"; 728 if (const MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o)) 729 printMachORebaseTable(MachO); 730 else { 731 errs() << "This operation is only currently supported " 732 "for Mach-O executable files.\n"; 733 return; 734 } 735 } 736 737 738 static void printPrivateFileHeader(const ObjectFile *o) { 739 if (o->isELF()) { 740 printELFFileHeader(o); 741 } else if (o->isCOFF()) { 742 printCOFFFileHeader(o); 743 } else if (o->isMachO()) { 744 printMachOFileHeader(o); 745 } 746 } 747 748 static void DumpObject(const ObjectFile *o) { 749 outs() << '\n'; 750 outs() << o->getFileName() 751 << ":\tfile format " << o->getFileFormatName() << "\n\n"; 752 753 if (Disassemble) 754 DisassembleObject(o, Relocations); 755 if (Relocations && !Disassemble) 756 PrintRelocations(o); 757 if (SectionHeaders) 758 PrintSectionHeaders(o); 759 if (SectionContents) 760 PrintSectionContents(o); 761 if (SymbolTable) 762 PrintSymbolTable(o); 763 if (UnwindInfo) 764 PrintUnwindInfo(o); 765 if (PrivateHeaders) 766 printPrivateFileHeader(o); 767 if (ExportsTrie) 768 printExportsTrie(o); 769 if (Rebase) 770 printRebaseTable(o); 771 } 772 773 /// @brief Dump each object file in \a a; 774 static void DumpArchive(const Archive *a) { 775 for (Archive::child_iterator i = a->child_begin(), e = a->child_end(); i != e; 776 ++i) { 777 ErrorOr<std::unique_ptr<Binary>> ChildOrErr = i->getAsBinary(); 778 if (std::error_code EC = ChildOrErr.getError()) { 779 // Ignore non-object files. 780 if (EC != object_error::invalid_file_type) 781 errs() << ToolName << ": '" << a->getFileName() << "': " << EC.message() 782 << ".\n"; 783 continue; 784 } 785 if (ObjectFile *o = dyn_cast<ObjectFile>(&*ChildOrErr.get())) 786 DumpObject(o); 787 else 788 errs() << ToolName << ": '" << a->getFileName() << "': " 789 << "Unrecognized file type.\n"; 790 } 791 } 792 793 /// @brief Open file and figure out how to dump it. 794 static void DumpInput(StringRef file) { 795 // If file isn't stdin, check that it exists. 796 if (file != "-" && !sys::fs::exists(file)) { 797 errs() << ToolName << ": '" << file << "': " << "No such file\n"; 798 return; 799 } 800 801 if (MachOOpt && Disassemble) { 802 DisassembleInputMachO(file); 803 return; 804 } 805 806 // Attempt to open the binary. 807 ErrorOr<OwningBinary<Binary>> BinaryOrErr = createBinary(file); 808 if (std::error_code EC = BinaryOrErr.getError()) { 809 errs() << ToolName << ": '" << file << "': " << EC.message() << ".\n"; 810 return; 811 } 812 Binary &Binary = *BinaryOrErr.get().getBinary(); 813 814 if (Archive *a = dyn_cast<Archive>(&Binary)) 815 DumpArchive(a); 816 else if (ObjectFile *o = dyn_cast<ObjectFile>(&Binary)) 817 DumpObject(o); 818 else 819 errs() << ToolName << ": '" << file << "': " << "Unrecognized file type.\n"; 820 } 821 822 int main(int argc, char **argv) { 823 // Print a stack trace if we signal out. 824 sys::PrintStackTraceOnErrorSignal(); 825 PrettyStackTraceProgram X(argc, argv); 826 llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. 827 828 // Initialize targets and assembly printers/parsers. 829 llvm::InitializeAllTargetInfos(); 830 llvm::InitializeAllTargetMCs(); 831 llvm::InitializeAllAsmParsers(); 832 llvm::InitializeAllDisassemblers(); 833 834 // Register the target printer for --version. 835 cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion); 836 837 cl::ParseCommandLineOptions(argc, argv, "llvm object file dumper\n"); 838 TripleName = Triple::normalize(TripleName); 839 840 ToolName = argv[0]; 841 842 // Defaults to a.out if no filenames specified. 843 if (InputFilenames.size() == 0) 844 InputFilenames.push_back("a.out"); 845 846 if (!Disassemble 847 && !Relocations 848 && !SectionHeaders 849 && !SectionContents 850 && !SymbolTable 851 && !UnwindInfo 852 && !PrivateHeaders 853 && !ExportsTrie 854 && !Rebase) { 855 cl::PrintHelpMessage(); 856 return 2; 857 } 858 859 std::for_each(InputFilenames.begin(), InputFilenames.end(), 860 DumpInput); 861 862 return 0; 863 } 864