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)
Unified · Split
| @@ -19,9 +19,7 @@ typedef union { long long __ll; long double __ld; } max_align_t; · 18 unmodified lines | ||
| 19 | 19 | #undef offsetof |
| 20 | 20 | #define offsetof(type, field) __builtin_offsetof(type, field) |
| 21 | 21 | |
| 22 | −#if defined __i386__ || defined __x86_64__ | |
| 23 | 22 | void *alloca(size_t size); |
| 24 | −#endif | |
| 25 | 23 | |
| 26 | 24 | #endif |
| 27 | 25 | |
| @@ -347,12 +347,8 @@ · 346 unmodified lines | ||
| 347 | 347 | __MAYBE_REDIR(void*, calloc, (__SIZE_TYPE__, __SIZE_TYPE__)) |
| 348 | 348 | __MAYBE_REDIR(void*, memalign, (__SIZE_TYPE__, __SIZE_TYPE__)) |
| 349 | 349 | __MAYBE_REDIR(void, free, (void*)) |
| 350 | −#if defined __i386__ || defined __x86_64__ | |
| 351 | 350 | __BOTH(void*, alloca, (__SIZE_TYPE__)) |
| 352 | 351 | void *alloca(__SIZE_TYPE__); |
| 353 | −#else | |
| 354 | − __BUILTIN(void*, alloca, (__SIZE_TYPE__)) | |
| 355 | −#endif | |
| 356 | 352 | __BUILTIN(void, abort, (void)) |
| 357 | 353 | __BOUND(void, longjmp, ()) |
| 358 | 354 | #if !defined _WIN32 |
| @@ -35,12 +35,12 @@ endif · 34 unmodified lines | ||
| 35 | 35 | |
| 36 | 36 | XFLAGS += -I$(TOP) |
| 37 | 37 | |
| 38 | −I386_O = libtcc1.o alloca-bt.o $(COMMON_O) | |
| 39 | −X86_64_O = libtcc1.o alloca-bt.o $(COMMON_O) | |
| 38 | +I386_O = libtcc1.o $(COMMON_O) | |
| 39 | +X86_64_O = libtcc1.o $(COMMON_O) | |
| 40 | 40 | ARM_O = libtcc1.o armeabi.o armflush.o $(COMMON_O) |
| 41 | 41 | ARM64_O = lib-arm64.o $(COMMON_O) |
| 42 | 42 | RISCV64_O = lib-arm64.o $(COMMON_O) |
| 43 | −COMMON_O = stdatomic.o atomic.o builtin.o alloca.o | |
| 43 | +COMMON_O = stdatomic.o atomic.o builtin.o alloca.o alloca-bt.o | |
| 44 | 44 | WIN_O = crt1.o crt1w.o wincrt1.o wincrt1w.o dllcrt1.o dllmain.o |
| 45 | 45 | LIN_O = dsohandle.o |
| 46 | 46 | OSX_O = |
| @@ -92,5 +92,109 @@ p3: · 91 unmodified lines | ||
| 92 | 92 | ret |
| 93 | 93 | #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 | + | |
| 149 | +p101: | |
| 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 | + | |
| 161 | +p102: | |
| 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 | + | |
| 170 | +p100: | |
| 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 | 200 | #endif |
| @@ -70,25 +70,18 @@ p3: · 69 unmodified lines | ||
| 70 | 70 | /* ---------------------------------------------- */ |
| 71 | 71 | #elif defined __arm__ |
| 72 | 72 | |
| 73 | − .text | |
| 74 | − .align 2 | |
| 75 | − .global alloca | |
| 76 | − .type alloca, %function | |
| 77 | −alloca: | |
| 73 | +.globl _(alloca) | |
| 74 | +_(alloca): | |
| 78 | 75 | rsb sp, r0, sp |
| 79 | 76 | bic sp, sp, #7 |
| 80 | 77 | mov r0, sp |
| 81 | 78 | mov pc, lr |
| 82 | − .size alloca, .-alloca | |
| 83 | 79 | |
| 84 | 80 | /* ---------------------------------------------- */ |
| 85 | 81 | #elif defined __aarch64__ || defined __arm64__ |
| 86 | 82 | |
| 87 | − .text | |
| 88 | − .align 2 | |
| 89 | − .global alloca | |
| 90 | − .type alloca, %function | |
| 91 | −alloca: | |
| 83 | +.globl _(alloca) | |
| 84 | +_(alloca): | |
| 92 | 85 | #ifdef __TINYC__ |
| 93 | 86 | .int 0x91003c00 |
| 94 | 87 | .int 0x927cec00 |
| @@ -102,16 +95,16 @@ alloca: · 7 unmodified lines | ||
| 102 | 95 | .int 0xcb2163ff |
| 103 | 96 | .int 0xcb010000 |
| 104 | 97 | .int 0x17fffffa |
| 105 | −#endif | |
| 106 | 98 | .int 0xb4000040 |
| 99 | +#endif | |
| 107 | 100 | .int 0xcb2063ff |
| 108 | 101 | .int 0x910003e0 |
| 109 | 102 | .int 0xd65f03c0 |
| 110 | 103 | #else |
| 111 | 104 | add x0, x0, #15 // Round up to 16-byte boundary |
| 112 | 105 | and x0, x0, #-16 // Ensure 16-byte alignment |
| 113 | − cbz x0, p100 // If size is 0, skip to return | |
| 114 | 106 | #ifdef _WIN32 |
| 107 | + cbz x0, p100 // If size is 0, skip to return | |
| 115 | 108 | // Windows requires page-wise allocation with stack probing |
| 116 | 109 | mov x1, #4096 // Page size = 4096 bytes |
| 117 | 110 | |
| @@ -140,20 +133,16 @@ p100: · 22 unmodified lines | ||
| 140 | 133 | mov x0, sp // Return allocated address |
| 141 | 134 | ret // Return to caller |
| 142 | 135 | #endif |
| 143 | − .size alloca, .-alloca | |
| 136 | + | |
| 144 | 137 | /* ---------------------------------------------- */ |
| 145 | 138 | #elif defined __riscv |
| 146 | 139 | |
| 147 | − .text | |
| 148 | − .align 2 | |
| 149 | − .global alloca | |
| 150 | − .type alloca, %function | |
| 151 | −alloca: | |
| 152 | − sub sp, sp, a0 | |
| 153 | − addi sp, sp, -15 | |
| 154 | − andi sp, sp, -16 | |
| 155 | − add a0, sp, zero | |
| 156 | − ret | |
| 157 | − .size alloca, .-alloca | |
| 158 | −/* ---------------------------------------------- */ | |
| 140 | +.globl _(alloca) | |
| 141 | +_(alloca): | |
| 142 | + sub sp, sp, a0 | |
| 143 | + addi sp, sp, -15 | |
| 144 | + andi sp, sp, -16 | |
| 145 | + add a0, sp, zero | |
| 146 | + ret | |
| 147 | + | |
| 159 | 148 | #endif |
| @@ -40,7 +40,7 @@ · 39 unmodified lines | ||
| 40 | 40 | #elif defined(TCC_TARGET_ARM64) |
| 41 | 41 | #include "arm64-gen.c" |
| 42 | 42 | #include "arm64-link.c" |
| 43 | −#include "arm-asm.c" | |
| 43 | +#include "arm64-asm.c" | |
| 44 | 44 | #elif defined(TCC_TARGET_C67) |
| 45 | 45 | #include "c67-gen.c" |
| 46 | 46 | #include "c67-link.c" |
| @@ -385,7 +385,7 @@ extern long double strtold (const char *__nptr, char **__endptr); · 384 unmodified lines | ||
| 385 | 385 | #elif defined TCC_TARGET_ARM64 |
| 386 | 386 | # include "arm64-gen.c" |
| 387 | 387 | # include "arm64-link.c" |
| 388 | −# include "arm-asm.c" | |
| 388 | +# include "arm64-asm.c" | |
| 389 | 389 | #elif defined TCC_TARGET_C67 |
| 390 | 390 | # define TCC_TARGET_COFF |
| 391 | 391 | # include "coff.h" |
| @@ -984,6 +984,23 @@ static void asm_parse_directive(TCCState *s1, int global) · 983 unmodified lines | ||
| 984 | 984 | skip('@'); |
| 985 | 985 | next(); |
| 986 | 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 | 1004 | default: |
| 988 | 1005 | tcc_error("unknown assembler directive '.%s'", get_tok_str(tok, NULL)); |
| 989 | 1006 | break; |
| @@ -1701,10 +1701,8 @@ ST_FUNC void gbound_args(int nb_args) · 1700 unmodified lines | ||
| 1701 | 1701 | gfunc_call(1); |
| 1702 | 1702 | func_bound_add_epilog = 1; |
| 1703 | 1703 | } |
| 1704 | −#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 | |
| 1705 | 1704 | if (v == TOK_alloca) |
| 1706 | 1705 | func_bound_add_epilog = 1; |
| 1707 | −#endif | |
| 1708 | 1706 | #if TARGETOS_NetBSD |
| 1709 | 1707 | if (v == TOK_longjmp) /* undo rename to __longjmp14 */ |
| 1710 | 1708 | sv->sym->asm_label = TOK___bound_longjmp; |
| @@ -301,9 +301,7 @@ · 300 unmodified lines | ||
| 301 | 301 | DEF(TOK___fixxfdi, "__fixxfdi") |
| 302 | 302 | #endif |
| 303 | 303 | |
| 304 | −#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 | |
| 305 | 304 | DEF(TOK_alloca, "alloca") |
| 306 | −#endif | |
| 307 | 305 | |
| 308 | 306 | #if defined TCC_TARGET_PE |
| 309 | 307 | DEF(TOK___chkstk, "__chkstk") |
| @@ -415,6 +413,7 @@ · 105 unmodified lines | ||
| 415 | 413 | DEF_ASMDIR(long) |
| 416 | 414 | DEF_ASMDIR(int) |
| 417 | 415 | DEF_ASMDIR(symver) |
| 416 | + DEF_ASMDIR(reloc) | |
| 418 | 417 | DEF_ASMDIR(section) /* must be last directive */ |
| 419 | 418 | |
| 420 | 419 | #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 |
| @@ -169,14 +169,6 @@ int test13(void) · 168 unmodified lines | ||
| 169 | 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 | − | |
| 180 | 172 | int test14(void) |
| 181 | 173 | { |
| 182 | 174 | char *p = alloca(TAB_SIZE); |
| @@ -184,7 +176,6 @@ int test14(void) · 1 unmodified line | ||
| 184 | 176 | memset(p, 'a', TAB_SIZE); |
| 185 | 177 | p[TAB_SIZE-1] = 0; |
| 186 | 178 | ret = strlen(p); |
| 187 | − allocf(p); | |
| 188 | 179 | return ret; |
| 189 | 180 | } |
| 190 | 181 | |
| @@ -196,7 +187,6 @@ int test15(void) · 5 unmodified lines | ||
| 196 | 187 | memset(p, 'a', TAB_SIZE); |
| 197 | 188 | p[TAB_SIZE-1] = 0; |
| 198 | 189 | ret = strlen(p); |
| 199 | − allocf(p); | |
| 200 | 190 | return ret; |
| 201 | 191 | } |
| 202 | 192 | |
| @@ -211,8 +201,6 @@ int test16() · 8 unmodified lines | ||
| 211 | 201 | |
| 212 | 202 | /* Test alloca embedded in a larger expression */ |
| 213 | 203 | printf("alloca : %s : %s\n", p, strcpy(q=alloca(strlen(demo)+1),demo) ); |
| 214 | − allocf(p); | |
| 215 | − allocf(q); | |
| 216 | 204 | |
| 217 | 205 | return 0; |
| 218 | 206 | } |
| @@ -228,8 +216,6 @@ int test17() · 9 unmodified lines | ||
| 228 | 216 | |
| 229 | 217 | /* Test alloca embedded in a larger expression */ |
| 230 | 218 | printf("alloca : %s : %s\n", p, strcpy(q=alloca(strlen(demo)),demo) ); |
| 231 | − allocf(p); | |
| 232 | − allocf(q); | |
| 233 | 219 | |
| 234 | 220 | return 0; |
| 235 | 221 | } |
| @@ -2941,14 +2941,12 @@ void old_style_function_test(void) · 2940 unmodified lines | ||
| 2941 | 2941 | |
| 2942 | 2942 | void alloca_test() |
| 2943 | 2943 | { |
| 2944 | −#if defined __i386__ || defined __x86_64__ || defined __arm__ | |
| 2945 | 2944 | char *p = alloca(16); |
| 2946 | 2945 | strcpy(p,"123456789012345"); |
| 2947 | 2946 | printf("alloca: p is %s\n", p); |
| 2948 | 2947 | char *demo = "This is only a test.\n"; |
| 2949 | 2948 | /* Test alloca embedded in a larger expression */ |
| 2950 | 2949 | printf("alloca: %s\n", strcpy(alloca(strlen(demo)+1),demo) ); |
| 2951 | −#endif | |
| 2952 | 2950 | } |
| 2953 | 2951 | |
| 2954 | 2952 | void *bounds_checking_is_enabled() |
| @@ -4208,7 +4206,6 @@ double get100 () { return 100.0; } · 1253 unmodified lines | ||
| 4208 | 4206 | |
| 4209 | 4207 | void callsave_test(void) |
| 4210 | 4208 | { |
| 4211 | −#if defined __i386__ || defined __x86_64__ || defined __arm__ | |
| 4212 | 4209 | int i, s; double *d; double t; |
| 4213 | 4210 | s = sizeof (double); |
| 4214 | 4211 | printf ("callsavetest: %d\n", s); |
| @@ -4221,7 +4218,6 @@ void callsave_test(void) · 6 unmodified lines | ||
| 4221 | 4218 | generates a segfault. */ |
| 4222 | 4219 | i = d[0] > get100 (); |
| 4223 | 4220 | printf ("%d\n", i); |
| 4224 | −#endif | |
| 4225 | 4221 | } |
| 4226 | 4222 | |
| 4227 | 4223 | |