1// REQUIRES: ppc 2 3// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o 4// RUN: ld.lld -shared %t.o -z separate-code -o %t.so 5// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s 6// RUN: llvm-readelf -r %t.so | FileCheck --check-prefix=OutputRelocs %s 7// RUN: llvm-objdump --section-headers %t.so | FileCheck --check-prefix=CheckGot %s 8// RUN: llvm-objdump -d %t.so | FileCheck --check-prefix=Dis %s 9 10// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o 11// RUN: ld.lld -shared %t.o -z separate-code -o %t.so 12// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s 13// RUN: llvm-readelf -r %t.so | FileCheck --check-prefix=OutputRelocs %s 14// RUN: llvm-objdump --section-headers %t.so | FileCheck --check-prefix=CheckGot %s 15// RUN: llvm-objdump -d %t.so | FileCheck --check-prefix=Dis %s 16 17 .text 18 .abiversion 2 19 .globl test 20 .p2align 4 21 .type test,@function 22test: 23.Lfunc_gep0: 24 addis 2, 12, .TOC.-.Lfunc_gep0@ha 25 addi 2, 2, .TOC.-.Lfunc_gep0@l 26.Lfunc_lep0: 27 .localentry test, .Lfunc_lep0-.Lfunc_gep0 28 mflr 0 29 std 0, 16(1) 30 stdu 1, -32(1) 31 addis 3, 2, i@got@tlsld@ha 32 addi 3, 3, i@got@tlsld@l 33 bl __tls_get_addr(i@tlsld) 34 nop 35 addis 3, 3, i@dtprel@ha 36 lwa 3, i@dtprel@l(3) 37 ld 0, 16(1) 38 mtlr 0 39 blr 40 41 .globl test_hi 42 .p2align 4 43 .type test_hi,@function 44test_hi: 45 lis 3, j@got@tlsld@h 46 blr 47 48 .globl test_16 49 .p2align 4 50 .type test_16,@function 51test_16: 52 li 3, k@got@tlsld 53 blr 54 55 .type i,@object 56 .section .tdata,"awT",@progbits 57 .p2align 2 58i: 59 .long 55 60 .size i, 4 61 62 .type j,@object 63 .section .tbss,"awT",@nobits 64 .p2align 2 65j: 66 .long 0 67 .size j, 4 68 69 .type k,@object 70 .section .tdata,"awT",@progbits 71 .p2align 3 72k: 73 .quad 66 74 .size k, 8 75 76// Verify that the input contains all the R_PPC64_GOT_TLSLD16* relocations, as 77// well as the DTPREL relocations used in a typical medium code model 78// local-dynamic variable access. 79// InputRelocs: Relocation section '.rela.text' 80// InputRelocs: R_PPC64_GOT_TLSLD16_HA {{[0-9a-f]+}} i + 0 81// InputRelocs: R_PPC64_GOT_TLSLD16_LO {{[0-9a-f]+}} i + 0 82// InputRelocs: R_PPC64_TLSLD {{[0-9a-f]+}} i + 0 83// InputRelocs: R_PPC64_DTPREL16_HA {{[0-9a-f]+}} i + 0 84// InputRelocs: R_PPC64_DTPREL16_LO_DS {{[0-9a-f]+}} i + 0 85// InputRelocs: R_PPC64_GOT_TLSLD16_HI {{[0-9a-f]+}} j + 0 86// InputRelocs: R_PPC64_GOT_TLSLD16 {{[0-9a-f]+}} k + 0 87 88// The local dynamic version of tls needs to use the same mechanism to look up 89// a variables address as general-dynamic. ie a call to __tls_get_addr with the 90// address of a tls_index struct as the argument. However for local-dynamic 91// variables all will have the same ti_module, and the offset field is left as 92// as 0, so the same struct can be used for every local-dynamic variable 93// used in the shared-object. 94// OutputRelocs: Relocation section '.rela.dyn' at offset 0x{{[0-9a-f]+}} contains 1 entries: 95// OutputRelocs-NEXT: Offset Info Type Symbol's Value Symbol's Name + Addend 96// OutputRelocs-NEXT: R_PPC64_DTPMOD64 97 98// Check that the got has 3 entries, 1 for the TOC and 1 structure of 2 entries 99// for the tls variables. Also verify the address so we can check the offsets 100// we calculate for each relocation type. 101// CheckGot: got 00000018 0000000000020100 102 103// got starts at 0x20100 so .TOC. will be 0x28100, and the tls_index struct is 104// at 0x20108. 105 106// #ha(i@got@tlsld) --> (0x20108 - 0x28100 + 0x8000) >> 16 = 0 107// #lo(i@got@tlsld) --> (0x20108 - 0x28100) = -7ff8 = -32760 108// When calculating offset relative to the dynamic thread pointer we have to 109// adjust by 0x8000 since each DTV pointer points 0x8000 bytes past the start of 110// its TLS block. 111// #ha(i@dtprel) --> (0x0 -0x8000 + 0x8000) >> 16 = 0 112// #lo(i@dtprel) --> (0x0 -0x8000) = -0x8000 = -32768 113// Dis: <test>: 114// Dis: addis 3, 2, 0 115// Dis-NEXT: addi 3, 3, -32760 116// Dis-NEXT: bl 0x10060 117// Dis-NEXT: ld 2, 24(1) 118// Dis-NEXT: addis 3, 3, 0 119// Dis-NEXT: lwa 3, -32768(3) 120 121 122// #hi(j@got@tlsld) --> (0x20108 - 0x28100 ) > 16 = -1 123// Dis: <test_hi>: 124// Dis: lis 3, -1 125 126// k@got@tlsld --> (0x20108 - 0x28100) = -7ff8 = -32760 127// Dis: <test_16>: 128// Dis: li 3, -32760 129