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