Skip to content

Commit 7f52be8

Browse files
committed
Another take at eliminating UB in patchedcode.S with Apple linkers
1 parent d2bb5f3 commit 7f52be8

File tree

4 files changed

+96
-46
lines changed

4 files changed

+96
-46
lines changed

src/coreclr/pal/inc/unixasmmacrosamd64.inc

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -52,25 +52,6 @@ C_FUNC(\Name):
5252
.cfi_endproc
5353
.endm
5454

55-
// Special version of the LEAF_ENTRY macro that should be used inside
56-
// patchable code region to prevent the linker from relocating the code.
57-
// On most Unix platforms this is identical to LEAF_ENTRY. However, on
58-
// Apple platforms it produces the function entry points at .alt_entry
59-
// symbols that create external labels but keep the whole patched region
60-
// as single atom for the linker.
61-
.macro LEAF_ENTRY_PATCHABLE Name, Section
62-
#if defined(__APPLE__)
63-
.text
64-
.p2align 4
65-
.alt_entry C_FUNC(\Name)
66-
.private_extern C_FUNC(\Name)
67-
C_FUNC(\Name):
68-
.cfi_startproc
69-
#else
70-
LEAF_ENTRY \Name, \Section
71-
#endif
72-
.endm
73-
7455
.macro LEAF_END_MARKED Name, Section
7556
#if defined(__APPLE__)
7657
.alt_entry C_FUNC(\Name\()_End)

src/coreclr/pal/inc/unixasmmacrosarm64.inc

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -63,25 +63,6 @@ C_FUNC(\Name):
6363
.cfi_endproc
6464
.endm
6565

66-
// Special version of the LEAF_ENTRY macro that should be used inside
67-
// patchable code region to prevent the linker from relocating the code.
68-
// On most Unix platforms this is identical to LEAF_ENTRY. However, on
69-
// Apple platforms it produces the function entry points at .alt_entry
70-
// symbols that create external labels but keep the whole patched region
71-
// as single atom for the linker.
72-
.macro LEAF_ENTRY_PATCHABLE Name, Section
73-
#if defined(__APPLE__)
74-
.text
75-
.p2align 2
76-
.alt_entry C_FUNC(\Name)
77-
.private_extern C_FUNC(\Name)
78-
C_FUNC(\Name):
79-
.cfi_startproc
80-
#else
81-
LEAF_ENTRY \Name, \Section
82-
#endif
83-
.endm
84-
8566
.macro LEAF_END_MARKED Name, Section
8667
#if defined(__APPLE__)
8768
.alt_entry C_FUNC(\Name\()_End)

src/coreclr/vm/amd64/patchedcode.S

Lines changed: 59 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,57 @@
55
#include "unixasmmacros.inc"
66
#include "asmconstants.h"
77

8+
// On Apple platforms we emit the whole patched region as single function
9+
// with .alt_entry labels for individual write barrier helpers. This ensures
10+
// the linker doesn't relocate or split the code and treats it as single
11+
// atom. We also need to be careful to produce the correct unwinding
12+
// information.
13+
14+
//-----------------------------------------------------------------------------
15+
// The following Macros help in WRITE_BARRIER Implementations
16+
// WRITE_BARRIER_ENTRY
17+
//
18+
// Declare the start of a write barrier function. Use similarly to NESTED_ENTRY. This is the only legal way
19+
// to declare a write barrier function.
20+
//
21+
.macro WRITE_BARRIER_ENTRY name
22+
#if defined(__APPLE__)
23+
.text
24+
.p2align 4
25+
.alt_entry C_FUNC(\name)
26+
.private_extern C_FUNC(\name)
27+
C_FUNC(\name):
28+
#else
29+
LEAF_ENTRY \name, _TEXT
30+
#endif
31+
.endm
32+
33+
// WRITE_BARRIER_END
34+
//
35+
// The partner to WRITE_BARRIER_ENTRY, used like NESTED_END.
36+
//
37+
.macro WRITE_BARRIER_END name
38+
#if defined(__APPLE__)
39+
.alt_entry C_FUNC(\name\()_End)
40+
.private_extern C_FUNC(\name\()_End)
41+
C_FUNC(\name\()_End):
42+
// make sure this symbol gets its own address
43+
nop
44+
#else
45+
LEAF_END_MARKED \name, _TEXT
46+
#endif
47+
.endm
48+
849
// Mark start of the code region that we patch at runtime
50+
#if defined(__APPLE__)
51+
.global C_FUNC(JIT_PatchedCodeStart)
52+
C_FUNC(JIT_PatchedCodeStart):
53+
.cfi_startproc
54+
#else
955
LEAF_ENTRY JIT_PatchedCodeStart, _TEXT
1056
ret
1157
LEAF_END JIT_PatchedCodeStart, _TEXT
58+
#endif
1259

1360

1461
// There is an even more optimized version of these helpers possible which takes
@@ -24,7 +71,7 @@ LEAF_END JIT_PatchedCodeStart, _TEXT
2471
// it needs to have it's card updated
2572
//
2673
// void JIT_CheckedWriteBarrier(Object** dst, Object* src)
27-
LEAF_ENTRY_PATCHABLE JIT_CheckedWriteBarrier, _TEXT
74+
WRITE_BARRIER_ENTRY JIT_CheckedWriteBarrier
2875

2976
// When WRITE_BARRIER_CHECK is defined _NotInHeap will write the reference
3077
// but if it isn't then it will just return.
@@ -45,7 +92,7 @@ LEAF_ENTRY_PATCHABLE JIT_CheckedWriteBarrier, _TEXT
4592
// See comment above about possible AV
4693
mov [rdi], rsi
4794
ret
48-
LEAF_END_MARKED JIT_CheckedWriteBarrier, _TEXT
95+
WRITE_BARRIER_END JIT_CheckedWriteBarrier
4996

5097

5198
// This is used by the mechanism to hold either the JIT_WriteBarrier_PreGrow
@@ -54,7 +101,7 @@ LEAF_END_MARKED JIT_CheckedWriteBarrier, _TEXT
54101
// larger of the two functions (JIT_WriteBarrier_PostGrow) to ensure we have created
55102
// enough space to copy that code in.
56103
.balign 16
57-
LEAF_ENTRY_PATCHABLE JIT_WriteBarrier, _TEXT
104+
WRITE_BARRIER_ENTRY JIT_WriteBarrier
58105
#ifdef _DEBUG
59106
// In debug builds, this just contains jump to the debug version of the write barrier by default
60107
jmp C_FUNC(JIT_WriteBarrier_Debug)
@@ -237,9 +284,16 @@ LEAF_ENTRY_PATCHABLE JIT_WriteBarrier, _TEXT
237284
// make sure this is bigger than any of the others
238285
.balign 16
239286
nop
240-
LEAF_END_MARKED JIT_WriteBarrier, _TEXT
287+
WRITE_BARRIER_END JIT_WriteBarrier
241288

242289
// Mark start of the code region that we patch at runtime
243-
LEAF_ENTRY_PATCHABLE JIT_PatchedCodeLast, _TEXT
290+
#if defined(__APPLE__)
291+
.private_extern C_FUNC(JIT_PatchedCodeLast)
292+
.alt_entry C_FUNC(JIT_PatchedCodeLast)
293+
C_FUNC(JIT_PatchedCodeLast):
294+
.cfi_endproc
295+
#else
296+
LEAF_ENTRY JIT_PatchedCodeLast, _TEXT
244297
ret
245298
LEAF_END JIT_PatchedCodeLast, _TEXT
299+
#endif

src/coreclr/vm/arm64/patchedcode.S

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@
55
#include "unixasmmacros.inc"
66
#include "patchedcodeconstants.h"
77

8+
// On Apple platforms we emit the whole patched region as single function
9+
// with .alt_entry labels for individual write barrier helpers. This ensures
10+
// the linker doesn't relocate or split the code and treats it as single
11+
// atom. We also need to be careful to produce the correct unwinding
12+
// information.
13+
814
//-----------------------------------------------------------------------------
915
// The following Macros help in WRITE_BARRIER Implementations
1016
// WRITE_BARRIER_ENTRY
@@ -13,23 +19,45 @@
1319
// to declare a write barrier function.
1420
//
1521
.macro WRITE_BARRIER_ENTRY name
16-
LEAF_ENTRY_PATCHABLE \name, _TEXT
22+
#if defined(__APPLE__)
23+
.text
24+
.p2align 2
25+
.alt_entry C_FUNC(\name)
26+
.private_extern C_FUNC(\name)
27+
C_FUNC(\name):
28+
#else
29+
LEAF_ENTRY \name, _TEXT
30+
#endif
1731
.endm
1832

1933
// WRITE_BARRIER_END
2034
//
2135
// The partner to WRITE_BARRIER_ENTRY, used like NESTED_END.
2236
//
2337
.macro WRITE_BARRIER_END name
38+
#if defined(__APPLE__)
39+
.alt_entry C_FUNC(\name\()_End)
40+
.private_extern C_FUNC(\name\()_End)
41+
C_FUNC(\name\()_End):
42+
// make sure this symbol gets its own address
43+
nop
44+
#else
2445
LEAF_END_MARKED \name, _TEXT
46+
#endif
2547
.endm
2648

2749
.balign 64 // Align to power of two at least as big as patchable literal pool so that it fits optimally in cache line
2850
//------------------------------------------
2951
// Start of the writeable code region
52+
#if defined(__APPLE__)
53+
.global C_FUNC(JIT_PatchedCodeStart)
54+
C_FUNC(JIT_PatchedCodeStart):
55+
.cfi_startproc
56+
#else
3057
LEAF_ENTRY JIT_PatchedCodeStart, _TEXT
3158
ret lr
3259
LEAF_END JIT_PatchedCodeStart, _TEXT
60+
#endif
3361

3462
//-----------------------------------------------------------------------------
3563
// void JIT_ByRefWriteBarrier
@@ -145,10 +173,16 @@ WRITE_BARRIER_END JIT_WriteBarrier_Table
145173

146174
// ------------------------------------------------------------------
147175
// End of the writeable code region
148-
LEAF_ENTRY_PATCHABLE JIT_PatchedCodeLast, _TEXT
176+
#if defined(__APPLE__)
177+
.private_extern C_FUNC(JIT_PatchedCodeLast)
178+
.alt_entry C_FUNC(JIT_PatchedCodeLast)
179+
C_FUNC(JIT_PatchedCodeLast):
180+
.cfi_endproc
181+
#else
182+
LEAF_ENTRY JIT_PatchedCodeLast, _TEXT
149183
ret lr
150184
LEAF_END JIT_PatchedCodeLast, _TEXT
151-
185+
#endif
152186

153187

154188
//-----------------------------------------------------------------------------

0 commit comments

Comments
 (0)