summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-objdump
diff options
context:
space:
mode:
authorKevin Enderby <enderby@apple.com>2015-01-09 19:22:37 +0000
committerKevin Enderby <enderby@apple.com>2015-01-09 19:22:37 +0000
commit131d1770f6e00ed07f418f21d4b9b4fd2955a3e0 (patch)
treec86aaf89c1443ae9e9ffda46903a9aa3ddb511e4 /llvm/tools/llvm-objdump
parenteb16112e97957050bff43fed43a9ef3168410440 (diff)
downloadbcm5719-llvm-131d1770f6e00ed07f418f21d4b9b4fd2955a3e0.tar.gz
bcm5719-llvm-131d1770f6e00ed07f418f21d4b9b4fd2955a3e0.zip
Add the option, -universal-headers, used with -macho to print the Mach-O universal headers to llvm-objdump.
llvm-svn: 225537
Diffstat (limited to 'llvm/tools/llvm-objdump')
-rw-r--r--llvm/tools/llvm-objdump/MachODump.cpp216
-rw-r--r--llvm/tools/llvm-objdump/llvm-objdump.cpp3
-rw-r--r--llvm/tools/llvm-objdump/llvm-objdump.h1
3 files changed, 207 insertions, 13 deletions
diff --git a/llvm/tools/llvm-objdump/MachODump.cpp b/llvm/tools/llvm-objdump/MachODump.cpp
index afb8d4bf66a..153edfab52c 100644
--- a/llvm/tools/llvm-objdump/MachODump.cpp
+++ b/llvm/tools/llvm-objdump/MachODump.cpp
@@ -66,6 +66,10 @@ static cl::opt<bool>
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"));
+
static cl::list<std::string>
ArchFlags("arch", cl::desc("architecture(s) from a Mach-O file to dump"),
cl::ZeroOrMore);
@@ -294,12 +298,18 @@ static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF);
static void ProcessMachO(StringRef Filename, MachOObjectFile *MachOOF,
StringRef ArchiveMemberName = StringRef(),
StringRef ArchitectureName = StringRef()) {
- outs() << Filename;
- if (!ArchiveMemberName.empty())
- outs() << '(' << ArchiveMemberName << ')';
- if (!ArchitectureName.empty())
- outs() << " (architecture " << ArchitectureName << ")";
- outs() << ":\n";
+ // 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.
+ if (Disassemble || PrivateHeaders || ExportsTrie || Rebase || Bind ||
+ LazyBind || WeakBind) {
+ outs() << Filename;
+ if (!ArchiveMemberName.empty())
+ outs() << '(' << ArchiveMemberName << ')';
+ if (!ArchitectureName.empty())
+ outs() << " (architecture " << ArchitectureName << ")";
+ outs() << ":\n";
+ }
if (Disassemble)
DisassembleMachO(Filename, MachOOF);
@@ -331,6 +341,179 @@ static void ProcessMachO(StringRef Filename, MachOObjectFile *MachOOF,
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";
+ }
+}
+
// 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
@@ -372,6 +555,10 @@ void llvm::ParseInputMachO(StringRef Filename) {
}
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) {
@@ -2765,12 +2952,17 @@ static void PrintMachHeader(uint32_t magic, uint32_t cputype,
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";
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp
index 74fd9710b3f..aff6272d2fa 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -891,7 +891,8 @@ int main(int argc, char **argv) {
&& !Rebase
&& !Bind
&& !LazyBind
- && !WeakBind) {
+ && !WeakBind
+ && !(UniversalHeaders && MachOOpt)) {
cl::PrintHelpMessage();
return 2;
}
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.h b/llvm/tools/llvm-objdump/llvm-objdump.h
index 01e2b75a9e1..f829dd1a71c 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.h
+++ b/llvm/tools/llvm-objdump/llvm-objdump.h
@@ -34,6 +34,7 @@ extern cl::opt<bool> Rebase;
extern cl::opt<bool> Bind;
extern cl::opt<bool> LazyBind;
extern cl::opt<bool> WeakBind;
+extern cl::opt<bool> UniversalHeaders;
// Various helper functions.
bool error(std::error_code ec);
OpenPOWER on IntegriCloud