History

Add support for apple m1

The apple m1 uses position independent executables (pie). I have implemented this in tccmacho.c Apple also uses the stack different for var_args. Also characters are signed instead of unsigned. This is implemented in arm64-gen.c/tccdefs.h Add bounds checking lib to lib/Makefile. Add underscore support in lib/atomic.S and lib/fetch_and_add.S Disable __clear_cache in lib/lib-arm64.c (Use system version). I will try to fix this in future push. Disable test_asm_call in tests/tcctest.c. Clang does not support @plt. Also disable weak symbols test. I will try to fix weak support in future push. Disable tests/tests2/124_atomic_counter.c for 64BITS. This is a bug in the atomic code and will be fixed in future push. You have to use --dwarf configure option. stabs only works with -run. tested on apple x86_64(10.5) and arm64(12.3).

herman ten brugge committed 3 years ago

Commit c8ef84c1 parent c6b722f10 files · +736 −129Browse files

Unified · Split

10 files
  1. arm64-gen.c +42 −10
  2. include/tccdefs.h +7 −0
  3. lib/Makefile +1 −1
  4. lib/atomic.S +51 −44
  5. lib/fetch_and_add.S +22 −13
  6. lib/lib-arm64.c +1 −1
  7. tccelf.c +1 −1
  8. tccmacho.c +606 −54
  9. tests/tcctest.c +3 −5
  10. tests/tests2/124_atomic_counter.c +2 −0
arm64-gen.c+42−10
@@ -38,7 +38,9 @@ · 37 unmodified lines
3838
3939 #define MAX_ALIGN 16
4040
41+#ifndef TCC_TARGET_MACHO
4142 #define CHAR_IS_UNSIGNED
43+#endif
4244
4345 /* define if return values need to be extended explicitely
4446 at caller side (for interfacing with non-TCC compilers) */
@@ -810,7 +812,7 @@ static int arm64_hfa(CType *type, unsigned *fsize) · 765 unmodified lines
810812 return 0;
811813 }
812814
813−static unsigned long arm64_pcs_aux(int n, CType **type, unsigned long *a)
815+static unsigned long arm64_pcs_aux(int variadic, int n, CType **type, unsigned long *a)
814816 {
815817 int nx = 0; // next integer register
816818 int nv = 0; // next vector register
@@ -827,6 +829,12 @@ static unsigned long arm64_pcs_aux(int n, CType **type, unsigned long *a) · 10 unmodified lines
827829 else
828830 size = type_size(type[i], &align);
829831
832+#if defined(__APPLE__)
833+ if (variadic && i == variadic) {
834+ nx = 8;
835+ nv = 8;
836+ }
837+#endif
830838 if (hfa)
831839 // B.2
832840 ;
@@ -931,7 +939,7 @@ static unsigned long arm64_pcs_aux(int n, CType **type, unsigned long *a) · 98 unmodified lines
931939 return ns - 32;
932940 }
933941
934−static unsigned long arm64_pcs(int n, CType **type, unsigned long *a)
942+static unsigned long arm64_pcs(int variadic, int n, CType **type, unsigned long *a)
935943 {
936944 unsigned long stack;
937945
@@ -939,12 +947,12 @@ static unsigned long arm64_pcs(int n, CType **type, unsigned long *a) · 1 unmodified line
939947 if ((type[0]->t & VT_BTYPE) == VT_VOID)
940948 a[0] = -1;
941949 else {
942− arm64_pcs_aux(1, type, a);
950+ arm64_pcs_aux(0, 1, type, a);
943951 assert(a[0] == 0 || a[0] == 1 || a[0] == 16);
944952 }
945953
946954 // Argument types:
947− stack = arm64_pcs_aux(n, type + 1, a + 1);
955+ stack = arm64_pcs_aux(variadic, n, type + 1, a + 1);
948956
949957 if (0) {
950958 int i;
@@ -970,6 +978,16 @@ static unsigned long arm64_pcs(int n, CType **type, unsigned long *a) · 19 unmodified lines
970978 return stack;
971979 }
972980
981+static int n_func_args(CType *type)
982+{
983+ int n_args = 0;
984+ Sym *arg;
985+
986+ for (arg = type->ref->next; arg; arg = arg->next)
987+ n_args++;
988+ return n_args;
989+}
990+
973991 ST_FUNC void gfunc_call(int nb_args)
974992 {
975993 CType *return_type;
@@ -977,6 +995,8 @@ ST_FUNC void gfunc_call(int nb_args) · 1 unmodified line
977995 unsigned long *a, *a1;
978996 unsigned long stack;
979997 int i;
998+ int variadic = (vtop[-nb_args].type.ref->f.func_type == FUNC_ELLIPSIS);
999+ int var_nb_arg = n_func_args(&vtop[-nb_args].type);
9801000
9811001 #ifdef CONFIG_TCC_BCHECK
9821002 if (tcc_state->do_bounds_check)
@@ -995,7 +1015,7 @@ ST_FUNC void gfunc_call(int nb_args) · 12 unmodified lines
9951015 for (i = 0; i < nb_args; i++)
9961016 t[nb_args - i] = &vtop[-i].type;
9971017
998− stack = arm64_pcs(nb_args, t, a);
1018+ stack = arm64_pcs(variadic ? var_nb_arg : 0, nb_args, t, a);
9991019
10001020 // Allocate space for structs replaced by pointer:
10011021 for (i = nb_args; i; i--)
@@ -1055,7 +1075,7 @@ ST_FUNC void gfunc_call(int nb_args) · 53 unmodified lines
10551075 }
10561076 else {
10571077 gv(RC_INT);
1058− arm64_strx(arm64_type_size(vtop[0].type.t),
1078+ arm64_strx(3, // arm64_type_size(vtop[0].type.t),
10591079 intr(vtop[0].r), 31, a[i] - 32);
10601080 }
10611081 }
@@ -1167,6 +1187,8 @@ ST_FUNC void gfunc_prolog(Sym *func_sym) · 105 unmodified lines
11671187 int use_x8 = 0;
11681188 int last_int = 0;
11691189 int last_float = 0;
1190+ int variadic = func_sym->type.ref->f.func_type == FUNC_ELLIPSIS;
1191+ int var_nb_arg = n_func_args(&func_sym->type);
11701192
11711193 func_vc = 144; // offset of where x8 is stored
11721194
@@ -1178,9 +1200,9 @@ ST_FUNC void gfunc_prolog(Sym *func_sym) · 5 unmodified lines
11781200 for (sym = func_type->ref; sym; sym = sym->next)
11791201 t[i++] = &sym->type;
11801202
1181− arm64_func_va_list_stack = arm64_pcs(n - 1, t, a);
1203+ arm64_func_va_list_stack = arm64_pcs(variadic ? var_nb_arg : 0, n - 1, t, a);
11821204
1183− if (func_sym->type.ref->f.func_type == FUNC_ELLIPSIS) {
1205+ if (variadic) {
11841206 use_x8 = 1;
11851207 last_int = 4;
11861208 last_float = 4;
@@ -1282,6 +1304,7 @@ ST_FUNC void gen_va_start(void) · 95 unmodified lines
12821304 o(0x910383be); // add x30,x29,#224
12831305 o(0xf900001e | r << 5); // str x30,[x(r)]
12841306
1307+#if !defined(__APPLE__)
12851308 if (arm64_func_va_list_gr_offs) {
12861309 if (arm64_func_va_list_stack)
12871310 o(0x910383be); // add x30,x29,#224
@@ -1298,6 +1321,7 @@ ST_FUNC void gen_va_start(void) · 10 unmodified lines
12981321
12991322 arm64_movimm(30, arm64_func_va_list_vr_offs);
13001323 o(0xb9001c1e | r << 5); // str w30,[x(r),#28]
1324+#endif
13011325
13021326 --vtop;
13031327 }
@@ -1321,6 +1345,7 @@ ST_FUNC void gen_va_arg(CType *t) · 17 unmodified lines
13211345
13221346 if (!hfa) {
13231347 uint32_t n = size > 16 ? 8 : (size + 7) & -8;
1348+#if !defined(__APPLE__)
13241349 o(0xb940181e | r0 << 5); // ldr w30,[x(r0),#24] // __gr_offs
13251350 if (align == 16) {
13261351 assert(0); // this path untested but needed for __uint128_t
@@ -1329,23 +1354,28 @@ ST_FUNC void gen_va_arg(CType *t) · 2 unmodified lines
13291354 }
13301355 o(0x310003c0 | r1 | n << 10); // adds w(r1),w30,#(n)
13311356 o(0x540000ad); // b.le .+20
1357+#endif
13321358 o(0xf9400000 | r1 | r0 << 5); // ldr x(r1),[x(r0)] // __stack
13331359 o(0x9100001e | r1 << 5 | n << 10); // add x30,x(r1),#(n)
13341360 o(0xf900001e | r0 << 5); // str x30,[x(r0)] // __stack
1361+#if !defined(__APPLE__)
13351362 o(0x14000004); // b .+16
13361363 o(0xb9001800 | r1 | r0 << 5); // str w(r1),[x(r0),#24] // __gr_offs
13371364 o(0xf9400400 | r1 | r0 << 5); // ldr x(r1),[x(r0),#8] // __gr_top
13381365 o(0x8b3ec000 | r1 | r1 << 5); // add x(r1),x(r1),w30,sxtw
1366+#endif
13391367 if (size > 16)
13401368 o(0xf9400000 | r1 | r1 << 5); // ldr x(r1),[x(r1)]
13411369 }
13421370 else {
1343− uint32_t rsz = hfa << 4;
13441371 uint32_t ssz = (size + 7) & -(uint32_t)8;
1372+#if !defined(__APPLE__)
1373+ uint32_t rsz = hfa << 4;
13451374 uint32_t b1, b2;
13461375 o(0xb9401c1e | r0 << 5); // ldr w30,[x(r0),#28] // __vr_offs
13471376 o(0x310003c0 | r1 | rsz << 10); // adds w(r1),w30,#(rsz)
13481377 b1 = ind; o(0x5400000d); // b.le lab1
1378+#endif
13491379 o(0xf9400000 | r1 | r0 << 5); // ldr x(r1),[x(r0)] // __stack
13501380 if (fsize == 16) {
13511381 o(0x91003c00 | r1 | r1 << 5); // add x(r1),x(r1),#15
@@ -1353,6 +1383,7 @@ ST_FUNC void gen_va_arg(CType *t) · 1 unmodified line
13531383 }
13541384 o(0x9100001e | r1 << 5 | ssz << 10); // add x30,x(r1),#(ssz)
13551385 o(0xf900001e | r0 << 5); // str x30,[x(r0)] // __stack
1386+#if !defined(__APPLE__)
13561387 b2 = ind; o(0x14000000); // b lab2
13571388 // lab1:
13581389 write32le(cur_text_section->data + b1, 0x5400000d | (ind - b1) << 3);
@@ -1376,6 +1407,7 @@ ST_FUNC void gen_va_arg(CType *t) · 17 unmodified lines
13761407 }
13771408 // lab2:
13781409 write32le(cur_text_section->data + b2, 0x14000000 | (ind - b2) >> 2);
1410+#endif
13791411 }
13801412 }
13811413
@@ -1390,7 +1422,7 @@ ST_FUNC void gfunc_return(CType *func_type) · 8 unmodified lines
13901422 CType *t = func_type;
13911423 unsigned long a;
13921424
1393− arm64_pcs(0, &t, &a);
1425+ arm64_pcs(0, 0, &t, &a);
13941426 switch (a) {
13951427 case -1:
13961428 break;
include/tccdefs.h+7−0
@@ -207,11 +207,18 @@ · 206 unmodified lines
207207 &~3), *(type *)(ap - ((sizeof(type)+3)&~3)))
208208
209209 #elif defined __aarch64__
210+#if defined __APPLE__
211+ typedef struct {
212+ void *__stack;
213+ } __builtin_va_list;
214+
215+#else
210216 typedef struct {
211217 void *__stack, *__gr_top, *__vr_top;
212218 int __gr_offs, __vr_offs;
213219 } __builtin_va_list;
214220
221+#endif
215222 #elif defined __riscv
216223 typedef char *__builtin_va_list;
217224 #define __va_reg_size (__riscv_xlen >> 3)
lib/Makefile+1−1
@@ -55,7 +55,7 @@ OBJ-x86_64-osx = $(X86_64_O) va_list.o $(BCHECK_O) · 54 unmodified lines
5555 OBJ-i386-win32 = $(I386_O) chkstk.o $(B_O) $(WIN_O)
5656 OBJ-x86_64-win32 = $(X86_64_O) chkstk.o $(B_O) $(WIN_O)
5757 OBJ-arm64 = $(ARM64_O) $(BCHECK_O) $(DSO_O)
58−OBJ-arm64-osx = $(ARM64_O) va_list.o
58+OBJ-arm64-osx = $(ARM64_O) $(BCHECK_O)
5959 OBJ-arm = $(ARM_O) $(BCHECK_O) $(DSO_O)
6060 OBJ-arm-fpa = $(ARM_O) $(DSO_O)
6161 OBJ-arm-fpa-ld = $(ARM_O) $(DSO_O)
lib/atomic.S+51−44
@@ -5,6 +5,13 @@ · 4 unmodified lines
55 * __atomic_compare_exchange_4
66 * __atomic_compare_exchange_8
77 */
8+
9+#ifdef __leading_underscore
10+# define _(s) _##s
11+#else
12+# define _(s) s
13+#endif
14+
815 #if defined __arm__
916
1017 #ifndef __TINYC__
@@ -14,9 +21,9 @@ · 3 unmodified lines
1421 .text
1522 .align 2
1623
17− .global __atomic_compare_exchange_1
18− .type __atomic_compare_exchange_1, %function
19−__atomic_compare_exchange_1:
24+ .global _(__atomic_compare_exchange_1)
25+ .type _(__atomic_compare_exchange_1), %function
26+_(__atomic_compare_exchange_1):
2027 #ifdef __TINYC__
2128 .int 0xe52de004
2229 .int 0xe5d13000
@@ -50,11 +57,11 @@ __atomic_compare_exchange_1: · 27 unmodified lines
5057 strbne ip, [r1]
5158 ldr pc, [sp], #4
5259 #endif
53− .size __atomic_compare_exchange_1, .-__atomic_compare_exchange_1
60+ .size _(__atomic_compare_exchange_1), .-_(__atomic_compare_exchange_1)
5461
55− .global __atomic_compare_exchange_2
56− .type __atomic_compare_exchange_2, %function
57−__atomic_compare_exchange_2:
62+ .global _(__atomic_compare_exchange_2)
63+ .type _(__atomic_compare_exchange_2), %function
64+_(__atomic_compare_exchange_2):
5865 #ifdef __TINYC__
5966 .int 0xe52de004
6067 .int 0xe1d130b0
@@ -88,11 +95,11 @@ __atomic_compare_exchange_2: · 27 unmodified lines
8895 strhne ip, [r1]
8996 ldr pc, [sp], #4
9097 #endif
91− .size __atomic_compare_exchange_2, .-__atomic_compare_exchange_2
98+ .size _(__atomic_compare_exchange_2), .-_(__atomic_compare_exchange_2)
9299
93− .global __atomic_compare_exchange_4
94− .type __atomic_compare_exchange_4, %function
95−__atomic_compare_exchange_4:
100+ .global _(__atomic_compare_exchange_4)
101+ .type _(__atomic_compare_exchange_4), %function
102+_(__atomic_compare_exchange_4):
96103 #ifdef __TINYC__
97104 .int 0xe52de004
98105 .int 0xe5913000
@@ -126,7 +133,7 @@ __atomic_compare_exchange_4: · 27 unmodified lines
126133 strne ip, [r1]
127134 ldr pc, [sp], #4
128135 #endif
129− .size __atomic_compare_exchange_4, .-__atomic_compare_exchange_4
136+ .size _(__atomic_compare_exchange_4), .-_(__atomic_compare_exchange_4)
130137
131138 /* ---------------------------------------------- */
132139 #elif defined __aarch64__
@@ -134,9 +141,9 @@ __atomic_compare_exchange_4: · 1 unmodified line
134141 .text
135142 .align 2
136143
137− .global __atomic_compare_exchange_1
138− .type __atomic_compare_exchange_1, %function
139−__atomic_compare_exchange_1:
144+ .global _(__atomic_compare_exchange_1)
145+ .type _(__atomic_compare_exchange_1), %function
146+_(__atomic_compare_exchange_1):
140147 #ifdef __TINYC__
141148 .int 0xa9be7bfd
142149 .int 0x910003fd
@@ -187,11 +194,11 @@ __atomic_compare_exchange_1: · 44 unmodified lines
187194 ldp x29, x30, [sp], 32
188195 ret
189196 #endif
190− .size __atomic_compare_exchange_1, .-__atomic_compare_exchange_1
197+ .size _(__atomic_compare_exchange_1), .-_(__atomic_compare_exchange_1)
191198
192− .global __atomic_compare_exchange_2
193− .type __atomic_compare_exchange_2, %function
194−__atomic_compare_exchange_2:
199+ .global _(__atomic_compare_exchange_2)
200+ .type _(__atomic_compare_exchange_2), %function
201+_(__atomic_compare_exchange_2):
195202 #ifdef __TINYC__
196203 .int 0xa9be7bfd
197204 .int 0x910003fd
@@ -242,11 +249,11 @@ __atomic_compare_exchange_2: · 44 unmodified lines
242249 ldp x29, x30, [sp], 32
243250 ret
244251 #endif
245− .size __atomic_compare_exchange_2, .-__atomic_compare_exchange_2
252+ .size _(__atomic_compare_exchange_2), .-_(__atomic_compare_exchange_2)
246253
247− .global __atomic_compare_exchange_4
248− .type __atomic_compare_exchange_4, %function
249−__atomic_compare_exchange_4:
254+ .global _(__atomic_compare_exchange_4)
255+ .type _(__atomic_compare_exchange_4), %function
256+_(__atomic_compare_exchange_4):
250257 #ifdef __TINYC__
251258 .int 0xa9be7bfd
252259 .int 0x910003fd
@@ -297,11 +304,11 @@ __atomic_compare_exchange_4: · 44 unmodified lines
297304 ldp x29, x30, [sp], 32
298305 ret
299306 #endif
300− .size __atomic_compare_exchange_4, .-__atomic_compare_exchange_4
307+ .size _(__atomic_compare_exchange_4), .-_(__atomic_compare_exchange_4)
301308
302− .global __atomic_compare_exchange_8
303− .type __atomic_compare_exchange_8, %function
304−__atomic_compare_exchange_8:
309+ .global _(__atomic_compare_exchange_8)
310+ .type _(__atomic_compare_exchange_8), %function
311+_(__atomic_compare_exchange_8):
305312 #ifdef __TINYC__
306313 .int 0xa9be7bfd
307314 .int 0x910003fd
@@ -352,7 +359,7 @@ __atomic_compare_exchange_8: · 44 unmodified lines
352359 ldp x29, x30, [sp], 32
353360 ret
354361 #endif
355− .size __atomic_compare_exchange_8, .-__atomic_compare_exchange_8
362+ .size _(__atomic_compare_exchange_8), .-_(__atomic_compare_exchange_8)
356363
357364 /* ---------------------------------------------- */
358365 #elif defined __riscv
@@ -360,9 +367,9 @@ __atomic_compare_exchange_8: · 1 unmodified line
360367 .text
361368 .align 2
362369
363− .global __atomic_compare_exchange_1
364− .type __atomic_compare_exchange_1, %function
365−__atomic_compare_exchange_1:
370+ .global _(__atomic_compare_exchange_1)
371+ .type _(__atomic_compare_exchange_1), %function
372+_(__atomic_compare_exchange_1):
366373 #ifdef __TINYC__
367374 .short 0x1141
368375 .short 0x86ba
@@ -443,11 +450,11 @@ __atomic_compare_exchange_1: · 74 unmodified lines
443450 addi sp,sp,16
444451 jr ra
445452 #endif
446− .size __atomic_compare_exchange_1, .-__atomic_compare_exchange_1
453+ .size _(__atomic_compare_exchange_1), .-_(__atomic_compare_exchange_1)
447454
448− .global __atomic_compare_exchange_2
449− .type __atomic_compare_exchange_2, %function
450−__atomic_compare_exchange_2:
455+ .global _(__atomic_compare_exchange_2)
456+ .type _(__atomic_compare_exchange_2), %function
457+_(__atomic_compare_exchange_2):
451458 #ifdef __TINYC__
452459 .short 0x1141
453460 .short 0x86ba
@@ -530,11 +537,11 @@ __atomic_compare_exchange_2: · 76 unmodified lines
530537 addi sp,sp,16
531538 jr ra
532539 #endif
533− .size __atomic_compare_exchange_2, .-__atomic_compare_exchange_2
540+ .size _(__atomic_compare_exchange_2), .-_(__atomic_compare_exchange_2)
534541
535− .global __atomic_compare_exchange_4
536− .type __atomic_compare_exchange_4, %function
537−__atomic_compare_exchange_4:
542+ .global _(__atomic_compare_exchange_4)
543+ .type _(__atomic_compare_exchange_4), %function
544+_(__atomic_compare_exchange_4):
538545 #ifdef __TINYC__
539546 .short 0x419c
540547 .int 0x0f50000f
@@ -565,11 +572,11 @@ __atomic_compare_exchange_4: · 24 unmodified lines
565572 andi a0,a0,1
566573 ret
567574 #endif
568− .size __atomic_compare_exchange_4, .-__atomic_compare_exchange_4
575+ .size _(__atomic_compare_exchange_4), .-_(__atomic_compare_exchange_4)
569576
570− .global __atomic_compare_exchange_8
571− .type __atomic_compare_exchange_8, %function
572−__atomic_compare_exchange_8:
577+ .global _(__atomic_compare_exchange_8)
578+ .type _(__atomic_compare_exchange_8), %function
579+_(__atomic_compare_exchange_8):
573580 #ifdef __TINYC__
574581 .short 0x619c
575582 .int 0x0f50000f
@@ -600,7 +607,7 @@ __atomic_compare_exchange_8: · 24 unmodified lines
600607 andi a0,a0,1
601608 ret
602609 #endif
603− .size __atomic_compare_exchange_8, .-__atomic_compare_exchange_8
610+ .size _(__atomic_compare_exchange_8), .-_(__atomic_compare_exchange_8)
604611
605612 /* ---------------------------------------------- */
606613 #endif
lib/fetch_and_add.S+22−13
@@ -1,11 +1,20 @@
11 /* ---------------------------------------------- */
2+#ifdef __leading_underscore
3+# define _(s) _##s
4+#else
5+# define _(s) s
6+#endif
7+
8+.globl _(__bound_alloca)
9+_(__bound_alloca):
10+
211 #if defined __arm__
312
413 .text
514 .align 2
6− .global fetch_and_add_arm
7− .type fetch_and_add_arm, %function
8−fetch_and_add_arm:
15+ .global _(fetch_and_add_arm)
16+ .type _(fetch_and_add_arm), %function
17+_(fetch_and_add_arm):
918 mcr p15, #0, r0, c7, c10, #5
1019 .L0:
1120 ldrex r3, [r0]
@@ -15,16 +24,16 @@ fetch_and_add_arm: · 3 unmodified lines
1524 bne .L0
1625 mcr p15, #0, r0, c7, c10, #5
1726 bx lr
18− .size fetch_and_add_arm, .-fetch_and_add_arm
27+ .size _(fetch_and_add_arm), .-_(fetch_and_add_arm)
1928
2029 /* ---------------------------------------------- */
2130 #elif defined __aarch64__
2231
2332 .text
2433 .align 2
25− .global fetch_and_add_arm64
26− .type fetch_and_add_arm64, %function
27−fetch_and_add_arm64:
34+ .global _(fetch_and_add_arm64)
35+ .type _(fetch_and_add_arm64), %function
36+_(fetch_and_add_arm64):
2837 #ifdef __TINYC__
2938 .int 0x885f7c02
3039 .int 0x0b010042
@@ -36,21 +45,21 @@ fetch_and_add_arm64: · 5 unmodified lines
3645 ldxr w2, [x0]
3746 add w2, w2, w1
3847 stlxr w3, w2, [x0]
39− cbnz w3, fetch_and_add_arm64
48+ cbnz w3, _(fetch_and_add_arm64)
4049 dmb ish
4150 ret
4251 #endif
4352
44− .size fetch_and_add_arm64, .-fetch_and_add_arm64
53+ .size _(fetch_and_add_arm64), .-_(fetch_and_add_arm64)
4554
4655 /* ---------------------------------------------- */
4756 #elif defined __riscv
4857
4958 .text
5059 .align 2
51− .global fetch_and_add_riscv64
52− .type fetch_and_add_riscv64, %function
53−fetch_and_add_riscv64:
60+ .global _(fetch_and_add_riscv64)
61+ .type _(fetch_and_add_riscv64), %function
62+_(fetch_and_add_riscv64):
5463 #ifdef __TINYC__
5564 .int 0x0f50000f
5665 .int 0x004b5202f
@@ -61,7 +70,7 @@ fetch_and_add_riscv64: · 4 unmodified lines
6170 ret
6271 #endif
6372
64− .size fetch_and_add_riscv64, .-fetch_and_add_riscv64
73+ .size _(fetch_and_add_riscv64), .-_(fetch_and_add_riscv64)
6574
6675 /* ---------------------------------------------- */
6776 #endif
lib/lib-arm64.c+1−1
@@ -24,7 +24,7 @@ void *memcpy(void*,void*,__SIZE_TYPE__); · 23 unmodified lines
2424 #include <string.h>
2525 #endif
2626
27−#ifndef __riscv
27+#if !defined __riscv && !defined __APPLE__
2828 void __clear_cache(void *beg, void *end)
2929 {
3030 __arm64_clear_cache(beg, end);
tccelf.c+1−1
@@ -1487,7 +1487,7 @@ static void add_init_array_defines(TCCState *s1, const char *section_name) · 1486 unmodified lines
14871487 addr_t end_offset;
14881488 char buf[1024];
14891489 s = find_section_create(s1, section_name, 0);
1490− if (!s) {
1490+ if (!s || !(s->sh_flags & SHF_ALLOC)) {
14911491 end_offset = 0;
14921492 s = data_section;
14931493 } else {
tccmacho.c+606−54
@@ -31,9 +31,28 @@ · 30 unmodified lines
3131 to setup our own crt code. We're not using lazy linking, so even function
3232 calls are resolved at startup. */
3333
34+#if !defined TCC_TARGET_X86_64 && !defined TCC_TARGET_ARM64
35+#error Platform not supported
36+#endif
37+
3438 #define DEBUG_MACHO 0
3539 #define dprintf if (DEBUG_MACHO) printf
3640
41+#define MH_EXECUTE (0x2)
42+#define MH_DYLDLINK (0x4)
43+#define MH_PIE (0x200000)
44+
45+#define CPU_SUBTYPE_LIB64 (0x80000000)
46+#define CPU_SUBTYPE_X86_ALL (3)
47+#define CPU_SUBTYPE_ARM64_ALL (0)
48+
49+#define CPU_ARCH_ABI64 (0x01000000)
50+
51+#define CPU_TYPE_X86 (7)
52+#define CPU_TYPE_X86_64 (CPU_TYPE_X86 | CPU_ARCH_ABI64)
53+#define CPU_TYPE_ARM (12)
54+#define CPU_TYPE_ARM64 (CPU_TYPE_ARM | CPU_ARCH_ABI64)
55+
3756 struct fat_header {
3857 uint32_t magic; /* FAT_MAGIC or FAT_MAGIC_64 */
3958 uint32_t nfat_arch; /* number of structs that follow */
@@ -86,6 +105,7 @@ struct load_command { · 46 unmodified lines
86105 #define LC_LOAD_DYLINKER 0xe
87106 #define LC_SEGMENT_64 0x19
88107 #define LC_REEXPORT_DYLIB (0x1f | LC_REQ_DYLD)
108+#define LC_DYLD_INFO_ONLY (0x22|LC_REQ_DYLD)
89109 #define LC_MAIN (0x28|LC_REQ_DYLD)
90110
91111 typedef int vm_prot_t;
@@ -122,6 +142,8 @@ struct section_64 { /* for 64-bit architectures */ · 30 unmodified lines
122142 #define S_REGULAR 0x0
123143 #define S_ZEROFILL 0x1
124144 #define S_NON_LAZY_SYMBOL_POINTERS 0x6
145+#define S_LAZY_SYMBOL_POINTERS 0x7
146+#define S_SYMBOL_STUBS 0x8
125147 #define S_MOD_INIT_FUNC_POINTERS 0x9
126148 #define S_MOD_TERM_FUNC_POINTERS 0xa
127149
@@ -187,6 +209,38 @@ struct dysymtab_command { · 59 unmodified lines
187209 uint32_t nlocrel; /* number of local relocation entries */
188210 };
189211
212+#define BIND_OPCODE_DONE 0x00
213+#define BIND_OPCODE_SET_DYLIB_SPECIAL_IMM 0x30
214+#define BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM 0x40
215+#define BIND_OPCODE_SET_TYPE_IMM 0x50
216+#define BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB 0x70
217+#define BIND_OPCODE_DO_BIND 0x90
218+
219+#define BIND_TYPE_POINTER 1
220+#define BIND_SPECIAL_DYLIB_FLAT_LOOKUP -2
221+
222+#define REBASE_OPCODE_DONE 0x00
223+#define REBASE_OPCODE_SET_TYPE_IMM 0x10
224+#define REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB 0x20
225+#define REBASE_OPCODE_DO_REBASE_IMM_TIMES 0x50
226+
227+#define REBASE_TYPE_POINTER 1
228+
229+struct dyld_info_command {
230+ uint32_t cmd; /* LC_DYLD_INFO or LC_DYLD_INFO_ONLY */
231+ uint32_t cmdsize; /* sizeof(struct dyld_info_command) */
232+ uint32_t rebase_off; /* file offset to rebase info */
233+ uint32_t rebase_size; /* size of rebase info */
234+ uint32_t bind_off; /* file offset to binding info */
235+ uint32_t bind_size; /* size of binding info */
236+ uint32_t weak_bind_off; /* file offset to weak binding info */
237+ uint32_t weak_bind_size; /* size of weak binding info */
238+ uint32_t lazy_bind_off; /* file offset to lazy binding info */
239+ uint32_t lazy_bind_size; /* size of lazy binding infs */
240+ uint32_t export_off; /* file offset to lazy binding info */
241+ uint32_t export_size; /* size of lazy binding infs */
242+};
243+
190244 #define INDIRECT_SYMBOL_LOCAL 0x80000000
191245
192246 struct entry_point_command {
@@ -201,6 +255,7 @@ enum skind { · 8 unmodified lines
201255 sk_discard,
202256 sk_text,
203257 sk_stubs,
258+ sk_stub_helper,
204259 sk_ro_data,
205260 sk_uw_info,
206261 sk_nl_ptr, // non-lazy pointers, aka GOT
@@ -208,6 +263,14 @@ enum skind { · 1 unmodified line
208263 sk_init,
209264 sk_fini,
210265 sk_rw_data,
266+ sk_stab,
267+ sk_stab_str,
268+ sk_debug_info,
269+ sk_debug_abbrev,
270+ sk_debug_line,
271+ sk_debug_aranges,
272+ sk_debug_str,
273+ sk_debug_line_str,
211274 sk_bss,
212275 sk_linkedit,
213276 sk_last
@@ -241,9 +304,26 @@ struct macho { · 27 unmodified lines
241304 } sk_to_sect[sk_last];
242305 int *elfsectomacho;
243306 int *e2msym;
244− Section *symtab, *strtab, *wdata, *indirsyms, *stubs;
245− int stubsym;
307+ Section *rebase, *binding, *lazy_binding, *exports;
308+ Section *symtab, *strtab, *wdata, *indirsyms;
309+ Section *stubs, *stub_helper, *la_symbol_ptr;
310+ int nr_plt, n_got;
311+ struct dyld_info_command *dyldinfo;
312+ int stubsym, helpsym, lasym, dyld_private, dyld_stub_binder;
246313 uint32_t ilocal, iextdef, iundef;
314+ int n_lazy_bind_rebase;
315+ struct lazy_bind_rebase {
316+ int section;
317+ int bind;
318+ int bind_offset;
319+ int la_symbol_offset;
320+ ElfW_Rel rel;
321+ } *lazy_bind_rebase;
322+ int n_bind;
323+ struct bind {
324+ int section;
325+ ElfW_Rel rel;
326+ } *bind;
247327 };
248328
249329 #define SHT_LINKEDIT (SHT_LOOS + 42)
@@ -306,20 +386,165 @@ static void * add_dylib(struct macho *mo, char *name) · 56 unmodified lines
306386 return lc;
307387 }
308388
389+static void write_uleb128(Section *section, uint64_t value)
390+{
391+ do {
392+ unsigned char byte = value & 0x7f;
393+ uint8_t *ptr = section_ptr_add(section, 1);
394+
395+ value >>= 7;
396+ *ptr = byte | (value ? 0x80 : 0);
397+ } while (value != 0);
398+}
399+
400+static void tcc_macho_add_destructor(TCCState *s1)
401+{
402+ int init_sym, mh_execute_header, at_exit_sym;
403+ Section *s;
404+ ElfW_Rel *rel;
405+ uint8_t *ptr;
406+
407+ s = find_section(s1, ".fini_array");
408+ if (s->data_offset == 0)
409+ return;
410+ init_sym = put_elf_sym(s1->symtab, text_section->data_offset, 0,
411+ ELFW(ST_INFO)(STB_LOCAL, STT_FUNC), 0,
412+ text_section->sh_num, "___GLOBAL_init_65535");
413+ mh_execute_header = put_elf_sym(s1->symtab, 0x100000000ll, 0,
414+ ELFW(ST_INFO)(STB_LOCAL, STT_OBJECT), 0,
415+ SHN_ABS, "__mh_execute_header");
416+ at_exit_sym = put_elf_sym(s1->symtab, 0, 0,
417+ ELFW(ST_INFO)(STB_GLOBAL, STT_FUNC), 0,
418+ SHN_UNDEF, "___cxa_atexit");
419+#ifdef TCC_TARGET_X86_64
420+ ptr = section_ptr_add(text_section, 4);
421+ ptr[0] = 0x55; // pushq %rbp
422+ ptr[1] = 0x48; // movq %rsp, %rbp
423+ ptr[2] = 0x89;
424+ ptr[3] = 0xe5;
425+ for_each_elem(s->reloc, 0, rel, ElfW_Rel) {
426+ int sym_index = ELFW(R_SYM)(rel->r_info);
427+
428+ ptr = section_ptr_add(text_section, 26);
429+ ptr[0] = 0x48; // lea destructor(%rip),%rax
430+ ptr[1] = 0x8d;
431+ ptr[2] = 0x05;
432+ put_elf_reloca(s1->symtab, text_section,
433+ text_section->data_offset - 23,
434+ R_X86_64_PC32, sym_index, -4);
435+ ptr[7] = 0x48; // mov %rax,%rdi
436+ ptr[8] = 0x89;
437+ ptr[9] = 0xc7;
438+ ptr[10] = 0x31; // xorl %ecx, %ecx
439+ ptr[11] = 0xc9;
440+ ptr[12] = 0x89; // movl %ecx, %esi
441+ ptr[13] = 0xce;
442+ ptr[14] = 0x48; // lea mh_execute_header(%rip),%rdx
443+ ptr[15] = 0x8d;
444+ ptr[16] = 0x15;
445+ put_elf_reloca(s1->symtab, text_section,
446+ text_section->data_offset - 9,
447+ R_X86_64_PC32, mh_execute_header, -4);
448+ ptr[21] = 0xe8; // call __cxa_atexit
449+ put_elf_reloca(s1->symtab, text_section,
450+ text_section->data_offset - 4,
451+ R_X86_64_PLT32, at_exit_sym, -4);
452+ }
453+ ptr = section_ptr_add(text_section, 2);
454+ ptr[0] = 0x5d; // pop %rbp
455+ ptr[1] = 0xc3; // ret
456+#elif defined TCC_TARGET_ARM64
457+ ptr = section_ptr_add(text_section, 8);
458+ write32le(ptr, 0xa9bf7bfd); // stp x29, x30, [sp, #-16]!
459+ write32le(ptr + 4, 0x910003fd); // mov x29, sp
460+ for_each_elem(s->reloc, 0, rel, ElfW_Rel) {
461+ int sym_index = ELFW(R_SYM)(rel->r_info);
462+
463+ ptr = section_ptr_add(text_section, 24);
464+ put_elf_reloc(s1->symtab, text_section,
465+ text_section->data_offset - 24,
466+ R_AARCH64_ADR_PREL_PG_HI21, sym_index);
467+ write32le(ptr, 0x90000000); // adrp x0, destructor@page
468+ put_elf_reloc(s1->symtab, text_section,
469+ text_section->data_offset - 20,
470+ R_AARCH64_LDST8_ABS_LO12_NC, sym_index);
471+ write32le(ptr + 4, 0x91000000); // add x0,x0,destructor@pageoff
472+ write32le(ptr + 8, 0xd2800001); // mov x1, #0
473+ put_elf_reloc(s1->symtab, text_section,
474+ text_section->data_offset - 12,
475+ R_AARCH64_ADR_PREL_PG_HI21, mh_execute_header);
476+ write32le(ptr + 12, 0x90000002); // adrp x2, mh_execute_header@page
477+ put_elf_reloc(s1->symtab, text_section,
478+ text_section->data_offset - 8,
479+ R_AARCH64_LDST8_ABS_LO12_NC, mh_execute_header);
480+ write32le(ptr + 16, 0x91000042); // add x2,x2,mh_execute_header@pageoff
481+ put_elf_reloc(s1->symtab, text_section,
482+ text_section->data_offset - 4,
483+ R_AARCH64_CALL26, at_exit_sym);
484+ write32le(ptr + 20, 0x94000000); // bl __cxa_atexit
485+ }
486+ ptr = section_ptr_add(text_section, 8);
487+ write32le(ptr, 0xa8c17bfd); // ldp x29, x30, [sp], #16
488+ write32le(ptr + 4, 0xd65f03c0); // ret
489+#endif
490+ s->reloc->data_offset = s->data_offset = 0;
491+ s->sh_flags &= ~SHF_ALLOC;
492+ add_array (s1, ".init_array", init_sym);
493+}
494+
309495 static void check_relocs(TCCState *s1, struct macho *mo)
310496 {
497+ uint8_t *jmp;
311498 Section *s;
312499 ElfW_Rel *rel;
313500 ElfW(Sym) *sym;
314501 int i, type, gotplt_entry, sym_index, for_code;
502+ int sh_num, debug, bind_offset, la_symbol_offset;
503+ uint32_t *pi, *goti;
315504 struct sym_attr *attr;
316505
317− s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
318506 mo->indirsyms = new_section(s1, "LEINDIR", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE);
507+
508+#ifdef TCC_TARGET_X86_64
509+ jmp = section_ptr_add(mo->stub_helper, 16);
510+ jmp[0] = 0x4c; /* leaq _dyld_private(%rip), %r11 */
511+ jmp[1] = 0x8d;
512+ jmp[2] = 0x1d;
513+ put_elf_reloca(s1->symtab, mo->stub_helper, 3,
514+ R_X86_64_PC32, mo->dyld_private, -4);
515+ jmp[7] = 0x41; /* pushq %r11 */
516+ jmp[8] = 0x53;
517+ jmp[9] = 0xff; /* jmpq *dyld_stub_binder@GOT(%rip) */
518+ jmp[10] = 0x25;
519+ put_elf_reloca(s1->symtab, mo->stub_helper, 11,
520+ R_X86_64_GOTPCREL, mo->dyld_stub_binder, -4);
521+ jmp[15] = 0x90; /* nop */
522+#elif defined TCC_TARGET_ARM64
523+ jmp = section_ptr_add(mo->stub_helper, 24);
524+ put_elf_reloc(s1->symtab, mo->stub_helper, 0,
525+ R_AARCH64_ADR_PREL_PG_HI21, mo->dyld_private);
526+ write32le(jmp, 0x90000011); // adrp x17, _dyld_private@page
527+ put_elf_reloc(s1->symtab, mo->stub_helper, 4,
528+ R_AARCH64_LDST64_ABS_LO12_NC, mo->dyld_private);
529+ write32le(jmp + 4, 0x91000231); // add x17,x17,_dyld_private@pageoff
530+ write32le(jmp + 8, 0xa9bf47f0); // stp x16/x17, [sp, #-16]!
531+ put_elf_reloc(s1->symtab, mo->stub_helper, 12,
532+ R_AARCH64_ADR_GOT_PAGE, mo->dyld_stub_binder);
533+ write32le(jmp + 12, 0x90000010); // adrp x16, dyld_stub_binder@page
534+ put_elf_reloc(s1->symtab, mo->stub_helper, 16,
535+ R_AARCH64_LD64_GOT_LO12_NC, mo->dyld_stub_binder);
536+ write32le(jmp + 16, 0xf9400210); // ldr x16,[x16,dyld_stub_binder@pageoff]
537+ write32le(jmp + 20, 0xd61f0200); // br x16
538+#endif
539+
540+ goti = NULL;
541+ mo->nr_plt = mo->n_got = 0;
319542 for (i = 1; i < s1->nb_sections; i++) {
320543 s = s1->sections[i];
321544 if (s->sh_type != SHT_RELX)
322545 continue;
546+ sh_num = s1->sections[s->sh_info]->sh_num;
547+ debug = sh_num >= s1->dwlo && sh_num < s1->dwhi;
323548 for_each_elem(s, 0, rel, ElfW_Rel) {
324549 type = ELFW(R_TYPE)(rel->r_info);
325550 gotplt_entry = gotplt_entry_type(type);
@@ -329,44 +554,150 @@ static void check_relocs(TCCState *s1, struct macho *mo) · 3 unmodified lines
329554 address due to codegen (i.e. a reloc requiring a got slot). */
330555 sym_index = ELFW(R_SYM)(rel->r_info);
331556 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
332− if (sym->st_shndx == SHN_UNDEF
333− || gotplt_entry == ALWAYS_GOTPLT_ENTRY) {
557+ if (!debug &&
558+ (sym->st_shndx == SHN_UNDEF
559+ || gotplt_entry == ALWAYS_GOTPLT_ENTRY)) {
334560 attr = get_sym_attr(s1, sym_index, 1);
335561 if (!attr->dyn_index) {
336− uint32_t *pi = section_ptr_add(mo->indirsyms, sizeof(*pi));
337562 attr->got_offset = s1->got->data_offset;
338563 attr->plt_offset = -1;
339564 attr->dyn_index = 1; /* used as flag */
340− section_ptr_add(s1->got, PTR_SIZE);
565+ section_ptr_add(s1->got, PTR_SIZE);
566+ put_elf_reloc(s1->symtab, s1->got, attr->got_offset,
567+ R_DATA_PTR, sym_index);
568+ goti = tcc_realloc(goti, (mo->n_got + 1) * sizeof(*goti));
341569 if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) {
342570 if (sym->st_shndx == SHN_UNDEF)
343− tcc_error("undefined local symbol???");
344− *pi = INDIRECT_SYMBOL_LOCAL;
345− /* The pointer slot we generated must point to the
346− symbol, whose address is only known after layout,
347− so register a simple relocation for that. */
348− put_elf_reloc(s1->symtab, s1->got, attr->got_offset,
349− R_DATA_PTR, sym_index);
350− } else
351− *pi = mo->e2msym[sym_index];
571+ tcc_error("undefined local symbo: '%s'",
572+ (char *) symtab_section->link->data + sym->st_name);
573+ goti[mo->n_got++] = INDIRECT_SYMBOL_LOCAL;
574+ } else {
575+ goti[mo->n_got++] = mo->e2msym[sym_index];
576+ if (sym->st_shndx == SHN_UNDEF
577+#ifdef TCC_TARGET_X86_64
578+ && type == R_X86_64_GOTPCREL
579+#elif defined TCC_TARGET_ARM64
580+ && type == R_AARCH64_ADR_GOT_PAGE
581+#endif
582+ ) {
583+ mo->bind =
584+ tcc_realloc(mo->bind,
585+ (mo->n_bind + 1) *
586+ sizeof(struct bind));
587+ mo->bind[mo->n_bind].section = s1->got->reloc->sh_info;
588+ mo->bind[mo->n_bind].rel = *rel;
589+ mo->bind[mo->n_bind].rel.r_offset = attr->got_offset;
590+ mo->n_bind++;
591+ s1->got->reloc->data_offset -= sizeof (ElfW_Rel);
592+ }
593+ }
352594 }
353− if (for_code) {
595+ if (for_code && sym->st_shndx == SHN_UNDEF) {
354596 if (attr->plt_offset == -1) {
355− uint8_t *jmp;
597+ pi = section_ptr_add(mo->indirsyms, sizeof(*pi));
598+ *pi = mo->e2msym[sym_index];
599+ mo->nr_plt++;
356600 attr->plt_offset = mo->stubs->data_offset;
601+#ifdef TCC_TARGET_X86_64
602+ if (type != R_X86_64_PLT32)
603+ continue;
604+ /* __stubs */
357605 jmp = section_ptr_add(mo->stubs, 6);
358− jmp[0] = 0xff; /* jmpq *ofs(%rip) */
606+ jmp[0] = 0xff; /* jmpq *__la_symbol_ptr(%rip) */
359607 jmp[1] = 0x25;
360− put_elf_reloc(s1->symtab, mo->stubs,
361− attr->plt_offset + 2,
362− R_X86_64_GOTPCREL, sym_index);
608+ put_elf_reloca(s1->symtab, mo->stubs,
609+ mo->stubs->data_offset - 4,
610+ R_X86_64_PC32, mo->lasym,
611+ mo->la_symbol_ptr->data_offset - 4);
612+
613+ /* __stub_helper */
614+ bind_offset = mo->stub_helper->data_offset + 1;
615+ jmp = section_ptr_add(mo->stub_helper, 10);
616+ jmp[0] = 0x68; /* pushq $bind_offset */
617+ jmp[5] = 0xe9; /* jmpq __stub_helper */
618+ write32le(jmp + 6, -mo->stub_helper->data_offset);
619+
620+ /* __la_symbol_ptr */
621+ la_symbol_offset = mo->la_symbol_ptr->data_offset;
622+ put_elf_reloca(s1->symtab, mo->la_symbol_ptr,
623+ mo->la_symbol_ptr->data_offset,
624+ R_DATA_PTR, mo->helpsym,
625+ mo->stub_helper->data_offset - 10);
626+ jmp = section_ptr_add(mo->la_symbol_ptr, PTR_SIZE);
627+#elif defined TCC_TARGET_ARM64
628+ if (type != R_AARCH64_CALL26)
629+ continue;
630+ /* __stubs */
631+ jmp = section_ptr_add(mo->stubs, 12);
632+ put_elf_reloca(s1->symtab, mo->stubs,
633+ mo->stubs->data_offset - 12,
634+ R_AARCH64_ADR_PREL_PG_HI21, mo->lasym,
635+ mo->la_symbol_ptr->data_offset);
636+ write32le(jmp, // adrp x16, __la_symbol_ptr@page
637+ 0x90000010);
638+ put_elf_reloca(s1->symtab, mo->stubs,
639+ mo->stubs->data_offset - 8,
640+ R_AARCH64_LDST64_ABS_LO12_NC, mo->lasym,
641+ mo->la_symbol_ptr->data_offset);
642+ write32le(jmp + 4, // ldr x16,[x16, __la_symbol_ptr@pageoff]
643+ 0xf9400210);
644+ write32le(jmp + 8, // br x16
645+ 0xd61f0200);
646+
647+ /* __stub_helper */
648+ bind_offset = mo->stub_helper->data_offset + 8;
649+ jmp = section_ptr_add(mo->stub_helper, 12);
650+ write32le(jmp + 0, // ldr w16, l0
651+ 0x18000050);
652+ write32le(jmp + 4, // b stubHelperHeader
653+ 0x14000000 +
654+ ((-(mo->stub_helper->data_offset - 8) / 4) &
655+ 0x3ffffff));
656+ write32le(jmp + 8, 0); // l0: .long bind_offset
657+
658+ /* __la_symbol_ptr */
659+ la_symbol_offset = mo->la_symbol_ptr->data_offset;
660+ put_elf_reloca(s1->symtab, mo->la_symbol_ptr,
661+ mo->la_symbol_ptr->data_offset,
662+ R_DATA_PTR, mo->helpsym,
663+ mo->stub_helper->data_offset - 12);
664+ jmp = section_ptr_add(mo->la_symbol_ptr, PTR_SIZE);
665+#endif
666+ mo->lazy_bind_rebase =
667+ tcc_realloc(mo->lazy_bind_rebase,
668+ (mo->n_lazy_bind_rebase + 1) *
669+ sizeof(struct lazy_bind_rebase));
670+ mo->lazy_bind_rebase[mo->n_lazy_bind_rebase].section =
671+ mo->stub_helper->reloc->sh_info;
672+ mo->lazy_bind_rebase[mo->n_lazy_bind_rebase].bind = 1;
673+ mo->lazy_bind_rebase[mo->n_lazy_bind_rebase].bind_offset = bind_offset;
674+ mo->lazy_bind_rebase[mo->n_lazy_bind_rebase].la_symbol_offset = la_symbol_offset;
675+ mo->lazy_bind_rebase[mo->n_lazy_bind_rebase].rel = *rel;
676+ mo->lazy_bind_rebase[mo->n_lazy_bind_rebase].rel.r_offset =
677+ attr->plt_offset;
678+ mo->n_lazy_bind_rebase++;
363679 }
364680 rel->r_info = ELFW(R_INFO)(mo->stubsym, type);
365681 rel->r_addend += attr->plt_offset;
366682 }
367683 }
684+ if (type == R_DATA_PTR) {
685+ mo->lazy_bind_rebase =
686+ tcc_realloc(mo->lazy_bind_rebase,
687+ (mo->n_lazy_bind_rebase + 1) *
688+ sizeof(struct lazy_bind_rebase));
689+ mo->lazy_bind_rebase[mo->n_lazy_bind_rebase].section = s->sh_info;
690+ mo->lazy_bind_rebase[mo->n_lazy_bind_rebase].bind = 0;
691+ mo->lazy_bind_rebase[mo->n_lazy_bind_rebase].rel = *rel;
692+ mo->n_lazy_bind_rebase++;
693+ }
368694 }
369695 }
696+ pi = section_ptr_add(mo->indirsyms, mo->n_got * sizeof(*pi));
697+ memcpy(pi, goti, mo->n_got * sizeof(*pi));
698+ pi = section_ptr_add(mo->indirsyms, mo->nr_plt * sizeof(*pi));
699+ memcpy(pi, mo->indirsyms->data, mo->nr_plt * sizeof(*pi));
700+ tcc_free(goti);
370701 }
371702
372703 static int check_symbols(TCCState *s1, struct macho *mo)
@@ -444,9 +775,12 @@ static void convert_symbol(TCCState *s1, struct macho *mo, struct nlist_64 *pn) · 71 unmodified lines
444775 n.n_type = N_ABS, n.n_sect = 0;
445776 else if (sym->st_shndx >= SHN_LORESERVE)
446777 tcc_error("unhandled ELF symbol section %d %s", sym->st_shndx, name);
447− else if (!mo->elfsectomacho[sym->st_shndx])
448− tcc_error("ELF section %d not mapped into Mach-O for symbol %s",
449− sym->st_shndx, name);
778+ else if (!mo->elfsectomacho[sym->st_shndx]) {
779+ int sh_num = s1->sections[sym->st_shndx]->sh_num;
780+ if (sh_num < s1->dwlo || sh_num >= s1->dwhi)
781+ tcc_error("ELF section %d(%s) not mapped into Mach-O for symbol %s",
782+ sym->st_shndx, s1->sections[sym->st_shndx]->name, name);
783+ }
450784 else
451785 n.n_sect = mo->elfsectomacho[sym->st_shndx];
452786 if (ELFW(ST_BIND)(sym->st_info) == STB_GLOBAL)
@@ -465,9 +799,9 @@ static void convert_symbols(TCCState *s1, struct macho *mo) · 12 unmodified lines
465799 convert_symbol(s1, mo, pn);
466800 }
467801
468−static int machosymcmp(const void *_a, const void *_b)
802+static int machosymcmp(const void *_a, const void *_b, void *arg)
469803 {
470− TCCState *s1 = tcc_state;
804+ TCCState *s1 = arg;
471805 int ea = ((struct nlist_64 *)_a)->n_value;
472806 int eb = ((struct nlist_64 *)_b)->n_value;
473807 ElfSym *sa = (ElfSym *)symtab_section->data + ea;
@@ -492,6 +826,37 @@ static int machosymcmp(const void *_a, const void *_b) · 18 unmodified lines
492826 return ea - eb;
493827 }
494828
829+/* cannot use qsort because code has to be reentrant */
830+static void tcc_qsort (void *base, size_t nel, size_t width,
831+ int (*comp)(const void *, const void *, void *), void *arg)
832+{
833+ size_t wnel, gap, wgap, i, j, k;
834+ char *a, *b, tmp;
835+
836+ wnel = width * nel;
837+ for (gap = 0; ++gap < nel;)
838+ gap *= 3;
839+ while ( gap /= 3 ) {
840+ wgap = width * gap;
841+ for (i = wgap; i < wnel; i += width) {
842+ for (j = i - wgap; ;j -= wgap) {
843+ a = j + (char *)base;
844+ b = a + wgap;
845+ if ( (*comp)(a, b, arg) <= 0 )
846+ break;
847+ k = width;
848+ do {
849+ tmp = *a;
850+ *a++ = *b;
851+ *b++ = tmp;
852+ } while ( --k );
853+ if (j < wgap)
854+ break;
855+ }
856+ }
857+ }
858+}
859+
495860 static void create_symtab(TCCState *s1, struct macho *mo)
496861 {
497862 int sym_index, sym_end;
@@ -500,9 +865,30 @@ static void create_symtab(TCCState *s1, struct macho *mo) · 2 unmodified lines
500865 /* Stub creation belongs to check_relocs, but we need to create
501866 the symbol now, so its included in the sorting. */
502867 mo->stubs = new_section(s1, "__stubs", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
868+ mo->stub_helper = new_section(s1, "__stub_helper", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
869+ s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
870+ mo->la_symbol_ptr = new_section(s1, "__la_symbol_ptr", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
503871 mo->stubsym = put_elf_sym(s1->symtab, 0, 0,
504872 ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0,
505873 mo->stubs->sh_num, ".__stubs");
874+ mo->helpsym = put_elf_sym(s1->symtab, 0, 0,
875+ ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0,
876+ mo->stub_helper->sh_num, ".__stub_helper");
877+ mo->lasym = put_elf_sym(s1->symtab, 0, 0,
878+ ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0,
879+ mo->la_symbol_ptr->sh_num, ".__la_symbol_ptr");
880+ section_ptr_add(data_section, -data_section->data_offset & (PTR_SIZE - 1));
881+ mo->dyld_private = put_elf_sym(s1->symtab, data_section->data_offset, PTR_SIZE,
882+ ELFW(ST_INFO)(STB_LOCAL, STT_OBJECT), 0,
883+ data_section->sh_num, ".__dyld_private");
884+ section_ptr_add(data_section, PTR_SIZE);
885+ mo->dyld_stub_binder = put_elf_sym(s1->symtab, 0, 0,
886+ ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT), 0,
887+ SHN_UNDEF, "dyld_stub_binder");
888+ mo->rebase = new_section(s1, "REBASE", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE);
889+ mo->binding = new_section(s1, "BINDING", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE);
890+ mo->lazy_binding = new_section(s1, "LAZY_BINDING", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE);
891+ mo->exports = new_section(s1, "EXPORT", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE);
506892
507893 mo->symtab = new_section(s1, "LESYMTAB", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE);
508894 mo->strtab = new_section(s1, "LESTRTAB", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE);
@@ -515,9 +901,7 @@ static void create_symtab(TCCState *s1, struct macho *mo) · 6 unmodified lines
515901 pn[sym_index - 1].n_strx = put_elf_str(mo->strtab, name);
516902 pn[sym_index - 1].n_value = sym_index;
517903 }
518− tcc_enter_state(s1); /* qsort needs global state */
519− qsort(pn, sym_end - 1, sizeof(*pn), machosymcmp);
520− tcc_exit_state(s1);
904+ tcc_qsort(pn, sym_end - 1, sizeof(*pn), machosymcmp, s1);
521905 mo->e2msym = tcc_malloc(sym_end * sizeof(*mo->e2msym));
522906 mo->e2msym[0] = -1;
523907 for (sym_index = 1; sym_index < sym_end; ++sym_index) {
@@ -530,22 +914,121 @@ const struct { · 6 unmodified lines
530914 uint32_t flags;
531915 const char *name;
532916 } skinfo[sk_last] = {
533− /*[sk_unknown] =*/ { 0 },
534− /*[sk_discard] =*/ { 0 },
535− /*[sk_text] =*/ { 1, S_REGULAR | S_ATTR_PURE_INSTRUCTIONS
536− | S_ATTR_SOME_INSTRUCTIONS, "__text" },
537− /*[sk_stubs] =*/ { 0 },
538− /*[sk_ro_data] =*/ { 1, S_REGULAR, "__rodata" },
539− /*[sk_uw_info] =*/ { 0 },
540− /*[sk_nl_ptr] =*/ { 2, S_NON_LAZY_SYMBOL_POINTERS, "__got" },
541− /*[sk_la_ptr] =*/ { 0 },
542− /*[sk_init] =*/ { 2, S_MOD_INIT_FUNC_POINTERS, "__mod_init_func" },
543− /*[sk_fini] =*/ { 2, S_MOD_TERM_FUNC_POINTERS, "__mod_term_func" },
544− /*[sk_rw_data] =*/ { 2, S_REGULAR, "__data" },
545− /*[sk_bss] =*/ { 2, S_ZEROFILL, "__bss" },
546− /*[sk_linkedit] =*/ { 3, S_REGULAR, NULL },
917+ /*[sk_unknown] =*/ { 0 },
918+ /*[sk_discard] =*/ { 0 },
919+ /*[sk_text] =*/ { 1, S_REGULAR | S_ATTR_PURE_INSTRUCTIONS
920+ | S_ATTR_SOME_INSTRUCTIONS, "__text" },
921+ /*[sk_stubs] =*/ { 1, S_REGULAR | S_ATTR_PURE_INSTRUCTIONS | S_SYMBOL_STUBS
922+ | S_ATTR_SOME_INSTRUCTIONS , "__stubs" },
923+ /*[sk_stub_helper] =*/ { 1, S_REGULAR | S_ATTR_PURE_INSTRUCTIONS
924+ | S_ATTR_SOME_INSTRUCTIONS , "__stub_helper" },
925+ /*[sk_ro_data] =*/ { 1, S_REGULAR, "__rodata" },
926+ /*[sk_uw_info] =*/ { 0 },
927+ /*[sk_nl_ptr] =*/ { 2, S_NON_LAZY_SYMBOL_POINTERS, "__got" },
928+ /*[sk_la_ptr] =*/ { 2, S_LAZY_SYMBOL_POINTERS, "__la_symbol_ptr" },
929+ /*[sk_init] =*/ { 2, S_MOD_INIT_FUNC_POINTERS, "__mod_init_func" },
930+ /*[sk_fini] =*/ { 2, S_MOD_TERM_FUNC_POINTERS, "__mod_term_func" },
931+ /*[sk_rw_data] =*/ { 2, S_REGULAR, "__data" },
932+ /*[sk_stab] =*/ { 2, S_REGULAR, "__stab" },
933+ /*[sk_stab_str] =*/ { 2, S_REGULAR, "__stab_str" },
934+ /*[sk_debug_info] =*/ { 2, S_REGULAR, "__debug_info" },
935+ /*[sk_debug_abbrev] =*/ { 2, S_REGULAR, "__debug_abbrev" },
936+ /*[sk_debug_line] =*/ { 2, S_REGULAR, "__debug_line" },
937+ /*[sk_debug_aranges] =*/ { 2, S_REGULAR, "__debug_aranges" },
938+ /*[sk_debug_str] =*/ { 2, S_REGULAR, "__debug_str" },
939+ /*[sk_debug_line_str] =*/ { 2, S_REGULAR, "__debug_line_str" },
940+ /*[sk_bss] =*/ { 2, S_ZEROFILL, "__bss" },
941+ /*[sk_linkedit] =*/ { 3, S_REGULAR, NULL },
547942 };
548943
944+static void set_segment_and_offset(struct macho *mo, addr_t addr,
945+ uint8_t *ptr, int opcode,
946+ Section *sec, addr_t offset)
947+{
948+ int i;
949+ struct segment_command_64 *seg = NULL;
950+
951+ for (i = 1; i < mo->nseg - 1; i++) {
952+ seg = get_segment(mo, i);
953+ if (addr >= seg->vmaddr && addr < (seg->vmaddr + seg->vmsize))
954+ break;
955+ }
956+ *ptr = opcode | i;
957+ write_uleb128(sec, offset - seg->vmaddr);
958+}
959+
960+static void do_bind_rebase(TCCState *s1, struct macho *mo)
961+{
962+ int i;
963+ uint8_t *ptr;
964+ ElfW(Sym) *sym;
965+ char *name;
966+
967+ for (i = 0; i < mo->n_lazy_bind_rebase; i++) {
968+ int sym_index = ELFW(R_SYM)(mo->lazy_bind_rebase[i].rel.r_info);
969+ Section *s = s1->sections[mo->lazy_bind_rebase[i].section];
970+
971+ sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
972+ name = (char *) symtab_section->link->data + sym->st_name;
973+ if (mo->lazy_bind_rebase[i].bind) {
974+ write32le(mo->stub_helper->data +
975+ mo->lazy_bind_rebase[i].bind_offset,
976+ mo->lazy_binding->data_offset);
977+ ptr = section_ptr_add(mo->lazy_binding, 1);
978+ set_segment_and_offset(mo, mo->la_symbol_ptr->sh_addr, ptr,
979+ BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB,
980+ mo->lazy_binding,
981+ mo->la_symbol_ptr->sh_addr +
982+ mo->lazy_bind_rebase[i].la_symbol_offset);
983+ ptr = section_ptr_add(mo->lazy_binding, 5 + strlen(name));
984+ *ptr++ = BIND_OPCODE_SET_DYLIB_SPECIAL_IMM |
985+ (BIND_SPECIAL_DYLIB_FLAT_LOOKUP & 0xf);
986+ *ptr++ = BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM | 0;
987+ strcpy(ptr, name);
988+ ptr += strlen(name) + 1;
989+ *ptr++ = BIND_OPCODE_DO_BIND;
990+ *ptr = BIND_OPCODE_DONE;
991+ }
992+ else {
993+ ptr = section_ptr_add(mo->rebase, 2);
994+ *ptr++ = REBASE_OPCODE_SET_TYPE_IMM | REBASE_TYPE_POINTER;
995+ set_segment_and_offset(mo, s->sh_addr, ptr,
996+ REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB,
997+ mo->rebase,
998+ mo->lazy_bind_rebase[i].rel.r_offset +
999+ s->sh_addr);
1000+ ptr = section_ptr_add(mo->rebase, 1);
1001+ *ptr = REBASE_OPCODE_DO_REBASE_IMM_TIMES | 1;
1002+ }
1003+ }
1004+ for (i = 0; i < mo->n_bind; i++) {
1005+ int sym_index = ELFW(R_SYM)(mo->bind[i].rel.r_info);
1006+ Section *s = s1->sections[mo->bind[i].section];
1007+
1008+ sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1009+ name = (char *) symtab_section->link->data + sym->st_name;
1010+ ptr = section_ptr_add(mo->binding, 5 + strlen(name));
1011+ *ptr++ = BIND_OPCODE_SET_DYLIB_SPECIAL_IMM |
1012+ (BIND_SPECIAL_DYLIB_FLAT_LOOKUP & 0xf);
1013+ *ptr++ = BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM | 0;
1014+ strcpy(ptr, name);
1015+ ptr += strlen(name) + 1;
1016+ *ptr++ = BIND_OPCODE_SET_TYPE_IMM | BIND_TYPE_POINTER;
1017+ set_segment_and_offset(mo, s->sh_addr, ptr,
1018+ BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB,
1019+ mo->binding,
1020+ mo->bind[i].rel.r_offset + s->sh_addr);
1021+ ptr = section_ptr_add(mo->binding, 1);
1022+ *ptr++ = BIND_OPCODE_DO_BIND;
1023+ }
1024+ if (mo->rebase->data_offset) {
1025+ ptr = section_ptr_add(mo->rebase, 1);
1026+ *ptr = REBASE_OPCODE_DONE;
1027+ }
1028+ tcc_free(mo->lazy_bind_rebase);
1029+ tcc_free(mo->bind);
1030+}
1031+
5491032 static void collect_sections(TCCState *s1, struct macho *mo)
5501033 {
5511034 int i, sk, numsec;
@@ -584,6 +1067,7 @@ static void collect_sections(TCCState *s1, struct macho *mo) · 32 unmodified lines
5841067 str = (char*)dyldlc + dyldlc->name;
5851068 strcpy(str, "/usr/lib/dyld");
5861069
1070+ mo->dyldinfo = add_lc(mo, LC_DYLD_INFO_ONLY, sizeof(*mo->dyldinfo));
5871071 symlc = add_lc(mo, LC_SYMTAB, sizeof(*symlc));
5881072 dysymlc = add_lc(mo, LC_DYSYMTAB, sizeof(*dysymlc));
5891073
@@ -610,12 +1094,37 @@ static void collect_sections(TCCState *s1, struct macho *mo) · 20 unmodified lines
6101094 case SHT_FINI_ARRAY: sk = sk_fini; break;
6111095 case SHT_NOBITS: sk = sk_bss; break;
6121096 case SHT_SYMTAB: sk = sk_discard; break;
613− case SHT_STRTAB: sk = s == stabstr_section ? sk_ro_data : sk_discard; break;
1097+ case SHT_STRTAB:
1098+ if (s == stabstr_section)
1099+ sk = sk_stab_str;
1100+ else
1101+ sk = sk_discard;
1102+ break;
6141103 case SHT_RELX: sk = sk_discard; break;
6151104 case SHT_LINKEDIT: sk = sk_linkedit; break;
6161105 case SHT_PROGBITS:
617− if (s == s1->got)
1106+ if (s == mo->stubs)
1107+ sk = sk_stubs;
1108+ else if (s == mo->stub_helper)
1109+ sk = sk_stub_helper;
1110+ else if (s == s1->got)
6181111 sk = sk_nl_ptr;
1112+ else if (s == mo->la_symbol_ptr)
1113+ sk = sk_la_ptr;
1114+ else if (s == stab_section)
1115+ sk = sk_stab;
1116+ else if (s == dwarf_info_section)
1117+ sk = sk_debug_info;
1118+ else if (s == dwarf_abbrev_section)
1119+ sk = sk_debug_abbrev;
1120+ else if (s == dwarf_line_section)
1121+ sk = sk_debug_line;
1122+ else if (s == dwarf_aranges_section)
1123+ sk = sk_debug_aranges;
1124+ else if (s == dwarf_str_section)
1125+ sk = sk_debug_str;
1126+ else if (s == dwarf_line_str_section)
1127+ sk = sk_debug_line_str;
6191128 else if (flags & SHF_EXECINSTR)
6201129 sk = sk_text;
6211130 else if (flags & SHF_WRITE)
@@ -637,9 +1146,14 @@ static void collect_sections(TCCState *s1, struct macho *mo) · 15 unmodified lines
6371146 mo->elfsectomacho = tcc_mallocz(sizeof(*mo->elfsectomacho) * s1->nb_sections);
6381147 for (sk = sk_unknown; sk < sk_last; sk++) {
6391148 struct section_64 *sec = NULL;
1149+#define SEG_PAGE_SIZE 16384
1150+ if (sk == sk_linkedit)
1151+ do_bind_rebase(s1, mo);
6401152 if (seg) {
641− seg->vmsize = curaddr - seg->vmaddr;
642− seg->filesize = fileofs - seg->fileoff;
1153+ seg->vmsize = (curaddr - seg->vmaddr + SEG_PAGE_SIZE - 1) & -SEG_PAGE_SIZE;
1154+ seg->filesize = (fileofs - seg->fileoff + SEG_PAGE_SIZE - 1) & -SEG_PAGE_SIZE;
1155+ curaddr = seg->vmaddr + seg->vmsize;
1156+ fileofs = seg->fileoff + seg->filesize;
6431157 }
6441158 if (skinfo[sk].seg && mo->sk_to_sect[sk].s) {
6451159 uint64_t al = 0;
@@ -652,6 +1166,16 @@ static void collect_sections(TCCState *s1, struct macho *mo) · 6 unmodified lines
6521166 mo->sk_to_sect[sk].machosect = si;
6531167 sec = get_section(seg, si);
6541168 sec->flags = skinfo[sk].flags;
1169+ if (sk == sk_stubs)
1170+#ifdef TCC_TARGET_X86_64
1171+ sec->reserved2 = 6;
1172+#elif defined TCC_TARGET_ARM64
1173+ sec->reserved2 = 12;
1174+#endif
1175+ if (sk == sk_nl_ptr)
1176+ sec->reserved1 = mo->nr_plt;
1177+ if (sk == sk_la_ptr)
1178+ sec->reserved1 = mo->nr_plt + mo->n_got;
6551179 }
6561180 if (seg->vmaddr == -1) {
6571181 curaddr = (curaddr + 4095) & -4096;
@@ -737,6 +1261,23 @@ static void collect_sections(TCCState *s1, struct macho *mo) · 79 unmodified lines
7371261 dysymlc->nundefsym = symlc->nsyms - dysymlc->iundefsym;
7381262 dysymlc->indirectsymoff = mo->indirsyms->sh_offset;
7391263 dysymlc->nindirectsyms = mo->indirsyms->data_offset / sizeof(uint32_t);
1264+
1265+ if (mo->rebase->data_offset) {
1266+ mo->dyldinfo->rebase_off = mo->rebase->sh_offset;
1267+ mo->dyldinfo->rebase_size = mo->rebase->data_offset;
1268+ }
1269+ if (mo->binding->data_offset) {
1270+ mo->dyldinfo->bind_off = mo->binding->sh_offset;
1271+ mo->dyldinfo->bind_size = mo->binding->data_offset;
1272+ }
1273+ if (mo->lazy_binding->data_offset) {
1274+ mo->dyldinfo->lazy_bind_off = mo->lazy_binding->sh_offset;
1275+ mo->dyldinfo->lazy_bind_size = mo->lazy_binding->data_offset;
1276+ }
1277+ if (mo->exports->data_offset) {
1278+ mo->dyldinfo->export_off = mo->exports->sh_offset;
1279+ mo->dyldinfo->export_size = mo->exports->data_offset;
1280+ }
7401281 }
7411282
7421283 static void macho_write(TCCState *s1, struct macho *mo, FILE *fp)
@@ -745,10 +1286,15 @@ static void macho_write(TCCState *s1, struct macho *mo, FILE *fp) · 2 unmodified lines
7451286 uint64_t fileofs = 0;
7461287 Section *s;
7471288 mo->mh.mh.magic = MH_MAGIC_64;
748− mo->mh.mh.cputype = 0x1000007; // x86_64
749− mo->mh.mh.cpusubtype = 0x80000003;// all | CPU_SUBTYPE_LIB64
750− mo->mh.mh.filetype = 2; // MH_EXECUTE
751− mo->mh.mh.flags = 4; // DYLDLINK
1289+#ifdef TCC_TARGET_X86_64
1290+ mo->mh.mh.cputype = CPU_TYPE_X86_64;
1291+ mo->mh.mh.cpusubtype = CPU_SUBTYPE_LIB64 | CPU_SUBTYPE_X86_ALL;
1292+#elif defined TCC_TARGET_ARM64
1293+ mo->mh.mh.cputype = CPU_TYPE_ARM64;
1294+ mo->mh.mh.cpusubtype = CPU_SUBTYPE_ARM64_ALL;
1295+#endif
1296+ mo->mh.mh.filetype = MH_EXECUTE;
1297+ mo->mh.mh.flags = MH_DYLDLINK | MH_PIE;
7521298 mo->mh.mh.ncmds = mo->nlc;
7531299 mo->mh.mh.sizeofcmds = 0;
7541300 for (i = 0; i < mo->nlc; i++)
@@ -803,6 +1349,7 @@ ST_FUNC int macho_output_file(TCCState *s1, const char *filename) · 48 unmodified lines
8031349 printf("<- %s\n", filename);
8041350
8051351 tcc_add_runtime(s1);
1352+ tcc_macho_add_destructor(s1);
8061353 resolve_common_syms(s1);
8071354 create_symtab(s1, &mo);
8081355 check_relocs(s1, &mo);
@@ -959,8 +1506,13 @@ ST_FUNC int macho_load_dll(TCCState * s1, int fd, const char* filename, int lev) · 150 unmodified lines
9591506 fh.nfat_arch * sizeof(*fa));
9601507 swap = fh.magic == FAT_CIGAM;
9611508 for (i = 0; i < SWAP(fh.nfat_arch); i++)
962− if (SWAP(fa[i].cputype) == 0x01000007 /* CPU_TYPE_X86_64 */
963− && SWAP(fa[i].cpusubtype) == 3) /* CPU_SUBTYPE_X86_ALL */
1509+#ifdef TCC_TARGET_X86_64
1510+ if (SWAP(fa[i].cputype) == CPU_TYPE_X86_64
1511+ && SWAP(fa[i].cpusubtype) == CPU_SUBTYPE_X86_ALL)
1512+#elif defined TCC_TARGET_ARM64
1513+ if (SWAP(fa[i].cputype) == CPU_TYPE_ARM64
1514+ && SWAP(fa[i].cpusubtype) == CPU_SUBTYPE_ARM64_ALL)
1515+#endif
9641516 break;
9651517 if (i == SWAP(fh.nfat_arch)) {
9661518 tcc_free(fa);
tests/tcctest.c+3−5
@@ -3648,7 +3648,7 @@ void test_asm_dead_code(void) · 3647 unmodified lines
36483648
36493649 void test_asm_call(void)
36503650 {
3651−#if defined __x86_64__ && !defined _WIN64
3651+#if defined __x86_64__ && !defined _WIN64 && !defined(__APPLE__)
36523652 static char str[] = "PATH";
36533653 char *s;
36543654 /* This tests if a reference to an undefined symbol from an asm
@@ -3660,10 +3660,8 @@ void test_asm_call(void) · 5 unmodified lines
36603660 tested here). */
36613661 /* two pushes so stack remains aligned */
36623662 asm volatile ("push %%rdi; push %%rdi; mov %0, %%rdi;"
3663−#if 1 && !defined(__TINYC__) && (defined(__PIC__) || defined(__PIE__)) && !defined(__APPLE__)
3663+#if 1 && !defined(__TINYC__) && (defined(__PIC__) || defined(__PIE__))
36643664 "call getenv@plt;"
3665−#elif defined(__APPLE__)
3666− "call _getenv;"
36673665 #else
36683666 "call getenv;"
36693667 #endif
@@ -3892,7 +3890,7 @@ void builtin_test(void) · 222 unmodified lines
38923890 //printf("bera: %p\n", __builtin_extract_return_addr((void*)43));
38933891 }
38943892
3895−#ifdef _WIN32
3893+#if defined _WIN32 || defined __APPLE__
38963894 void weak_test(void) {}
38973895 #else
38983896 extern int __attribute__((weak)) weak_f1(void);
tests/tests2/124_atomic_counter.c+2−0
@@ -14,9 +14,11 @@ · 13 unmodified lines
1414 abort(); \
1515 } while (0)
1616
17+#ifndef __APPLE__
1718 #if defined __x86_64__ || defined __aarch64__ || defined __riscv
1819 #define HAS_64BITS
1920 #endif
21+#endif
2022
2123 typedef struct {
2224 atomic_flag flag;

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