From 5fcb412ed0831ad763810f9b424149b3b353451a Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Tue, 19 Jan 2021 11:42:52 -0800 Subject: [PATCH] [ELF] Support R_PPC64_ADDR16_HIGH R_PPC64_ADDR16_HI represents bits 16-31 of a 32-bit value R_PPC64_ADDR16_HIGH represents bits 16-31 of a 64-bit value. In the Linux kernel, `LOAD_REG_IMMEDIATE_SYM` defined in `arch/powerpc/include/asm/ppc_asm.h` uses @l, @high, @higher, @highest to load the 64-bit value of a symbol. Fixes https://github.com/ClangBuiltLinux/linux/issues/1260 --- lld/ELF/Arch/PPC64.cpp | 4 ++++ lld/test/ELF/ppc64-reloc-addr.s | 5 +++++ lld/test/ELF/ppc64-reloc-addr16-err.s | 2 ++ 3 files changed, 11 insertions(+) diff --git a/lld/ELF/Arch/PPC64.cpp b/lld/ELF/Arch/PPC64.cpp index ebd94f6..03ecc81 100644 --- a/lld/ELF/Arch/PPC64.cpp +++ b/lld/ELF/Arch/PPC64.cpp @@ -948,6 +948,7 @@ RelExpr PPC64::getRelExpr(RelType type, const Symbol &s, case R_PPC64_ADDR16_DS: case R_PPC64_ADDR16_HA: case R_PPC64_ADDR16_HI: + case R_PPC64_ADDR16_HIGH: case R_PPC64_ADDR16_HIGHER: case R_PPC64_ADDR16_HIGHERA: case R_PPC64_ADDR16_HIGHEST: @@ -1230,6 +1231,9 @@ void PPC64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const { checkInt(loc, val, 32, rel); write16(loc, hi(val)); break; + case R_PPC64_ADDR16_HIGH: + write16(loc, hi(val)); + break; case R_PPC64_ADDR16_HIGHER: case R_PPC64_TPREL16_HIGHER: write16(loc, higher(val)); diff --git a/lld/test/ELF/ppc64-reloc-addr.s b/lld/test/ELF/ppc64-reloc-addr.s index 7eb13c2..d7b0a3d 100644 --- a/lld/test/ELF/ppc64-reloc-addr.s +++ b/lld/test/ELF/ppc64-reloc-addr.s @@ -25,6 +25,11 @@ .section .R_PPC64_ADDR16_HA,"ax",@progbits lis 4, b@ha +# CHECK-LABEL: <.R_PPC64_ADDR16_HIGH>: +# CHECK-NEXT: lis 4, -30293 +.section .R_PPC64_ADDR16_HIGH,"ax",@progbits + lis 4, a@high + # CHECK-LABEL: <.R_PPC64_ADDR16_HIGHER>: # CHECK-NEXT: li 3, 17767 .section .R_PPC64_ADDR16_HIGHER,"ax",@progbits diff --git a/lld/test/ELF/ppc64-reloc-addr16-err.s b/lld/test/ELF/ppc64-reloc-addr16-err.s index 1b221d5..fe225b5 100644 --- a/lld/test/ELF/ppc64-reloc-addr16-err.s +++ b/lld/test/ELF/ppc64-reloc-addr16-err.s @@ -18,3 +18,5 @@ lis 4, a@h # R_PPC64_ADDR16_HI .ifdef HA lis 4, a@ha # R_PPC64_ADDR16_HA .endif + +lis 4, a@high # R_PPC64_ADDR16_HIGH -- 2.7.4