From: Tim Northover Date: Tue, 14 May 2019 11:25:44 +0000 (+0000) Subject: AArch64: support binutils-like things on arm64_32. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=38bc73c7a8363f8105cc9592b0fed7bf2ba59134;p=llvm AArch64: support binutils-like things on arm64_32. This adds support for the arm64_32 watchOS ABI to LLVM's low level tools, teaching them about the specific MachO choices and constants needed to disassemble things. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@360663 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h index 3a7497cd00e..136871771e9 100644 --- a/include/llvm/ADT/Triple.h +++ b/include/llvm/ADT/Triple.h @@ -49,6 +49,7 @@ public: armeb, // ARM (big endian): armeb aarch64, // AArch64 (little endian): aarch64 aarch64_be, // AArch64 (big endian): aarch64_be + aarch64_32, // AArch64 (little endian) ILP32: aarch64_32 arc, // ARC: Synopsys ARC avr, // AVR: Atmel AVR microcontroller bpfel, // eBPF or extended BPF or 64-bit BPF (little endian) diff --git a/include/llvm/BinaryFormat/MachO.h b/include/llvm/BinaryFormat/MachO.h index e3b4d40fe94..089add56836 100644 --- a/include/llvm/BinaryFormat/MachO.h +++ b/include/llvm/BinaryFormat/MachO.h @@ -1401,7 +1401,8 @@ inline void SET_COMM_ALIGN(uint16_t &n_desc, uint8_t align) { enum : uint32_t { // Capability bits used in the definition of cpu_type. CPU_ARCH_MASK = 0xff000000, // Mask for architecture bits - CPU_ARCH_ABI64 = 0x01000000 // 64 bit ABI + CPU_ARCH_ABI64 = 0x01000000, // 64 bit ABI + CPU_ARCH_ABI64_32 = 0x02000000, // ILP32 ABI on 64-bit hardware }; // Constants for the cputype field. @@ -1414,6 +1415,7 @@ enum CPUType { CPU_TYPE_MC98000 = 10, // Old Motorola PowerPC CPU_TYPE_ARM = 12, CPU_TYPE_ARM64 = CPU_TYPE_ARM | CPU_ARCH_ABI64, + CPU_TYPE_ARM64_32 = CPU_TYPE_ARM | CPU_ARCH_ABI64_32, CPU_TYPE_SPARC = 14, CPU_TYPE_POWERPC = 18, CPU_TYPE_POWERPC64 = CPU_TYPE_POWERPC | CPU_ARCH_ABI64 @@ -1487,6 +1489,8 @@ enum CPUSubTypeARM64 { CPU_SUBTYPE_ARM64E = 2, }; +enum CPUSubTypeARM64_32 { CPU_SUBTYPE_ARM64_32_V8 = 1 }; + enum CPUSubTypeSPARC { CPU_SUBTYPE_SPARC_ALL = 0 }; enum CPUSubTypePowerPC { diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index d8bcf10f075..ba811071b97 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -1100,7 +1100,8 @@ static Error checkThreadCommand(const MachOObjectFile &Obj, "flavor number " + Twine(nflavor) + " in " + CmdName + " command"); } - } else if (cputype == MachO::CPU_TYPE_ARM64) { + } else if (cputype == MachO::CPU_TYPE_ARM64 || + cputype == MachO::CPU_TYPE_ARM64_32) { if (flavor == MachO::ARM_THREAD_STATE64) { if (count != MachO::ARM_THREAD_STATE64_COUNT) return malformedError("load command " + Twine(LoadCommandIndex) + @@ -2170,7 +2171,8 @@ void MachOObjectFile::getRelocationTypeName( res = Table[RType]; break; } - case Triple::aarch64: { + case Triple::aarch64: + case Triple::aarch64_32: { static const char *const Table[] = { "ARM64_RELOC_UNSIGNED", "ARM64_RELOC_SUBTRACTOR", "ARM64_RELOC_BRANCH26", "ARM64_RELOC_PAGE21", @@ -2498,6 +2500,8 @@ StringRef MachOObjectFile::getFileFormatName() const { return "Mach-O 32-bit i386"; case MachO::CPU_TYPE_ARM: return "Mach-O arm"; + case MachO::CPU_TYPE_ARM64_32: + return "Mach-O arm64 (ILP32)"; case MachO::CPU_TYPE_POWERPC: return "Mach-O 32-bit ppc"; default: @@ -2527,6 +2531,8 @@ Triple::ArchType MachOObjectFile::getArch(uint32_t CPUType) { return Triple::arm; case MachO::CPU_TYPE_ARM64: return Triple::aarch64; + case MachO::CPU_TYPE_ARM64_32: + return Triple::aarch64_32; case MachO::CPU_TYPE_POWERPC: return Triple::ppc; case MachO::CPU_TYPE_POWERPC64: @@ -2633,6 +2639,17 @@ Triple MachOObjectFile::getArchTriple(uint32_t CPUType, uint32_t CPUSubType, default: return Triple(); } + case MachO::CPU_TYPE_ARM64_32: + switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) { + case MachO::CPU_SUBTYPE_ARM64_32_V8: + if (McpuDefault) + *McpuDefault = "cyclone"; + if (ArchFlag) + *ArchFlag = "arm64_32"; + return Triple("arm64_32-apple-darwin"); + default: + return Triple(); + } case MachO::CPU_TYPE_POWERPC: switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) { case MachO::CPU_SUBTYPE_POWERPC_ALL: @@ -2676,6 +2693,7 @@ bool MachOObjectFile::isValidArch(StringRef ArchFlag) { .Case("armv7m", true) .Case("armv7s", true) .Case("arm64", true) + .Case("arm64_32", true) .Case("ppc", true) .Case("ppc64", true) .Default(false); diff --git a/lib/Support/ARMTargetParser.cpp b/lib/Support/ARMTargetParser.cpp index 7b8ec2f3390..c57da4cb202 100644 --- a/lib/Support/ARMTargetParser.cpp +++ b/lib/Support/ARMTargetParser.cpp @@ -248,7 +248,7 @@ ARM::EndianKind ARM::parseArchEndian(StringRef Arch) { return EndianKind::LITTLE; } - if (Arch.startswith("aarch64")) + if (Arch.startswith("aarch64") || Arch.startswith("aarch64_32")) return EndianKind::LITTLE; return EndianKind::INVALID; @@ -289,8 +289,12 @@ StringRef ARM::getCanonicalArchName(StringRef Arch) { StringRef Error = ""; // Begins with "arm" / "thumb", move past it. - if (A.startswith("arm64")) + if (A.startswith("arm64_32")) + offset = 8; + else if (A.startswith("arm64")) offset = 5; + else if (A.startswith("aarch64_32")) + offset = 10; else if (A.startswith("arm")) offset = 3; else if (A.startswith("thumb")) diff --git a/lib/Support/Triple.cpp b/lib/Support/Triple.cpp index a5a25d20400..639519ce6ec 100644 --- a/lib/Support/Triple.cpp +++ b/lib/Support/Triple.cpp @@ -22,6 +22,7 @@ StringRef Triple::getArchTypeName(ArchType Kind) { case aarch64: return "aarch64"; case aarch64_be: return "aarch64_be"; + case aarch64_32: return "aarch64_32"; case arm: return "arm"; case armeb: return "armeb"; case arc: return "arc"; @@ -80,7 +81,8 @@ StringRef Triple::getArchTypePrefix(ArchType Kind) { return StringRef(); case aarch64: - case aarch64_be: return "aarch64"; + case aarch64_be: + case aarch64_32: return "aarch64"; case arc: return "arc"; @@ -260,8 +262,10 @@ Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) { return StringSwitch(Name) .Case("aarch64", aarch64) .Case("aarch64_be", aarch64_be) + .Case("aarch64_32", aarch64_32) .Case("arc", arc) .Case("arm64", aarch64) // "arm64" is an alias for "aarch64" + .Case("arm64_32", aarch64_32) .Case("arm", arm) .Case("armeb", armeb) .Case("avr", avr) @@ -389,8 +393,10 @@ static Triple::ArchType parseArch(StringRef ArchName) { .Case("xscaleeb", Triple::armeb) .Case("aarch64", Triple::aarch64) .Case("aarch64_be", Triple::aarch64_be) + .Case("aarch64_32", Triple::aarch64_32) .Case("arc", Triple::arc) .Case("arm64", Triple::aarch64) + .Case("arm64_32", Triple::aarch64_32) .Case("arm", Triple::arm) .Case("armeb", Triple::armeb) .Case("thumb", Triple::thumb) @@ -636,6 +642,7 @@ static Triple::ObjectFormatType getDefaultFormat(const Triple &T) { switch (T.getArch()) { case Triple::UnknownArch: case Triple::aarch64: + case Triple::aarch64_32: case Triple::arm: case Triple::thumb: case Triple::x86: @@ -1219,6 +1226,7 @@ static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) { case llvm::Triple::msp430: return 16; + case llvm::Triple::aarch64_32: case llvm::Triple::arc: case llvm::Triple::arm: case llvm::Triple::armeb: @@ -1299,6 +1307,7 @@ Triple Triple::get32BitArchVariant() const { T.setArch(UnknownArch); break; + case Triple::aarch64_32: case Triple::amdil: case Triple::hsail: case Triple::spir: @@ -1390,6 +1399,7 @@ Triple Triple::get64BitArchVariant() const { // Already 64-bit. break; + case Triple::aarch64_32: T.setArch(Triple::aarch64); break; case Triple::arm: T.setArch(Triple::aarch64); break; case Triple::armeb: T.setArch(Triple::aarch64_be); break; case Triple::le32: T.setArch(Triple::le64); break; @@ -1500,6 +1510,7 @@ Triple Triple::getLittleEndianArchVariant() const { bool Triple::isLittleEndian() const { switch (getArch()) { case Triple::aarch64: + case Triple::aarch64_32: case Triple::amdgcn: case Triple::amdil64: case Triple::amdil: diff --git a/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index 15322a14e6d..149b00a29f8 100644 --- a/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -5514,6 +5514,8 @@ extern "C" void LLVMInitializeAArch64AsmParser() { RegisterMCAsmParser X(getTheAArch64leTarget()); RegisterMCAsmParser Y(getTheAArch64beTarget()); RegisterMCAsmParser Z(getTheARM64Target()); + RegisterMCAsmParser W(getTheARM64_32Target()); + RegisterMCAsmParser V(getTheAArch64_32Target()); } #define GET_REGISTER_MATCHER diff --git a/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp b/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp index c260deb2884..e020a74e187 100644 --- a/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp +++ b/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp @@ -286,11 +286,19 @@ extern "C" void LLVMInitializeAArch64Disassembler() { createAArch64ExternalSymbolizer); TargetRegistry::RegisterMCSymbolizer(getTheAArch64beTarget(), createAArch64ExternalSymbolizer); + TargetRegistry::RegisterMCDisassembler(getTheAArch64_32Target(), + createAArch64Disassembler); + TargetRegistry::RegisterMCSymbolizer(getTheAArch64_32Target(), + createAArch64ExternalSymbolizer); TargetRegistry::RegisterMCDisassembler(getTheARM64Target(), createAArch64Disassembler); TargetRegistry::RegisterMCSymbolizer(getTheARM64Target(), createAArch64ExternalSymbolizer); + TargetRegistry::RegisterMCDisassembler(getTheARM64_32Target(), + createAArch64Disassembler); + TargetRegistry::RegisterMCSymbolizer(getTheARM64_32Target(), + createAArch64ExternalSymbolizer); } static const unsigned FPR128DecoderTable[] = { diff --git a/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp b/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp index e178be3b89d..b50659aec2d 100644 --- a/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp +++ b/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp @@ -512,6 +512,7 @@ enum CompactUnwindEncodings { // FIXME: This should be in a separate file. class DarwinAArch64AsmBackend : public AArch64AsmBackend { const MCRegisterInfo &MRI; + bool IsILP32; /// Encode compact unwind stack adjustment for frameless functions. /// See UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK in compact_unwind_encoding.h. @@ -522,13 +523,18 @@ class DarwinAArch64AsmBackend : public AArch64AsmBackend { public: DarwinAArch64AsmBackend(const Target &T, const Triple &TT, - const MCRegisterInfo &MRI) - : AArch64AsmBackend(T, TT, /*IsLittleEndian*/ true), MRI(MRI) {} + const MCRegisterInfo &MRI, bool IsILP32) + : AArch64AsmBackend(T, TT, /*IsLittleEndian*/ true), MRI(MRI), + IsILP32(IsILP32) {} std::unique_ptr createObjectTargetWriter() const override { - return createAArch64MachObjectWriter(MachO::CPU_TYPE_ARM64, - MachO::CPU_SUBTYPE_ARM64_ALL); + if (IsILP32) + return createAArch64MachObjectWriter( + MachO::CPU_TYPE_ARM64_32, MachO::CPU_SUBTYPE_ARM64_32_V8, true); + else + return createAArch64MachObjectWriter(MachO::CPU_TYPE_ARM64, + MachO::CPU_SUBTYPE_ARM64_ALL, false); } /// Generate the compact unwind encoding from the CFI directives. @@ -710,8 +716,10 @@ MCAsmBackend *llvm::createAArch64leAsmBackend(const Target &T, const MCRegisterInfo &MRI, const MCTargetOptions &Options) { const Triple &TheTriple = STI.getTargetTriple(); - if (TheTriple.isOSBinFormatMachO()) - return new DarwinAArch64AsmBackend(T, TheTriple, MRI); + if (TheTriple.isOSBinFormatMachO()) { + const bool IsILP32 = TheTriple.isArch32Bit(); + return new DarwinAArch64AsmBackend(T, TheTriple, MRI, IsILP32); + } if (TheTriple.isOSBinFormatCOFF()) return new COFFAArch64AsmBackend(T, TheTriple); diff --git a/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp b/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp index 8d9fbce0e3a..06dd0599363 100644 --- a/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp +++ b/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp @@ -191,7 +191,8 @@ static MCInstrAnalysis *createAArch64InstrAnalysis(const MCInstrInfo *Info) { // Force static initialization. extern "C" void LLVMInitializeAArch64TargetMC() { for (Target *T : {&getTheAArch64leTarget(), &getTheAArch64beTarget(), - &getTheARM64Target()}) { + &getTheAArch64_32Target(), &getTheARM64Target(), + &getTheARM64_32Target()}) { // Register the MC asm info. RegisterMCAsmInfoFn X(*T, createAArch64MCAsmInfo); @@ -227,7 +228,8 @@ extern "C" void LLVMInitializeAArch64TargetMC() { } // Register the asm backend. - for (Target *T : {&getTheAArch64leTarget(), &getTheARM64Target()}) + for (Target *T : {&getTheAArch64leTarget(), &getTheAArch64_32Target(), + &getTheARM64Target(), &getTheARM64_32Target()}) TargetRegistry::RegisterMCAsmBackend(*T, createAArch64leAsmBackend); TargetRegistry::RegisterMCAsmBackend(getTheAArch64beTarget(), createAArch64beAsmBackend); diff --git a/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.h b/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.h index 4a690c66278..fbf60b2e669 100644 --- a/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.h +++ b/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.h @@ -38,7 +38,9 @@ class raw_pwrite_stream; Target &getTheAArch64leTarget(); Target &getTheAArch64beTarget(); +Target &getTheAArch64_32Target(); Target &getTheARM64Target(); +Target &getTheARM64_32Target(); MCCodeEmitter *createAArch64MCCodeEmitter(const MCInstrInfo &MCII, const MCRegisterInfo &MRI, @@ -56,7 +58,8 @@ std::unique_ptr createAArch64ELFObjectWriter(uint8_t OSABI, bool IsILP32); std::unique_ptr -createAArch64MachObjectWriter(uint32_t CPUType, uint32_t CPUSubtype); +createAArch64MachObjectWriter(uint32_t CPUType, uint32_t CPUSubtype, + bool IsILP32); std::unique_ptr createAArch64WinCOFFObjectWriter(); diff --git a/lib/Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cpp b/lib/Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cpp index e8d9e3d1f72..b3ce5ef22ee 100644 --- a/lib/Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cpp +++ b/lib/Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cpp @@ -37,8 +37,8 @@ class AArch64MachObjectWriter : public MCMachObjectTargetWriter { unsigned &Log2Size, const MCAssembler &Asm); public: - AArch64MachObjectWriter(uint32_t CPUType, uint32_t CPUSubtype) - : MCMachObjectTargetWriter(true /* is64Bit */, CPUType, CPUSubtype) {} + AArch64MachObjectWriter(uint32_t CPUType, uint32_t CPUSubtype, bool IsILP32) + : MCMachObjectTargetWriter(!IsILP32 /* is64Bit */, CPUType, CPUSubtype) {} void recordRelocation(MachObjectWriter *Writer, MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, @@ -404,6 +404,8 @@ void AArch64MachObjectWriter::recordRelocation( } std::unique_ptr -llvm::createAArch64MachObjectWriter(uint32_t CPUType, uint32_t CPUSubtype) { - return llvm::make_unique(CPUType, CPUSubtype); +llvm::createAArch64MachObjectWriter(uint32_t CPUType, uint32_t CPUSubtype, + bool IsILP32) { + return llvm::make_unique(CPUType, CPUSubtype, + IsILP32); } diff --git a/lib/Target/AArch64/TargetInfo/AArch64TargetInfo.cpp b/lib/Target/AArch64/TargetInfo/AArch64TargetInfo.cpp index e710f463935..08276e08a39 100644 --- a/lib/Target/AArch64/TargetInfo/AArch64TargetInfo.cpp +++ b/lib/Target/AArch64/TargetInfo/AArch64TargetInfo.cpp @@ -18,21 +18,34 @@ Target &getTheAArch64beTarget() { static Target TheAArch64beTarget; return TheAArch64beTarget; } +Target &getTheAArch64_32Target() { + static Target TheAArch64leTarget; + return TheAArch64leTarget; +} Target &getTheARM64Target() { static Target TheARM64Target; return TheARM64Target; } +Target &getTheARM64_32Target() { + static Target TheARM64_32Target; + return TheARM64_32Target; +} } // namespace llvm extern "C" void LLVMInitializeAArch64TargetInfo() { // Now register the "arm64" name for use with "-march". We don't want it to - // take possession of the Triple::aarch64 tag though. + // take possession of the Triple::aarch64 tags though. TargetRegistry::RegisterTarget(getTheARM64Target(), "arm64", "ARM64 (little endian)", "AArch64", [](Triple::ArchType) { return false; }, true); + TargetRegistry::RegisterTarget(getTheARM64_32Target(), "arm64_32", + "ARM64 (little endian ILP32)", "AArch64", + [](Triple::ArchType) { return false; }, true); RegisterTarget Z( getTheAArch64leTarget(), "aarch64", "AArch64 (little endian)", "AArch64"); RegisterTarget W( getTheAArch64beTarget(), "aarch64_be", "AArch64 (big endian)", "AArch64"); + RegisterTarget X( + getTheAArch64_32Target(), "aarch64_32", "AArch64 (little endian ILP32)", "AArch64"); } diff --git a/test/Object/AArch64/nm-trivial-object-arm64_32.test b/test/Object/AArch64/nm-trivial-object-arm64_32.test new file mode 100644 index 00000000000..274513c4a09 --- /dev/null +++ b/test/Object/AArch64/nm-trivial-object-arm64_32.test @@ -0,0 +1,5 @@ +RUN: llvm-nm -arch arm64_32 %p/../Inputs/trivial-object-test.macho-arm64_32 \ +RUN: | FileCheck %s + +CHECK: 00000000 T _foo +CHECK: 00000000 t ltmp0 diff --git a/test/Object/Inputs/trivial-object-test.macho-arm64_32 b/test/Object/Inputs/trivial-object-test.macho-arm64_32 new file mode 100644 index 00000000000..22b173c4ee8 Binary files /dev/null and b/test/Object/Inputs/trivial-object-test.macho-arm64_32 differ diff --git a/test/tools/llvm-objdump/AArch64/Inputs/arm64_32-fat.o b/test/tools/llvm-objdump/AArch64/Inputs/arm64_32-fat.o new file mode 100644 index 00000000000..ea5f9d05e34 Binary files /dev/null and b/test/tools/llvm-objdump/AArch64/Inputs/arm64_32-fat.o differ diff --git a/test/tools/llvm-objdump/AArch64/Inputs/thread.macho-arm64_32 b/test/tools/llvm-objdump/AArch64/Inputs/thread.macho-arm64_32 new file mode 100644 index 00000000000..a46c0ed0bb8 Binary files /dev/null and b/test/tools/llvm-objdump/AArch64/Inputs/thread.macho-arm64_32 differ diff --git a/test/tools/llvm-objdump/AArch64/arm64_32-fat.test b/test/tools/llvm-objdump/AArch64/arm64_32-fat.test new file mode 100644 index 00000000000..dc9b319e3c4 --- /dev/null +++ b/test/tools/llvm-objdump/AArch64/arm64_32-fat.test @@ -0,0 +1,7 @@ +RUN: llvm-objdump -macho -universal-headers %p/Inputs/arm64_32-fat.o | FileCheck %s + +CHECK: cputype CPU_TYPE_ARM64_32 +CHECK-NEXT: cpusubtype CPU_SUBTYPE_ARM64_32_V8 + +CHECK: cputype CPU_TYPE_ARM64 +CHECK-NEXT: cpusubtype CPU_SUBTYPE_ARM64_ALL diff --git a/test/tools/llvm-objdump/AArch64/arm64_32.s b/test/tools/llvm-objdump/AArch64/arm64_32.s new file mode 100644 index 00000000000..050719d9051 --- /dev/null +++ b/test/tools/llvm-objdump/AArch64/arm64_32.s @@ -0,0 +1,8 @@ +// RUN: llvm-mc -triple arm64_32-apple-watchos %s -filetype=obj -o %t +// RUN: llvm-objdump -macho -d %t | FileCheck %s +// RUN: llvm-objdump -macho -private-headers %t | FileCheck %s --check-prefix=CHECK-HEADERS + +// CHECK: ldr x0, [x2] +ldr x0, [x2] + +// CHECK-HEADERS: MH_MAGIC ARM64_32 V8 diff --git a/test/tools/llvm-objdump/AArch64/macho-print-thread-arm64_32.test b/test/tools/llvm-objdump/AArch64/macho-print-thread-arm64_32.test new file mode 100644 index 00000000000..7bacb54ae80 --- /dev/null +++ b/test/tools/llvm-objdump/AArch64/macho-print-thread-arm64_32.test @@ -0,0 +1,19 @@ +RUN: llvm-objdump -macho -private-headers %p/Inputs/thread.macho-arm64_32 | FileCheck %s + +CHECK: Load command 0 +CHECK: cmd LC_UNIXTHREAD +CHECK: cmdsize 288 +CHECK: flavor ARM_THREAD_STATE64 +CHECK: count ARM_THREAD_STATE64_COUNT +CHECK: x0 0x0000000000000000 x1 0x0000000000000000 x2 0x0000000000000000 +CHECK: x3 0x0000000000000000 x4 0x0000000000000000 x5 0x0000000000000000 +CHECK: x6 0x0000000000000000 x7 0x0000000000000000 x8 0x0000000000000000 +CHECK: x9 0x0000000000000000 x10 0x0000000000000000 x11 0x0000000000000000 +CHECK: x12 0x0000000000000000 x13 0x0000000000000000 x14 0x0000000000000000 +CHECK: x15 0x0000000000000000 x16 0x0000000000000000 x17 0x0000000000000000 +CHECK: x18 0x0000000000000000 x19 0x0000000000000000 x20 0x0000000000000000 +CHECK: x21 0x0000000000000000 x22 0x0000000000000000 x23 0x0000000000000000 +CHECK: x24 0x0000000000000000 x25 0x0000000000000000 x26 0x0000000000000000 +CHECK: x27 0x0000000000000000 x28 0x0000000000000000 fp 0x0000000000000000 +CHECK: lr 0x0000000000000000 sp 0x0000000000000000 pc 0x0000000000007fd4 +CHECK: cpsr 0x00000000 diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp index 42b82ae5a9d..9d8161937b4 100644 --- a/tools/llvm-objdump/MachODump.cpp +++ b/tools/llvm-objdump/MachODump.cpp @@ -776,6 +776,7 @@ static void PrintRType(const uint64_t cputype, const unsigned r_type) { outs() << arm_r_types[r_type]; break; case MachO::CPU_TYPE_ARM64: + case MachO::CPU_TYPE_ARM64_32: outs() << arm64_r_types[r_type]; break; default: @@ -951,7 +952,8 @@ static void PrintRelocationEntries(const MachOObjectFile *O, // plain: symbolnum/value if (cputype == MachO::CPU_TYPE_ARM && r_type == MachO::ARM_RELOC_PAIR) outs() << format("other_half = 0x%04x\n", (unsigned int)r_address); - else if (cputype == MachO::CPU_TYPE_ARM64 && + else if ((cputype == MachO::CPU_TYPE_ARM64 || + cputype == MachO::CPU_TYPE_ARM64_32) && r_type == MachO::ARM64_RELOC_ADDEND) outs() << format("addend = 0x%06x\n", (unsigned int)r_symbolnum); else { @@ -2040,6 +2042,17 @@ static void printCPUType(uint32_t cputype, uint32_t cpusubtype) { break; } break; + case MachO::CPU_TYPE_ARM64_32: + switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) { + case MachO::CPU_SUBTYPE_ARM64_32_V8: + outs() << " cputype CPU_TYPE_ARM64_32\n"; + outs() << " cpusubtype CPU_SUBTYPE_ARM64_32_V8\n"; + break; + default: + printUnknownCPUType(cputype, cpusubtype); + break; + } + break; default: printUnknownCPUType(cputype, cpusubtype); break; @@ -8118,6 +8131,17 @@ static void PrintMachHeader(uint32_t magic, uint32_t cputype, break; } break; + case MachO::CPU_TYPE_ARM64_32: + outs() << " ARM64_32"; + switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) { + case MachO::CPU_SUBTYPE_ARM64_32_V8: + outs() << " V8"; + break; + default: + outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK); + break; + } + break; case MachO::CPU_TYPE_POWERPC: outs() << " PPC"; switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) { @@ -9681,7 +9705,8 @@ static void PrintThreadCommand(MachO::thread_command t, const char *Ptr, begin += count * sizeof(uint32_t); } } - } else if (cputype == MachO::CPU_TYPE_ARM64) { + } else if (cputype == MachO::CPU_TYPE_ARM64 || + cputype == MachO::CPU_TYPE_ARM64_32) { while (begin < end) { if (end - begin > (ptrdiff_t)sizeof(uint32_t)) { memcpy((char *)&flavor, begin, sizeof(uint32_t));