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 //===----------------------------------------------------------------------===// 15 16 #include "llvm-objdump.h" 17 #include "MCFunction.h" 18 #include "llvm/Object/Archive.h" 19 #include "llvm/Object/ObjectFile.h" 20 #include "llvm/ADT/OwningPtr.h" 21 #include "llvm/ADT/Triple.h" 22 #include "llvm/ADT/STLExtras.h" 23 #include "llvm/MC/MCAsmInfo.h" 24 #include "llvm/MC/MCDisassembler.h" 25 #include "llvm/MC/MCInst.h" 26 #include "llvm/MC/MCInstPrinter.h" 27 #include "llvm/MC/MCSubtargetInfo.h" 28 #include "llvm/Support/Casting.h" 29 #include "llvm/Support/CommandLine.h" 30 #include "llvm/Support/Debug.h" 31 #include "llvm/Support/FileSystem.h" 32 #include "llvm/Support/Format.h" 33 #include "llvm/Support/GraphWriter.h" 34 #include "llvm/Support/Host.h" 35 #include "llvm/Support/ManagedStatic.h" 36 #include "llvm/Support/MemoryBuffer.h" 37 #include "llvm/Support/MemoryObject.h" 38 #include "llvm/Support/PrettyStackTrace.h" 39 #include "llvm/Support/Signals.h" 40 #include "llvm/Support/SourceMgr.h" 41 #include "llvm/Support/TargetRegistry.h" 42 #include "llvm/Support/TargetSelect.h" 43 #include "llvm/Support/raw_ostream.h" 44 #include "llvm/Support/system_error.h" 45 #include <algorithm> 46 #include <cstring> 47 using namespace llvm; 48 using namespace object; 49 50 static cl::list<std::string> 51 InputFilenames(cl::Positional, cl::desc("<input object files>"),cl::ZeroOrMore); 52 53 static cl::opt<bool> 54 Disassemble("disassemble", 55 cl::desc("Display assembler mnemonics for the machine instructions")); 56 static cl::alias 57 Disassembled("d", cl::desc("Alias for --disassemble"), 58 cl::aliasopt(Disassemble)); 59 60 static cl::opt<bool> 61 Relocations("r", cl::desc("Display the relocation entries in the file")); 62 63 static cl::opt<bool> 64 MachO("macho", cl::desc("Use MachO specific object file parser")); 65 static cl::alias 66 MachOm("m", cl::desc("Alias for --macho"), cl::aliasopt(MachO)); 67 68 cl::opt<std::string> 69 llvm::TripleName("triple", cl::desc("Target triple to disassemble for, " 70 "see -version for available targets")); 71 72 cl::opt<std::string> 73 llvm::ArchName("arch", cl::desc("Target arch to disassemble for, " 74 "see -version for available targets")); 75 76 static cl::opt<bool> 77 SectionHeaders("section-headers", cl::desc("Display summaries of the headers " 78 "for each section.")); 79 static cl::alias 80 SectionHeadersShort("headers", cl::desc("Alias for --section-headers"), 81 cl::aliasopt(SectionHeaders)); 82 static cl::alias 83 SectionHeadersShorter("h", cl::desc("Alias for --section-headers"), 84 cl::aliasopt(SectionHeaders)); 85 86 static StringRef ToolName; 87 88 static bool error(error_code ec) { 89 if (!ec) return false; 90 91 outs() << ToolName << ": error reading file: " << ec.message() << ".\n"; 92 outs().flush(); 93 return true; 94 } 95 96 static const Target *GetTarget(const ObjectFile *Obj = NULL) { 97 // Figure out the target triple. 98 llvm::Triple TT("unknown-unknown-unknown"); 99 if (TripleName.empty()) { 100 if (Obj) 101 TT.setArch(Triple::ArchType(Obj->getArch())); 102 } else 103 TT.setTriple(Triple::normalize(TripleName)); 104 105 if (!ArchName.empty()) 106 TT.setArchName(ArchName); 107 108 TripleName = TT.str(); 109 110 // Get the target specific parser. 111 std::string Error; 112 const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, Error); 113 if (TheTarget) 114 return TheTarget; 115 116 errs() << ToolName << ": error: unable to get target for '" << TripleName 117 << "', see --version and --triple.\n"; 118 return 0; 119 } 120 121 void llvm::DumpBytes(StringRef bytes) { 122 static const char hex_rep[] = "0123456789abcdef"; 123 // FIXME: The real way to do this is to figure out the longest instruction 124 // and align to that size before printing. I'll fix this when I get 125 // around to outputting relocations. 126 // 15 is the longest x86 instruction 127 // 3 is for the hex rep of a byte + a space. 128 // 1 is for the null terminator. 129 enum { OutputSize = (15 * 3) + 1 }; 130 char output[OutputSize]; 131 132 assert(bytes.size() <= 15 133 && "DumpBytes only supports instructions of up to 15 bytes"); 134 memset(output, ' ', sizeof(output)); 135 unsigned index = 0; 136 for (StringRef::iterator i = bytes.begin(), 137 e = bytes.end(); i != e; ++i) { 138 output[index] = hex_rep[(*i & 0xF0) >> 4]; 139 output[index + 1] = hex_rep[*i & 0xF]; 140 index += 3; 141 } 142 143 output[sizeof(output) - 1] = 0; 144 outs() << output; 145 } 146 147 static void DisassembleObject(const ObjectFile *Obj) { 148 const Target *TheTarget = GetTarget(Obj); 149 if (!TheTarget) { 150 // GetTarget prints out stuff. 151 return; 152 } 153 154 outs() << '\n'; 155 outs() << Obj->getFileName() 156 << ":\tfile format " << Obj->getFileFormatName() << "\n\n"; 157 158 error_code ec; 159 for (section_iterator i = Obj->begin_sections(), 160 e = Obj->end_sections(); 161 i != e; i.increment(ec)) { 162 if (error(ec)) break; 163 bool text; 164 if (error(i->isText(text))) break; 165 if (!text) continue; 166 167 // Make a list of all the symbols in this section. 168 std::vector<std::pair<uint64_t, StringRef> > Symbols; 169 for (symbol_iterator si = Obj->begin_symbols(), 170 se = Obj->end_symbols(); 171 si != se; si.increment(ec)) { 172 bool contains; 173 if (!error(i->containsSymbol(*si, contains)) && contains) { 174 uint64_t Address; 175 if (error(si->getOffset(Address))) break; 176 StringRef Name; 177 if (error(si->getName(Name))) break; 178 Symbols.push_back(std::make_pair(Address, Name)); 179 } 180 } 181 182 // Sort the symbols by address, just in case they didn't come in that way. 183 array_pod_sort(Symbols.begin(), Symbols.end()); 184 185 StringRef name; 186 if (error(i->getName(name))) break; 187 outs() << "Disassembly of section " << name << ':'; 188 189 // If the section has no symbols just insert a dummy one and disassemble 190 // the whole section. 191 if (Symbols.empty()) 192 Symbols.push_back(std::make_pair(0, name)); 193 194 // Set up disassembler. 195 OwningPtr<const MCAsmInfo> AsmInfo(TheTarget->createMCAsmInfo(TripleName)); 196 197 if (!AsmInfo) { 198 errs() << "error: no assembly info for target " << TripleName << "\n"; 199 return; 200 } 201 202 OwningPtr<const MCSubtargetInfo> STI( 203 TheTarget->createMCSubtargetInfo(TripleName, "", "")); 204 205 if (!STI) { 206 errs() << "error: no subtarget info for target " << TripleName << "\n"; 207 return; 208 } 209 210 OwningPtr<const MCDisassembler> DisAsm( 211 TheTarget->createMCDisassembler(*STI)); 212 if (!DisAsm) { 213 errs() << "error: no disassembler for target " << TripleName << "\n"; 214 return; 215 } 216 217 int AsmPrinterVariant = AsmInfo->getAssemblerDialect(); 218 OwningPtr<MCInstPrinter> IP(TheTarget->createMCInstPrinter( 219 AsmPrinterVariant, *AsmInfo, *STI)); 220 if (!IP) { 221 errs() << "error: no instruction printer for target " << TripleName 222 << '\n'; 223 return; 224 } 225 226 StringRef Bytes; 227 if (error(i->getContents(Bytes))) break; 228 StringRefMemoryObject memoryObject(Bytes); 229 uint64_t Size; 230 uint64_t Index; 231 uint64_t SectSize; 232 if (error(i->getSize(SectSize))) break; 233 234 // Disassemble symbol by symbol. 235 for (unsigned si = 0, se = Symbols.size(); si != se; ++si) { 236 uint64_t Start = Symbols[si].first; 237 uint64_t End; 238 // The end is either the size of the section or the beginning of the next 239 // symbol. 240 if (si == se - 1) 241 End = SectSize; 242 // Make sure this symbol takes up space. 243 else if (Symbols[si + 1].first != Start) 244 End = Symbols[si + 1].first - 1; 245 else 246 // This symbol has the same address as the next symbol. Skip it. 247 continue; 248 249 outs() << '\n' << Symbols[si].second << ":\n"; 250 251 #ifndef NDEBUG 252 raw_ostream &DebugOut = DebugFlag ? dbgs() : nulls(); 253 #else 254 raw_ostream &DebugOut = nulls(); 255 #endif 256 257 for (Index = Start; Index < End; Index += Size) { 258 MCInst Inst; 259 260 if (DisAsm->getInstruction(Inst, Size, memoryObject, Index, 261 DebugOut, nulls())) { 262 uint64_t addr; 263 if (error(i->getAddress(addr))) break; 264 outs() << format("%8x:\t", addr + Index); 265 DumpBytes(StringRef(Bytes.data() + Index, Size)); 266 IP->printInst(&Inst, outs(), ""); 267 outs() << "\n"; 268 } else { 269 errs() << ToolName << ": warning: invalid instruction encoding\n"; 270 if (Size == 0) 271 Size = 1; // skip illegible bytes 272 } 273 } 274 } 275 } 276 } 277 278 static void PrintRelocations(const ObjectFile *o) { 279 error_code ec; 280 for (section_iterator si = o->begin_sections(), se = o->end_sections(); 281 si != se; si.increment(ec)){ 282 if (error(ec)) return; 283 if (si->begin_relocations() == si->end_relocations()) 284 continue; 285 StringRef secname; 286 if (error(si->getName(secname))) continue; 287 outs() << "RELOCATION RECORDS FOR [" << secname << "]:\n"; 288 for (relocation_iterator ri = si->begin_relocations(), 289 re = si->end_relocations(); 290 ri != re; ri.increment(ec)) { 291 if (error(ec)) return; 292 293 uint64_t address; 294 SmallString<32> relocname; 295 SmallString<32> valuestr; 296 if (error(ri->getTypeName(relocname))) continue; 297 if (error(ri->getAddress(address))) continue; 298 if (error(ri->getValueString(valuestr))) continue; 299 outs() << address << " " << relocname << " " << valuestr << "\n"; 300 } 301 outs() << "\n"; 302 } 303 } 304 305 static void PrintSectionHeaders(const ObjectFile *o) { 306 outs() << "Sections:\n" 307 "Idx Name Size Address Type\n"; 308 error_code ec; 309 unsigned i = 0; 310 for (section_iterator si = o->begin_sections(), se = o->end_sections(); 311 si != se; si.increment(ec)) { 312 if (error(ec)) return; 313 StringRef Name; 314 if (error(si->getName(Name))) return; 315 uint64_t Address; 316 if (error(si->getAddress(Address))) return; 317 uint64_t Size; 318 if (error(si->getSize(Size))) return; 319 bool Text, Data, BSS; 320 if (error(si->isText(Text))) return; 321 if (error(si->isData(Data))) return; 322 if (error(si->isBSS(BSS))) return; 323 std::string Type = (std::string(Text ? "TEXT " : "") + 324 (Data ? "DATA " : "") + (BSS ? "BSS" : "")); 325 outs() << format("%3d %-13s %09"PRIx64" %017"PRIx64" %s\n", i, Name.str().c_str(), Size, 326 Address, Type.c_str()); 327 ++i; 328 } 329 } 330 331 static void DumpObject(const ObjectFile *o) { 332 if (Disassemble) 333 DisassembleObject(o); 334 if (Relocations) 335 PrintRelocations(o); 336 if (SectionHeaders) 337 PrintSectionHeaders(o); 338 } 339 340 /// @brief Dump each object file in \a a; 341 static void DumpArchive(const Archive *a) { 342 for (Archive::child_iterator i = a->begin_children(), 343 e = a->end_children(); i != e; ++i) { 344 OwningPtr<Binary> child; 345 if (error_code ec = i->getAsBinary(child)) { 346 errs() << ToolName << ": '" << a->getFileName() << "': " << ec.message() 347 << ".\n"; 348 continue; 349 } 350 if (ObjectFile *o = dyn_cast<ObjectFile>(child.get())) 351 DumpObject(o); 352 else 353 errs() << ToolName << ": '" << a->getFileName() << "': " 354 << "Unrecognized file type.\n"; 355 } 356 } 357 358 /// @brief Open file and figure out how to dump it. 359 static void DumpInput(StringRef file) { 360 // If file isn't stdin, check that it exists. 361 if (file != "-" && !sys::fs::exists(file)) { 362 errs() << ToolName << ": '" << file << "': " << "No such file\n"; 363 return; 364 } 365 366 if (MachO && Disassemble) { 367 DisassembleInputMachO(file); 368 return; 369 } 370 371 // Attempt to open the binary. 372 OwningPtr<Binary> binary; 373 if (error_code ec = createBinary(file, binary)) { 374 errs() << ToolName << ": '" << file << "': " << ec.message() << ".\n"; 375 return; 376 } 377 378 if (Archive *a = dyn_cast<Archive>(binary.get())) { 379 DumpArchive(a); 380 } else if (ObjectFile *o = dyn_cast<ObjectFile>(binary.get())) { 381 DumpObject(o); 382 } else { 383 errs() << ToolName << ": '" << file << "': " << "Unrecognized file type.\n"; 384 } 385 } 386 387 int main(int argc, char **argv) { 388 // Print a stack trace if we signal out. 389 sys::PrintStackTraceOnErrorSignal(); 390 PrettyStackTraceProgram X(argc, argv); 391 llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. 392 393 // Initialize targets and assembly printers/parsers. 394 llvm::InitializeAllTargetInfos(); 395 llvm::InitializeAllTargetMCs(); 396 llvm::InitializeAllAsmParsers(); 397 llvm::InitializeAllDisassemblers(); 398 399 cl::ParseCommandLineOptions(argc, argv, "llvm object file dumper\n"); 400 TripleName = Triple::normalize(TripleName); 401 402 ToolName = argv[0]; 403 404 // Defaults to a.out if no filenames specified. 405 if (InputFilenames.size() == 0) 406 InputFilenames.push_back("a.out"); 407 408 if (!Disassemble && !Relocations && !SectionHeaders) { 409 cl::PrintHelpMessage(); 410 return 2; 411 } 412 413 std::for_each(InputFilenames.begin(), InputFilenames.end(), 414 DumpInput); 415 416 return 0; 417 } 418