#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Triple.h"
+#include "llvm/MC/MCAnalysis/MCAtom.h"
+#include "llvm/MC/MCAnalysis/MCFunction.h"
+#include "llvm/MC/MCAnalysis/MCModule.h"
+#include "llvm/MC/MCAnalysis/MCModuleYAML.h"
+#include "llvm/MC/MCAnalysis/MCObjectSymbolizer.h"
#include "llvm/MC/MCAsmInfo.h"
-#include "llvm/MC/MCAtom.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDisassembler.h"
-#include "llvm/MC/MCFunction.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstPrinter.h"
#include "llvm/MC/MCInstrAnalysis.h"
#include "llvm/MC/MCInstrInfo.h"
-#include "llvm/MC/MCModule.h"
-#include "llvm/MC/MCModuleYAML.h"
#include "llvm/MC/MCObjectDisassembler.h"
#include "llvm/MC/MCObjectFileInfo.h"
-#include "llvm/MC/MCObjectSymbolizer.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCRelocationInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
llvm::TripleName("triple", cl::desc("Target triple to disassemble for, "
"see -version for available targets"));
+cl::opt<std::string>
+llvm::MCPU("mcpu",
+ cl::desc("Target a specific cpu type (-mcpu=help for details)"),
+ cl::value_desc("cpu-name"),
+ cl::init(""));
+
cl::opt<std::string>
llvm::ArchName("arch", cl::desc("Target arch to disassemble for, "
"see -version for available targets"));
SectionHeadersShorter("h", cl::desc("Alias for --section-headers"),
cl::aliasopt(SectionHeaders));
-static cl::list<std::string>
-MAttrs("mattr",
+cl::list<std::string>
+llvm::MAttrs("mattr",
cl::CommaSeparated,
cl::desc("Target specific attributes"),
cl::value_desc("a1,+a2,-a3,..."));
}
std::unique_ptr<const MCSubtargetInfo> STI(
- TheTarget->createMCSubtargetInfo(TripleName, "", FeaturesStr));
+ TheTarget->createMCSubtargetInfo(TripleName, MCPU, FeaturesStr));
if (!STI) {
errs() << "error: no subtarget info for target " << TripleName << "\n";
return;
std::vector<RelocationRef>::const_iterator rel_end = Rels.end();
// Disassemble symbol by symbol.
for (unsigned si = 0, se = Symbols.size(); si != se; ++si) {
+
uint64_t Start = Symbols[si].first;
- uint64_t End;
- // The end is either the size of the section or the beginning of the next
- // symbol.
- if (si == se - 1)
- End = SectSize;
- // Make sure this symbol takes up space.
- else if (Symbols[si + 1].first != Start)
- End = Symbols[si + 1].first - 1;
- else
- // This symbol has the same address as the next symbol. Skip it.
+ // The end is either the section end or the beginning of the next symbol.
+ uint64_t End = (si == se - 1) ? SectSize : Symbols[si + 1].first;
+ // If this symbol has the same address as the next symbol, then skip it.
+ if (Start == End)
continue;
outs() << '\n' << Symbols[si].second << ":\n";
static void PrintRelocations(const ObjectFile *Obj) {
StringRef Fmt = Obj->getBytesInAddress() > 4 ? "%016" PRIx64 :
"%08" PRIx64;
+ // Regular objdump doesn't print relocations in non-relocatable object
+ // files.
+ if (!Obj->isRelocatableObject())
+ return;
+
for (const SectionRef &Section : Obj->sections()) {
if (Section.relocation_begin() == Section.relocation_end())
continue;
bool BSS;
if (error(Section.getName(Name)))
continue;
- if (error(Section.getContents(Contents)))
- continue;
if (error(Section.getAddress(BaseAddr)))
continue;
if (error(Section.isBSS(BSS)))
outs() << "Contents of section " << Name << ":\n";
if (BSS) {
+ uint64_t Size;
+ if (error(Section.getSize(Size)))
+ continue;
outs() << format("<skipping contents of bss section at [%04" PRIx64
- ", %04" PRIx64 ")>\n", BaseAddr,
- BaseAddr + Contents.size());
+ ", %04" PRIx64 ")>\n",
+ BaseAddr, BaseAddr + Size);
continue;
}
+ if (error(Section.getContents(Contents)))
+ continue;
+
// Dump out the content as hex and printable ascii characters.
for (std::size_t addr = 0, end = Contents.size(); addr < end; addr += 16) {
outs() << format(" %04" PRIx64 " ", BaseAddr + addr);
if (const COFFObjectFile *coff = dyn_cast<COFFObjectFile>(o)) {
printCOFFUnwindInfo(coff);
- } else {
+ } else if (const MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
+ printMachOUnwindInfo(MachO);
+ else {
// TODO: Extract DWARF dump tool to objdump.
errs() << "This operation is only currently supported "
- "for COFF object files.\n";
+ "for COFF and MachO object files.\n";
return;
}
}
}
// Attempt to open the binary.
- ErrorOr<Binary *> BinaryOrErr = createBinary(file);
+ ErrorOr<std::unique_ptr<Binary>> BinaryOrErr = createBinary(file);
if (std::error_code EC = BinaryOrErr.getError()) {
errs() << ToolName << ": '" << file << "': " << EC.message() << ".\n";
return;
}
- std::unique_ptr<Binary> binary(BinaryOrErr.get());
+ Binary &Binary = *BinaryOrErr.get();
- if (Archive *a = dyn_cast<Archive>(binary.get()))
+ if (Archive *a = dyn_cast<Archive>(&Binary))
DumpArchive(a);
- else if (ObjectFile *o = dyn_cast<ObjectFile>(binary.get()))
+ else if (ObjectFile *o = dyn_cast<ObjectFile>(&Binary))
DumpObject(o);
else
errs() << ToolName << ": '" << file << "': " << "Unrecognized file type.\n";