Skip to content

Commit 8e8ccf4

Browse files
committed
[MIPS] Don't emit R_(MICRO)MIPS_JALR relocations against data symbols
The R_(MICRO)MIPS_JALR optimization only works when used against functions. Using the relocation against a data symbol (e.g. function pointer) will cause some linkers that don't ignore the hint in this case (e.g. LLD prior to commit 5bab291) to generate a relative branch to the data symbol which crashes at run time. Before this patch, LLVM was erroneously emitting these relocations against local-dynamic TLS function pointers and global function pointers with internal visibility. Reviewers: atanasyan, jrtc27, vstefanovic Reviewed By: atanasyan Differential Revision: https://reviews.llvm.org/D72571
1 parent 894f742 commit 8e8ccf4

File tree

2 files changed

+99
-53
lines changed

2 files changed

+99
-53
lines changed

llvm/lib/Target/Mips/MipsISelLowering.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -3111,6 +3111,14 @@ void MipsTargetLowering::AdjustInstrPostInstrSelection(MachineInstr &MI,
31113111
StringRef Sym;
31123112
if (const GlobalAddressSDNode *G =
31133113
dyn_cast_or_null<const GlobalAddressSDNode>(TargetAddr)) {
3114+
// We must not emit the R_MIPS_JALR relocation against data symbols
3115+
// since this will cause run-time crashes if the linker replaces the
3116+
// call instruction with a relative branch to the data symbol.
3117+
if (!isa<Function>(G->getGlobal())) {
3118+
LLVM_DEBUG(dbgs() << "Not adding R_MIPS_JALR against data symbol "
3119+
<< G->getGlobal()->getName() << "\n");
3120+
return;
3121+
}
31143122
Sym = G->getGlobal()->getName();
31153123
}
31163124
else if (const ExternalSymbolSDNode *ES =
@@ -3123,6 +3131,7 @@ void MipsTargetLowering::AdjustInstrPostInstrSelection(MachineInstr &MI,
31233131

31243132
MachineFunction *MF = MI.getParent()->getParent();
31253133
MCSymbol *S = MF->getContext().getOrCreateSymbol(Sym);
3134+
LLVM_DEBUG(dbgs() << "Adding R_MIPS_JALR against " << Sym << "\n");
31263135
MI.addOperand(MachineOperand::CreateMCSymbol(S, MipsII::MO_JALR));
31273136
}
31283137
}

llvm/test/CodeGen/Mips/reloc-jalr.ll

+90-53
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,64 @@
11
; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic -mips-tail-calls=1 \
22
; RUN: -O2 < %s | \
3-
; RUN: FileCheck %s -check-prefixes=ALL,JALR-32R2,TAILCALL-32R2
3+
; RUN: FileCheck %s -check-prefixes=ALL,JALR-ALL,JALR-32,JALR-32R2,TAILCALL-32R2
44

55
; RUN: llc -mtriple=mips64-linux-gnu -relocation-model=pic -mips-tail-calls=1 \
66
; RUN: -O2 < %s | \
7-
; RUN: FileCheck %s -check-prefixes=ALL,JALR-64R2,TAILCALL-64R2
7+
; RUN: FileCheck %s -check-prefixes=ALL,JALR-ALL,JALR-64,JALR-64R2,TAILCALL-64R2
88

99
; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic -mips-tail-calls=1 \
1010
; RUN: -O2 -mcpu=mips32r6 -mips-compact-branches=always < %s | \
11-
; RUN: FileCheck %s -check-prefixes=ALL,JALR-32R6,TAILCALL-32R6
11+
; RUN: FileCheck %s -check-prefixes=ALL,JALR-ALL,JALR-32,JALR-32R6,TAILCALL-32R6
1212

1313
; RUN: llc -mtriple=mips64-linux-gnu -relocation-model=pic -mips-tail-calls=1 \
1414
; RUN: -O2 -mcpu=mips64r6 -mips-compact-branches=always < %s | \
15-
; RUN: FileCheck %s -check-prefixes=ALL,JALR-64R6,TAILCALL-64R6
15+
; RUN: FileCheck %s -check-prefixes=ALL,JALR-ALL,JALR-64,JALR-64R6,TAILCALL-64R6
1616

1717
; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic -mips-tail-calls=1 \
1818
; RUN: -O2 -mcpu=mips32r6 -mips-compact-branches=never < %s | \
19-
; RUN: FileCheck %s -check-prefixes=ALL,JALR-32R2,TAILCALL-32R2
19+
; RUN: FileCheck %s -check-prefixes=ALL,JALR-ALL,JALR-32,JALR-32R2,TAILCALL-32R2
2020

2121
; RUN: llc -mtriple=mips64-linux-gnu -relocation-model=pic -mips-tail-calls=1 \
2222
; RUN: -O2 -mcpu=mips64r6 -mips-compact-branches=never < %s | \
23-
; RUN: FileCheck %s -check-prefixes=ALL,JALR-64R2,TAILCALL-64R2
23+
; RUN: FileCheck %s -check-prefixes=ALL,JALR-ALL,JALR-64,JALR-64R2,TAILCALL-64R2
2424

2525
; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic -mips-tail-calls=1 \
2626
; RUN: -O2 -mattr=+micromips -mcpu=mips32r2 < %s | \
27-
; RUN: FileCheck %s -check-prefixes=ALL,JALR-MM,TAILCALL-MM
27+
; RUN: FileCheck %s -check-prefixes=ALL,JALR-ALL,JALR-MM,TAILCALL-MM
2828

2929
; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic -mips-tail-calls=1 \
3030
; RUN: -O2 -mattr=+micromips -mcpu=mips32r6 < %s | \
31-
; RUN: FileCheck %s -check-prefixes=ALL,JALR-MM
31+
; RUN: FileCheck %s -check-prefixes=ALL,JALR-ALL,JALR-MM,TAILCALL-MM
3232

3333
; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic \
34-
; RUN: -O0 < %s | FileCheck %s -check-prefixes=ALL,JALR-32R2
34+
; RUN: -O0 < %s | FileCheck %s -check-prefixes=ALL,JALR-ALL,JALR-32,JALR-32R2,PIC-NOTAILCALL-R2
3535

3636
; RUN: llc -mtriple=mips64-linux-gnu -relocation-model=pic \
37-
; RUN: -O0 < %s | FileCheck %s -check-prefixes=ALL,JALR-64R2
37+
; RUN: -O0 < %s | FileCheck %s -check-prefixes=ALL,JALR-ALL,JALR-64,JALR-64R2,PIC-NOTAILCALL-R2
3838

3939
; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic \
4040
; RUN: -O0 -mcpu=mips32r6 -mips-compact-branches=always < %s | \
41-
; RUN: FileCheck %s -check-prefixes=ALL,JALR-32R6
41+
; RUN: FileCheck %s -check-prefixes=ALL,JALR-ALL,JALR-32,JALR-32R6,PIC-NOTAILCALL-R6
4242

4343
; RUN: llc -mtriple=mips64-linux-gnu -relocation-model=pic \
4444
; RUN: -O0 -mcpu=mips64r6 -mips-compact-branches=always < %s | \
45-
; RUN: FileCheck %s -check-prefixes=ALL,JALR-64R6
45+
; RUN: FileCheck %s -check-prefixes=ALL,JALR-ALL,JALR-64,JALR-64R6,PIC-NOTAILCALL-R6
4646

4747
; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic \
4848
; RUN: -O0 -mcpu=mips32r6 -mips-compact-branches=never < %s | \
49-
; RUN: FileCheck %s -check-prefixes=ALL,JALR-32R2
49+
; RUN: FileCheck %s -check-prefixes=ALL,JALR-ALL,JALR-32,JALR-32R2,PIC-NOTAILCALL-R2
5050

5151
; RUN: llc -mtriple=mips64-linux-gnu -relocation-model=pic \
5252
; RUN: -O0 -mcpu=mips64r6 -mips-compact-branches=never < %s | \
53-
; RUN: FileCheck %s -check-prefixes=ALL,JALR-64R2
53+
; RUN: FileCheck %s -check-prefixes=ALL,JALR-ALL,JALR-64,JALR-64R2,PIC-NOTAILCALL-R2
5454

5555
; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic \
5656
; RUN: -O0 -mattr=+micromips -mcpu=mips32r2 < %s | \
57-
; RUN: FileCheck %s -check-prefixes=ALL,JALR-MM
57+
; RUN: FileCheck %s -check-prefixes=ALL,JALR-ALL,JALR-MM,PIC-NOTAILCALL-MM
5858

5959
; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic \
6060
; RUN: -O0 -mattr=+micromips -mcpu=mips32r6 < %s | \
61-
; RUN: FileCheck %s -check-prefixes=ALL,JALR-MM
61+
; RUN: FileCheck %s -check-prefixes=ALL,JALR-ALL,JALR-MM,PIC-NOTAILCALL-MM
6262

6363
; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic -mips-tail-calls=1 \
6464
; RUN: -O2 -mips-jalr-reloc=false < %s | \
@@ -100,55 +100,92 @@ entry:
100100
define void @checkCall() {
101101
entry:
102102
; ALL-LABEL: checkCall:
103+
; ALL-NOT: MIPS_JALR
103104
call void @foo()
104-
; JALR-32R2: .reloc ([[TMPLABEL:.*]]), R_MIPS_JALR, foo
105-
; JALR-32R2-NEXT: [[TMPLABEL]]:
106-
; JALR-32R2-NEXT: jalr $25
107-
108-
; JALR-64R2: .reloc [[TMPLABEL:.*]], R_MIPS_JALR, foo
109-
; JALR-64R2-NEXT: [[TMPLABEL]]:
110-
; JALR-64R2-NEXT: jalr $25
111-
112-
; JALR-MM: .reloc ([[TMPLABEL:.*]]), R_MICROMIPS_JALR, foo
113-
; JALR-MM-NEXT: [[TMPLABEL]]:
114-
; JALR-MM-NEXT: jalr $25
115-
116-
; JALR-32R6: .reloc ([[TMPLABEL:.*]]), R_MIPS_JALR, foo
117-
; JALR-32R6-NEXT: [[TMPLABEL]]:
118-
; JALR-32R6-NEXT: jalrc $25
119-
120-
; JALR-64R6: .reloc [[TMPLABEL:.*]], R_MIPS_JALR, foo
121-
; JALR-64R6-NEXT: [[TMPLABEL]]:
122-
; JALR-64R6-NEXT: jalrc $25
123-
124-
; NORELOC-NOT: R_MIPS_JALR
105+
; JALR-32: .reloc ([[TMPLABEL:\$.+]]), R_MIPS_JALR, foo
106+
; JALR-64: .reloc [[TMPLABEL:\..+]], R_MIPS_JALR, foo
107+
; JALR-MM: .reloc ([[TMPLABEL:\$.+]]), R_MICROMIPS_JALR, foo
108+
; JALR-ALL-NEXT: [[TMPLABEL]]:
109+
; JALR-32R2-NEXT: jalr $25
110+
; JALR-64R2-NEXT: jalr $25
111+
; JALR-32R6-NEXT: jalrc $25
112+
; JALR-64R6-NEXT: jalrc $25
113+
; JALR-MM-NEXT: jalr $25
114+
; ALL-NOT: MIPS_JALR
125115
ret void
126116
}
127117

128118
define void @checkTailCall() {
129119
entry:
130120
; ALL-LABEL: checkTailCall:
121+
; ALL-NOT: MIPS_JALR
131122
tail call void @foo()
132-
; TAILCALL-32R2: .reloc ([[TMPLABEL:.*]]), R_MIPS_JALR, foo
133-
; TAILCALL-32R2-NEXT: [[TMPLABEL]]:
134-
; TAILCALL-32R2-NEXT: jr $25
123+
; JALR-32: .reloc ([[TMPLABEL:\$.+]]), R_MIPS_JALR, foo
124+
; JALR-64: .reloc [[TMPLABEL:\..+]], R_MIPS_JALR, foo
125+
; JALR-MM: .reloc ([[TMPLABEL:\$.+]]), R_MICROMIPS_JALR, foo
126+
; JALR-ALL-NEXT: [[TMPLABEL]]:
127+
; TAILCALL-32R2-NEXT: jr $25
128+
; TAILCALL-64R2-NEXT: jr $25
129+
; TAILCALL-MM-NEXT: jrc $25
130+
; TAILCALL-32R6-NEXT: jrc $25
131+
; TAILCALL-64R6-NEXT: jrc $25
132+
; PIC-NOTAILCALL-R2-NEXT: jalr $25
133+
; PIC-NOTAILCALL-R6-NEXT: jalrc $25
134+
; PIC-NOTAILCALL-MM-NEXT: jalr $25
135+
; ALL-NOT: MIPS_JALR
136+
ret void
137+
}
135138

136-
; TAILCALL-64R2: .reloc [[TMPLABEL:.*]], R_MIPS_JALR, foo
137-
; TAILCALL-64R2-NEXT: [[TMPLABEL]]:
138-
; TAILCALL-64R2-NEXT: jr $25
139+
; Check that we don't emit R_MIPS_JALR relocations against function pointers.
140+
; This resulted in run-time crashes until lld was modified to ignore
141+
; R_MIPS_JALR relocations against data symbols (commit 5bab291b7b).
142+
; However, the better approach is to not emit these relocations in the first
143+
; place so check that we no longer emit them.
144+
; Previously we were adding them for local dynamic TLS function pointers and
145+
; function pointers with internal linkage.
139146

140-
; TAILCALL-MM: .reloc ([[TMPLABEL:.*]]), R_MICROMIPS_JALR, foo
141-
; TAILCALL-MM-NEXT: [[TMPLABEL]]:
142-
; TAILCALL-MM-NEXT: jrc $25
147+
@fnptr_internal = internal global void()* @checkFunctionPointerCall
148+
@fnptr_internal_const = internal constant void()* @checkFunctionPointerCall
149+
@fnptr_const = constant void()* @checkFunctionPointerCall
150+
@fnptr_global = global void()* @checkFunctionPointerCall
143151

144-
; TAILCALL-32R6: .reloc ([[TMPLABEL:.*]]), R_MIPS_JALR, foo
145-
; TAILCALL-32R6-NEXT: [[TMPLABEL]]:
146-
; TAILCALL-32R6-NEXT: jrc $25
152+
define void @checkFunctionPointerCall() {
153+
entry:
154+
; ALL-LABEL: checkFunctionPointerCall:
155+
; ALL-NOT: MIPS_JALR
156+
%func_internal = load void()*, void()** @fnptr_internal
157+
call void %func_internal()
158+
%func_internal_const = load void()*, void()** @fnptr_internal_const
159+
call void %func_internal_const()
160+
%func_const = load void()*, void()** @fnptr_const
161+
call void %func_const()
162+
%func_global = load void()*, void()** @fnptr_global
163+
call void %func_global()
164+
ret void
165+
}
147166

148-
; TAILCALL-64R6: .reloc [[TMPLABEL:.*]], R_MIPS_JALR, foo
149-
; TAILCALL-64R6-NEXT: [[TMPLABEL]]:
150-
; TAILCALL-64R6-NEXT: jrc $25
167+
@tls_fnptr_gd = thread_local global void()* @checkTlsFunctionPointerCall
168+
@tls_fnptr_ld = thread_local(localdynamic) global void()* @checkTlsFunctionPointerCall
169+
@tls_fnptr_ie = thread_local(initialexec) global void()* @checkTlsFunctionPointerCall
170+
@tls_fnptr_le = thread_local(localexec) global void()* @checkTlsFunctionPointerCall
151171

152-
; NORELOC-NOT: R_MIPS_JALR
172+
define void @checkTlsFunctionPointerCall() {
173+
entry:
174+
; There should not be any *JALR relocations in this function other than the
175+
; calls to __tls_get_addr:
176+
; ALL-LABEL: checkTlsFunctionPointerCall:
177+
; ALL-NOT: MIPS_JALR
178+
; JALR-ALL: .reloc {{.+}}MIPS_JALR, __tls_get_addr
179+
; ALL-NOT: MIPS_JALR
180+
; JALR-ALL: .reloc {{.+}}MIPS_JALR, __tls_get_addr
181+
; ALL-NOT: _MIPS_JALR
182+
%func_gd = load void()*, void()** @tls_fnptr_gd
183+
call void %func_gd()
184+
%func_ld = load void()*, void()** @tls_fnptr_ld
185+
call void %func_ld()
186+
%func_ie = load void()*, void()** @tls_fnptr_ie
187+
call void %func_ie()
188+
%func_le = load void()*, void()** @tls_fnptr_le
189+
call void %func_le()
153190
ret void
154191
}

0 commit comments

Comments
 (0)