mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 20:32:21 +00:00
Add the option, -universal-headers, used with -macho to print the Mach-O universal headers to llvm-objdump.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225537 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
8cd39a2630
commit
6248d1b153
@ -51,6 +51,10 @@ public:
|
||||
|
||||
ObjectForArch getNext() const { return ObjectForArch(Parent, Index + 1); }
|
||||
uint32_t getCPUType() const { return Header.cputype; }
|
||||
uint32_t getCPUSubType() const { return Header.cpusubtype; }
|
||||
uint32_t getOffset() const { return Header.offset; }
|
||||
uint32_t getSize() const { return Header.size; }
|
||||
uint32_t getAlign() const { return Header.align; }
|
||||
std::string getArchTypeName() const {
|
||||
Triple T = MachOObjectFile::getArch(Header.cputype, Header.cpusubtype);
|
||||
return T.getArchName();
|
||||
|
@ -2,6 +2,8 @@ RUN: llvm-objdump %p/Inputs/macho-universal.x86_64.i386 -d -m -no-show-raw-insn
|
||||
RUN: | FileCheck %s -check-prefix UEXE-all
|
||||
RUN: llvm-objdump %p/Inputs/macho-universal-archive.x86_64.i386 -d -m -no-show-raw-insn -full-leading-addr -print-imm-hex -arch i386 \
|
||||
RUN: | FileCheck %s -check-prefix UArchive-i386
|
||||
RUN: llvm-objdump %p/Inputs/macho-universal.x86_64.i386 -universal-headers -m \
|
||||
RUN: | FileCheck %s -check-prefix FAT
|
||||
|
||||
UEXE-all: macho-universal.x86_64.i386 (architecture x86_64):
|
||||
UEXE-all: (__TEXT,__text) section
|
||||
@ -23,3 +25,20 @@ UArchive-i386: 00000001 movl %esp, %ebp
|
||||
UArchive-i386: 00000003 popl %ebp
|
||||
UArchive-i386: 00000004 retl
|
||||
|
||||
FAT: Fat headers
|
||||
FAT: fat_magic FAT_MAGIC
|
||||
FAT: nfat_arch 2
|
||||
FAT: architecture x86_64
|
||||
FAT: cputype CPU_TYPE_X86_64
|
||||
FAT: cpusubtype CPU_SUBTYPE_X86_64_ALL
|
||||
FAT: capabilities CPU_SUBTYPE_LIB64
|
||||
FAT: offset 4096
|
||||
FAT: size 4360
|
||||
FAT: align 2^12 (4096)
|
||||
FAT: architecture i386
|
||||
FAT: cputype CPU_TYPE_I386
|
||||
FAT: cpusubtype CPU_SUBTYPE_I386_ALL
|
||||
FAT: capabilities 0x0
|
||||
FAT: offset 12288
|
||||
FAT: size 4336
|
||||
FAT: align 2^12 (4096)
|
||||
|
@ -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";
|
||||
|
@ -891,7 +891,8 @@ int main(int argc, char **argv) {
|
||||
&& !Rebase
|
||||
&& !Bind
|
||||
&& !LazyBind
|
||||
&& !WeakBind) {
|
||||
&& !WeakBind
|
||||
&& !(UniversalHeaders && MachOOpt)) {
|
||||
cl::PrintHelpMessage();
|
||||
return 2;
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user