Index: lld/trunk/ELF/Arch/PPC64.cpp =================================================================== --- lld/trunk/ELF/Arch/PPC64.cpp +++ lld/trunk/ELF/Arch/PPC64.cpp @@ -63,7 +63,7 @@ static uint16_t applyPPCHighesta(uint64_t V) { return (V + 0x8000) >> 48; } PPC64::PPC64() { - PltRel = GotRel = R_PPC64_GLOB_DAT; + GotRel = R_PPC64_GLOB_DAT; RelativeRel = R_PPC64_RELATIVE; GotEntrySize = 8; GotPltEntrySize = 8; @@ -71,8 +71,14 @@ PltHeaderSize = 0; GotBaseSymInGotPlt = false; GotBaseSymOff = 0x8000; - if (Config->EKind == ELF64LEKind) + + if (Config->EKind == ELF64LEKind) { GotHeaderEntriesNum = 1; + GotPltHeaderEntriesNum = 2; + PltRel = R_PPC64_JMP_SLOT; + } else { + PltRel = R_PPC64_GLOB_DAT; + } // We need 64K pages (at least under glibc/Linux, the loader won't // set different permissions on a finer granularity than that). Index: lld/trunk/test/ELF/ppc64le-dynamic-relocations.s =================================================================== --- lld/trunk/test/ELF/ppc64le-dynamic-relocations.s +++ lld/trunk/test/ELF/ppc64le-dynamic-relocations.s @@ -0,0 +1,46 @@ +// REQUIRES: ppc +// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o +// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/shared-ppc64le.s -o %t2.o +// RUN: ld.lld -shared %t2.o -o %t2.so +// RUN: ld.lld %t.o %t2.so -o %t +// RUN: llvm-readobj -dyn-relocations %t | FileCheck %s +// RUN: llvm-objdump -D %t | FileCheck --check-prefix=DIS %s +// RUN: llvm-readelf -dynamic-table %t | FileCheck --check-prefix=DT %s + +// The dynamic relocation for foo should point to 16 bytes past the start of +// the .got.plt section. +// CHECK: Dynamic Relocations { +// CHECK-NEXT: 0x10020010 R_PPC64_JMP_SLOT foo 0x0 + +// There should be 2 reserved doublewords before the first entry. The dynamic +// linker will fill those in with the address of the resolver entry point and +// the dynamic object identifier. +// DIS: Disassembly of section .got.plt: +// DIS-NEXT: .got.plt: +// DIS-NEXT: 10020000: 00 00 00 00 +// DIS-NEXT: 10020004: 00 00 00 00 +// DIS-NEXT: 10020008: 00 00 00 00 +// DIS-NEXT: 1002000c: 00 00 00 00 +// DIS-NEXT: 10020010: 00 00 00 00 +// DIS-NEXT: 10020014: 00 00 00 00 + +// DT_PLTGOT should point to the start of the .got.plt section. +// DT: 0x0000000000000003 PLTGOT 0x10020000 + + .text + .abiversion 2 + .globl _start + .p2align 4 + .type _start,@function +_start: +.Lfunc_begin0: +.Lfunc_gep0: + addis 2, 12, .TOC.-.Lfunc_gep0@ha + addi 2, 2, .TOC.-.Lfunc_gep0@l +.Lfunc_lep0: + .localentry _start, .Lfunc_lep0-.Lfunc_gep0 + bl foo + nop + li 0, 1 + sc + .size _start, .-.Lfunc_begin0 Index: lld/trunk/test/ELF/ppc64le-plt-stub.s =================================================================== --- lld/trunk/test/ELF/ppc64le-plt-stub.s +++ lld/trunk/test/ELF/ppc64le-plt-stub.s @@ -32,6 +32,6 @@ // CHECK: .plt: // CHECK-NEXT: 18 00 41 f8 std 2, 24(1) // CHECK-NEXT: fe ff 82 3d addis 12, 2, -2 -// CHECK-NEXT: 48 7f 8c e9 ld 12, 32584(12) +// CHECK-NEXT: 40 7f 8c e9 ld 12, 32576(12) // CHECK-NEXT: a6 03 89 7d mtctr 12 // CHECK: 20 04 80 4e bctr