index 3f828128897510ba07b93feb7adc2f84d2367ece..d6e8e0a01a8697feaed01162a078046cf2c738bd 100644 (file)
#include "llvm/Support/Debug.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Format.h"
+#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/GraphWriter.h"
#include "llvm/Support/MachO.h"
#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/raw_ostream.h"
PrintImmHex("print-imm-hex",
cl::desc("Use hex format for immediate values"));
+cl::opt<bool> llvm::UniversalHeaders("universal-headers",
+ cl::desc("Print Mach-O universal headers "
+ "(requires -macho)"));
+
+cl::opt<bool>
+ llvm::ArchiveHeaders("archive-headers",
+ cl::desc("Print archive headers for Mach-O archives "
+ "(requires -macho)"));
+
+cl::opt<bool>
+ llvm::IndirectSymbols("indirect-symbols",
+ cl::desc("Print indirect symbol table for Mach-O "
+ "objects (requires -macho)"));
+
static cl::list<std::string>
ArchFlags("arch", cl::desc("architecture(s) from a Mach-O file to dump"),
cl::ZeroOrMore);
}
}
+static void PrintIndirectSymbolTable(MachOObjectFile *O, bool verbose,
+ uint32_t n, uint32_t count,
+ uint32_t stride, uint64_t addr) {
+ MachO::dysymtab_command Dysymtab = O->getDysymtabLoadCommand();
+ uint32_t nindirectsyms = Dysymtab.nindirectsyms;
+ if (n > nindirectsyms)
+ outs() << " (entries start past the end of the indirect symbol "
+ "table) (reserved1 field greater than the table size)";
+ else if (n + count > nindirectsyms)
+ outs() << " (entries extends past the end of the indirect symbol "
+ "table)";
+ outs() << "\n";
+ uint32_t cputype = O->getHeader().cputype;
+ if (cputype & MachO::CPU_ARCH_ABI64)
+ outs() << "address index";
+ else
+ outs() << "address index";
+ if (verbose)
+ outs() << " name\n";
+ else
+ outs() << "\n";
+ for (uint32_t j = 0; j < count && n + j < nindirectsyms; j++) {
+ if (cputype & MachO::CPU_ARCH_ABI64)
+ outs() << format("0x%016" PRIx64, addr + j * stride) << " ";
+ else
+ outs() << format("0x%08" PRIx32, addr + j * stride) << " ";
+ MachO::dysymtab_command Dysymtab = O->getDysymtabLoadCommand();
+ uint32_t indirect_symbol = O->getIndirectSymbolTableEntry(Dysymtab, n + j);
+ if (indirect_symbol == MachO::INDIRECT_SYMBOL_LOCAL) {
+ outs() << "LOCAL\n";
+ continue;
+ }
+ if (indirect_symbol ==
+ (MachO::INDIRECT_SYMBOL_LOCAL | MachO::INDIRECT_SYMBOL_ABS)) {
+ outs() << "LOCAL ABSOLUTE\n";
+ continue;
+ }
+ if (indirect_symbol == MachO::INDIRECT_SYMBOL_ABS) {
+ outs() << "ABSOLUTE\n";
+ continue;
+ }
+ outs() << format("%5u ", indirect_symbol);
+ MachO::symtab_command Symtab = O->getSymtabLoadCommand();
+ if (indirect_symbol < Symtab.nsyms) {
+ symbol_iterator Sym = O->getSymbolByIndex(indirect_symbol);
+ SymbolRef Symbol = *Sym;
+ StringRef SymName;
+ Symbol.getName(SymName);
+ outs() << SymName;
+ } else {
+ outs() << "?";
+ }
+ outs() << "\n";
+ }
+}
+
+static void PrintIndirectSymbols(MachOObjectFile *O, bool verbose) {
+ uint32_t LoadCommandCount = O->getHeader().ncmds;
+ MachOObjectFile::LoadCommandInfo Load = O->getFirstLoadCommandInfo();
+ for (unsigned I = 0;; ++I) {
+ if (Load.C.cmd == MachO::LC_SEGMENT_64) {
+ MachO::segment_command_64 Seg = O->getSegment64LoadCommand(Load);
+ for (unsigned J = 0; J < Seg.nsects; ++J) {
+ MachO::section_64 Sec = O->getSection64(Load, J);
+ uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
+ if (section_type == MachO::S_NON_LAZY_SYMBOL_POINTERS ||
+ section_type == MachO::S_LAZY_SYMBOL_POINTERS ||
+ section_type == MachO::S_LAZY_DYLIB_SYMBOL_POINTERS ||
+ section_type == MachO::S_THREAD_LOCAL_VARIABLE_POINTERS ||
+ section_type == MachO::S_SYMBOL_STUBS) {
+ uint32_t stride;
+ if (section_type == MachO::S_SYMBOL_STUBS)
+ stride = Sec.reserved2;
+ else
+ stride = 8;
+ if (stride == 0) {
+ outs() << "Can't print indirect symbols for (" << Sec.segname << ","
+ << Sec.sectname << ") "
+ << "(size of stubs in reserved2 field is zero)\n";
+ continue;
+ }
+ uint32_t count = Sec.size / stride;
+ outs() << "Indirect symbols for (" << Sec.segname << ","
+ << Sec.sectname << ") " << count << " entries";
+ uint32_t n = Sec.reserved1;
+ PrintIndirectSymbolTable(O, verbose, n, count, stride, Sec.addr);
+ }
+ }
+ } else if (Load.C.cmd == MachO::LC_SEGMENT) {
+ MachO::segment_command Seg = O->getSegmentLoadCommand(Load);
+ for (unsigned J = 0; J < Seg.nsects; ++J) {
+ MachO::section Sec = O->getSection(Load, J);
+ uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
+ if (section_type == MachO::S_NON_LAZY_SYMBOL_POINTERS ||
+ section_type == MachO::S_LAZY_SYMBOL_POINTERS ||
+ section_type == MachO::S_LAZY_DYLIB_SYMBOL_POINTERS ||
+ section_type == MachO::S_THREAD_LOCAL_VARIABLE_POINTERS ||
+ section_type == MachO::S_SYMBOL_STUBS) {
+ uint32_t stride;
+ if (section_type == MachO::S_SYMBOL_STUBS)
+ stride = Sec.reserved2;
+ else
+ stride = 4;
+ if (stride == 0) {
+ outs() << "Can't print indirect symbols for (" << Sec.segname << ","
+ << Sec.sectname << ") "
+ << "(size of stubs in reserved2 field is zero)\n";
+ continue;
+ }
+ uint32_t count = Sec.size / stride;
+ outs() << "Indirect symbols for (" << Sec.segname << ","
+ << Sec.sectname << ") " << count << " entries";
+ uint32_t n = Sec.reserved1;
+ PrintIndirectSymbolTable(O, verbose, n, count, stride, Sec.addr);
+ }
+ }
+ }
+ if (I == LoadCommandCount - 1)
+ break;
+ else
+ Load = O->getNextLoadCommandInfo(Load);
+ }
+}
+
// checkMachOAndArchFlags() checks to see if the ObjectFile is a Mach-O file
// and if it is and there is a list of architecture flags is specified then
// check to make sure this Mach-O file is one of those architectures or all
return true;
}
-static void DisassembleInputMachO2(StringRef Filename, MachOObjectFile *MachOOF,
- StringRef ArchiveMemberName = StringRef(),
- StringRef ArchitectureName = StringRef());
+static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF);
+
+// ProcessMachO() is passed a single opened Mach-O file, which may be an
+// archive member and or in a slice of a universal file. It prints the
+// the file name and header info and then processes it according to the
+// command line options.
+static void ProcessMachO(StringRef Filename, MachOObjectFile *MachOOF,
+ StringRef ArchiveMemberName = StringRef(),
+ StringRef ArchitectureName = StringRef()) {
+ // If we are doing some processing here on the Mach-O file print the header
+ // info. And don't print it otherwise like in the case of printing the
+ // UniversalHeaders or ArchiveHeaders.
+ if (Disassemble || PrivateHeaders || ExportsTrie || Rebase || Bind ||
+ LazyBind || WeakBind || IndirectSymbols) {
+ outs() << Filename;
+ if (!ArchiveMemberName.empty())
+ outs() << '(' << ArchiveMemberName << ')';
+ if (!ArchitectureName.empty())
+ outs() << " (architecture " << ArchitectureName << ")";
+ outs() << ":\n";
+ }
+
+ if (Disassemble)
+ DisassembleMachO(Filename, MachOOF);
+ if (IndirectSymbols)
+ PrintIndirectSymbols(MachOOF, true);
+ if (Relocations)
+ PrintRelocations(MachOOF);
+ if (SectionHeaders)
+ PrintSectionHeaders(MachOOF);
+ if (SectionContents)
+ PrintSectionContents(MachOOF);
+ if (SymbolTable)
+ PrintSymbolTable(MachOOF);
+ if (UnwindInfo)
+ printMachOUnwindInfo(MachOOF);
+ if (PrivateHeaders)
+ printMachOFileHeader(MachOOF);
+ if (ExportsTrie)
+ printExportsTrie(MachOOF);
+ if (Rebase)
+ printRebaseTable(MachOOF);
+ if (Bind)
+ printBindTable(MachOOF);
+ if (LazyBind)
+ printLazyBindTable(MachOOF);
+ if (WeakBind)
+ printWeakBindTable(MachOOF);
+}
+
+// printUnknownCPUType() helps print_fat_headers for unknown CPU's.
+static void printUnknownCPUType(uint32_t cputype, uint32_t cpusubtype) {
+ outs() << " cputype (" << cputype << ")\n";
+ outs() << " cpusubtype (" << cpusubtype << ")\n";
+}
+
+// printCPUType() helps print_fat_headers by printing the cputype and
+// pusubtype (symbolically for the one's it knows about).
+static void printCPUType(uint32_t cputype, uint32_t cpusubtype) {
+ switch (cputype) {
+ case MachO::CPU_TYPE_I386:
+ switch (cpusubtype) {
+ case MachO::CPU_SUBTYPE_I386_ALL:
+ outs() << " cputype CPU_TYPE_I386\n";
+ outs() << " cpusubtype CPU_SUBTYPE_I386_ALL\n";
+ break;
+ default:
+ printUnknownCPUType(cputype, cpusubtype);
+ break;
+ }
+ break;
+ case MachO::CPU_TYPE_X86_64:
+ switch (cpusubtype) {
+ case MachO::CPU_SUBTYPE_X86_64_ALL:
+ outs() << " cputype CPU_TYPE_X86_64\n";
+ outs() << " cpusubtype CPU_SUBTYPE_X86_64_ALL\n";
+ break;
+ case MachO::CPU_SUBTYPE_X86_64_H:
+ outs() << " cputype CPU_TYPE_X86_64\n";
+ outs() << " cpusubtype CPU_SUBTYPE_X86_64_H\n";
+ break;
+ default:
+ printUnknownCPUType(cputype, cpusubtype);
+ break;
+ }
+ break;
+ case MachO::CPU_TYPE_ARM:
+ switch (cpusubtype) {
+ case MachO::CPU_SUBTYPE_ARM_ALL:
+ outs() << " cputype CPU_TYPE_ARM\n";
+ outs() << " cpusubtype CPU_SUBTYPE_ARM_ALL\n";
+ break;
+ case MachO::CPU_SUBTYPE_ARM_V4T:
+ outs() << " cputype CPU_TYPE_ARM\n";
+ outs() << " cpusubtype CPU_SUBTYPE_ARM_V4T\n";
+ break;
+ case MachO::CPU_SUBTYPE_ARM_V5TEJ:
+ outs() << " cputype CPU_TYPE_ARM\n";
+ outs() << " cpusubtype CPU_SUBTYPE_ARM_V5TEJ\n";
+ break;
+ case MachO::CPU_SUBTYPE_ARM_XSCALE:
+ outs() << " cputype CPU_TYPE_ARM\n";
+ outs() << " cpusubtype CPU_SUBTYPE_ARM_XSCALE\n";
+ break;
+ case MachO::CPU_SUBTYPE_ARM_V6:
+ outs() << " cputype CPU_TYPE_ARM\n";
+ outs() << " cpusubtype CPU_SUBTYPE_ARM_V6\n";
+ break;
+ case MachO::CPU_SUBTYPE_ARM_V6M:
+ outs() << " cputype CPU_TYPE_ARM\n";
+ outs() << " cpusubtype CPU_SUBTYPE_ARM_V6M\n";
+ break;
+ case MachO::CPU_SUBTYPE_ARM_V7:
+ outs() << " cputype CPU_TYPE_ARM\n";
+ outs() << " cpusubtype CPU_SUBTYPE_ARM_V7\n";
+ break;
+ case MachO::CPU_SUBTYPE_ARM_V7EM:
+ outs() << " cputype CPU_TYPE_ARM\n";
+ outs() << " cpusubtype CPU_SUBTYPE_ARM_V7EM\n";
+ break;
+ case MachO::CPU_SUBTYPE_ARM_V7K:
+ outs() << " cputype CPU_TYPE_ARM\n";
+ outs() << " cpusubtype CPU_SUBTYPE_ARM_V7K\n";
+ break;
+ case MachO::CPU_SUBTYPE_ARM_V7M:
+ outs() << " cputype CPU_TYPE_ARM\n";
+ outs() << " cpusubtype CPU_SUBTYPE_ARM_V7M\n";
+ break;
+ case MachO::CPU_SUBTYPE_ARM_V7S:
+ outs() << " cputype CPU_TYPE_ARM\n";
+ outs() << " cpusubtype CPU_SUBTYPE_ARM_V7S\n";
+ break;
+ default:
+ printUnknownCPUType(cputype, cpusubtype);
+ break;
+ }
+ break;
+ case MachO::CPU_TYPE_ARM64:
+ switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
+ case MachO::CPU_SUBTYPE_ARM64_ALL:
+ outs() << " cputype CPU_TYPE_ARM64\n";
+ outs() << " cpusubtype CPU_SUBTYPE_ARM64_ALL\n";
+ break;
+ default:
+ printUnknownCPUType(cputype, cpusubtype);
+ break;
+ }
+ break;
+ default:
+ printUnknownCPUType(cputype, cpusubtype);
+ break;
+ }
+}
+
+static void printMachOUniversalHeaders(const object::MachOUniversalBinary *UB,
+ bool verbose) {
+ outs() << "Fat headers\n";
+ if (verbose)
+ outs() << "fat_magic FAT_MAGIC\n";
+ else
+ outs() << "fat_magic " << format("0x%" PRIx32, MachO::FAT_MAGIC) << "\n";
+
+ uint32_t nfat_arch = UB->getNumberOfObjects();
+ StringRef Buf = UB->getData();
+ uint64_t size = Buf.size();
+ uint64_t big_size = sizeof(struct MachO::fat_header) +
+ nfat_arch * sizeof(struct MachO::fat_arch);
+ outs() << "nfat_arch " << UB->getNumberOfObjects();
+ if (nfat_arch == 0)
+ outs() << " (malformed, contains zero architecture types)\n";
+ else if (big_size > size)
+ outs() << " (malformed, architectures past end of file)\n";
+ else
+ outs() << "\n";
+
+ for (uint32_t i = 0; i < nfat_arch; ++i) {
+ MachOUniversalBinary::ObjectForArch OFA(UB, i);
+ uint32_t cputype = OFA.getCPUType();
+ uint32_t cpusubtype = OFA.getCPUSubType();
+ outs() << "architecture ";
+ for (uint32_t j = 0; i != 0 && j <= i - 1; j++) {
+ MachOUniversalBinary::ObjectForArch other_OFA(UB, j);
+ uint32_t other_cputype = other_OFA.getCPUType();
+ uint32_t other_cpusubtype = other_OFA.getCPUSubType();
+ if (cputype != 0 && cpusubtype != 0 && cputype == other_cputype &&
+ (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) ==
+ (other_cpusubtype & ~MachO::CPU_SUBTYPE_MASK)) {
+ outs() << "(illegal duplicate architecture) ";
+ break;
+ }
+ }
+ if (verbose) {
+ outs() << OFA.getArchTypeName() << "\n";
+ printCPUType(cputype, cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
+ } else {
+ outs() << i << "\n";
+ outs() << " cputype " << cputype << "\n";
+ outs() << " cpusubtype " << (cpusubtype & ~MachO::CPU_SUBTYPE_MASK)
+ << "\n";
+ }
+ if (verbose &&
+ (cpusubtype & MachO::CPU_SUBTYPE_MASK) == MachO::CPU_SUBTYPE_LIB64)
+ outs() << " capabilities CPU_SUBTYPE_LIB64\n";
+ else
+ outs() << " capabilities "
+ << format("0x%" PRIx32,
+ (cpusubtype & MachO::CPU_SUBTYPE_MASK) >> 24) << "\n";
+ outs() << " offset " << OFA.getOffset();
+ if (OFA.getOffset() > size)
+ outs() << " (past end of file)";
+ if (OFA.getOffset() % (1 << OFA.getAlign()) != 0)
+ outs() << " (not aligned on it's alignment (2^" << OFA.getAlign() << ")";
+ outs() << "\n";
+ outs() << " size " << OFA.getSize();
+ big_size = OFA.getOffset() + OFA.getSize();
+ if (big_size > size)
+ outs() << " (past end of file)";
+ outs() << "\n";
+ outs() << " align 2^" << OFA.getAlign() << " (" << (1 << OFA.getAlign())
+ << ")\n";
+ }
+}
+
+static void printArchiveChild(Archive::Child &C, bool verbose,
+ bool print_offset) {
+ if (print_offset)
+ outs() << C.getChildOffset() << "\t";
+ sys::fs::perms Mode = C.getAccessMode();
+ if (verbose) {
+ // FIXME: this first dash, "-", is for (Mode & S_IFMT) == S_IFREG.
+ // But there is nothing in sys::fs::perms for S_IFMT or S_IFREG.
+ outs() << "-";
+ if (Mode & sys::fs::owner_read)
+ outs() << "r";
+ else
+ outs() << "-";
+ if (Mode & sys::fs::owner_write)
+ outs() << "w";
+ else
+ outs() << "-";
+ if (Mode & sys::fs::owner_exe)
+ outs() << "x";
+ else
+ outs() << "-";
+ if (Mode & sys::fs::group_read)
+ outs() << "r";
+ else
+ outs() << "-";
+ if (Mode & sys::fs::group_write)
+ outs() << "w";
+ else
+ outs() << "-";
+ if (Mode & sys::fs::group_exe)
+ outs() << "x";
+ else
+ outs() << "-";
+ if (Mode & sys::fs::others_read)
+ outs() << "r";
+ else
+ outs() << "-";
+ if (Mode & sys::fs::others_write)
+ outs() << "w";
+ else
+ outs() << "-";
+ if (Mode & sys::fs::others_exe)
+ outs() << "x";
+ else
+ outs() << "-";
+ } else {
+ outs() << format("0%o ", Mode);
+ }
+
+ unsigned UID = C.getUID();
+ outs() << format("%3d/", UID);
+ unsigned GID = C.getGID();
+ outs() << format("%-3d ", GID);
+ uint64_t Size = C.getRawSize();
+ outs() << format("%5d ", Size);
-void llvm::DisassembleInputMachO(StringRef Filename) {
+ StringRef RawLastModified = C.getRawLastModified();
+ if (verbose) {
+ unsigned Seconds;
+ if (RawLastModified.getAsInteger(10, Seconds))
+ outs() << "(date: \"%s\" contains non-decimal chars) " << RawLastModified;
+ else {
+ // Since cime(3) returns a 26 character string of the form:
+ // "Sun Sep 16 01:03:52 1973\n\0"
+ // just print 24 characters.
+ time_t t = Seconds;
+ outs() << format("%.24s ", ctime(&t));
+ }
+ } else {
+ outs() << RawLastModified << " ";
+ }
+
+ if (verbose) {
+ ErrorOr<StringRef> NameOrErr = C.getName();
+ if (NameOrErr.getError()) {
+ StringRef RawName = C.getRawName();
+ outs() << RawName << "\n";
+ } else {
+ StringRef Name = NameOrErr.get();
+ outs() << Name << "\n";
+ }
+ } else {
+ StringRef RawName = C.getRawName();
+ outs() << RawName << "\n";
+ }
+}
+
+static void printArchiveHeaders(Archive *A, bool verbose, bool print_offset) {
+ if (A->hasSymbolTable()) {
+ Archive::child_iterator S = A->getSymbolTableChild();
+ Archive::Child C = *S;
+ printArchiveChild(C, verbose, print_offset);
+ }
+ for (Archive::child_iterator I = A->child_begin(), E = A->child_end(); I != E;
+ ++I) {
+ Archive::Child C = *I;
+ printArchiveChild(C, verbose, print_offset);
+ }
+}
+
+// ParseInputMachO() parses the named Mach-O file in Filename and handles the
+// -arch flags selecting just those slices as specified by them and also parses
+// archive files. Then for each individual Mach-O file ProcessMachO() is
+// called to process the file based on the command line options.
+void llvm::ParseInputMachO(StringRef Filename) {
// Check for -arch all and verifiy the -arch flags are valid.
for (unsigned i = 0; i < ArchFlags.size(); ++i) {
if (ArchFlags[i] == "all") {
if (Archive *A = dyn_cast<Archive>(&Bin)) {
outs() << "Archive : " << Filename << "\n";
+ if (ArchiveHeaders)
+ printArchiveHeaders(A, true, false);
for (Archive::child_iterator I = A->child_begin(), E = A->child_end();
I != E; ++I) {
ErrorOr<std::unique_ptr<Binary>> ChildOrErr = I->getAsBinary();
if (MachOObjectFile *O = dyn_cast<MachOObjectFile>(&*ChildOrErr.get())) {
if (!checkMachOAndArchFlags(O, Filename))
return;
- DisassembleInputMachO2(Filename, O, O->getFileName());
+ ProcessMachO(Filename, O, O->getFileName());
}
}
return;
}
+ if (UniversalHeaders) {
+ if (MachOUniversalBinary *UB = dyn_cast<MachOUniversalBinary>(&Bin))
+ printMachOUniversalHeaders(UB, true);
+ }
if (MachOUniversalBinary *UB = dyn_cast<MachOUniversalBinary>(&Bin)) {
// If we have a list of architecture flags specified dump only those.
if (!ArchAll && ArchFlags.size() != 0) {
if (ObjOrErr) {
ObjectFile &O = *ObjOrErr.get();
if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&O))
- DisassembleInputMachO2(Filename, MachOOF, "", ArchitectureName);
+ ProcessMachO(Filename, MachOOF, "", ArchitectureName);
} else if (ErrorOr<std::unique_ptr<Archive>> AOrErr =
I->getAsArchive()) {
std::unique_ptr<Archive> &A = *AOrErr;
if (!ArchitectureName.empty())
outs() << " (architecture " << ArchitectureName << ")";
outs() << "\n";
+ if (ArchiveHeaders)
+ printArchiveHeaders(A.get(), true, false);
for (Archive::child_iterator AI = A->child_begin(),
AE = A->child_end();
AI != AE; ++AI) {
continue;
if (MachOObjectFile *O =
dyn_cast<MachOObjectFile>(&*ChildOrErr.get()))
- DisassembleInputMachO2(Filename, O, O->getFileName(),
- ArchitectureName);
+ ProcessMachO(Filename, O, O->getFileName(), ArchitectureName);
}
}
}
// No architecture flags were specified so if this contains a slice that
// matches the host architecture dump only that.
if (!ArchAll) {
- StringRef HostArchName = MachOObjectFile::getHostArch().getArchName();
for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
E = UB->end_objects();
I != E; ++I) {
- if (HostArchName == I->getArchTypeName()) {
+ if (MachOObjectFile::getHostArch().getArchName() ==
+ I->getArchTypeName()) {
ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile();
std::string ArchiveName;
ArchiveName.clear();
if (ObjOrErr) {
ObjectFile &O = *ObjOrErr.get();
if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&O))
- DisassembleInputMachO2(Filename, MachOOF);
+ ProcessMachO(Filename, MachOOF);
} else if (ErrorOr<std::unique_ptr<Archive>> AOrErr =
I->getAsArchive()) {
std::unique_ptr<Archive> &A = *AOrErr;
outs() << "Archive : " << Filename << "\n";
+ if (ArchiveHeaders)
+ printArchiveHeaders(A.get(), true, false);
for (Archive::child_iterator AI = A->child_begin(),
AE = A->child_end();
AI != AE; ++AI) {
continue;
if (MachOObjectFile *O =
dyn_cast<MachOObjectFile>(&*ChildOrErr.get()))
- DisassembleInputMachO2(Filename, O, O->getFileName());
+ ProcessMachO(Filename, O, O->getFileName());
}
}
return;
if (ObjOrErr) {
ObjectFile &Obj = *ObjOrErr.get();
if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&Obj))
- DisassembleInputMachO2(Filename, MachOOF, "", ArchitectureName);
+ ProcessMachO(Filename, MachOOF, "", ArchitectureName);
} else if (ErrorOr<std::unique_ptr<Archive>> AOrErr = I->getAsArchive()) {
std::unique_ptr<Archive> &A = *AOrErr;
outs() << "Archive : " << Filename;
if (!ArchitectureName.empty())
outs() << " (architecture " << ArchitectureName << ")";
outs() << "\n";
+ if (ArchiveHeaders)
+ printArchiveHeaders(A.get(), true, false);
for (Archive::child_iterator AI = A->child_begin(), AE = A->child_end();
AI != AE; ++AI) {
ErrorOr<std::unique_ptr<Binary>> ChildOrErr = AI->getAsBinary();
if (MachOObjectFile *O =
dyn_cast<MachOObjectFile>(&*ChildOrErr.get())) {
if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(O))
- DisassembleInputMachO2(Filename, MachOOF, MachOOF->getFileName(),
- ArchitectureName);
+ ProcessMachO(Filename, MachOOF, MachOOF->getFileName(),
+ ArchitectureName);
}
}
}
if (!checkMachOAndArchFlags(O, Filename))
return;
if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&*O)) {
- DisassembleInputMachO2(Filename, MachOOF);
+ ProcessMachO(Filename, MachOOF);
} else
errs() << "llvm-objdump: '" << Filename << "': "
<< "Object is not a Mach-O file type.\n";
CommentStream.resync();
}
-static void DisassembleInputMachO2(StringRef Filename, MachOObjectFile *MachOOF,
- StringRef ArchiveMemberName,
- StringRef ArchitectureName) {
+static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF) {
const char *McpuDefault = nullptr;
const Target *ThumbTarget = nullptr;
const Target *TheTarget = GetTarget(MachOOF, &McpuDefault, &ThumbTarget);
@@ -1829,7 +2299,7 @@ static void DisassembleInputMachO2(StringRef Filename, MachOObjectFile *MachOOF,
if (RelInfo) {
Symbolizer.reset(TheTarget->createMCSymbolizer(
TripleName, SymbolizerGetOpInfo, SymbolizerSymbolLookUp,
- &SymbolizerInfo, &Ctx, RelInfo.release()));
+ &SymbolizerInfo, &Ctx, std::move(RelInfo)));
DisAsm->setSymbolizer(std::move(Symbolizer));
}
int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
@@ -1877,7 +2347,7 @@ static void DisassembleInputMachO2(StringRef Filename, MachOObjectFile *MachOOF,
if (ThumbRelInfo) {
ThumbSymbolizer.reset(ThumbTarget->createMCSymbolizer(
ThumbTripleName, SymbolizerGetOpInfo, SymbolizerSymbolLookUp,
- &ThumbSymbolizerInfo, PtrThumbCtx, ThumbRelInfo.release()));
+ &ThumbSymbolizerInfo, PtrThumbCtx, std::move(ThumbRelInfo)));
ThumbDisAsm->setSymbolizer(std::move(ThumbSymbolizer));
}
int ThumbAsmPrinterVariant = ThumbAsmInfo->getAssemblerDialect();
@@ -1894,13 +2364,6 @@ static void DisassembleInputMachO2(StringRef Filename, MachOObjectFile *MachOOF,
return;
}
- outs() << Filename;
- if (!ArchiveMemberName.empty())
- outs() << '(' << ArchiveMemberName << ')';
- if (!ArchitectureName.empty())
- outs() << " (architecture " << ArchitectureName << ")";
- outs() << ":\n";
-
MachO::mach_header Header = MachOOF->getHeader();
// FIXME: Using the -cfg command line option, this code used to be able to
break;
case MachO::CPU_TYPE_X86_64:
outs() << " X86_64";
- case MachO::CPU_SUBTYPE_X86_64_ALL:
- outs() << " ALL";
- break;
- case MachO::CPU_SUBTYPE_X86_64_H:
- outs() << " Haswell";
- outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
+ switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
+ case MachO::CPU_SUBTYPE_X86_64_ALL:
+ outs() << " ALL";
+ break;
+ case MachO::CPU_SUBTYPE_X86_64_H:
+ outs() << " Haswell";
+ break;
+ default:
+ outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
+ break;
+ }
break;
case MachO::CPU_TYPE_ARM:
outs() << " ARM";
outs() << "\n";
}
-static void PrintRpathLoadCommand(MachO::rpath_command rpath,
- const char *Ptr) {
+static void PrintRpathLoadCommand(MachO::rpath_command rpath, const char *Ptr) {
outs() << " cmd LC_RPATH\n";
outs() << " cmdsize " << rpath.cmdsize;
if (rpath.cmdsize < sizeof(struct MachO::rpath_command))
}
static void PrintEncryptionInfoCommand64(MachO::encryption_info_command_64 ec,
- uint32_t object_size) {
+ uint32_t object_size) {
outs() << " cmd LC_ENCRYPTION_INFO_64\n";
outs() << " cmdsize " << ec.cmdsize;
if (ec.cmdsize != sizeof(struct MachO::encryption_info_command_64))
}
}
if (lo.count != i)
- outs() << " count " << lo.count << " does not match number of strings " << i
- << "\n";
+ outs() << " count " << lo.count << " does not match number of strings "
+ << i << "\n";
}
static void PrintSubFrameworkCommand(MachO::sub_framework_command sub,
}
static void PrintSubLibraryCommand(MachO::sub_library_command sub,
- const char *Ptr) {
+ const char *Ptr) {
outs() << " cmd LC_SUB_LIBRARY\n";
outs() << " cmdsize " << sub.cmdsize;
if (sub.cmdsize < sizeof(struct MachO::sub_library_command))
outs() << "\n";
}
-static void Print_xmm_reg(MachO::xmm_reg &r) {
+static void Print_xmm_reg(MachO::xmm_reg_t &r) {
uint32_t f;
outs() << "\t xmm_reg ";
for (f = 0; f < 16; f++)
else if (fpu.fpu_fcw.rc == MachO::x86_FP_RND_UP)
outs() << "FP_RND_UP ";
else if (fpu.fpu_fcw.rc == MachO::x86_FP_CHOP)
- outs() << "FP_CHOP ";
+ outs() << "FP_CHOP ";
outs() << "\n";
outs() << "\t status: invalid " << fpu.fpu_fsw.invalid;
outs() << " denorm " << fpu.fpu_fsw.denorm;
for (uint32_t f = 0; f < 6; f++) {
outs() << "\t ";
for (uint32_t g = 0; g < 16; g++)
- outs() << format("%02" PRIx32, fpu.fpu_rsrv4[f*g]) << " ";
+ outs() << format("%02" PRIx32, fpu.fpu_rsrv4[f * g]) << " ";
outs() << "\n";
}
outs() << "\t fpu_reserved1 " << format("0x%08" PRIx32, fpu.fpu_reserved1);
if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
memcpy((char *)&flavor, begin, sizeof(uint32_t));
begin += sizeof(uint32_t);
- } else{
+ } else {
flavor = 0;
begin = end;
}
if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
memcpy((char *)&count, begin, sizeof(uint32_t));
begin += sizeof(uint32_t);
- } else{
+ } else {
count = 0;
begin = end;
}
<< " (not x86_THREAD_STATE64_COUNT\n";
Print_x86_thread_state64_t(ts.uts.ts64);
} else {
- outs() << "\t tsh.flavor " << ts.tsh.flavor
- << " tsh.count " << ts.tsh.count << "\n";
+ outs() << "\t tsh.flavor " << ts.tsh.flavor << " tsh.count "
+ << ts.tsh.count << "\n";
}
} else if (flavor == MachO::x86_FLOAT_STATE) {
outs() << " flavor x86_FLOAT_STATE\n";
if (count == MachO::x86_FLOAT_STATE_COUNT)
outs() << " count x86_FLOAT_STATE_COUNT\n";
else
- outs() << " count " << count
- << " (not x86_FLOAT_STATE_COUNT)\n";
+ outs() << " count " << count << " (not x86_FLOAT_STATE_COUNT)\n";
struct MachO::x86_float_state_t fs;
left = end - begin;
if (left >= sizeof(MachO::x86_float_state_t)) {
swapStruct(fs);
if (fs.fsh.flavor == MachO::x86_FLOAT_STATE64) {
outs() << "\t fsh.flavor x86_FLOAT_STATE64 ";
- if (fs.fsh.count == MachO::x86_FLOAT_STATE64_COUNT)
+ if (fs.fsh.count == MachO::x86_FLOAT_STATE64_COUNT)
outs() << "fsh.count x86_FLOAT_STATE64_COUNT\n";
else
outs() << "fsh.count " << fs.fsh.count
<< " (not x86_FLOAT_STATE64_COUNT\n";
Print_x86_float_state_t(fs.ufs.fs64);
} else {
- outs() << "\t fsh.flavor " << fs.fsh.flavor
- << " fsh.count " << fs.fsh.count << "\n";
+ outs() << "\t fsh.flavor " << fs.fsh.flavor << " fsh.count "
+ << fs.fsh.count << "\n";
}
} else if (flavor == MachO::x86_EXCEPTION_STATE) {
outs() << " flavor x86_EXCEPTION_STATE\n";
if (count == MachO::x86_EXCEPTION_STATE_COUNT)
outs() << " count x86_EXCEPTION_STATE_COUNT\n";
else
- outs() << " count " << count
+ outs() << " count " << count
<< " (not x86_EXCEPTION_STATE_COUNT)\n";
struct MachO::x86_exception_state_t es;
left = end - begin;
swapStruct(es);
if (es.esh.flavor == MachO::x86_EXCEPTION_STATE64) {
outs() << "\t esh.flavor x86_EXCEPTION_STATE64\n";
- if (es.esh.count == MachO::x86_EXCEPTION_STATE64_COUNT)
+ if (es.esh.count == MachO::x86_EXCEPTION_STATE64_COUNT)
outs() << "\t esh.count x86_EXCEPTION_STATE64_COUNT\n";
else
outs() << "\t esh.count " << es.esh.count
<< " (not x86_EXCEPTION_STATE64_COUNT\n";
Print_x86_exception_state_t(es.ues.es64);
} else {
- outs() << "\t esh.flavor " << es.esh.flavor
- << " esh.count " << es.esh.count << "\n";
+ outs() << "\t esh.flavor " << es.esh.flavor << " esh.count "
+ << es.esh.count << "\n";
}
} else {
outs() << " flavor " << flavor << " (unknown)\n";
if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
memcpy((char *)&flavor, begin, sizeof(uint32_t));
begin += sizeof(uint32_t);
- } else{
+ } else {
flavor = 0;
begin = end;
}
if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
memcpy((char *)&count, begin, sizeof(uint32_t));
begin += sizeof(uint32_t);
- } else{
+ } else {
count = 0;
begin = end;
}
}
}
}
-
+
static void PrintDylibCommand(MachO::dylib_command dl, const char *Ptr) {
if (dl.cmd == MachO::LC_ID_DYLIB)
outs() << " cmd LC_ID_DYLIB\n";
static void PrintLoadCommands(const MachOObjectFile *Obj, uint32_t ncmds,
uint32_t filetype, uint32_t cputype,
bool verbose) {
+ if (ncmds == 0)
+ return;
StringRef Buf = Obj->getData();
MachOObjectFile::LoadCommandInfo Command = Obj->getFirstLoadCommandInfo();
for (unsigned i = 0;; ++i) {
MachO::entry_point_command Ep = Obj->getEntryPointCommand(Command);
PrintEntryPointCommand(Ep);
} else if (Command.C.cmd == MachO::LC_ENCRYPTION_INFO) {
- MachO::encryption_info_command Ei = Obj->getEncryptionInfoCommand(Command);
+ MachO::encryption_info_command Ei =
+ Obj->getEncryptionInfoCommand(Command);
PrintEncryptionInfoCommand(Ei, Buf.size());
} else if (Command.C.cmd == MachO::LC_ENCRYPTION_INFO_64) {
- MachO::encryption_info_command_64 Ei = Obj->getEncryptionInfoCommand64(Command);
+ MachO::encryption_info_command_64 Ei =
+ Obj->getEncryptionInfoCommand64(Command);
PrintEncryptionInfoCommand64(Ei, Buf.size());
} else if (Command.C.cmd == MachO::LC_LINKER_OPTION) {
- MachO::linker_option_command Lo = Obj->getLinkerOptionLoadCommand(Command);
+ MachO::linker_option_command Lo =
+ Obj->getLinkerOptionLoadCommand(Command);
PrintLinkerOptionCommand(Lo, Command.Ptr);
} else if (Command.C.cmd == MachO::LC_SUB_FRAMEWORK) {
MachO::sub_framework_command Sf = Obj->getSubFrameworkCommand(Command);