diff --git a/lld/MachO/Arch/ARM64.cpp b/lld/MachO/Arch/ARM64.cpp --- a/lld/MachO/Arch/ARM64.cpp +++ b/lld/MachO/Arch/ARM64.cpp @@ -25,11 +25,15 @@ namespace { -struct ARM64 : TargetInfo { +struct ARM64 : TargetInfo_LP64 { ARM64(); - int64_t getEmbeddedAddend(MemoryBufferRef, uint64_t offset, - const relocation_info) const override; + int64_t getEmbeddedAddend(llvm::MemoryBufferRef, + const llvm::MachO::section_64 &, + const llvm::MachO::relocation_info) const override; + int64_t getEmbeddedAddend(llvm::MemoryBufferRef, const llvm::MachO::section &, + const llvm::MachO::relocation_info) const override; + void relocateOne(uint8_t *loc, const Reloc &, uint64_t va, uint64_t pc) const override; @@ -77,7 +81,15 @@ return relocAttrsArray[type]; } -int64_t ARM64::getEmbeddedAddend(MemoryBufferRef mb, uint64_t offset, +int64_t ARM64::getEmbeddedAddend(llvm::MemoryBufferRef mb, + const llvm::MachO::section &sec, + const llvm::MachO::relocation_info rel) const { + assert(wordSize == 4 && "ARM64 is 64-bit"); + return -1; +} + +int64_t ARM64::getEmbeddedAddend(MemoryBufferRef mb, + const llvm::MachO::section_64 &sec, const relocation_info rel) const { if (rel.r_type != ARM64_RELOC_UNSIGNED && rel.r_type != ARM64_RELOC_SUBTRACTOR) { @@ -88,7 +100,7 @@ } auto *buf = reinterpret_cast(mb.getBufferStart()); - const uint8_t *loc = buf + offset + rel.r_address; + const uint8_t *loc = buf + sec.offset + rel.r_address; switch (rel.r_length) { case 2: return static_cast(read32le(loc)); @@ -292,7 +304,7 @@ write32le(loc, instruction); } -ARM64::ARM64() : TargetInfo(LP64()) { +ARM64::ARM64() : TargetInfo_LP64() { cpuType = CPU_TYPE_ARM64; cpuSubtype = CPU_SUBTYPE_ARM64_ALL; diff --git a/lld/MachO/Arch/X86_64.cpp b/lld/MachO/Arch/X86_64.cpp --- a/lld/MachO/Arch/X86_64.cpp +++ b/lld/MachO/Arch/X86_64.cpp @@ -22,11 +22,15 @@ namespace { -struct X86_64 : TargetInfo { +struct X86_64 : TargetInfo_LP64 { X86_64(); - int64_t getEmbeddedAddend(MemoryBufferRef, uint64_t offset, - const relocation_info) const override; + int64_t getEmbeddedAddend(llvm::MemoryBufferRef, + const llvm::MachO::section_64 &, + const llvm::MachO::relocation_info) const override; + int64_t getEmbeddedAddend(llvm::MemoryBufferRef, const llvm::MachO::section &, + const llvm::MachO::relocation_info) const override; + void relocateOne(uint8_t *loc, const Reloc &, uint64_t va, uint64_t relocVA) const override; @@ -77,10 +81,18 @@ } } -int64_t X86_64::getEmbeddedAddend(MemoryBufferRef mb, uint64_t offset, +int64_t X86_64::getEmbeddedAddend(llvm::MemoryBufferRef, + const llvm::MachO::section &, + const llvm::MachO::relocation_info) const { + assert(wordSize == 4 && "X86_64 is 64-bit"); + return -1; +} + +int64_t X86_64::getEmbeddedAddend(MemoryBufferRef mb, + const llvm::MachO::section_64 &sec, relocation_info rel) const { auto *buf = reinterpret_cast(mb.getBufferStart()); - const uint8_t *loc = buf + offset + rel.r_address; + const uint8_t *loc = buf + sec.offset + rel.r_address; switch (rel.r_length) { case 2: @@ -182,7 +194,7 @@ loc[-2] = 0x8d; } -X86_64::X86_64() : TargetInfo(LP64()) { +X86_64::X86_64() : TargetInfo_LP64() { cpuType = CPU_TYPE_X86_64; cpuSubtype = CPU_SUBTYPE_X86_64_ALL; diff --git a/lld/MachO/InputFiles.cpp b/lld/MachO/InputFiles.cpp --- a/lld/MachO/InputFiles.cpp +++ b/lld/MachO/InputFiles.cpp @@ -283,7 +283,7 @@ if (relInfo.r_address & R_SCATTERED) fatal("TODO: Scattered relocations not supported"); - int64_t embeddedAddend = target->getEmbeddedAddend(mb, sec.offset, relInfo); + int64_t embeddedAddend = target->getEmbeddedAddend(mb, sec, relInfo); assert(!(embeddedAddend && pairedAddend)); int64_t totalAddend = pairedAddend + embeddedAddend; Reloc r; diff --git a/lld/MachO/Target.h b/lld/MachO/Target.h --- a/lld/MachO/Target.h +++ b/lld/MachO/Target.h @@ -29,18 +29,17 @@ class TargetInfo { public: - template TargetInfo(LP) { - // Having these values available in TargetInfo allows us to access them - // without having to resort to templates. - pageZeroSize = LP::pageZeroSize; - wordSize = LP::wordSize; - } + TargetInfo(size_t wordSize, size_t pageZeroSize) + : wordSize(wordSize), pageZeroSize(pageZeroSize){}; virtual ~TargetInfo() = default; // Validate the relocation structure and get its addend. virtual int64_t - getEmbeddedAddend(llvm::MemoryBufferRef, uint64_t offset, + getEmbeddedAddend(llvm::MemoryBufferRef, const llvm::MachO::section_64 &, + const llvm::MachO::relocation_info) const = 0; + virtual int64_t + getEmbeddedAddend(llvm::MemoryBufferRef, const llvm::MachO::section &, const llvm::MachO::relocation_info) const = 0; virtual void relocateOne(uint8_t *loc, const Reloc &, uint64_t va, uint64_t relocVA) const = 0; @@ -70,16 +69,13 @@ uint32_t cpuType; uint32_t cpuSubtype; + size_t wordSize; uint64_t pageZeroSize; size_t stubSize; size_t stubHelperHeaderSize; size_t stubHelperEntrySize; - size_t wordSize; }; -TargetInfo *createX86_64TargetInfo(); -TargetInfo *createARM64TargetInfo(); - struct LP64 { using mach_header = llvm::MachO::mach_header_64; using nlist = structs::nlist_64; @@ -106,6 +102,19 @@ static constexpr size_t wordSize = 4; }; +class TargetInfo_ILP32 : public TargetInfo { +public: + TargetInfo_ILP32() : TargetInfo(ILP32::wordSize, ILP32::pageZeroSize){}; +}; + +class TargetInfo_LP64 : public TargetInfo { +public: + TargetInfo_LP64() : TargetInfo(LP64::wordSize, LP64::pageZeroSize){}; +}; + +TargetInfo *createX86_64TargetInfo(); +TargetInfo *createARM64TargetInfo(); + extern TargetInfo *target; } // namespace macho