History

Add bound check support for alloca on all targets

stddef.h, tccdefs.h, tccgen.c, tests/boundtest.c, tests/tcctest.c: - remove ifdef arround alloca lib/Makefile: - move alloca-bt.o to COMMON_O lib/alloca-bt.S: - add alloca bound check code for arm, arm64, riscv64 lib/alloca.S: - check for leading underscore tcc.h, libtcc.c: - include arm64-asm.c instead of arm-asm.c for arm64 tcctok.h, tccasm.c: - add simple reloc support (only for R_AARCH64_CALL26)

herman ten brugge committed 11 months ago

Commit 6da45941 parent fc424c912 files · +142 −59Browse files

Unified · Split

12 files
  1. include/stddef.h +0 −2
  2. include/tccdefs.h +0 −4
  3. lib/Makefile +3 −3
  4. lib/alloca-bt.S +104 −0
  5. lib/alloca.S +15 −26
  6. libtcc.c +1 −1
  7. tcc.h +1 −1
  8. tccasm.c +17 −0
  9. tccgen.c +0 −2
  10. tcctok.h +1 −2
  11. tests/boundtest.c +0 −14
  12. tests/tcctest.c +0 −4
include/stddef.h+0−2
@@ -19,9 +19,7 @@ typedef union { long long __ll; long double __ld; } max_align_t; · 18 unmodified lines
19#undef offsetof19#undef offsetof
20#define offsetof(type, field) __builtin_offsetof(type, field)20#define offsetof(type, field) __builtin_offsetof(type, field)
21 21
22#if defined __i386__ || defined __x86_64__
23void *alloca(size_t size);22void *alloca(size_t size);
24#endif
25 23
26#endif24#endif
27 25
include/tccdefs.h+0−4
@@ -347,12 +347,8 @@ · 346 unmodified lines
347 __MAYBE_REDIR(void*, calloc, (__SIZE_TYPE__, __SIZE_TYPE__))347 __MAYBE_REDIR(void*, calloc, (__SIZE_TYPE__, __SIZE_TYPE__))
348 __MAYBE_REDIR(void*, memalign, (__SIZE_TYPE__, __SIZE_TYPE__))348 __MAYBE_REDIR(void*, memalign, (__SIZE_TYPE__, __SIZE_TYPE__))
349 __MAYBE_REDIR(void, free, (void*))349 __MAYBE_REDIR(void, free, (void*))
350#if defined __i386__ || defined __x86_64__
351 __BOTH(void*, alloca, (__SIZE_TYPE__))350 __BOTH(void*, alloca, (__SIZE_TYPE__))
352 void *alloca(__SIZE_TYPE__);351 void *alloca(__SIZE_TYPE__);
353#else
354 __BUILTIN(void*, alloca, (__SIZE_TYPE__))
355#endif
356 __BUILTIN(void, abort, (void))352 __BUILTIN(void, abort, (void))
357 __BOUND(void, longjmp, ())353 __BOUND(void, longjmp, ())
358#if !defined _WIN32354#if !defined _WIN32
lib/Makefile+3−3
@@ -35,12 +35,12 @@ endif · 34 unmodified lines
35 35
36XFLAGS += -I$(TOP)36XFLAGS += -I$(TOP)
37 37
38I386_O = libtcc1.o alloca-bt.o $(COMMON_O)38I386_O = libtcc1.o $(COMMON_O)
39X86_64_O = libtcc1.o alloca-bt.o $(COMMON_O)39X86_64_O = libtcc1.o $(COMMON_O)
40ARM_O = libtcc1.o armeabi.o armflush.o $(COMMON_O)40ARM_O = libtcc1.o armeabi.o armflush.o $(COMMON_O)
41ARM64_O = lib-arm64.o $(COMMON_O)41ARM64_O = lib-arm64.o $(COMMON_O)
42RISCV64_O = lib-arm64.o $(COMMON_O)42RISCV64_O = lib-arm64.o $(COMMON_O)
43COMMON_O = stdatomic.o atomic.o builtin.o alloca.o43COMMON_O = stdatomic.o atomic.o builtin.o alloca.o alloca-bt.o
44WIN_O = crt1.o crt1w.o wincrt1.o wincrt1w.o dllcrt1.o dllmain.o44WIN_O = crt1.o crt1w.o wincrt1.o wincrt1w.o dllcrt1.o dllmain.o
45LIN_O = dsohandle.o45LIN_O = dsohandle.o
46OSX_O =46OSX_O =
lib/alloca-bt.S+104−0
@@ -92,5 +92,109 @@ p3: · 91 unmodified lines
92 ret92 ret
93#endif93#endif
94 94
95/* ---------------------------------------------- */
96#elif defined __arm__
97
98.globl _(__bound_alloca)
99_(__bound_alloca):
100 mov r1, r0
101 add r0, r0, #1
102 rsb sp, r0, sp
103 bic sp, sp, #7
104 mov r0, sp
105 push { lr }
106 bl _(__bound_new_region)
107 pop { lr }
108 mov r0, sp
109 mov pc, lr
110
111/* ---------------------------------------------- */
112#elif defined __aarch64__ || defined __arm64__
113
114.globl _(__bound_alloca)
115_(__bound_alloca):
116#ifdef __TINYC__
117 .int 0xaa0003e1
118 .int 0x91004000
119 .int 0x927cec00
120#ifdef _WIN32
121 .int 0xb4000160
122 .int 0xd2820002
123 .int 0xeb02001f
124 .int 0x540000c3
125 .int 0xcb2263e3
126 .int 0xf940007f
127 .int 0xcb2263ff
128 .int 0xcb020000
129 .int 0x17fffffa
130 .int 0xb4000040
131#endif
132 .int 0xcb2063ff
133 .int 0x910003e0
134 .int 0xa9bf7bfd
135 .reloc ., R_AARCH64_CALL26, _(__bound_new_region)
136 .int 0x94000000
137 .int 0xa8c17bfd
138 .int 0x910003e0
139 .int 0xd65f03c0
140#else
141 mov x1, x0
142 add x0, x0, #16 // Round up to 16-byte boundary
143 and x0, x0, #-16 // Ensure 16-byte alignment
144#ifdef _WIN32
145 cbz x0, p100 // If size is 0, skip to return
146 // Windows requires page-wise allocation with stack probing
147 mov x2, #4096 // Page size = 4096 bytes
148
149p101:
150 cmp x0, x2 // Compare remaining size with page size
151 b.lo p102 // If less than page, jump to remainder
152
153 // Probe first, then allocate
154 sub x3, sp, x2 // Calculate guard page address (sp - 4096)
155 ldr xzr, [x3] // Touch guard page FIRST
156 sub sp, sp, x2 // THEN allocate the page
157
158 sub x0, x0, x2 // Decrement remaining size
159 b p101 // Continue loop
160
161p102:
162 // Allocate remaining bytes (less than one page)
163 cbz x0, p100 // If no remaining bytes, skip
164 sub sp, sp, x0 // Allocate remaining space
165#else
166 // Non-Windows: simple one-time allocation
167 sub sp, sp, x0 // Allocate space on stack
168#endif
169
170p100:
171 mov x0, sp // Return allocated address
172 stp x29, x30, [sp, #-16]!
173 bl _(__bound_new_region)
174 ldp x29, x30, [sp], #16
175 mov x0, sp // Return allocated address
176 ret // Return to caller
177#endif
178
179/* ---------------------------------------------- */
180#elif defined __riscv
181
182.globl _(__bound_alloca)
183_(__bound_alloca):
184 mv a1, a0
185 sub sp, sp, a0
186 addi sp, sp, -16
187 andi sp, sp, -16
188 add a0, sp, zero
189 addi sp,sp,-16
190 sd s0,0(sp)
191 sd ra,8(sp)
192 jal _(__bound_new_region)
193 ld s0,0(sp)
194 ld ra,8(sp)
195 addi sp,sp,16
196 add a0, sp, zero
197 ret
198
95/* ---------------------------------------------- */199/* ---------------------------------------------- */
96#endif200#endif
lib/alloca.S+15−26
@@ -70,25 +70,18 @@ p3: · 69 unmodified lines
70/* ---------------------------------------------- */70/* ---------------------------------------------- */
71#elif defined __arm__71#elif defined __arm__
72 72
73 .text73.globl _(alloca)
74 .align 274_(alloca):
75 .global alloca
76 .type alloca, %function
77alloca:
78 rsb sp, r0, sp75 rsb sp, r0, sp
79 bic sp, sp, #776 bic sp, sp, #7
80 mov r0, sp77 mov r0, sp
81 mov pc, lr78 mov pc, lr
82 .size alloca, .-alloca
83 79
84/* ---------------------------------------------- */80/* ---------------------------------------------- */
85#elif defined __aarch64__ || defined __arm64__81#elif defined __aarch64__ || defined __arm64__
86 82
87 .text83.globl _(alloca)
88 .align 284_(alloca):
89 .global alloca
90 .type alloca, %function
91alloca:
92#ifdef __TINYC__85#ifdef __TINYC__
93 .int 0x91003c0086 .int 0x91003c00
94 .int 0x927cec0087 .int 0x927cec00
@@ -102,16 +95,16 @@ alloca: · 7 unmodified lines
102 .int 0xcb2163ff95 .int 0xcb2163ff
103 .int 0xcb01000096 .int 0xcb010000
104 .int 0x17fffffa97 .int 0x17fffffa
105#endif
106 .int 0xb400004098 .int 0xb4000040
99#endif
107 .int 0xcb2063ff100 .int 0xcb2063ff
108 .int 0x910003e0101 .int 0x910003e0
109 .int 0xd65f03c0102 .int 0xd65f03c0
110#else103#else
111 add x0, x0, #15 // Round up to 16-byte boundary104 add x0, x0, #15 // Round up to 16-byte boundary
112 and x0, x0, #-16 // Ensure 16-byte alignment105 and x0, x0, #-16 // Ensure 16-byte alignment
113 cbz x0, p100 // If size is 0, skip to return
114#ifdef _WIN32106#ifdef _WIN32
107 cbz x0, p100 // If size is 0, skip to return
115 // Windows requires page-wise allocation with stack probing108 // Windows requires page-wise allocation with stack probing
116 mov x1, #4096 // Page size = 4096 bytes109 mov x1, #4096 // Page size = 4096 bytes
117 110
@@ -140,20 +133,16 @@ p100: · 22 unmodified lines
140 mov x0, sp // Return allocated address133 mov x0, sp // Return allocated address
141 ret // Return to caller134 ret // Return to caller
142#endif135#endif
143 .size alloca, .-alloca136
144/* ---------------------------------------------- */137/* ---------------------------------------------- */
145#elif defined __riscv138#elif defined __riscv
146 139
147 .text140.globl _(alloca)
148 .align 2141_(alloca):
149 .global alloca142 sub sp, sp, a0
150 .type alloca, %function143 addi sp, sp, -15
151alloca:144 andi sp, sp, -16
152 sub sp, sp, a0145 add a0, sp, zero
153 addi sp, sp, -15146 ret
154 andi sp, sp, -16147
155 add a0, sp, zero
156 ret
157 .size alloca, .-alloca
158/* ---------------------------------------------- */
159#endif148#endif
libtcc.c+1−1
@@ -40,7 +40,7 @@ · 39 unmodified lines
40#elif defined(TCC_TARGET_ARM64)40#elif defined(TCC_TARGET_ARM64)
41#include "arm64-gen.c"41#include "arm64-gen.c"
42#include "arm64-link.c"42#include "arm64-link.c"
43#include "arm-asm.c"43#include "arm64-asm.c"
44#elif defined(TCC_TARGET_C67)44#elif defined(TCC_TARGET_C67)
45#include "c67-gen.c"45#include "c67-gen.c"
46#include "c67-link.c"46#include "c67-link.c"
tcc.h+1−1
@@ -385,7 +385,7 @@ extern long double strtold (const char *__nptr, char **__endptr); · 384 unmodified lines
385#elif defined TCC_TARGET_ARM64385#elif defined TCC_TARGET_ARM64
386# include "arm64-gen.c"386# include "arm64-gen.c"
387# include "arm64-link.c"387# include "arm64-link.c"
388# include "arm-asm.c"388# include "arm64-asm.c"
389#elif defined TCC_TARGET_C67389#elif defined TCC_TARGET_C67
390# define TCC_TARGET_COFF390# define TCC_TARGET_COFF
391# include "coff.h"391# include "coff.h"
tccasm.c+17−0
@@ -984,6 +984,23 @@ static void asm_parse_directive(TCCState *s1, int global) · 983 unmodified lines
984 skip('@');984 skip('@');
985 next();985 next();
986 break;986 break;
987 case TOK_ASMDIR_reloc:
988 {
989 ExprValue e;
990
991 next();
992 asm_expr(s1, &e);
993 skip(',');
994#ifdef __aarch64__
995 if (strcmp(get_tok_str(tok, NULL), "R_AARCH64_CALL26"))
996#endif
997 tcc_error("unimp: reloc '%s' unknown", get_tok_str(tok, NULL));
998 next();
999 skip(',');
1000 greloca(cur_text_section, get_asm_sym(tok, NULL), e.v, R_AARCH64_CALL26, 0);
1001 next();
1002 }
1003 break;
987 default:1004 default:
988 tcc_error("unknown assembler directive '.%s'", get_tok_str(tok, NULL));1005 tcc_error("unknown assembler directive '.%s'", get_tok_str(tok, NULL));
989 break;1006 break;
tccgen.c+0−2
@@ -1701,10 +1701,8 @@ ST_FUNC void gbound_args(int nb_args) · 1700 unmodified lines
1701 gfunc_call(1);1701 gfunc_call(1);
1702 func_bound_add_epilog = 1;1702 func_bound_add_epilog = 1;
1703 }1703 }
1704#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
1705 if (v == TOK_alloca)1704 if (v == TOK_alloca)
1706 func_bound_add_epilog = 1;1705 func_bound_add_epilog = 1;
1707#endif
1708#if TARGETOS_NetBSD1706#if TARGETOS_NetBSD
1709 if (v == TOK_longjmp) /* undo rename to __longjmp14 */1707 if (v == TOK_longjmp) /* undo rename to __longjmp14 */
1710 sv->sym->asm_label = TOK___bound_longjmp;1708 sv->sym->asm_label = TOK___bound_longjmp;
tcctok.h+1−2
@@ -301,9 +301,7 @@ · 300 unmodified lines
301 DEF(TOK___fixxfdi, "__fixxfdi")301 DEF(TOK___fixxfdi, "__fixxfdi")
302#endif302#endif
303 303
304#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
305 DEF(TOK_alloca, "alloca")304 DEF(TOK_alloca, "alloca")
306#endif
307 305
308#if defined TCC_TARGET_PE306#if defined TCC_TARGET_PE
309 DEF(TOK___chkstk, "__chkstk")307 DEF(TOK___chkstk, "__chkstk")
@@ -415,6 +413,7 @@ · 105 unmodified lines
415 DEF_ASMDIR(long)413 DEF_ASMDIR(long)
416 DEF_ASMDIR(int)414 DEF_ASMDIR(int)
417 DEF_ASMDIR(symver)415 DEF_ASMDIR(symver)
416 DEF_ASMDIR(reloc)
418 DEF_ASMDIR(section) /* must be last directive */417 DEF_ASMDIR(section) /* must be last directive */
419 418
420#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64419#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
tests/boundtest.c+0−14
@@ -169,14 +169,6 @@ int test13(void) · 168 unmodified lines
169 return strlen(tab);169 return strlen(tab);
170}170}
171 171
172#if defined __i386__ || defined __x86_64__
173#define allocf(x)
174#else
175#undef alloca
176#define alloca(x) malloc(x)
177#define allocf(x) free(x)
178#endif
179
180int test14(void)172int test14(void)
181{173{
182 char *p = alloca(TAB_SIZE);174 char *p = alloca(TAB_SIZE);
@@ -184,7 +176,6 @@ int test14(void) · 1 unmodified line
184 memset(p, 'a', TAB_SIZE);176 memset(p, 'a', TAB_SIZE);
185 p[TAB_SIZE-1] = 0;177 p[TAB_SIZE-1] = 0;
186 ret = strlen(p);178 ret = strlen(p);
187 allocf(p);
188 return ret;179 return ret;
189}180}
190 181
@@ -196,7 +187,6 @@ int test15(void) · 5 unmodified lines
196 memset(p, 'a', TAB_SIZE);187 memset(p, 'a', TAB_SIZE);
197 p[TAB_SIZE-1] = 0;188 p[TAB_SIZE-1] = 0;
198 ret = strlen(p);189 ret = strlen(p);
199 allocf(p);
200 return ret;190 return ret;
201}191}
202 192
@@ -211,8 +201,6 @@ int test16() · 8 unmodified lines
211 201
212 /* Test alloca embedded in a larger expression */202 /* Test alloca embedded in a larger expression */
213 printf("alloca : %s : %s\n", p, strcpy(q=alloca(strlen(demo)+1),demo) );203 printf("alloca : %s : %s\n", p, strcpy(q=alloca(strlen(demo)+1),demo) );
214 allocf(p);
215 allocf(q);
216 204
217 return 0;205 return 0;
218}206}
@@ -228,8 +216,6 @@ int test17() · 9 unmodified lines
228 216
229 /* Test alloca embedded in a larger expression */217 /* Test alloca embedded in a larger expression */
230 printf("alloca : %s : %s\n", p, strcpy(q=alloca(strlen(demo)),demo) );218 printf("alloca : %s : %s\n", p, strcpy(q=alloca(strlen(demo)),demo) );
231 allocf(p);
232 allocf(q);
233 219
234 return 0;220 return 0;
235}221}
tests/tcctest.c+0−4
@@ -2941,14 +2941,12 @@ void old_style_function_test(void) · 2940 unmodified lines
2941 2941
2942void alloca_test()2942void alloca_test()
2943{2943{
2944#if defined __i386__ || defined __x86_64__ || defined __arm__
2945 char *p = alloca(16);2944 char *p = alloca(16);
2946 strcpy(p,"123456789012345");2945 strcpy(p,"123456789012345");
2947 printf("alloca: p is %s\n", p);2946 printf("alloca: p is %s\n", p);
2948 char *demo = "This is only a test.\n";2947 char *demo = "This is only a test.\n";
2949 /* Test alloca embedded in a larger expression */2948 /* Test alloca embedded in a larger expression */
2950 printf("alloca: %s\n", strcpy(alloca(strlen(demo)+1),demo) );2949 printf("alloca: %s\n", strcpy(alloca(strlen(demo)+1),demo) );
2951#endif
2952}2950}
2953 2951
2954void *bounds_checking_is_enabled()2952void *bounds_checking_is_enabled()
@@ -4208,7 +4206,6 @@ double get100 () { return 100.0; } · 1253 unmodified lines
4208 4206
4209void callsave_test(void)4207void callsave_test(void)
4210{4208{
4211#if defined __i386__ || defined __x86_64__ || defined __arm__
4212 int i, s; double *d; double t;4209 int i, s; double *d; double t;
4213 s = sizeof (double);4210 s = sizeof (double);
4214 printf ("callsavetest: %d\n", s);4211 printf ("callsavetest: %d\n", s);
@@ -4221,7 +4218,6 @@ void callsave_test(void) · 6 unmodified lines
4221 generates a segfault. */4218 generates a segfault. */
4222 i = d[0] > get100 ();4219 i = d[0] > get100 ();
4223 printf ("%d\n", i);4220 printf ("%d\n", i);
4224#endif
4225}4221}
4226 4222
4227 4223

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t