From 1f820e35596bac036a7f759c4de41fcc2e642719 Mon Sep 17 00:00:00 2001 From: Jez Ng Date: Fri, 15 May 2020 12:02:40 -0700 Subject: [PATCH] [lld-macho] Support X86_64_RELOC_UNSIGNED Note that it's only used for non-pc-relative contexts. Reviewed By: MaskRay, smeenai Differential Revision: https://reviews.llvm.org/D80048 --- lld/MachO/Arch/X86_64.cpp | 5 +++++ lld/MachO/InputFiles.cpp | 6 ++++-- lld/MachO/InputSection.cpp | 2 +- lld/MachO/InputSection.h | 7 ++++--- lld/MachO/Target.h | 1 + lld/test/MachO/x86-64-reloc-unsigned.s | 24 ++++++++++++++++++++++++ 6 files changed, 39 insertions(+), 6 deletions(-) create mode 100644 lld/test/MachO/x86-64-reloc-unsigned.s diff --git a/lld/MachO/Arch/X86_64.cpp b/lld/MachO/Arch/X86_64.cpp index 08b23a5..21ae3d2 100644 --- a/lld/MachO/Arch/X86_64.cpp +++ b/lld/MachO/Arch/X86_64.cpp @@ -47,6 +47,8 @@ uint64_t X86_64::getImplicitAddend(const uint8_t *loc, uint8_t type) const { case X86_64_RELOC_SIGNED_4: case X86_64_RELOC_GOT_LOAD: return read32le(loc); + case X86_64_RELOC_UNSIGNED: + return read64le(loc); default: error("TODO: Unhandled relocation type " + std::to_string(type)); return 0; @@ -65,6 +67,9 @@ void X86_64::relocateOne(uint8_t *loc, uint8_t type, uint64_t val) const { // since the RIP has advanced by 4 at this point. write32le(loc, val - 4); break; + case X86_64_RELOC_UNSIGNED: + write64le(loc, val); + break; default: llvm_unreachable( "getImplicitAddend should have flagged all unhandled relocation types"); diff --git a/lld/MachO/InputFiles.cpp b/lld/MachO/InputFiles.cpp index cfd3df4..9093a08 100644 --- a/lld/MachO/InputFiles.cpp +++ b/lld/MachO/InputFiles.cpp @@ -173,11 +173,10 @@ void InputFile::parseRelocations(const section_64 &sec, fatal("TODO: Scattered relocations not supported"); auto rel = reinterpret_cast(anyRel); - if (!rel.r_pcrel) - fatal("TODO: Only pcrel relocations are supported"); Reloc r; r.type = rel.r_type; + r.pcrel = rel.r_pcrel; uint32_t secRelOffset = rel.r_address; uint64_t rawAddend = target->getImplicitAddend(buf + sec.offset + secRelOffset, r.type); @@ -186,6 +185,9 @@ void InputFile::parseRelocations(const section_64 &sec, r.target = symbols[rel.r_symbolnum]; r.addend = rawAddend; } else { + if (!rel.r_pcrel) + fatal("TODO: Only pcrel section relocations are supported"); + if (rel.r_symbolnum == 0 || rel.r_symbolnum > subsections.size()) fatal("invalid section index in relocation for offset " + std::to_string(r.offset) + " in section " + sec.sectname + diff --git a/lld/MachO/InputSection.cpp b/lld/MachO/InputSection.cpp index 5453c0b..84ed52d 100644 --- a/lld/MachO/InputSection.cpp +++ b/lld/MachO/InputSection.cpp @@ -43,7 +43,7 @@ void InputSection::writeTo(uint8_t *buf) { } uint64_t val = va + r.addend; - if (1) // TODO: handle non-pcrel relocations + if (r.pcrel) val -= getVA() + r.offset; target->relocateOne(buf + r.offset, r.type, val); } diff --git a/lld/MachO/InputSection.h b/lld/MachO/InputSection.h index 1d11b8e..5c21b83 100644 --- a/lld/MachO/InputSection.h +++ b/lld/MachO/InputSection.h @@ -24,12 +24,13 @@ class Symbol; struct Reloc { uint8_t type; - // Adding this offset to the address of the target symbol or subsection gives - // the destination that this relocation refers to. - uint32_t addend; + bool pcrel; // The offset from the start of the subsection that this relocation belongs // to. uint32_t offset; + // Adding this offset to the address of the target symbol or subsection gives + // the destination that this relocation refers to. + uint64_t addend; llvm::PointerUnion target; }; diff --git a/lld/MachO/Target.h b/lld/MachO/Target.h index 9781b70..1af7c03 100644 --- a/lld/MachO/Target.h +++ b/lld/MachO/Target.h @@ -29,6 +29,7 @@ enum { class TargetInfo { public: virtual ~TargetInfo() = default; + virtual uint64_t getImplicitAddend(const uint8_t *loc, uint8_t type) const = 0; virtual void relocateOne(uint8_t *loc, uint8_t type, uint64_t val) const = 0; diff --git a/lld/test/MachO/x86-64-reloc-unsigned.s b/lld/test/MachO/x86-64-reloc-unsigned.s new file mode 100644 index 0000000..976532f --- /dev/null +++ b/lld/test/MachO/x86-64-reloc-unsigned.s @@ -0,0 +1,24 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t.o +# RUN: lld -flavor darwinnew -o %t %t.o +# RUN: llvm-objdump --full-contents %t | FileCheck %s +# CHECK: Contents of section foo: +# CHECK: 2000 08200000 00000000 +# CHECK: Contents of section bar: +# CHECK: 2008 11311111 01000000 + +.globl _main, _foo, _bar + +.section __DATA,foo +_foo: +.quad _bar + +.section __DATA,bar +_bar: +## The unsigned relocation should support 64-bit addends +.quad _foo + 0x111111111 + +.text +_main: + mov $0, %rax + ret -- 2.7.4