Skip to content

[X86,lld] Handle relocation R_X86_64_REX2_GOTPCRELX #109783

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Sep 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 29 additions & 12 deletions lld/ELF/Arch/X86_64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,7 @@ RelExpr X86_64::getRelExpr(RelType type, const Symbol &s,
case R_X86_64_GOTPCREL:
case R_X86_64_GOTPCRELX:
case R_X86_64_REX_GOTPCRELX:
case R_X86_64_REX2_GOTPCRELX:
case R_X86_64_GOTTPOFF:
return R_GOT_PC;
case R_X86_64_GOTOFF64:
Expand Down Expand Up @@ -725,6 +726,7 @@ int64_t X86_64::getImplicitAddend(const uint8_t *buf, RelType type) const {
case R_X86_64_GOTPCREL:
case R_X86_64_GOTPCRELX:
case R_X86_64_REX_GOTPCRELX:
case R_X86_64_REX2_GOTPCRELX:
case R_X86_64_PC32:
case R_X86_64_GOTTPOFF:
case R_X86_64_PLT32:
Expand Down Expand Up @@ -808,6 +810,7 @@ void X86_64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
break;
case R_X86_64_GOTPCRELX:
case R_X86_64_REX_GOTPCRELX:
case R_X86_64_REX2_GOTPCRELX:
if (rel.expr != R_GOT_PC) {
relaxGot(loc, rel, val);
} else {
Expand Down Expand Up @@ -859,12 +862,13 @@ void X86_64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {

RelExpr X86_64::adjustGotPcExpr(RelType type, int64_t addend,
const uint8_t *loc) const {
// Only R_X86_64_[REX_]GOTPCRELX can be relaxed. GNU as may emit GOTPCRELX
// with addend != -4. Such an instruction does not load the full GOT entry, so
// we cannot relax the relocation. E.g. movl x@GOTPCREL+4(%rip), %rax
// (addend=0) loads the high 32 bits of the GOT entry.
// Only R_X86_64_[REX_]|[REX2_]GOTPCRELX can be relaxed. GNU as may emit
// GOTPCRELX with addend != -4. Such an instruction does not load the full GOT
// entry, so we cannot relax the relocation. E.g. movl x@GOTPCREL+4(%rip),
// %rax (addend=0) loads the high 32 bits of the GOT entry.
if (!ctx.arg.relax || addend != -4 ||
(type != R_X86_64_GOTPCRELX && type != R_X86_64_REX_GOTPCRELX))
(type != R_X86_64_GOTPCRELX && type != R_X86_64_REX_GOTPCRELX &&
type != R_X86_64_REX2_GOTPCRELX))
return R_GOT_PC;
const uint8_t op = loc[-2];
const uint8_t modRm = loc[-1];
Expand All @@ -880,7 +884,7 @@ RelExpr X86_64::adjustGotPcExpr(RelType type, int64_t addend,
if (op == 0xff && (modRm == 0x15 || modRm == 0x25))
return R_RELAX_GOT_PC;

// We don't support test/binop instructions without a REX prefix.
// We don't support test/binop instructions without a REX/REX2 prefix.
if (type == R_X86_64_GOTPCRELX)
return R_GOT_PC;

Expand All @@ -894,8 +898,8 @@ RelExpr X86_64::adjustGotPcExpr(RelType type, int64_t addend,
// "Intel 64 and IA-32 Architectures Software Developer's Manual V2"
// (http://www.intel.com/content/dam/www/public/us/en/documents/manuals/
// 64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf)
static void relaxGotNoPic(uint8_t *loc, uint64_t val, uint8_t op,
uint8_t modRm) {
static void relaxGotNoPic(uint8_t *loc, uint64_t val, uint8_t op, uint8_t modRm,
bool isRex2) {
const uint8_t rex = loc[-3];
// Convert "test %reg, foo@GOTPCREL(%rip)" to "test $foo, %reg".
if (op == 0x85) {
Expand All @@ -921,7 +925,7 @@ static void relaxGotNoPic(uint8_t *loc, uint64_t val, uint8_t op,
// See "TEST-Logical Compare" (4-428 Vol. 2B).
loc[-2] = 0xf7;

// Move R bit to the B bit in REX byte.
// Move R bit to the B bit in REX/REX2 byte.
// REX byte is encoded as 0100WRXB, where
// 0100 is 4bit fixed pattern.
// REX.W When 1, a 64-bit operand size is used. Otherwise, when 0, the
Expand All @@ -932,7 +936,17 @@ static void relaxGotNoPic(uint8_t *loc, uint64_t val, uint8_t op,
// REX.B This 1-bit value is an extension to the MODRM.rm field or the
// SIB.base field.
// See "2.2.1.2 More on REX Prefix Fields " (2-8 Vol. 2A).
loc[-3] = (rex & ~0x4) | (rex & 0x4) >> 2;
//
// REX2 prefix is encoded as 0xd5|M|R2|X2|B2|WRXB, where
// 0xd5 is 1byte fixed pattern.
// REX2's [W,R,X,B] have the same meanings as REX's.
// REX2.M encodes the map id.
// R2/X2/B2 provides the fifth and most siginicant bits of the R/X/B
// register identifiers, each of which can now address all 32 GPRs.
if (isRex2)
loc[-3] = (rex & ~0x44) | (rex & 0x44) >> 2;
else
loc[-3] = (rex & ~0x4) | (rex & 0x4) >> 2;
write32le(loc, val);
return;
}
Expand All @@ -953,7 +967,10 @@ static void relaxGotNoPic(uint8_t *loc, uint64_t val, uint8_t op,
// "INSTRUCTION SET REFERENCE, N-Z" (Vol. 2B 4-1) for
// descriptions about each operation.
loc[-2] = 0x81;
loc[-3] = (rex & ~0x4) | (rex & 0x4) >> 2;
if (isRex2)
loc[-3] = (rex & ~0x44) | (rex & 0x44) >> 2;
else
loc[-3] = (rex & ~0x4) | (rex & 0x4) >> 2;
write32le(loc, val);
}

Expand All @@ -974,7 +991,7 @@ static void relaxGot(uint8_t *loc, const Relocation &rel, uint64_t val) {
// We are relaxing a rip relative to an absolute, so compensate
// for the old -4 addend.
assert(!ctx.arg.isPic);
relaxGotNoPic(loc, val + 4, op, modRm);
relaxGotNoPic(loc, val + 4, op, modRm, rel.type == R_X86_64_REX2_GOTPCRELX);
return;
}

Expand Down
10 changes: 7 additions & 3 deletions lld/test/ELF/x86-64-gotpc-no-relax-err.s
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,25 @@
## `>>> defined in` for linker synthesized __stop_* symbols (there is no
## associated file or linker script line number).

# CHECK: error: {{.*}}:(.text+0x2): relocation R_X86_64_GOTPCRELX out of range: 2147483658 is not in [-2147483648, 2147483647]; references '__stop_data'
# CHECK: error: {{.*}}:(.text+0x2): relocation R_X86_64_GOTPCRELX out of range: 2147483666 is not in [-2147483648, 2147483647]; references '__stop_data'
# CHECK-NEXT: >>> defined in <internal>
# CHECK-EMPTY:
# CHECK-NEXT: error: {{.*}}:(.text+0x9): relocation R_X86_64_REX_GOTPCRELX out of range: 2147483651 is not in [-2147483648, 2147483647]; references '__stop_data'
# CHECK-NEXT: error: {{.*}}:(.text+0x9): relocation R_X86_64_REX_GOTPCRELX out of range: 2147483659 is not in [-2147483648, 2147483647]; references '__stop_data'
# CHECK-NEXT: >>> defined in <internal>
# CHECK-EMPTY:
# CHECK-NEXT: error: {{.*}}:(.text+0x11): relocation R_X86_64_REX2_GOTPCRELX out of range: 2147483651 is not in [-2147483648, 2147483647]; references '__stop_data'
# CHECK-NEXT: >>> defined in <internal>

#--- a.s
movl __stop_data@GOTPCREL(%rip), %eax # out of range
movq __stop_data@GOTPCREL(%rip), %rax # out of range
movq __stop_data@GOTPCREL(%rip), %r16 # out of range
movq __stop_data@GOTPCREL(%rip), %rax # in range

.section data,"aw",@progbits

#--- lds
SECTIONS {
.text 0x200000 : { *(.text) }
.got 0x80200010 : { *(.got) }
.got 0x80200016 : { *(.got) }
}
109 changes: 69 additions & 40 deletions lld/test/ELF/x86-64-gotpc-relax-nopic.s
Original file line number Diff line number Diff line change
Expand Up @@ -10,30 +10,39 @@
# SYMRELOC: Symbols [
# SYMRELOC: Symbol {
# SYMRELOC: Name: bar
# SYMRELOC-NEXT: Value: 0x203248
# SYMRELOC-NEXT: Value: 0x203290

## 2105751 = 0x202197 (bar)
# DISASM: Disassembly of section .text:
# DISASM-EMPTY:
# DISASM-NEXT: <_start>:
# DISASM-NEXT: 2011c8: adcl {{.*}}(%rip), %eax # 0x202240
# DISASM-NEXT: addl {{.*}}(%rip), %ebx # 0x202240
# DISASM-NEXT: andl {{.*}}(%rip), %ecx # 0x202240
# DISASM-NEXT: cmpl {{.*}}(%rip), %edx # 0x202240
# DISASM-NEXT: orl {{.*}}(%rip), %edi # 0x202240
# DISASM-NEXT: sbbl {{.*}}(%rip), %esi # 0x202240
# DISASM-NEXT: subl {{.*}}(%rip), %ebp # 0x202240
# DISASM-NEXT: xorl $0x203248, %r8d
# DISASM-NEXT: testl $0x203248, %r15d
# DISASM-NEXT: 201200: adcq $0x203248, %rax
# DISASM-NEXT: addq $0x203248, %rbx
# DISASM-NEXT: andq $0x203248, %rcx
# DISASM-NEXT: cmpq $0x203248, %rdx
# DISASM-NEXT: orq $0x203248, %rdi
# DISASM-NEXT: sbbq $0x203248, %rsi
# DISASM-NEXT: subq $0x203248, %rbp
# DISASM-NEXT: xorq $0x203248, %r8
# DISASM-NEXT: testq $0x203248, %r15
# DISASM-NEXT: 2011c8: adcl {{.*}}(%rip), %eax # 0x202288
# DISASM-NEXT: addl {{.*}}(%rip), %ebx # 0x202288
# DISASM-NEXT: andl {{.*}}(%rip), %ecx # 0x202288
# DISASM-NEXT: cmpl {{.*}}(%rip), %edx # 0x202288
# DISASM-NEXT: orl {{.*}}(%rip), %edi # 0x202288
# DISASM-NEXT: sbbl {{.*}}(%rip), %esi # 0x202288
# DISASM-NEXT: subl {{.*}}(%rip), %ebp # 0x202288
# DISASM-NEXT: xorl $0x203290, %r8d
# DISASM-NEXT: testl $0x203290, %r15d
# DISASM-NEXT: 201200: adcq $0x203290, %rax
# DISASM-NEXT: addq $0x203290, %rbx
# DISASM-NEXT: andq $0x203290, %rcx
# DISASM-NEXT: cmpq $0x203290, %rdx
# DISASM-NEXT: orq $0x203290, %rdi
# DISASM-NEXT: sbbq $0x203290, %rsi
# DISASM-NEXT: subq $0x203290, %rbp
# DISASM-NEXT: xorq $0x203290, %r8
# DISASM-NEXT: testq $0x203290, %r15
# DISASM-NEXT: 20123f: adcq $0x203290, %r16
# DISASM-NEXT: addq $0x203290, %r17
# DISASM-NEXT: andq $0x203290, %r18
# DISASM-NEXT: cmpq $0x203290, %r19
# DISASM-NEXT: orq $0x203290, %r20
# DISASM-NEXT: sbbq $0x203290, %r21
# DISASM-NEXT: subq $0x203290, %r22
# DISASM-NEXT: xorq $0x203290, %r23
# DISASM-NEXT: testq $0x203290, %r24

# RUN: ld.lld --hash-style=sysv -shared %t.o -o %t2
# RUN: llvm-readobj -S -r -d %t2 | FileCheck --check-prefix=SEC-PIC %s
Expand All @@ -46,8 +55,8 @@
# SEC-PIC-NEXT: SHF_ALLOC
# SEC-PIC-NEXT: SHF_WRITE
# SEC-PIC-NEXT: ]
# SEC-PIC-NEXT: Address: 0x2380
# SEC-PIC-NEXT: Offset: 0x380
# SEC-PIC-NEXT: Address: 0x23C8
# SEC-PIC-NEXT: Offset: 0x3C8
# SEC-PIC-NEXT: Size: 8
# SEC-PIC-NEXT: Link:
# SEC-PIC-NEXT: Info:
Expand All @@ -57,32 +66,41 @@
# SEC-PIC: 0x000000006FFFFFF9 RELACOUNT 1
# SEC-PIC: Relocations [
# SEC-PIC-NEXT: Section ({{.*}}) .rela.dyn {
# SEC-PIC-NEXT: 0x2380 R_X86_64_RELATIVE - 0x3388
# SEC-PIC-NEXT: 0x23C8 R_X86_64_RELATIVE - 0x33D0
# SEC-PIC-NEXT: }
# SEC-PIC-NEXT: ]

## Check that there was no relaxation performed. All values refer to got entry.
# DISASM-PIC: Disassembly of section .text:
# DISASM-PIC-EMPTY:
# DISASM-PIC-NEXT: <_start>:
# DISASM-PIC-NEXT: 1268: adcl {{.*}}(%rip), %eax # 0x2380
# DISASM-PIC-NEXT: addl {{.*}}(%rip), %ebx # 0x2380
# DISASM-PIC-NEXT: andl {{.*}}(%rip), %ecx # 0x2380
# DISASM-PIC-NEXT: cmpl {{.*}}(%rip), %edx # 0x2380
# DISASM-PIC-NEXT: orl {{.*}}(%rip), %edi # 0x2380
# DISASM-PIC-NEXT: sbbl {{.*}}(%rip), %esi # 0x2380
# DISASM-PIC-NEXT: subl {{.*}}(%rip), %ebp # 0x2380
# DISASM-PIC-NEXT: xorl {{.*}}(%rip), %r8d # 0x2380
# DISASM-PIC-NEXT: testl %r15d, {{.*}}(%rip) # 0x2380
# DISASM-PIC-NEXT: 12a0: adcq {{.*}}(%rip), %rax # 0x2380
# DISASM-PIC-NEXT: addq {{.*}}(%rip), %rbx # 0x2380
# DISASM-PIC-NEXT: andq {{.*}}(%rip), %rcx # 0x2380
# DISASM-PIC-NEXT: cmpq {{.*}}(%rip), %rdx # 0x2380
# DISASM-PIC-NEXT: orq {{.*}}(%rip), %rdi # 0x2380
# DISASM-PIC-NEXT: sbbq {{.*}}(%rip), %rsi # 0x2380
# DISASM-PIC-NEXT: subq {{.*}}(%rip), %rbp # 0x2380
# DISASM-PIC-NEXT: xorq {{.*}}(%rip), %r8 # 0x2380
# DISASM-PIC-NEXT: testq %r15, {{.*}}(%rip) # 0x2380
# DISASM-PIC-NEXT: 1268: adcl {{.*}}(%rip), %eax # 0x23c8
# DISASM-PIC-NEXT: addl {{.*}}(%rip), %ebx # 0x23c8
# DISASM-PIC-NEXT: andl {{.*}}(%rip), %ecx # 0x23c8
# DISASM-PIC-NEXT: cmpl {{.*}}(%rip), %edx # 0x23c8
# DISASM-PIC-NEXT: orl {{.*}}(%rip), %edi # 0x23c8
# DISASM-PIC-NEXT: sbbl {{.*}}(%rip), %esi # 0x23c8
# DISASM-PIC-NEXT: subl {{.*}}(%rip), %ebp # 0x23c8
# DISASM-PIC-NEXT: xorl {{.*}}(%rip), %r8d # 0x23c8
# DISASM-PIC-NEXT: testl %r15d, {{.*}}(%rip) # 0x23c8
# DISASM-PIC-NEXT: 12a0: adcq {{.*}}(%rip), %rax # 0x23c8
# DISASM-PIC-NEXT: addq {{.*}}(%rip), %rbx # 0x23c8
# DISASM-PIC-NEXT: andq {{.*}}(%rip), %rcx # 0x23c8
# DISASM-PIC-NEXT: cmpq {{.*}}(%rip), %rdx # 0x23c8
# DISASM-PIC-NEXT: orq {{.*}}(%rip), %rdi # 0x23c8
# DISASM-PIC-NEXT: sbbq {{.*}}(%rip), %rsi # 0x23c8
# DISASM-PIC-NEXT: subq {{.*}}(%rip), %rbp # 0x23c8
# DISASM-PIC-NEXT: xorq {{.*}}(%rip), %r8 # 0x23c8
# DISASM-PIC-NEXT: testq %r15, {{.*}}(%rip) # 0x23c8
# DISASM-PIC-NEXT: 12df: adcq {{.*}}(%rip), %r16 # 0x23c8
# DISASM-PIC-NEXT: addq {{.*}}(%rip), %r17 # 0x23c8
# DISASM-PIC-NEXT: andq {{.*}}(%rip), %r18 # 0x23c8
# DISASM-PIC-NEXT: cmpq {{.*}}(%rip), %r19 # 0x23c8
# DISASM-PIC-NEXT: orq {{.*}}(%rip), %r20 # 0x23c8
# DISASM-PIC-NEXT: sbbq {{.*}}(%rip), %r21 # 0x23c8
# DISASM-PIC-NEXT: subq {{.*}}(%rip), %r22 # 0x23c8
# DISASM-PIC-NEXT: xorq {{.*}}(%rip), %r23 # 0x23c8
# DISASM-PIC-NEXT: testq %r24, {{.*}}(%rip) # 0x23c8

.data
.type bar, @object
Expand Down Expand Up @@ -115,3 +133,14 @@ _start:
subq bar@GOTPCREL(%rip), %rbp
xorq bar@GOTPCREL(%rip), %r8
testq %r15, bar@GOTPCREL(%rip)

## R_X86_64_REX2_GOTPCRELX
adcq bar@GOTPCREL(%rip), %r16
addq bar@GOTPCREL(%rip), %r17
andq bar@GOTPCREL(%rip), %r18
cmpq bar@GOTPCREL(%rip), %r19
orq bar@GOTPCREL(%rip), %r20
sbbq bar@GOTPCREL(%rip), %r21
subq bar@GOTPCREL(%rip), %r22
xorq bar@GOTPCREL(%rip), %r23
testq %r24, bar@GOTPCREL(%rip)
54 changes: 40 additions & 14 deletions lld/test/ELF/x86-64-gotpc-relax.s
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# REQUIRES: x86
## Test R_X86_64_GOTPCRELX and R_X86_64_REX_GOTPCRELX GOT optimization.
## Test R_X86_64_GOTPCRELX and R_X86_64_REX_GOTPCRELX/R_X86_64_REX2_GOTPCRELX GOT optimization.

# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
# RUN: ld.lld %t.o -o %t1 --no-apply-dynamic-relocs
Expand All @@ -15,16 +15,16 @@

## In our implementation, .got is retained even if all GOT-generating relocations are optimized.
# CHECK: Name Type Address Off Size ES Flg Lk Inf Al
# CHECK: .iplt PROGBITS 0000000000201280 000280 000010 00 AX 0 0 16
# CHECK-NEXT: .got PROGBITS 0000000000202290 000290 000000 00 WA 0 0 8
# CHECK: .iplt PROGBITS 00000000002012e0 0002e0 000010 00 AX 0 0 16
# CHECK-NEXT: .got PROGBITS 00000000002022f0 0002f0 000000 00 WA 0 0 8

## There is one R_X86_64_IRELATIVE relocations.
# RELOC-LABEL: Relocation section '.rela.dyn' at offset {{.*}} contains 1 entry:
# CHECK: Offset Info Type Symbol's Value Symbol's Name + Addend
# CHECK: 0000000000203290 0000000000000025 R_X86_64_IRELATIVE 2011e2
# CHECK: 00000000002032f0 0000000000000025 R_X86_64_IRELATIVE 2011e2
# CHECK-LABEL: Hex dump of section '.got.plt':
# NOAPPLY-NEXT: 0x00203290 00000000 00000000
# APPLY-NEXT: 0x00203290 e2112000 00000000
# NOAPPLY-NEXT: 0x002032f0 00000000 00000000
# APPLY-NEXT: 0x002032f0 e2112000 00000000

# 0x201173 + 7 - 10 = 0x201170
# 0x20117a + 7 - 17 = 0x201170
Expand All @@ -43,20 +43,20 @@
# DISASM-NEXT: leaq -17(%rip), %rax
# DISASM-NEXT: leaq -23(%rip), %rax
# DISASM-NEXT: leaq -30(%rip), %rax
# DISASM-NEXT: movq 8330(%rip), %rax
# DISASM-NEXT: movq 8323(%rip), %rax
# DISASM-NEXT: movq 8426(%rip), %rax
# DISASM-NEXT: movq 8419(%rip), %rax
# DISASM-NEXT: leaq -52(%rip), %rax
# DISASM-NEXT: leaq -59(%rip), %rax
# DISASM-NEXT: leaq -65(%rip), %rax
# DISASM-NEXT: leaq -72(%rip), %rax
# DISASM-NEXT: movq 8288(%rip), %rax
# DISASM-NEXT: movq 8281(%rip), %rax
# DISASM-NEXT: movq 8384(%rip), %rax
# DISASM-NEXT: movq 8377(%rip), %rax
# DISASM-NEXT: callq 0x2011e0 <foo>
# DISASM-NEXT: callq 0x2011e0 <foo>
# DISASM-NEXT: callq 0x2011e1 <hid>
# DISASM-NEXT: callq 0x2011e1 <hid>
# DISASM-NEXT: callq *8251(%rip)
# DISASM-NEXT: callq *8245(%rip)
# DISASM-NEXT: callq *8347(%rip)
# DISASM-NEXT: callq *8341(%rip)
# DISASM-NEXT: jmp 0x2011e0 <foo>
# DISASM-NEXT: nop
# DISASM-NEXT: jmp 0x2011e0 <foo>
Expand All @@ -65,13 +65,26 @@
# DISASM-NEXT: nop
# DISASM-NEXT: jmp 0x2011e1 <hid>
# DISASM-NEXT: nop
# DISASM-NEXT: jmpq *8215(%rip)
# DISASM-NEXT: jmpq *8209(%rip)
# DISASM-NEXT: jmpq *8311(%rip)
# DISASM-NEXT: jmpq *8305(%rip)
# DISASM-NEXT: leaq -167(%rip), %r16
# DISASM-NEXT: leaq -175(%rip), %r16
# DISASM-NEXT: leaq -182(%rip), %r16
# DISASM-NEXT: leaq -190(%rip), %r16
# DISASM-NEXT: movq 8265(%rip), %r16
# DISASM-NEXT: movq 8257(%rip), %r16
# DISASM-NEXT: leaq -215(%rip), %r16
# DISASM-NEXT: leaq -223(%rip), %r16
# DISASM-NEXT: leaq -230(%rip), %r16
# DISASM-NEXT: leaq -238(%rip), %r16
# DISASM-NEXT: movq 8217(%rip), %r16
# DISASM-NEXT: movq 8209(%rip), %r16

# NORELAX-LABEL: <_start>:
# NORELAX-COUNT-12: movq
# NORELAX-COUNT-6: callq *
# NORELAX-COUNT-6: jmpq *
# NORELAX-COUNT-12: movq

.text
.globl foo
Expand Down Expand Up @@ -120,3 +133,16 @@ _start:
jmp *hid@GOTPCREL(%rip)
jmp *ifunc@GOTPCREL(%rip)
jmp *ifunc@GOTPCREL(%rip)

movq foo@GOTPCREL(%rip), %r16
movq foo@GOTPCREL(%rip), %r16
movq hid@GOTPCREL(%rip), %r16
movq hid@GOTPCREL(%rip), %r16
movq ifunc@GOTPCREL(%rip), %r16
movq ifunc@GOTPCREL(%rip), %r16
movq foo@GOTPCREL(%rip), %r16
movq foo@GOTPCREL(%rip), %r16
movq hid@GOTPCREL(%rip), %r16
movq hid@GOTPCREL(%rip), %r16
movq ifunc@GOTPCREL(%rip), %r16
movq ifunc@GOTPCREL(%rip), %r16
Loading