1# REQUIRES: ppc 2# RUN: llvm-mc -filetype=obj -triple=powerpc %s -o %t.o 3# RUN: echo '.globl f, g, h; f: g: h:' | llvm-mc -filetype=obj -triple=powerpc - -o %t1.o 4# RUN: ld.lld -shared %t1.o -soname t1.so -o %t1.so 5# RUN: echo 'bl f+0x8000@plt' | llvm-mc -filetype=obj -triple=powerpc - -o %t2.o 6 7## Check we can create PLT entries for -fPIE or -fpie executable. 8# RUN: ld.lld -pie %t.o %t1.so %t2.o -o %t 9# RUN: llvm-readobj -r %t | FileCheck --check-prefix=RELOC %s 10# RUN: llvm-readobj -d %t | FileCheck --check-prefix=DYN %s 11# RUN: llvm-readelf -S %t | FileCheck --check-prefix=SEC %s 12# RUN: llvm-readelf -x .plt %t | FileCheck --check-prefix=HEX %s 13# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefixes=CHECK,PIE %s 14 15## Check we can create PLT entries for -fPIC or -fpic DSO. 16# RUN: ld.lld -shared %t.o %t1.so %t2.o -o %t 17# RUN: llvm-readobj -r %t | FileCheck --check-prefix=RELOC %s 18# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefixes=CHECK,SHARED %s 19 20# RELOC: .rela.dyn { 21# RELOC-NEXT: R_PPC_ADDR32 f 0x0 22# RELOC-NEXT: R_PPC_ADDR32 g 0x0 23# RELOC-NEXT: R_PPC_ADDR32 h 0x0 24# RELOC-NEXT: } 25# RELOC-NEXT: .rela.plt { 26# RELOC-NEXT: R_PPC_JMP_SLOT f 0x0 27# RELOC-NEXT: R_PPC_JMP_SLOT g 0x0 28# RELOC-NEXT: R_PPC_JMP_SLOT h 0x0 29# RELOC-NEXT: } 30 31# SEC: .got PROGBITS 00020370 32# DYN: PPC_GOT 0x20370 33 34## .got2+0x8000-0x10004 = 0x30000+0x8000-0x10004 = 65536*2+32764 35# CHECK-LABEL: <_start>: 36# PIE-NEXT: bcl 20, 31, 0x10210 37# PIE-NEXT: 10210: mflr 30 38# PIE-NEXT: addis 30, 30, 3 39# PIE-NEXT: addi 30, 30, -32404 40## Two bl 00008000.got2.plt_pic32.f 41# PIE-NEXT: bl 0x10244 42# PIE-NEXT: bl 0x10244 43## Two bl 00008000.got2.plt_pic32.g 44# PIE-NEXT: bl 0x10254 45# PIE-NEXT: bl 0x10254 46## Two bl 00008000.got2.plt_pic32.h 47# PIE-NEXT: bl 0x10264 48# PIE-NEXT: bl 0x10264 49# PIE-NEXT: addis 30, 30, {{.*}} 50# PIE-NEXT: addi 30, 30, {{.*}} 51## bl 00008000.plt_pic32.f 52# PIE-NEXT: bl 0x10274 53## bl 00008000.plt_pic32.f 54# PIE-NEXT: bl 0x10284 55# SHARED-NEXT: bcl 20, 31, 0x10230 56# SHARED-NEXT: 10230: mflr 30 57# SHARED-NEXT: addis 30, 30, 3 58# SHARED-NEXT: addi 30, 30, -32420 59# SHARED-NEXT: bl 0x10264 60# SHARED-NEXT: bl 0x10264 61# SHARED-NEXT: bl 0x10274 62# SHARED-NEXT: bl 0x10274 63# SHARED-NEXT: bl 0x10284 64# SHARED-NEXT: bl 0x10284 65# SHARED-NEXT: addis 30, 30, {{.*}} 66# SHARED-NEXT: addi 30, 30, {{.*}} 67# SHARED-NEXT: bl 0x10294 68# SHARED-NEXT: bl 0x102a4 69# CHECK-EMPTY: 70 71## -fPIC call stubs of f and g. 72# CHECK-NEXT: <00008000.got2.plt_pic32.f>: 73# CHECK-NEXT: lwz 11, 32760(30) 74# CHECK-NEXT: mtctr 11 75# CHECK-NEXT: bctr 76# CHECK-NEXT: nop 77# CHECK-EMPTY: 78# CHECK-NEXT: <00008000.got2.plt_pic32.g>: 79# CHECK-NEXT: lwz 11, 32764(30) 80# CHECK-NEXT: mtctr 11 81# CHECK-NEXT: bctr 82# CHECK-NEXT: nop 83# CHECK-EMPTY: 84 85## The -fPIC call stub of h needs two instructions addis+lwz to represent the offset 65536*1-32768. 86# CHECK-NEXT: <00008000.got2.plt_pic32.h>: 87# CHECK-NEXT: addis 11, 30, 1 88# CHECK-NEXT: lwz 11, -32768(11) 89# CHECK-NEXT: mtctr 11 90# CHECK-NEXT: bctr 91# CHECK-EMPTY: 92 93## -fpic call stub of f. 94# CHECK-NEXT: <00000000.plt_pic32.f>: 95# CHECK-NEXT: addis 11, 30, 2 96# CHECK-NEXT: lwz 11, 4(11) 97# CHECK-NEXT: mtctr 11 98# CHECK-NEXT: bctr 99# CHECK-EMPTY: 100 101## Another -fPIC call stub of f from another object file %t2.o 102## .got2 may have different addresses in different object files, 103## so the call stub cannot be shared. 104# CHECK-NEXT: <00008000.got2.plt_pic32.f>: 105 106## In Secure PLT ABI, .plt stores function pointers to first instructions of .glink 107# HEX: 0x00040374 00010294 00010298 0001029c 108 109## These instructions are referenced by .plt entries. 110# CHECK: [[#%x,GLINK:]] <.glink>: 111# CHECK-NEXT: b 0x[[#%x,GLINK+12]] 112# CHECK-NEXT: b 0x[[#%x,GLINK+12]] 113# CHECK-NEXT: b 0x[[#%x,GLINK+12]] 114 115## PLTresolve 116## Operand of addi: 0x102cc-.glink = 24 117# CHECK-NEXT: addis 11, 11, 0 118# CHECK-NEXT: mflr 0 119# CHECK-NEXT: bcl 20, 31, 0x[[#%x,NEXT:]] 120# CHECK-NEXT: [[#%x,NEXT]]: addi 11, 11, 24 121 122# CHECK-NEXT: mflr 12 123# CHECK-NEXT: mtlr 0 124# CHECK-NEXT: sub 11, 11, 12 125 126## Operand of lwz in -pie mode: &.got[1] - 0x102bc = 0x20380+4 - 0x102bc = 65536*1+200 127# CHECK-NEXT: addis 12, 12, 1 128# PIE-NEXT: lwz 0, 200(12) 129# SHARED-NEXT: lwz 0, 184(12) 130 131# PIE-NEXT: lwz 12, 204(12) 132# SHARED-NEXT: lwz 12, 188(12) 133# CHECK-NEXT: mtctr 0 134# CHECK-NEXT: add 0, 11, 11 135# CHECK-NEXT: add 11, 0, 11 136# CHECK-NEXT: bctr 137 138.section .got2,"aw" 139.space 65516 140.long f 141.long g 142.long h 143 144.text 145.globl _start 146_start: 147 bcl 20,31,.L 148.L: 149 mflr 30 150 addis 30, 30, .got2+0x8000-.L@ha 151 addi 30, 30, .got2+0x8000-.L@l 152 bl f+0x8000@plt 153 bl f+0x8000@plt 154 bl g+0x8000@plt 155 bl g+0x8000@plt 156 bl h+0x8000@plt 157 bl h+0x8000@plt 158 159## An addend of 0 indicates r30 is stored in _GLOBAL_OFFSET_TABLE_. 160## The existing thunk is incompatible, thus it cannot be reused. 161 addis 30, 30, _GLOBAL_OFFSET_TABLE_-.L@ha 162 addi 30, 30, _GLOBAL_OFFSET_TABLE_-.L@l 163 bl f@plt 164