Index: ELF/Arch/PPC64.cpp =================================================================== --- ELF/Arch/PPC64.cpp +++ ELF/Arch/PPC64.cpp @@ -536,6 +536,8 @@ RelExpr PPC64::getRelExpr(RelType type, const Symbol &s, const uint8_t *loc) const { switch (type) { + case R_PPC64_UADDR64: + return R_ABS; case R_PPC64_GOT16: case R_PPC64_GOT16_DS: case R_PPC64_GOT16_HA: @@ -618,6 +620,8 @@ RelType PPC64::getDynRel(RelType type) const { if (type == R_PPC64_ADDR64 || type == R_PPC64_TOC) return R_PPC64_ADDR64; + if (type == R_PPC64_UADDR64) + return type; return R_PPC64_NONE; } @@ -852,6 +856,7 @@ write32(loc, val); break; case R_PPC64_ADDR64: + case R_PPC64_UADDR64: case R_PPC64_REL64: case R_PPC64_TOC: write64(loc, val); Index: test/ELF/ppc64-reloc-uaddr.s =================================================================== --- /dev/null +++ test/ELF/ppc64-reloc-uaddr.s @@ -0,0 +1,36 @@ +# REQUIRES: ppc +# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o +# RUN: ld.lld -pie %t.o --defsym=external=42 -o %t +# RUN: llvm-readobj -r -x .data %t | FileCheck --check-prefix=PIE %s +# RUN: ld.lld -shared %t.o -o %t.so +# RUN: llvm-readobj -r %t.so | FileCheck --check-prefix=SHARED %s + +## 'local' and 'global' are non-preemptable, but we have to use R_PPC64_UADDR64, +## instead of misaligned R_PPC64_RELATIVE. +# PIE: .rela.dyn { +# PIE-NEXT: 0x20001 R_PPC64_UADDR64 - 0x1 +# PIE-NEXT: 0x20011 R_PPC64_UADDR64 - 0x3 +# PIE-NEXT: } + +## 'external' is absolute of value 42. The field is filled at link time. +# PIE: section '.data': +# PIE-NEXT: 0x00020000 00000000 00000000 002c0000 00000000 +# PIE-NEXT: 0x00020010 00000000 00000000 00 + +## 'local' is non-preemptable, but we have to use R_PPC64_UADDR64. +## Preemptable 'external' and 'global' are associated with symbols. +# SHARED: .rela.dyn { +# SHARED-NEXT: 0x20001 R_PPC64_UADDR64 - 0x1 +# SHARED-NEXT: 0x20009 R_PPC64_UADDR64 external 0x2 +# SHARED-NEXT: 0x20011 R_PPC64_UADDR64 global 0x3 +# SHARED-NEXT: } + +.data +.globl global +global: +local: + +.byte 0 +.quad local + 1 +.quad external + 2 +.quad global + 3