Index: ELF/Target.h =================================================================== --- ELF/Target.h +++ ELF/Target.h @@ -83,6 +83,7 @@ bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override; void relocateOne(uint8_t *Buf, const void *RelP, uint32_t Type, uint64_t BaseAddr, uint64_t SymVA) const override; + bool isRelRelative(uint32_t Type) const override; }; class PPCTargetInfo final : public TargetInfo { Index: ELF/Target.cpp =================================================================== --- ELF/Target.cpp +++ ELF/Target.cpp @@ -225,6 +225,7 @@ PCRelReloc = R_PPC64_REL24; GotReloc = R_PPC64_GLOB_DAT; GotRefReloc = R_PPC64_REL64; + RelativeReloc = R_PPC64_RELATIVE; PltEntrySize = 32; PageSize = 65536; VAStart = 0x10000000; @@ -291,6 +292,19 @@ return S.isShared() || (S.isUndefined() && S.isWeak()); } +bool PPC64TargetInfo::isRelRelative(uint32_t Type) const { + switch (Type) { + default: + return false; + case R_PPC64_REL24: + case R_PPC64_REL14: + case R_PPC64_REL14_BRTAKEN: + case R_PPC64_REL14_BRNTAKEN: + case R_PPC64_REL32: + return true; + } +} + void PPC64TargetInfo::relocateOne(uint8_t *Buf, const void *RelP, uint32_t Type, uint64_t BaseAddr, uint64_t SymVA) const { typedef ELFFile::Elf_Rela Elf_Rela; Index: test/elf2/relative-dynamic-reloc-ppc64.s =================================================================== --- /dev/null +++ test/elf2/relative-dynamic-reloc-ppc64.s @@ -0,0 +1,65 @@ +// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o +// RUN: ld.lld2 -shared %t.o -o %t.so +// RUN: llvm-readobj -t -r -dyn-symbols %t.so | FileCheck %s + +// Test that we create R_PPC64_RELATIVE relocations but don't put any +// symbols in the dynamic symbol table. + +// CHECK: Relocations [ +// CHECK-NEXT: Section ({{.*}}) .rela.dyn { +// CHECK-NEXT: 0x[[FOO_ADDR:.*]] R_PPC64_RELATIVE - 0x[[FOO_ADDR]] +// CHECK-NEXT: 0x[[BAR_ADDR:.*]] R_PPC64_RELATIVE - 0x[[BAR_ADDR]] +// CHECK-NEXT: 0x20010 R_PPC64_RELATIVE - 0x20009 +// CHECK-NEXT: 0x{{.*}} R_PPC64_RELATIVE - 0x[[ZED_ADDR:.*]] +// CHECK-NEXT: 0x{{.*}} R_PPC64_RELATIVE - 0x[[FOO_ADDR]] +// CHECK-NEXT: 0x10008 R_PPC64_ADDR64 external 0x0 +// CHECK-NEXT: } +// CHECK-NEXT: ] + +// CHECK: Symbols [ +// CHECK: Name: foo +// CHECK-NEXT: Value: 0x[[FOO_ADDR]] +// CHECK: Name: bar +// CHECK-NEXT: Value: 0x[[BAR_ADDR]] +// CHECK: Name: zed +// CHECK-NEXT: Value: 0x[[ZED_ADDR]] +// CHECK: ] + +// CHECK: DynamicSymbols [ +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: @ (0) +// CHECK-NEXT: Value: 0x0 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Local +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: Undefined +// CHECK-NEXT: } +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: external@ +// CHECK-NEXT: Value: 0x0 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Global +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: Undefined +// CHECK-NEXT: } +// CHECK-NEXT: ] + +foo: + .quad foo + + .hidden bar + .global bar +bar: + .quad bar + .quad bar + 1 + + .hidden zed + .comm zed,1 + .quad zed + + .section abc,"a" + .quad foo + + .quad external