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 00020368 32# DYN: PPC_GOT 0x20368 33 34## .got2+0x8000-0x10004 = 0x30000+0x8000-0x10004 = 65536*2+32764 35# CHECK-LABEL: _start: 36# CHECK-NEXT: bcl 20, 31, .+4 37# PIE-NEXT: 10210: mflr 30 38# PIE-NEXT: addis 30, 30, 3 39# PIE-NEXT: addi 30, 30, -32412 40# SHARED-NEXT: 10230: mflr 30 41# SHARED-NEXT: addis 30, 30, 3 42# SHARED-NEXT: addi 30, 30, -32420 43 44## Two bl 00008000.got2.plt_pic32.f 45# CHECK-NEXT: bl .+40 46# CHECK-NEXT: bl .+36 47## Two bl 00008000.got2.plt_pic32.g 48# CHECK-NEXT: bl .+48 49# CHECK-NEXT: bl .+44 50## Two bl 00008000.got2.plt_pic32.h 51# CHECK-NEXT: bl .+56 52# CHECK-NEXT: bl .+52 53# CHECK-NEXT: addis 30, 30, {{.*}} 54# CHECK-NEXT: addi 30, 30, {{.*}} 55## bl 00008000.plt_pic32.f 56# CHECK-NEXT: bl .+56 57## bl 00008000.plt_pic32.f 58# CHECK-NEXT: bl .+68 59# CHECK-EMPTY: 60 61## -fPIC call stubs of f and g. 62# CHECK-NEXT: 00008000.got2.plt_pic32.f: 63# CHECK-NEXT: lwz 11, 32760(30) 64# CHECK-NEXT: mtctr 11 65# CHECK-NEXT: bctr 66# CHECK-NEXT: nop 67# CHECK-EMPTY: 68# CHECK-NEXT: 00008000.got2.plt_pic32.g: 69# CHECK-NEXT: lwz 11, 32764(30) 70# CHECK-NEXT: mtctr 11 71# CHECK-NEXT: bctr 72# CHECK-NEXT: nop 73# CHECK-EMPTY: 74 75## The -fPIC call stub of h needs two instructions addis+lwz to represent the offset 65536*1-32768. 76# CHECK-NEXT: 00008000.got2.plt_pic32.h: 77# CHECK-NEXT: addis 11, 30, 1 78# CHECK-NEXT: lwz 11, -32768(11) 79# CHECK-NEXT: mtctr 11 80# CHECK-NEXT: bctr 81# CHECK-EMPTY: 82 83## -fpic call stub of f. 84# CHECK-NEXT: 00000000.plt_pic32.f: 85# CHECK-NEXT: addis 11, 30, 2 86# CHECK-NEXT: lwz 11, 4(11) 87# CHECK-NEXT: mtctr 11 88# CHECK-NEXT: bctr 89# CHECK-EMPTY: 90 91## Another -fPIC call stub of f from another object file %t2.o 92## .got2 may have different addresses in different object files, 93## so the call stub cannot be shared. 94# CHECK-NEXT: 00008000.got2.plt_pic32.f: 95 96## In Secure PLT ABI, .plt stores function pointers to first instructions of .glink 97# HEX: 0x0004036c 00010294 00010298 0001029c 98 99## These instructions are referenced by .plt entries. 100# PIE: 00010294 .glink: 101# SHARED: 000102b4 .glink: 102# CHECK-NEXT: b .+12 103# CHECK-NEXT: b .+8 104# CHECK-NEXT: b .+4 105 106## PLTresolve 107## Operand of addi: 0x100a8-.glink = 24 108# CHECK-NEXT: addis 11, 11, 0 109# CHECK-NEXT: mflr 0 110# CHECK-NEXT: bcl 20, 31, .+4 111# PIE-NEXT: 102ac: addi 11, 11, 24 112# SHARED-NEXT: 102cc: addi 11, 11, 24 113 114# CHECK-NEXT: mflr 12 115# CHECK-NEXT: mtlr 0 116# CHECK-NEXT: subf 11, 12, 11 117 118## Operand of lwz in -pie mode: &.got[1] - 0x100a8 = 0x20088+4 - 0x100a8 = 65536*1-28 119# CHECK-NEXT: addis 12, 12, 1 120# PIE-NEXT: lwz 0, 192(12) 121# SHARED-NEXT: lwz 0, 184(12) 122 123# PIE-NEXT: lwz 12, 196(12) 124# SHARED-NEXT: lwz 12, 188(12) 125# CHECK-NEXT: mtctr 0 126# CHECK-NEXT: add 0, 11, 11 127# CHECK-NEXT: add 11, 0, 11 128# CHECK-NEXT: bctr 129 130.section .got2,"aw" 131.space 65516 132.long f 133.long g 134.long h 135 136.text 137.globl _start 138_start: 139 bcl 20,31,.L 140.L: 141 mflr 30 142 addis 30, 30, .got2+0x8000-.L@ha 143 addi 30, 30, .got2+0x8000-.L@l 144 bl f+0x8000@plt 145 bl f+0x8000@plt 146 bl g+0x8000@plt 147 bl g+0x8000@plt 148 bl h+0x8000@plt 149 bl h+0x8000@plt 150 151## An addend of 0 indicates r30 is stored in _GLOBAL_OFFSET_TABLE_. 152## The existing thunk is incompatible, thus it cannot be reused. 153 addis 30, 30, _GLOBAL_OFFSET_TABLE_-.L@ha 154 addi 30, 30, _GLOBAL_OFFSET_TABLE_-.L@l 155 bl f@plt 156