Skip to content

Commit 31dd29c

Browse files
authored
[X86,lld] Handle relocation R_X86_64_REX2_GOTPCRELX (llvm#109783)
For mov name@GOTPCREL(%rip), %reg test %reg, name@GOTPCREL(%rip) binop name@GOTPCREL(%rip), %reg where binop is one of adc, add, and, cmp, or, sbb, sub, xor instructions, we added R_X86_64_REX2_GOTPCRELX = 43 in llvm#106681. Linker can treat R_X86_64_REX2_GOTPCRELX as R_X86_64_GOTPCREL or convert the above instructions to lea name(%rip), %reg mov $name, %reg test $name, %reg binop $name, %reg if the first byte of the instruction at the relocation `offset - 4` is `0xd5` (namely, encoded w/ REX2 prefix) when possible. Binutils patch: bminor/binutils-gdb@3d5a60d Binutils mailthread: https://sourceware.org/pipermail/binutils/2023-December/131462.html ABI discussion: https://groups.google.com/g/x86-64-abi/c/KbzaNHRB6QU Blog: https://kanrobert.github.io/rfc/All-about-APX-relocation
1 parent c3e4998 commit 31dd29c

File tree

4 files changed

+145
-69
lines changed

4 files changed

+145
-69
lines changed

lld/ELF/Arch/X86_64.cpp

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,7 @@ RelExpr X86_64::getRelExpr(RelType type, const Symbol &s,
388388
case R_X86_64_GOTPCREL:
389389
case R_X86_64_GOTPCRELX:
390390
case R_X86_64_REX_GOTPCRELX:
391+
case R_X86_64_REX2_GOTPCRELX:
391392
case R_X86_64_GOTTPOFF:
392393
return R_GOT_PC;
393394
case R_X86_64_GOTOFF64:
@@ -725,6 +726,7 @@ int64_t X86_64::getImplicitAddend(const uint8_t *buf, RelType type) const {
725726
case R_X86_64_GOTPCREL:
726727
case R_X86_64_GOTPCRELX:
727728
case R_X86_64_REX_GOTPCRELX:
729+
case R_X86_64_REX2_GOTPCRELX:
728730
case R_X86_64_PC32:
729731
case R_X86_64_GOTTPOFF:
730732
case R_X86_64_PLT32:
@@ -808,6 +810,7 @@ void X86_64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
808810
break;
809811
case R_X86_64_GOTPCRELX:
810812
case R_X86_64_REX_GOTPCRELX:
813+
case R_X86_64_REX2_GOTPCRELX:
811814
if (rel.expr != R_GOT_PC) {
812815
relaxGot(loc, rel, val);
813816
} else {
@@ -859,12 +862,13 @@ void X86_64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
859862

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

883-
// We don't support test/binop instructions without a REX prefix.
887+
// We don't support test/binop instructions without a REX/REX2 prefix.
884888
if (type == R_X86_64_GOTPCRELX)
885889
return R_GOT_PC;
886890

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

924-
// Move R bit to the B bit in REX byte.
928+
// Move R bit to the B bit in REX/REX2 byte.
925929
// REX byte is encoded as 0100WRXB, where
926930
// 0100 is 4bit fixed pattern.
927931
// REX.W When 1, a 64-bit operand size is used. Otherwise, when 0, the
@@ -932,7 +936,17 @@ static void relaxGotNoPic(uint8_t *loc, uint64_t val, uint8_t op,
932936
// REX.B This 1-bit value is an extension to the MODRM.rm field or the
933937
// SIB.base field.
934938
// See "2.2.1.2 More on REX Prefix Fields " (2-8 Vol. 2A).
935-
loc[-3] = (rex & ~0x4) | (rex & 0x4) >> 2;
939+
//
940+
// REX2 prefix is encoded as 0xd5|M|R2|X2|B2|WRXB, where
941+
// 0xd5 is 1byte fixed pattern.
942+
// REX2's [W,R,X,B] have the same meanings as REX's.
943+
// REX2.M encodes the map id.
944+
// R2/X2/B2 provides the fifth and most siginicant bits of the R/X/B
945+
// register identifiers, each of which can now address all 32 GPRs.
946+
if (isRex2)
947+
loc[-3] = (rex & ~0x44) | (rex & 0x44) >> 2;
948+
else
949+
loc[-3] = (rex & ~0x4) | (rex & 0x4) >> 2;
936950
write32le(loc, val);
937951
return;
938952
}
@@ -953,7 +967,10 @@ static void relaxGotNoPic(uint8_t *loc, uint64_t val, uint8_t op,
953967
// "INSTRUCTION SET REFERENCE, N-Z" (Vol. 2B 4-1) for
954968
// descriptions about each operation.
955969
loc[-2] = 0x81;
956-
loc[-3] = (rex & ~0x4) | (rex & 0x4) >> 2;
970+
if (isRex2)
971+
loc[-3] = (rex & ~0x44) | (rex & 0x44) >> 2;
972+
else
973+
loc[-3] = (rex & ~0x4) | (rex & 0x4) >> 2;
957974
write32le(loc, val);
958975
}
959976

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

lld/test/ELF/x86-64-gotpc-no-relax-err.s

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,25 @@
77
## `>>> defined in` for linker synthesized __stop_* symbols (there is no
88
## associated file or linker script line number).
99

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

1619
#--- a.s
1720
movl __stop_data@GOTPCREL(%rip), %eax # out of range
1821
movq __stop_data@GOTPCREL(%rip), %rax # out of range
22+
movq __stop_data@GOTPCREL(%rip), %r16 # out of range
1923
movq __stop_data@GOTPCREL(%rip), %rax # in range
2024

2125
.section data,"aw",@progbits
2226

2327
#--- lds
2428
SECTIONS {
2529
.text 0x200000 : { *(.text) }
26-
.got 0x80200010 : { *(.got) }
30+
.got 0x80200016 : { *(.got) }
2731
}

lld/test/ELF/x86-64-gotpc-relax-nopic.s

Lines changed: 69 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -10,30 +10,39 @@
1010
# SYMRELOC: Symbols [
1111
# SYMRELOC: Symbol {
1212
# SYMRELOC: Name: bar
13-
# SYMRELOC-NEXT: Value: 0x203248
13+
# SYMRELOC-NEXT: Value: 0x203290
1414

1515
## 2105751 = 0x202197 (bar)
1616
# DISASM: Disassembly of section .text:
1717
# DISASM-EMPTY:
1818
# DISASM-NEXT: <_start>:
19-
# DISASM-NEXT: 2011c8: adcl {{.*}}(%rip), %eax # 0x202240
20-
# DISASM-NEXT: addl {{.*}}(%rip), %ebx # 0x202240
21-
# DISASM-NEXT: andl {{.*}}(%rip), %ecx # 0x202240
22-
# DISASM-NEXT: cmpl {{.*}}(%rip), %edx # 0x202240
23-
# DISASM-NEXT: orl {{.*}}(%rip), %edi # 0x202240
24-
# DISASM-NEXT: sbbl {{.*}}(%rip), %esi # 0x202240
25-
# DISASM-NEXT: subl {{.*}}(%rip), %ebp # 0x202240
26-
# DISASM-NEXT: xorl $0x203248, %r8d
27-
# DISASM-NEXT: testl $0x203248, %r15d
28-
# DISASM-NEXT: 201200: adcq $0x203248, %rax
29-
# DISASM-NEXT: addq $0x203248, %rbx
30-
# DISASM-NEXT: andq $0x203248, %rcx
31-
# DISASM-NEXT: cmpq $0x203248, %rdx
32-
# DISASM-NEXT: orq $0x203248, %rdi
33-
# DISASM-NEXT: sbbq $0x203248, %rsi
34-
# DISASM-NEXT: subq $0x203248, %rbp
35-
# DISASM-NEXT: xorq $0x203248, %r8
36-
# DISASM-NEXT: testq $0x203248, %r15
19+
# DISASM-NEXT: 2011c8: adcl {{.*}}(%rip), %eax # 0x202288
20+
# DISASM-NEXT: addl {{.*}}(%rip), %ebx # 0x202288
21+
# DISASM-NEXT: andl {{.*}}(%rip), %ecx # 0x202288
22+
# DISASM-NEXT: cmpl {{.*}}(%rip), %edx # 0x202288
23+
# DISASM-NEXT: orl {{.*}}(%rip), %edi # 0x202288
24+
# DISASM-NEXT: sbbl {{.*}}(%rip), %esi # 0x202288
25+
# DISASM-NEXT: subl {{.*}}(%rip), %ebp # 0x202288
26+
# DISASM-NEXT: xorl $0x203290, %r8d
27+
# DISASM-NEXT: testl $0x203290, %r15d
28+
# DISASM-NEXT: 201200: adcq $0x203290, %rax
29+
# DISASM-NEXT: addq $0x203290, %rbx
30+
# DISASM-NEXT: andq $0x203290, %rcx
31+
# DISASM-NEXT: cmpq $0x203290, %rdx
32+
# DISASM-NEXT: orq $0x203290, %rdi
33+
# DISASM-NEXT: sbbq $0x203290, %rsi
34+
# DISASM-NEXT: subq $0x203290, %rbp
35+
# DISASM-NEXT: xorq $0x203290, %r8
36+
# DISASM-NEXT: testq $0x203290, %r15
37+
# DISASM-NEXT: 20123f: adcq $0x203290, %r16
38+
# DISASM-NEXT: addq $0x203290, %r17
39+
# DISASM-NEXT: andq $0x203290, %r18
40+
# DISASM-NEXT: cmpq $0x203290, %r19
41+
# DISASM-NEXT: orq $0x203290, %r20
42+
# DISASM-NEXT: sbbq $0x203290, %r21
43+
# DISASM-NEXT: subq $0x203290, %r22
44+
# DISASM-NEXT: xorq $0x203290, %r23
45+
# DISASM-NEXT: testq $0x203290, %r24
3746

3847
# RUN: ld.lld --hash-style=sysv -shared %t.o -o %t2
3948
# RUN: llvm-readobj -S -r -d %t2 | FileCheck --check-prefix=SEC-PIC %s
@@ -46,8 +55,8 @@
4655
# SEC-PIC-NEXT: SHF_ALLOC
4756
# SEC-PIC-NEXT: SHF_WRITE
4857
# SEC-PIC-NEXT: ]
49-
# SEC-PIC-NEXT: Address: 0x2380
50-
# SEC-PIC-NEXT: Offset: 0x380
58+
# SEC-PIC-NEXT: Address: 0x23C8
59+
# SEC-PIC-NEXT: Offset: 0x3C8
5160
# SEC-PIC-NEXT: Size: 8
5261
# SEC-PIC-NEXT: Link:
5362
# SEC-PIC-NEXT: Info:
@@ -57,32 +66,41 @@
5766
# SEC-PIC: 0x000000006FFFFFF9 RELACOUNT 1
5867
# SEC-PIC: Relocations [
5968
# SEC-PIC-NEXT: Section ({{.*}}) .rela.dyn {
60-
# SEC-PIC-NEXT: 0x2380 R_X86_64_RELATIVE - 0x3388
69+
# SEC-PIC-NEXT: 0x23C8 R_X86_64_RELATIVE - 0x33D0
6170
# SEC-PIC-NEXT: }
6271
# SEC-PIC-NEXT: ]
6372

6473
## Check that there was no relaxation performed. All values refer to got entry.
6574
# DISASM-PIC: Disassembly of section .text:
6675
# DISASM-PIC-EMPTY:
6776
# DISASM-PIC-NEXT: <_start>:
68-
# DISASM-PIC-NEXT: 1268: adcl {{.*}}(%rip), %eax # 0x2380
69-
# DISASM-PIC-NEXT: addl {{.*}}(%rip), %ebx # 0x2380
70-
# DISASM-PIC-NEXT: andl {{.*}}(%rip), %ecx # 0x2380
71-
# DISASM-PIC-NEXT: cmpl {{.*}}(%rip), %edx # 0x2380
72-
# DISASM-PIC-NEXT: orl {{.*}}(%rip), %edi # 0x2380
73-
# DISASM-PIC-NEXT: sbbl {{.*}}(%rip), %esi # 0x2380
74-
# DISASM-PIC-NEXT: subl {{.*}}(%rip), %ebp # 0x2380
75-
# DISASM-PIC-NEXT: xorl {{.*}}(%rip), %r8d # 0x2380
76-
# DISASM-PIC-NEXT: testl %r15d, {{.*}}(%rip) # 0x2380
77-
# DISASM-PIC-NEXT: 12a0: adcq {{.*}}(%rip), %rax # 0x2380
78-
# DISASM-PIC-NEXT: addq {{.*}}(%rip), %rbx # 0x2380
79-
# DISASM-PIC-NEXT: andq {{.*}}(%rip), %rcx # 0x2380
80-
# DISASM-PIC-NEXT: cmpq {{.*}}(%rip), %rdx # 0x2380
81-
# DISASM-PIC-NEXT: orq {{.*}}(%rip), %rdi # 0x2380
82-
# DISASM-PIC-NEXT: sbbq {{.*}}(%rip), %rsi # 0x2380
83-
# DISASM-PIC-NEXT: subq {{.*}}(%rip), %rbp # 0x2380
84-
# DISASM-PIC-NEXT: xorq {{.*}}(%rip), %r8 # 0x2380
85-
# DISASM-PIC-NEXT: testq %r15, {{.*}}(%rip) # 0x2380
77+
# DISASM-PIC-NEXT: 1268: adcl {{.*}}(%rip), %eax # 0x23c8
78+
# DISASM-PIC-NEXT: addl {{.*}}(%rip), %ebx # 0x23c8
79+
# DISASM-PIC-NEXT: andl {{.*}}(%rip), %ecx # 0x23c8
80+
# DISASM-PIC-NEXT: cmpl {{.*}}(%rip), %edx # 0x23c8
81+
# DISASM-PIC-NEXT: orl {{.*}}(%rip), %edi # 0x23c8
82+
# DISASM-PIC-NEXT: sbbl {{.*}}(%rip), %esi # 0x23c8
83+
# DISASM-PIC-NEXT: subl {{.*}}(%rip), %ebp # 0x23c8
84+
# DISASM-PIC-NEXT: xorl {{.*}}(%rip), %r8d # 0x23c8
85+
# DISASM-PIC-NEXT: testl %r15d, {{.*}}(%rip) # 0x23c8
86+
# DISASM-PIC-NEXT: 12a0: adcq {{.*}}(%rip), %rax # 0x23c8
87+
# DISASM-PIC-NEXT: addq {{.*}}(%rip), %rbx # 0x23c8
88+
# DISASM-PIC-NEXT: andq {{.*}}(%rip), %rcx # 0x23c8
89+
# DISASM-PIC-NEXT: cmpq {{.*}}(%rip), %rdx # 0x23c8
90+
# DISASM-PIC-NEXT: orq {{.*}}(%rip), %rdi # 0x23c8
91+
# DISASM-PIC-NEXT: sbbq {{.*}}(%rip), %rsi # 0x23c8
92+
# DISASM-PIC-NEXT: subq {{.*}}(%rip), %rbp # 0x23c8
93+
# DISASM-PIC-NEXT: xorq {{.*}}(%rip), %r8 # 0x23c8
94+
# DISASM-PIC-NEXT: testq %r15, {{.*}}(%rip) # 0x23c8
95+
# DISASM-PIC-NEXT: 12df: adcq {{.*}}(%rip), %r16 # 0x23c8
96+
# DISASM-PIC-NEXT: addq {{.*}}(%rip), %r17 # 0x23c8
97+
# DISASM-PIC-NEXT: andq {{.*}}(%rip), %r18 # 0x23c8
98+
# DISASM-PIC-NEXT: cmpq {{.*}}(%rip), %r19 # 0x23c8
99+
# DISASM-PIC-NEXT: orq {{.*}}(%rip), %r20 # 0x23c8
100+
# DISASM-PIC-NEXT: sbbq {{.*}}(%rip), %r21 # 0x23c8
101+
# DISASM-PIC-NEXT: subq {{.*}}(%rip), %r22 # 0x23c8
102+
# DISASM-PIC-NEXT: xorq {{.*}}(%rip), %r23 # 0x23c8
103+
# DISASM-PIC-NEXT: testq %r24, {{.*}}(%rip) # 0x23c8
86104

87105
.data
88106
.type bar, @object
@@ -115,3 +133,14 @@ _start:
115133
subq bar@GOTPCREL(%rip), %rbp
116134
xorq bar@GOTPCREL(%rip), %r8
117135
testq %r15, bar@GOTPCREL(%rip)
136+
137+
## R_X86_64_REX2_GOTPCRELX
138+
adcq bar@GOTPCREL(%rip), %r16
139+
addq bar@GOTPCREL(%rip), %r17
140+
andq bar@GOTPCREL(%rip), %r18
141+
cmpq bar@GOTPCREL(%rip), %r19
142+
orq bar@GOTPCREL(%rip), %r20
143+
sbbq bar@GOTPCREL(%rip), %r21
144+
subq bar@GOTPCREL(%rip), %r22
145+
xorq bar@GOTPCREL(%rip), %r23
146+
testq %r24, bar@GOTPCREL(%rip)

lld/test/ELF/x86-64-gotpc-relax.s

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# REQUIRES: x86
2-
## Test R_X86_64_GOTPCRELX and R_X86_64_REX_GOTPCRELX GOT optimization.
2+
## Test R_X86_64_GOTPCRELX and R_X86_64_REX_GOTPCRELX/R_X86_64_REX2_GOTPCRELX GOT optimization.
33

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

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

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

2929
# 0x201173 + 7 - 10 = 0x201170
3030
# 0x20117a + 7 - 17 = 0x201170
@@ -43,20 +43,20 @@
4343
# DISASM-NEXT: leaq -17(%rip), %rax
4444
# DISASM-NEXT: leaq -23(%rip), %rax
4545
# DISASM-NEXT: leaq -30(%rip), %rax
46-
# DISASM-NEXT: movq 8330(%rip), %rax
47-
# DISASM-NEXT: movq 8323(%rip), %rax
46+
# DISASM-NEXT: movq 8426(%rip), %rax
47+
# DISASM-NEXT: movq 8419(%rip), %rax
4848
# DISASM-NEXT: leaq -52(%rip), %rax
4949
# DISASM-NEXT: leaq -59(%rip), %rax
5050
# DISASM-NEXT: leaq -65(%rip), %rax
5151
# DISASM-NEXT: leaq -72(%rip), %rax
52-
# DISASM-NEXT: movq 8288(%rip), %rax
53-
# DISASM-NEXT: movq 8281(%rip), %rax
52+
# DISASM-NEXT: movq 8384(%rip), %rax
53+
# DISASM-NEXT: movq 8377(%rip), %rax
5454
# DISASM-NEXT: callq 0x2011e0 <foo>
5555
# DISASM-NEXT: callq 0x2011e0 <foo>
5656
# DISASM-NEXT: callq 0x2011e1 <hid>
5757
# DISASM-NEXT: callq 0x2011e1 <hid>
58-
# DISASM-NEXT: callq *8251(%rip)
59-
# DISASM-NEXT: callq *8245(%rip)
58+
# DISASM-NEXT: callq *8347(%rip)
59+
# DISASM-NEXT: callq *8341(%rip)
6060
# DISASM-NEXT: jmp 0x2011e0 <foo>
6161
# DISASM-NEXT: nop
6262
# DISASM-NEXT: jmp 0x2011e0 <foo>
@@ -65,13 +65,26 @@
6565
# DISASM-NEXT: nop
6666
# DISASM-NEXT: jmp 0x2011e1 <hid>
6767
# DISASM-NEXT: nop
68-
# DISASM-NEXT: jmpq *8215(%rip)
69-
# DISASM-NEXT: jmpq *8209(%rip)
68+
# DISASM-NEXT: jmpq *8311(%rip)
69+
# DISASM-NEXT: jmpq *8305(%rip)
70+
# DISASM-NEXT: leaq -167(%rip), %r16
71+
# DISASM-NEXT: leaq -175(%rip), %r16
72+
# DISASM-NEXT: leaq -182(%rip), %r16
73+
# DISASM-NEXT: leaq -190(%rip), %r16
74+
# DISASM-NEXT: movq 8265(%rip), %r16
75+
# DISASM-NEXT: movq 8257(%rip), %r16
76+
# DISASM-NEXT: leaq -215(%rip), %r16
77+
# DISASM-NEXT: leaq -223(%rip), %r16
78+
# DISASM-NEXT: leaq -230(%rip), %r16
79+
# DISASM-NEXT: leaq -238(%rip), %r16
80+
# DISASM-NEXT: movq 8217(%rip), %r16
81+
# DISASM-NEXT: movq 8209(%rip), %r16
7082

7183
# NORELAX-LABEL: <_start>:
7284
# NORELAX-COUNT-12: movq
7385
# NORELAX-COUNT-6: callq *
7486
# NORELAX-COUNT-6: jmpq *
87+
# NORELAX-COUNT-12: movq
7588

7689
.text
7790
.globl foo
@@ -120,3 +133,16 @@ _start:
120133
jmp *hid@GOTPCREL(%rip)
121134
jmp *ifunc@GOTPCREL(%rip)
122135
jmp *ifunc@GOTPCREL(%rip)
136+
137+
movq foo@GOTPCREL(%rip), %r16
138+
movq foo@GOTPCREL(%rip), %r16
139+
movq hid@GOTPCREL(%rip), %r16
140+
movq hid@GOTPCREL(%rip), %r16
141+
movq ifunc@GOTPCREL(%rip), %r16
142+
movq ifunc@GOTPCREL(%rip), %r16
143+
movq foo@GOTPCREL(%rip), %r16
144+
movq foo@GOTPCREL(%rip), %r16
145+
movq hid@GOTPCREL(%rip), %r16
146+
movq hid@GOTPCREL(%rip), %r16
147+
movq ifunc@GOTPCREL(%rip), %r16
148+
movq ifunc@GOTPCREL(%rip), %r16

0 commit comments

Comments
 (0)