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
38 38
39#define MAX_ALIGN 1639#define MAX_ALIGN 16
40 40
41#ifndef TCC_TARGET_MACHO
41#define CHAR_IS_UNSIGNED42#define CHAR_IS_UNSIGNED
43#endif
42 44
43/* define if return values need to be extended explicitely45/* define if return values need to be extended explicitely
44 at caller side (for interfacing with non-TCC compilers) */46 at caller side (for interfacing with non-TCC compilers) */
@@ -810,7 +812,7 @@ static int arm64_hfa(CType *type, unsigned *fsize) · 765 unmodified lines
810 return 0;812 return 0;
811}813}
812 814
813static unsigned long arm64_pcs_aux(int n, CType **type, unsigned long *a)815static unsigned long arm64_pcs_aux(int variadic, int n, CType **type, unsigned long *a)
814{816{
815 int nx = 0; // next integer register817 int nx = 0; // next integer register
816 int nv = 0; // next vector register818 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
827 else829 else
828 size = type_size(type[i], &align);830 size = type_size(type[i], &align);
829 831
832#if defined(__APPLE__)
833 if (variadic && i == variadic) {
834 nx = 8;
835 nv = 8;
836 }
837#endif
830 if (hfa)838 if (hfa)
831 // B.2839 // B.2
832 ;840 ;
@@ -931,7 +939,7 @@ static unsigned long arm64_pcs_aux(int n, CType **type, unsigned long *a) · 98 unmodified lines
931 return ns - 32;939 return ns - 32;
932}940}
933 941
934static unsigned long arm64_pcs(int n, CType **type, unsigned long *a)942static unsigned long arm64_pcs(int variadic, int n, CType **type, unsigned long *a)
935{943{
936 unsigned long stack;944 unsigned long stack;
937 945
@@ -939,12 +947,12 @@ static unsigned long arm64_pcs(int n, CType **type, unsigned long *a) · 1 unmodified line
939 if ((type[0]->t & VT_BTYPE) == VT_VOID)947 if ((type[0]->t & VT_BTYPE) == VT_VOID)
940 a[0] = -1;948 a[0] = -1;
941 else {949 else {
942 arm64_pcs_aux(1, type, a);950 arm64_pcs_aux(0, 1, type, a);
943 assert(a[0] == 0 || a[0] == 1 || a[0] == 16);951 assert(a[0] == 0 || a[0] == 1 || a[0] == 16);
944 }952 }
945 953
946 // Argument types:954 // Argument types:
947 stack = arm64_pcs_aux(n, type + 1, a + 1);955 stack = arm64_pcs_aux(variadic, n, type + 1, a + 1);
948 956
949 if (0) {957 if (0) {
950 int i;958 int i;
@@ -970,6 +978,16 @@ static unsigned long arm64_pcs(int n, CType **type, unsigned long *a) · 19 unmodified lines
970 return stack;978 return stack;
971}979}
972 980
981static 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
973ST_FUNC void gfunc_call(int nb_args)991ST_FUNC void gfunc_call(int nb_args)
974{992{
975 CType *return_type;993 CType *return_type;
@@ -977,6 +995,8 @@ ST_FUNC void gfunc_call(int nb_args) · 1 unmodified line
977 unsigned long *a, *a1;995 unsigned long *a, *a1;
978 unsigned long stack;996 unsigned long stack;
979 int i;997 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);
980 1000
981#ifdef CONFIG_TCC_BCHECK1001#ifdef CONFIG_TCC_BCHECK
982 if (tcc_state->do_bounds_check)1002 if (tcc_state->do_bounds_check)
@@ -995,7 +1015,7 @@ ST_FUNC void gfunc_call(int nb_args) · 12 unmodified lines
995 for (i = 0; i < nb_args; i++)1015 for (i = 0; i < nb_args; i++)
996 t[nb_args - i] = &vtop[-i].type;1016 t[nb_args - i] = &vtop[-i].type;
997 1017
998 stack = arm64_pcs(nb_args, t, a);1018 stack = arm64_pcs(variadic ? var_nb_arg : 0, nb_args, t, a);
999 1019
1000 // Allocate space for structs replaced by pointer:1020 // Allocate space for structs replaced by pointer:
1001 for (i = nb_args; i; i--)1021 for (i = nb_args; i; i--)
@@ -1055,7 +1075,7 @@ ST_FUNC void gfunc_call(int nb_args) · 53 unmodified lines
1055 }1075 }
1056 else {1076 else {
1057 gv(RC_INT);1077 gv(RC_INT);
1058 arm64_strx(arm64_type_size(vtop[0].type.t),1078 arm64_strx(3, // arm64_type_size(vtop[0].type.t),
1059 intr(vtop[0].r), 31, a[i] - 32);1079 intr(vtop[0].r), 31, a[i] - 32);
1060 }1080 }
1061 }1081 }
@@ -1167,6 +1187,8 @@ ST_FUNC void gfunc_prolog(Sym *func_sym) · 105 unmodified lines
1167 int use_x8 = 0;1187 int use_x8 = 0;
1168 int last_int = 0;1188 int last_int = 0;
1169 int last_float = 0;1189 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);
1170 1192
1171 func_vc = 144; // offset of where x8 is stored1193 func_vc = 144; // offset of where x8 is stored
1172 1194
@@ -1178,9 +1200,9 @@ ST_FUNC void gfunc_prolog(Sym *func_sym) · 5 unmodified lines
1178 for (sym = func_type->ref; sym; sym = sym->next)1200 for (sym = func_type->ref; sym; sym = sym->next)
1179 t[i++] = &sym->type;1201 t[i++] = &sym->type;
1180 1202
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);
1182 1204
1183 if (func_sym->type.ref->f.func_type == FUNC_ELLIPSIS) {1205 if (variadic) {
1184 use_x8 = 1;1206 use_x8 = 1;
1185 last_int = 4;1207 last_int = 4;
1186 last_float = 4;1208 last_float = 4;
@@ -1282,6 +1304,7 @@ ST_FUNC void gen_va_start(void) · 95 unmodified lines
1282 o(0x910383be); // add x30,x29,#2241304 o(0x910383be); // add x30,x29,#224
1283 o(0xf900001e | r << 5); // str x30,[x(r)]1305 o(0xf900001e | r << 5); // str x30,[x(r)]
1284 1306
1307#if !defined(__APPLE__)
1285 if (arm64_func_va_list_gr_offs) {1308 if (arm64_func_va_list_gr_offs) {
1286 if (arm64_func_va_list_stack)1309 if (arm64_func_va_list_stack)
1287 o(0x910383be); // add x30,x29,#2241310 o(0x910383be); // add x30,x29,#224
@@ -1298,6 +1321,7 @@ ST_FUNC void gen_va_start(void) · 10 unmodified lines
1298 1321
1299 arm64_movimm(30, arm64_func_va_list_vr_offs);1322 arm64_movimm(30, arm64_func_va_list_vr_offs);
1300 o(0xb9001c1e | r << 5); // str w30,[x(r),#28]1323 o(0xb9001c1e | r << 5); // str w30,[x(r),#28]
1324#endif
1301 1325
1302 --vtop;1326 --vtop;
1303}1327}
@@ -1321,6 +1345,7 @@ ST_FUNC void gen_va_arg(CType *t) · 17 unmodified lines
1321 1345
1322 if (!hfa) {1346 if (!hfa) {
1323 uint32_t n = size > 16 ? 8 : (size + 7) & -8;1347 uint32_t n = size > 16 ? 8 : (size + 7) & -8;
1348#if !defined(__APPLE__)
1324 o(0xb940181e | r0 << 5); // ldr w30,[x(r0),#24] // __gr_offs1349 o(0xb940181e | r0 << 5); // ldr w30,[x(r0),#24] // __gr_offs
1325 if (align == 16) {1350 if (align == 16) {
1326 assert(0); // this path untested but needed for __uint128_t1351 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
1329 }1354 }
1330 o(0x310003c0 | r1 | n << 10); // adds w(r1),w30,#(n)1355 o(0x310003c0 | r1 | n << 10); // adds w(r1),w30,#(n)
1331 o(0x540000ad); // b.le .+201356 o(0x540000ad); // b.le .+20
1357#endif
1332 o(0xf9400000 | r1 | r0 << 5); // ldr x(r1),[x(r0)] // __stack1358 o(0xf9400000 | r1 | r0 << 5); // ldr x(r1),[x(r0)] // __stack
1333 o(0x9100001e | r1 << 5 | n << 10); // add x30,x(r1),#(n)1359 o(0x9100001e | r1 << 5 | n << 10); // add x30,x(r1),#(n)
1334 o(0xf900001e | r0 << 5); // str x30,[x(r0)] // __stack1360 o(0xf900001e | r0 << 5); // str x30,[x(r0)] // __stack
1361#if !defined(__APPLE__)
1335 o(0x14000004); // b .+161362 o(0x14000004); // b .+16
1336 o(0xb9001800 | r1 | r0 << 5); // str w(r1),[x(r0),#24] // __gr_offs1363 o(0xb9001800 | r1 | r0 << 5); // str w(r1),[x(r0),#24] // __gr_offs
1337 o(0xf9400400 | r1 | r0 << 5); // ldr x(r1),[x(r0),#8] // __gr_top1364 o(0xf9400400 | r1 | r0 << 5); // ldr x(r1),[x(r0),#8] // __gr_top
1338 o(0x8b3ec000 | r1 | r1 << 5); // add x(r1),x(r1),w30,sxtw1365 o(0x8b3ec000 | r1 | r1 << 5); // add x(r1),x(r1),w30,sxtw
1366#endif
1339 if (size > 16)1367 if (size > 16)
1340 o(0xf9400000 | r1 | r1 << 5); // ldr x(r1),[x(r1)]1368 o(0xf9400000 | r1 | r1 << 5); // ldr x(r1),[x(r1)]
1341 }1369 }
1342 else {1370 else {
1343 uint32_t rsz = hfa << 4;
1344 uint32_t ssz = (size + 7) & -(uint32_t)8;1371 uint32_t ssz = (size + 7) & -(uint32_t)8;
1372#if !defined(__APPLE__)
1373 uint32_t rsz = hfa << 4;
1345 uint32_t b1, b2;1374 uint32_t b1, b2;
1346 o(0xb9401c1e | r0 << 5); // ldr w30,[x(r0),#28] // __vr_offs1375 o(0xb9401c1e | r0 << 5); // ldr w30,[x(r0),#28] // __vr_offs
1347 o(0x310003c0 | r1 | rsz << 10); // adds w(r1),w30,#(rsz)1376 o(0x310003c0 | r1 | rsz << 10); // adds w(r1),w30,#(rsz)
1348 b1 = ind; o(0x5400000d); // b.le lab11377 b1 = ind; o(0x5400000d); // b.le lab1
1378#endif
1349 o(0xf9400000 | r1 | r0 << 5); // ldr x(r1),[x(r0)] // __stack1379 o(0xf9400000 | r1 | r0 << 5); // ldr x(r1),[x(r0)] // __stack
1350 if (fsize == 16) {1380 if (fsize == 16) {
1351 o(0x91003c00 | r1 | r1 << 5); // add x(r1),x(r1),#151381 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
1353 }1383 }
1354 o(0x9100001e | r1 << 5 | ssz << 10); // add x30,x(r1),#(ssz)1384 o(0x9100001e | r1 << 5 | ssz << 10); // add x30,x(r1),#(ssz)
1355 o(0xf900001e | r0 << 5); // str x30,[x(r0)] // __stack1385 o(0xf900001e | r0 << 5); // str x30,[x(r0)] // __stack
1386#if !defined(__APPLE__)
1356 b2 = ind; o(0x14000000); // b lab21387 b2 = ind; o(0x14000000); // b lab2
1357 // lab1:1388 // lab1:
1358 write32le(cur_text_section->data + b1, 0x5400000d | (ind - b1) << 3);1389 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
1376 }1407 }
1377 // lab2:1408 // lab2:
1378 write32le(cur_text_section->data + b2, 0x14000000 | (ind - b2) >> 2);1409 write32le(cur_text_section->data + b2, 0x14000000 | (ind - b2) >> 2);
1410#endif
1379 }1411 }
1380}1412}
1381 1413
@@ -1390,7 +1422,7 @@ ST_FUNC void gfunc_return(CType *func_type) · 8 unmodified lines
1390 CType *t = func_type;1422 CType *t = func_type;
1391 unsigned long a;1423 unsigned long a;
1392 1424
1393 arm64_pcs(0, &t, &a);1425 arm64_pcs(0, 0, &t, &a);
1394 switch (a) {1426 switch (a) {
1395 case -1:1427 case -1:
1396 break;1428 break;
include/tccdefs.h+7−0
@@ -207,11 +207,18 @@ · 206 unmodified lines
207 &~3), *(type *)(ap - ((sizeof(type)+3)&~3)))207 &~3), *(type *)(ap - ((sizeof(type)+3)&~3)))
208 208
209#elif defined __aarch64__209#elif defined __aarch64__
210#if defined __APPLE__
211 typedef struct {
212 void *__stack;
213 } __builtin_va_list;
214
215#else
210 typedef struct {216 typedef struct {
211 void *__stack, *__gr_top, *__vr_top;217 void *__stack, *__gr_top, *__vr_top;
212 int __gr_offs, __vr_offs;218 int __gr_offs, __vr_offs;
213 } __builtin_va_list;219 } __builtin_va_list;
214 220
221#endif
215#elif defined __riscv222#elif defined __riscv
216 typedef char *__builtin_va_list;223 typedef char *__builtin_va_list;
217 #define __va_reg_size (__riscv_xlen >> 3)224 #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
55OBJ-i386-win32 = $(I386_O) chkstk.o $(B_O) $(WIN_O)55OBJ-i386-win32 = $(I386_O) chkstk.o $(B_O) $(WIN_O)
56OBJ-x86_64-win32 = $(X86_64_O) chkstk.o $(B_O) $(WIN_O)56OBJ-x86_64-win32 = $(X86_64_O) chkstk.o $(B_O) $(WIN_O)
57OBJ-arm64 = $(ARM64_O) $(BCHECK_O) $(DSO_O)57OBJ-arm64 = $(ARM64_O) $(BCHECK_O) $(DSO_O)
58OBJ-arm64-osx = $(ARM64_O) va_list.o58OBJ-arm64-osx = $(ARM64_O) $(BCHECK_O)
59OBJ-arm = $(ARM_O) $(BCHECK_O) $(DSO_O)59OBJ-arm = $(ARM_O) $(BCHECK_O) $(DSO_O)
60OBJ-arm-fpa = $(ARM_O) $(DSO_O)60OBJ-arm-fpa = $(ARM_O) $(DSO_O)
61OBJ-arm-fpa-ld = $(ARM_O) $(DSO_O)61OBJ-arm-fpa-ld = $(ARM_O) $(DSO_O)
lib/atomic.S+51−44
@@ -5,6 +5,13 @@ · 4 unmodified lines
5 * __atomic_compare_exchange_45 * __atomic_compare_exchange_4
6 * __atomic_compare_exchange_86 * __atomic_compare_exchange_8
7 */7 */
8
9#ifdef __leading_underscore
10# define _(s) _##s
11#else
12# define _(s) s
13#endif
14
8#if defined __arm__15#if defined __arm__
9 16
10#ifndef __TINYC__17#ifndef __TINYC__
@@ -14,9 +21,9 @@ · 3 unmodified lines
14 .text21 .text
15 .align 222 .align 2
16 23
17 .global __atomic_compare_exchange_124 .global _(__atomic_compare_exchange_1)
18 .type __atomic_compare_exchange_1, %function25 .type _(__atomic_compare_exchange_1), %function
19__atomic_compare_exchange_1:26_(__atomic_compare_exchange_1):
20#ifdef __TINYC__27#ifdef __TINYC__
21 .int 0xe52de00428 .int 0xe52de004
22 .int 0xe5d1300029 .int 0xe5d13000
@@ -50,11 +57,11 @@ __atomic_compare_exchange_1: · 27 unmodified lines
50 strbne ip, [r1]57 strbne ip, [r1]
51 ldr pc, [sp], #458 ldr pc, [sp], #4
52#endif59#endif
53 .size __atomic_compare_exchange_1, .-__atomic_compare_exchange_160 .size _(__atomic_compare_exchange_1), .-_(__atomic_compare_exchange_1)
54 61
55 .global __atomic_compare_exchange_262 .global _(__atomic_compare_exchange_2)
56 .type __atomic_compare_exchange_2, %function63 .type _(__atomic_compare_exchange_2), %function
57__atomic_compare_exchange_2:64_(__atomic_compare_exchange_2):
58#ifdef __TINYC__65#ifdef __TINYC__
59 .int 0xe52de00466 .int 0xe52de004
60 .int 0xe1d130b067 .int 0xe1d130b0
@@ -88,11 +95,11 @@ __atomic_compare_exchange_2: · 27 unmodified lines
88 strhne ip, [r1]95 strhne ip, [r1]
89 ldr pc, [sp], #496 ldr pc, [sp], #4
90#endif97#endif
91 .size __atomic_compare_exchange_2, .-__atomic_compare_exchange_298 .size _(__atomic_compare_exchange_2), .-_(__atomic_compare_exchange_2)
92 99
93 .global __atomic_compare_exchange_4100 .global _(__atomic_compare_exchange_4)
94 .type __atomic_compare_exchange_4, %function101 .type _(__atomic_compare_exchange_4), %function
95__atomic_compare_exchange_4:102_(__atomic_compare_exchange_4):
96#ifdef __TINYC__103#ifdef __TINYC__
97 .int 0xe52de004104 .int 0xe52de004
98 .int 0xe5913000105 .int 0xe5913000
@@ -126,7 +133,7 @@ __atomic_compare_exchange_4: · 27 unmodified lines
126 strne ip, [r1]133 strne ip, [r1]
127 ldr pc, [sp], #4134 ldr pc, [sp], #4
128#endif135#endif
129 .size __atomic_compare_exchange_4, .-__atomic_compare_exchange_4136 .size _(__atomic_compare_exchange_4), .-_(__atomic_compare_exchange_4)
130 137
131/* ---------------------------------------------- */138/* ---------------------------------------------- */
132#elif defined __aarch64__139#elif defined __aarch64__
@@ -134,9 +141,9 @@ __atomic_compare_exchange_4: · 1 unmodified line
134 .text141 .text
135 .align 2142 .align 2
136 143
137 .global __atomic_compare_exchange_1144 .global _(__atomic_compare_exchange_1)
138 .type __atomic_compare_exchange_1, %function145 .type _(__atomic_compare_exchange_1), %function
139__atomic_compare_exchange_1:146_(__atomic_compare_exchange_1):
140#ifdef __TINYC__147#ifdef __TINYC__
141 .int 0xa9be7bfd148 .int 0xa9be7bfd
142 .int 0x910003fd149 .int 0x910003fd
@@ -187,11 +194,11 @@ __atomic_compare_exchange_1: · 44 unmodified lines
187 ldp x29, x30, [sp], 32194 ldp x29, x30, [sp], 32
188 ret195 ret
189#endif196#endif
190 .size __atomic_compare_exchange_1, .-__atomic_compare_exchange_1197 .size _(__atomic_compare_exchange_1), .-_(__atomic_compare_exchange_1)
191 198
192 .global __atomic_compare_exchange_2199 .global _(__atomic_compare_exchange_2)
193 .type __atomic_compare_exchange_2, %function200 .type _(__atomic_compare_exchange_2), %function
194__atomic_compare_exchange_2:201_(__atomic_compare_exchange_2):
195#ifdef __TINYC__202#ifdef __TINYC__
196 .int 0xa9be7bfd203 .int 0xa9be7bfd
197 .int 0x910003fd204 .int 0x910003fd
@@ -242,11 +249,11 @@ __atomic_compare_exchange_2: · 44 unmodified lines
242 ldp x29, x30, [sp], 32249 ldp x29, x30, [sp], 32
243 ret250 ret
244#endif251#endif
245 .size __atomic_compare_exchange_2, .-__atomic_compare_exchange_2252 .size _(__atomic_compare_exchange_2), .-_(__atomic_compare_exchange_2)
246 253
247 .global __atomic_compare_exchange_4254 .global _(__atomic_compare_exchange_4)
248 .type __atomic_compare_exchange_4, %function255 .type _(__atomic_compare_exchange_4), %function
249__atomic_compare_exchange_4:256_(__atomic_compare_exchange_4):
250#ifdef __TINYC__257#ifdef __TINYC__
251 .int 0xa9be7bfd258 .int 0xa9be7bfd
252 .int 0x910003fd259 .int 0x910003fd
@@ -297,11 +304,11 @@ __atomic_compare_exchange_4: · 44 unmodified lines
297 ldp x29, x30, [sp], 32304 ldp x29, x30, [sp], 32
298 ret305 ret
299#endif306#endif
300 .size __atomic_compare_exchange_4, .-__atomic_compare_exchange_4307 .size _(__atomic_compare_exchange_4), .-_(__atomic_compare_exchange_4)
301 308
302 .global __atomic_compare_exchange_8309 .global _(__atomic_compare_exchange_8)
303 .type __atomic_compare_exchange_8, %function310 .type _(__atomic_compare_exchange_8), %function
304__atomic_compare_exchange_8:311_(__atomic_compare_exchange_8):
305#ifdef __TINYC__312#ifdef __TINYC__
306 .int 0xa9be7bfd313 .int 0xa9be7bfd
307 .int 0x910003fd314 .int 0x910003fd
@@ -352,7 +359,7 @@ __atomic_compare_exchange_8: · 44 unmodified lines
352 ldp x29, x30, [sp], 32359 ldp x29, x30, [sp], 32
353 ret360 ret
354#endif361#endif
355 .size __atomic_compare_exchange_8, .-__atomic_compare_exchange_8362 .size _(__atomic_compare_exchange_8), .-_(__atomic_compare_exchange_8)
356 363
357/* ---------------------------------------------- */364/* ---------------------------------------------- */
358#elif defined __riscv365#elif defined __riscv
@@ -360,9 +367,9 @@ __atomic_compare_exchange_8: · 1 unmodified line
360 .text367 .text
361 .align 2368 .align 2
362 369
363 .global __atomic_compare_exchange_1370 .global _(__atomic_compare_exchange_1)
364 .type __atomic_compare_exchange_1, %function371 .type _(__atomic_compare_exchange_1), %function
365__atomic_compare_exchange_1:372_(__atomic_compare_exchange_1):
366#ifdef __TINYC__373#ifdef __TINYC__
367 .short 0x1141374 .short 0x1141
368 .short 0x86ba375 .short 0x86ba
@@ -443,11 +450,11 @@ __atomic_compare_exchange_1: · 74 unmodified lines
443 addi sp,sp,16450 addi sp,sp,16
444 jr ra451 jr ra
445#endif452#endif
446 .size __atomic_compare_exchange_1, .-__atomic_compare_exchange_1453 .size _(__atomic_compare_exchange_1), .-_(__atomic_compare_exchange_1)
447 454
448 .global __atomic_compare_exchange_2455 .global _(__atomic_compare_exchange_2)
449 .type __atomic_compare_exchange_2, %function456 .type _(__atomic_compare_exchange_2), %function
450__atomic_compare_exchange_2:457_(__atomic_compare_exchange_2):
451#ifdef __TINYC__458#ifdef __TINYC__
452 .short 0x1141459 .short 0x1141
453 .short 0x86ba460 .short 0x86ba
@@ -530,11 +537,11 @@ __atomic_compare_exchange_2: · 76 unmodified lines
530 addi sp,sp,16537 addi sp,sp,16
531 jr ra538 jr ra
532#endif539#endif
533 .size __atomic_compare_exchange_2, .-__atomic_compare_exchange_2540 .size _(__atomic_compare_exchange_2), .-_(__atomic_compare_exchange_2)
534 541
535 .global __atomic_compare_exchange_4542 .global _(__atomic_compare_exchange_4)
536 .type __atomic_compare_exchange_4, %function543 .type _(__atomic_compare_exchange_4), %function
537__atomic_compare_exchange_4:544_(__atomic_compare_exchange_4):
538#ifdef __TINYC__545#ifdef __TINYC__
539 .short 0x419c546 .short 0x419c
540 .int 0x0f50000f547 .int 0x0f50000f
@@ -565,11 +572,11 @@ __atomic_compare_exchange_4: · 24 unmodified lines
565 andi a0,a0,1572 andi a0,a0,1
566 ret573 ret
567#endif574#endif
568 .size __atomic_compare_exchange_4, .-__atomic_compare_exchange_4575 .size _(__atomic_compare_exchange_4), .-_(__atomic_compare_exchange_4)
569 576
570 .global __atomic_compare_exchange_8577 .global _(__atomic_compare_exchange_8)
571 .type __atomic_compare_exchange_8, %function578 .type _(__atomic_compare_exchange_8), %function
572__atomic_compare_exchange_8:579_(__atomic_compare_exchange_8):
573#ifdef __TINYC__580#ifdef __TINYC__
574 .short 0x619c581 .short 0x619c
575 .int 0x0f50000f582 .int 0x0f50000f
@@ -600,7 +607,7 @@ __atomic_compare_exchange_8: · 24 unmodified lines
600 andi a0,a0,1607 andi a0,a0,1
601 ret608 ret
602#endif609#endif
603 .size __atomic_compare_exchange_8, .-__atomic_compare_exchange_8610 .size _(__atomic_compare_exchange_8), .-_(__atomic_compare_exchange_8)
604 611
605/* ---------------------------------------------- */612/* ---------------------------------------------- */
606#endif613#endif
lib/fetch_and_add.S+22−13
@@ -1,11 +1,20 @@
1/* ---------------------------------------------- */1/* ---------------------------------------------- */
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
2#if defined __arm__11#if defined __arm__
3 12
4 .text13 .text
5 .align 214 .align 2
6 .global fetch_and_add_arm15 .global _(fetch_and_add_arm)
7 .type fetch_and_add_arm, %function16 .type _(fetch_and_add_arm), %function
8fetch_and_add_arm:17_(fetch_and_add_arm):
9 mcr p15, #0, r0, c7, c10, #518 mcr p15, #0, r0, c7, c10, #5
10.L0:19.L0:
11 ldrex r3, [r0]20 ldrex r3, [r0]
@@ -15,16 +24,16 @@ fetch_and_add_arm: · 3 unmodified lines
15 bne .L024 bne .L0
16 mcr p15, #0, r0, c7, c10, #525 mcr p15, #0, r0, c7, c10, #5
17 bx lr26 bx lr
18 .size fetch_and_add_arm, .-fetch_and_add_arm27 .size _(fetch_and_add_arm), .-_(fetch_and_add_arm)
19 28
20/* ---------------------------------------------- */29/* ---------------------------------------------- */
21#elif defined __aarch64__30#elif defined __aarch64__
22 31
23 .text32 .text
24 .align 233 .align 2
25 .global fetch_and_add_arm6434 .global _(fetch_and_add_arm64)
26 .type fetch_and_add_arm64, %function35 .type _(fetch_and_add_arm64), %function
27fetch_and_add_arm64:36_(fetch_and_add_arm64):
28#ifdef __TINYC__37#ifdef __TINYC__
29 .int 0x885f7c0238 .int 0x885f7c02
30 .int 0x0b01004239 .int 0x0b010042
@@ -36,21 +45,21 @@ fetch_and_add_arm64: · 5 unmodified lines
36 ldxr w2, [x0]45 ldxr w2, [x0]
37 add w2, w2, w146 add w2, w2, w1
38 stlxr w3, w2, [x0]47 stlxr w3, w2, [x0]
39 cbnz w3, fetch_and_add_arm6448 cbnz w3, _(fetch_and_add_arm64)
40 dmb ish49 dmb ish
41 ret50 ret
42#endif51#endif
43 52
44 .size fetch_and_add_arm64, .-fetch_and_add_arm6453 .size _(fetch_and_add_arm64), .-_(fetch_and_add_arm64)
45 54
46/* ---------------------------------------------- */55/* ---------------------------------------------- */
47#elif defined __riscv56#elif defined __riscv
48 57
49 .text58 .text
50 .align 259 .align 2
51 .global fetch_and_add_riscv6460 .global _(fetch_and_add_riscv64)
52 .type fetch_and_add_riscv64, %function61 .type _(fetch_and_add_riscv64), %function
53fetch_and_add_riscv64:62_(fetch_and_add_riscv64):
54#ifdef __TINYC__63#ifdef __TINYC__
55 .int 0x0f50000f64 .int 0x0f50000f
56 .int 0x004b5202f65 .int 0x004b5202f
@@ -61,7 +70,7 @@ fetch_and_add_riscv64: · 4 unmodified lines
61 ret70 ret
62#endif71#endif
63 72
64 .size fetch_and_add_riscv64, .-fetch_and_add_riscv6473 .size _(fetch_and_add_riscv64), .-_(fetch_and_add_riscv64)
65 74
66/* ---------------------------------------------- */75/* ---------------------------------------------- */
67#endif76#endif
lib/lib-arm64.c+1−1
@@ -24,7 +24,7 @@ void *memcpy(void*,void*,__SIZE_TYPE__); · 23 unmodified lines
24#include <string.h>24#include <string.h>
25#endif25#endif
26 26
27#ifndef __riscv27#if !defined __riscv && !defined __APPLE__
28void __clear_cache(void *beg, void *end)28void __clear_cache(void *beg, void *end)
29{29{
30 __arm64_clear_cache(beg, end);30 __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
1487 addr_t end_offset;1487 addr_t end_offset;
1488 char buf[1024];1488 char buf[1024];
1489 s = find_section_create(s1, section_name, 0);1489 s = find_section_create(s1, section_name, 0);
1490 if (!s) {1490 if (!s || !(s->sh_flags & SHF_ALLOC)) {
1491 end_offset = 0;1491 end_offset = 0;
1492 s = data_section;1492 s = data_section;
1493 } else {1493 } else {
tccmacho.c+606−54
@@ -31,9 +31,28 @@ · 30 unmodified lines
31 to setup our own crt code. We're not using lazy linking, so even function31 to setup our own crt code. We're not using lazy linking, so even function
32 calls are resolved at startup. */32 calls are resolved at startup. */
33 33
34#if !defined TCC_TARGET_X86_64 && !defined TCC_TARGET_ARM64
35#error Platform not supported
36#endif
37
34#define DEBUG_MACHO 038#define DEBUG_MACHO 0
35#define dprintf if (DEBUG_MACHO) printf39#define dprintf if (DEBUG_MACHO) printf
36 40
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
37struct fat_header {56struct fat_header {
38 uint32_t magic; /* FAT_MAGIC or FAT_MAGIC_64 */57 uint32_t magic; /* FAT_MAGIC or FAT_MAGIC_64 */
39 uint32_t nfat_arch; /* number of structs that follow */58 uint32_t nfat_arch; /* number of structs that follow */
@@ -86,6 +105,7 @@ struct load_command { · 46 unmodified lines
86#define LC_LOAD_DYLINKER 0xe105#define LC_LOAD_DYLINKER 0xe
87#define LC_SEGMENT_64 0x19106#define LC_SEGMENT_64 0x19
88#define LC_REEXPORT_DYLIB (0x1f | LC_REQ_DYLD)107#define LC_REEXPORT_DYLIB (0x1f | LC_REQ_DYLD)
108#define LC_DYLD_INFO_ONLY (0x22|LC_REQ_DYLD)
89#define LC_MAIN (0x28|LC_REQ_DYLD)109#define LC_MAIN (0x28|LC_REQ_DYLD)
90 110
91typedef int vm_prot_t;111typedef int vm_prot_t;
@@ -122,6 +142,8 @@ struct section_64 { /* for 64-bit architectures */ · 30 unmodified lines
122#define S_REGULAR 0x0142#define S_REGULAR 0x0
123#define S_ZEROFILL 0x1143#define S_ZEROFILL 0x1
124#define S_NON_LAZY_SYMBOL_POINTERS 0x6144#define S_NON_LAZY_SYMBOL_POINTERS 0x6
145#define S_LAZY_SYMBOL_POINTERS 0x7
146#define S_SYMBOL_STUBS 0x8
125#define S_MOD_INIT_FUNC_POINTERS 0x9147#define S_MOD_INIT_FUNC_POINTERS 0x9
126#define S_MOD_TERM_FUNC_POINTERS 0xa148#define S_MOD_TERM_FUNC_POINTERS 0xa
127 149
@@ -187,6 +209,38 @@ struct dysymtab_command { · 59 unmodified lines
187 uint32_t nlocrel; /* number of local relocation entries */209 uint32_t nlocrel; /* number of local relocation entries */
188};210};
189 211
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
229struct 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
190#define INDIRECT_SYMBOL_LOCAL 0x80000000244#define INDIRECT_SYMBOL_LOCAL 0x80000000
191 245
192struct entry_point_command {246struct entry_point_command {
@@ -201,6 +255,7 @@ enum skind { · 8 unmodified lines
201 sk_discard,255 sk_discard,
202 sk_text,256 sk_text,
203 sk_stubs,257 sk_stubs,
258 sk_stub_helper,
204 sk_ro_data,259 sk_ro_data,
205 sk_uw_info,260 sk_uw_info,
206 sk_nl_ptr, // non-lazy pointers, aka GOT261 sk_nl_ptr, // non-lazy pointers, aka GOT
@@ -208,6 +263,14 @@ enum skind { · 1 unmodified line
208 sk_init,263 sk_init,
209 sk_fini,264 sk_fini,
210 sk_rw_data,265 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,
211 sk_bss,274 sk_bss,
212 sk_linkedit,275 sk_linkedit,
213 sk_last276 sk_last
@@ -241,9 +304,26 @@ struct macho { · 27 unmodified lines
241 } sk_to_sect[sk_last];304 } sk_to_sect[sk_last];
242 int *elfsectomacho;305 int *elfsectomacho;
243 int *e2msym;306 int *e2msym;
244 Section *symtab, *strtab, *wdata, *indirsyms, *stubs;307 Section *rebase, *binding, *lazy_binding, *exports;
245 int stubsym;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;
246 uint32_t ilocal, iextdef, iundef;313 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;
247};327};
248 328
249#define SHT_LINKEDIT (SHT_LOOS + 42)329#define SHT_LINKEDIT (SHT_LOOS + 42)
@@ -306,20 +386,165 @@ static void * add_dylib(struct macho *mo, char *name) · 56 unmodified lines
306 return lc;386 return lc;
307}387}
308 388
389static 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
400static 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
309static void check_relocs(TCCState *s1, struct macho *mo)495static void check_relocs(TCCState *s1, struct macho *mo)
310{496{
497 uint8_t *jmp;
311 Section *s;498 Section *s;
312 ElfW_Rel *rel;499 ElfW_Rel *rel;
313 ElfW(Sym) *sym;500 ElfW(Sym) *sym;
314 int i, type, gotplt_entry, sym_index, for_code;501 int i, type, gotplt_entry, sym_index, for_code;
502 int sh_num, debug, bind_offset, la_symbol_offset;
503 uint32_t *pi, *goti;
315 struct sym_attr *attr;504 struct sym_attr *attr;
316 505
317 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
318 mo->indirsyms = new_section(s1, "LEINDIR", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE);506 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;
319 for (i = 1; i < s1->nb_sections; i++) {542 for (i = 1; i < s1->nb_sections; i++) {
320 s = s1->sections[i];543 s = s1->sections[i];
321 if (s->sh_type != SHT_RELX)544 if (s->sh_type != SHT_RELX)
322 continue;545 continue;
546 sh_num = s1->sections[s->sh_info]->sh_num;
547 debug = sh_num >= s1->dwlo && sh_num < s1->dwhi;
323 for_each_elem(s, 0, rel, ElfW_Rel) {548 for_each_elem(s, 0, rel, ElfW_Rel) {
324 type = ELFW(R_TYPE)(rel->r_info);549 type = ELFW(R_TYPE)(rel->r_info);
325 gotplt_entry = gotplt_entry_type(type);550 gotplt_entry = gotplt_entry_type(type);
@@ -329,44 +554,150 @@ static void check_relocs(TCCState *s1, struct macho *mo) · 3 unmodified lines
329 address due to codegen (i.e. a reloc requiring a got slot). */554 address due to codegen (i.e. a reloc requiring a got slot). */
330 sym_index = ELFW(R_SYM)(rel->r_info);555 sym_index = ELFW(R_SYM)(rel->r_info);
331 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];556 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
332 if (sym->st_shndx == SHN_UNDEF557 if (!debug &&
333 || gotplt_entry == ALWAYS_GOTPLT_ENTRY) {558 (sym->st_shndx == SHN_UNDEF
559 || gotplt_entry == ALWAYS_GOTPLT_ENTRY)) {
334 attr = get_sym_attr(s1, sym_index, 1);560 attr = get_sym_attr(s1, sym_index, 1);
335 if (!attr->dyn_index) {561 if (!attr->dyn_index) {
336 uint32_t *pi = section_ptr_add(mo->indirsyms, sizeof(*pi));
337 attr->got_offset = s1->got->data_offset;562 attr->got_offset = s1->got->data_offset;
338 attr->plt_offset = -1;563 attr->plt_offset = -1;
339 attr->dyn_index = 1; /* used as flag */564 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));
341 if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) {569 if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) {
342 if (sym->st_shndx == SHN_UNDEF)570 if (sym->st_shndx == SHN_UNDEF)
343 tcc_error("undefined local symbol???");571 tcc_error("undefined local symbo: '%s'",
344 *pi = INDIRECT_SYMBOL_LOCAL;572 (char *) symtab_section->link->data + sym->st_name);
345 /* The pointer slot we generated must point to the573 goti[mo->n_got++] = INDIRECT_SYMBOL_LOCAL;
346 symbol, whose address is only known after layout,574 } else {
347 so register a simple relocation for that. */575 goti[mo->n_got++] = mo->e2msym[sym_index];
348 put_elf_reloc(s1->symtab, s1->got, attr->got_offset,576 if (sym->st_shndx == SHN_UNDEF
349 R_DATA_PTR, sym_index);577#ifdef TCC_TARGET_X86_64
350 } else578 && type == R_X86_64_GOTPCREL
351 *pi = mo->e2msym[sym_index];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 }
352 }594 }
353 if (for_code) {595 if (for_code && sym->st_shndx == SHN_UNDEF) {
354 if (attr->plt_offset == -1) {596 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++;
356 attr->plt_offset = mo->stubs->data_offset;600 attr->plt_offset = mo->stubs->data_offset;
601#ifdef TCC_TARGET_X86_64
602 if (type != R_X86_64_PLT32)
603 continue;
604 /* __stubs */
357 jmp = section_ptr_add(mo->stubs, 6);605 jmp = section_ptr_add(mo->stubs, 6);
358 jmp[0] = 0xff; /* jmpq *ofs(%rip) */606 jmp[0] = 0xff; /* jmpq *__la_symbol_ptr(%rip) */
359 jmp[1] = 0x25;607 jmp[1] = 0x25;
360 put_elf_reloc(s1->symtab, mo->stubs,608 put_elf_reloca(s1->symtab, mo->stubs,
361 attr->plt_offset + 2,609 mo->stubs->data_offset - 4,
362 R_X86_64_GOTPCREL, sym_index);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++;
363 }679 }
364 rel->r_info = ELFW(R_INFO)(mo->stubsym, type);680 rel->r_info = ELFW(R_INFO)(mo->stubsym, type);
365 rel->r_addend += attr->plt_offset;681 rel->r_addend += attr->plt_offset;
366 }682 }
367 }683 }
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 }
368 }694 }
369 }695 }
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);
370}701}
371 702
372static int check_symbols(TCCState *s1, struct macho *mo)703static 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
444 n.n_type = N_ABS, n.n_sect = 0;775 n.n_type = N_ABS, n.n_sect = 0;
445 else if (sym->st_shndx >= SHN_LORESERVE)776 else if (sym->st_shndx >= SHN_LORESERVE)
446 tcc_error("unhandled ELF symbol section %d %s", sym->st_shndx, name);777 tcc_error("unhandled ELF symbol section %d %s", sym->st_shndx, name);
447 else if (!mo->elfsectomacho[sym->st_shndx])778 else if (!mo->elfsectomacho[sym->st_shndx]) {
448 tcc_error("ELF section %d not mapped into Mach-O for symbol %s",779 int sh_num = s1->sections[sym->st_shndx]->sh_num;
449 sym->st_shndx, name);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 }
450 else784 else
451 n.n_sect = mo->elfsectomacho[sym->st_shndx];785 n.n_sect = mo->elfsectomacho[sym->st_shndx];
452 if (ELFW(ST_BIND)(sym->st_info) == STB_GLOBAL)786 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
465 convert_symbol(s1, mo, pn);799 convert_symbol(s1, mo, pn);
466}800}
467 801
468static int machosymcmp(const void *_a, const void *_b)802static int machosymcmp(const void *_a, const void *_b, void *arg)
469{803{
470 TCCState *s1 = tcc_state;804 TCCState *s1 = arg;
471 int ea = ((struct nlist_64 *)_a)->n_value;805 int ea = ((struct nlist_64 *)_a)->n_value;
472 int eb = ((struct nlist_64 *)_b)->n_value;806 int eb = ((struct nlist_64 *)_b)->n_value;
473 ElfSym *sa = (ElfSym *)symtab_section->data + ea;807 ElfSym *sa = (ElfSym *)symtab_section->data + ea;
@@ -492,6 +826,37 @@ static int machosymcmp(const void *_a, const void *_b) · 18 unmodified lines
492 return ea - eb;826 return ea - eb;
493}827}
494 828
829/* cannot use qsort because code has to be reentrant */
830static 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
495static void create_symtab(TCCState *s1, struct macho *mo)860static void create_symtab(TCCState *s1, struct macho *mo)
496{861{
497 int sym_index, sym_end;862 int sym_index, sym_end;
@@ -500,9 +865,30 @@ static void create_symtab(TCCState *s1, struct macho *mo) · 2 unmodified lines
500 /* Stub creation belongs to check_relocs, but we need to create865 /* Stub creation belongs to check_relocs, but we need to create
501 the symbol now, so its included in the sorting. */866 the symbol now, so its included in the sorting. */
502 mo->stubs = new_section(s1, "__stubs", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);867 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);
503 mo->stubsym = put_elf_sym(s1->symtab, 0, 0,871 mo->stubsym = put_elf_sym(s1->symtab, 0, 0,
504 ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0,872 ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0,
505 mo->stubs->sh_num, ".__stubs");873 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);
506 892
507 mo->symtab = new_section(s1, "LESYMTAB", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE);893 mo->symtab = new_section(s1, "LESYMTAB", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE);
508 mo->strtab = new_section(s1, "LESTRTAB", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE);894 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
515 pn[sym_index - 1].n_strx = put_elf_str(mo->strtab, name);901 pn[sym_index - 1].n_strx = put_elf_str(mo->strtab, name);
516 pn[sym_index - 1].n_value = sym_index;902 pn[sym_index - 1].n_value = sym_index;
517 }903 }
518 tcc_enter_state(s1); /* qsort needs global state */904 tcc_qsort(pn, sym_end - 1, sizeof(*pn), machosymcmp, s1);
519 qsort(pn, sym_end - 1, sizeof(*pn), machosymcmp);
520 tcc_exit_state(s1);
521 mo->e2msym = tcc_malloc(sym_end * sizeof(*mo->e2msym));905 mo->e2msym = tcc_malloc(sym_end * sizeof(*mo->e2msym));
522 mo->e2msym[0] = -1;906 mo->e2msym[0] = -1;
523 for (sym_index = 1; sym_index < sym_end; ++sym_index) {907 for (sym_index = 1; sym_index < sym_end; ++sym_index) {
@@ -530,22 +914,121 @@ const struct { · 6 unmodified lines
530 uint32_t flags;914 uint32_t flags;
531 const char *name;915 const char *name;
532} skinfo[sk_last] = {916} skinfo[sk_last] = {
533 /*[sk_unknown] =*/ { 0 },917 /*[sk_unknown] =*/ { 0 },
534 /*[sk_discard] =*/ { 0 },918 /*[sk_discard] =*/ { 0 },
535 /*[sk_text] =*/ { 1, S_REGULAR | S_ATTR_PURE_INSTRUCTIONS919 /*[sk_text] =*/ { 1, S_REGULAR | S_ATTR_PURE_INSTRUCTIONS
536 | S_ATTR_SOME_INSTRUCTIONS, "__text" },920 | S_ATTR_SOME_INSTRUCTIONS, "__text" },
537 /*[sk_stubs] =*/ { 0 },921 /*[sk_stubs] =*/ { 1, S_REGULAR | S_ATTR_PURE_INSTRUCTIONS | S_SYMBOL_STUBS
538 /*[sk_ro_data] =*/ { 1, S_REGULAR, "__rodata" },922 | S_ATTR_SOME_INSTRUCTIONS , "__stubs" },
539 /*[sk_uw_info] =*/ { 0 },923 /*[sk_stub_helper] =*/ { 1, S_REGULAR | S_ATTR_PURE_INSTRUCTIONS
540 /*[sk_nl_ptr] =*/ { 2, S_NON_LAZY_SYMBOL_POINTERS, "__got" },924 | S_ATTR_SOME_INSTRUCTIONS , "__stub_helper" },
541 /*[sk_la_ptr] =*/ { 0 },925 /*[sk_ro_data] =*/ { 1, S_REGULAR, "__rodata" },
542 /*[sk_init] =*/ { 2, S_MOD_INIT_FUNC_POINTERS, "__mod_init_func" },926 /*[sk_uw_info] =*/ { 0 },
543 /*[sk_fini] =*/ { 2, S_MOD_TERM_FUNC_POINTERS, "__mod_term_func" },927 /*[sk_nl_ptr] =*/ { 2, S_NON_LAZY_SYMBOL_POINTERS, "__got" },
544 /*[sk_rw_data] =*/ { 2, S_REGULAR, "__data" },928 /*[sk_la_ptr] =*/ { 2, S_LAZY_SYMBOL_POINTERS, "__la_symbol_ptr" },
545 /*[sk_bss] =*/ { 2, S_ZEROFILL, "__bss" },929 /*[sk_init] =*/ { 2, S_MOD_INIT_FUNC_POINTERS, "__mod_init_func" },
546 /*[sk_linkedit] =*/ { 3, S_REGULAR, NULL },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 },
547};942};
548 943
944static 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
960static 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
549static void collect_sections(TCCState *s1, struct macho *mo)1032static void collect_sections(TCCState *s1, struct macho *mo)
550{1033{
551 int i, sk, numsec;1034 int i, sk, numsec;
@@ -584,6 +1067,7 @@ static void collect_sections(TCCState *s1, struct macho *mo) · 32 unmodified lines
584 str = (char*)dyldlc + dyldlc->name;1067 str = (char*)dyldlc + dyldlc->name;
585 strcpy(str, "/usr/lib/dyld");1068 strcpy(str, "/usr/lib/dyld");
586 1069
1070 mo->dyldinfo = add_lc(mo, LC_DYLD_INFO_ONLY, sizeof(*mo->dyldinfo));
587 symlc = add_lc(mo, LC_SYMTAB, sizeof(*symlc));1071 symlc = add_lc(mo, LC_SYMTAB, sizeof(*symlc));
588 dysymlc = add_lc(mo, LC_DYSYMTAB, sizeof(*dysymlc));1072 dysymlc = add_lc(mo, LC_DYSYMTAB, sizeof(*dysymlc));
589 1073
@@ -610,12 +1094,37 @@ static void collect_sections(TCCState *s1, struct macho *mo) · 20 unmodified lines
610 case SHT_FINI_ARRAY: sk = sk_fini; break;1094 case SHT_FINI_ARRAY: sk = sk_fini; break;
611 case SHT_NOBITS: sk = sk_bss; break;1095 case SHT_NOBITS: sk = sk_bss; break;
612 case SHT_SYMTAB: sk = sk_discard; break;1096 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;
614 case SHT_RELX: sk = sk_discard; break;1103 case SHT_RELX: sk = sk_discard; break;
615 case SHT_LINKEDIT: sk = sk_linkedit; break;1104 case SHT_LINKEDIT: sk = sk_linkedit; break;
616 case SHT_PROGBITS:1105 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)
618 sk = sk_nl_ptr;1111 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;
619 else if (flags & SHF_EXECINSTR)1128 else if (flags & SHF_EXECINSTR)
620 sk = sk_text;1129 sk = sk_text;
621 else if (flags & SHF_WRITE)1130 else if (flags & SHF_WRITE)
@@ -637,9 +1146,14 @@ static void collect_sections(TCCState *s1, struct macho *mo) · 15 unmodified lines
637 mo->elfsectomacho = tcc_mallocz(sizeof(*mo->elfsectomacho) * s1->nb_sections);1146 mo->elfsectomacho = tcc_mallocz(sizeof(*mo->elfsectomacho) * s1->nb_sections);
638 for (sk = sk_unknown; sk < sk_last; sk++) {1147 for (sk = sk_unknown; sk < sk_last; sk++) {
639 struct section_64 *sec = NULL;1148 struct section_64 *sec = NULL;
1149#define SEG_PAGE_SIZE 16384
1150 if (sk == sk_linkedit)
1151 do_bind_rebase(s1, mo);
640 if (seg) {1152 if (seg) {
641 seg->vmsize = curaddr - seg->vmaddr;1153 seg->vmsize = (curaddr - seg->vmaddr + SEG_PAGE_SIZE - 1) & -SEG_PAGE_SIZE;
642 seg->filesize = fileofs - seg->fileoff;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;
643 }1157 }
644 if (skinfo[sk].seg && mo->sk_to_sect[sk].s) {1158 if (skinfo[sk].seg && mo->sk_to_sect[sk].s) {
645 uint64_t al = 0;1159 uint64_t al = 0;
@@ -652,6 +1166,16 @@ static void collect_sections(TCCState *s1, struct macho *mo) · 6 unmodified lines
652 mo->sk_to_sect[sk].machosect = si;1166 mo->sk_to_sect[sk].machosect = si;
653 sec = get_section(seg, si);1167 sec = get_section(seg, si);
654 sec->flags = skinfo[sk].flags;1168 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;
655 }1179 }
656 if (seg->vmaddr == -1) {1180 if (seg->vmaddr == -1) {
657 curaddr = (curaddr + 4095) & -4096;1181 curaddr = (curaddr + 4095) & -4096;
@@ -737,6 +1261,23 @@ static void collect_sections(TCCState *s1, struct macho *mo) · 79 unmodified lines
737 dysymlc->nundefsym = symlc->nsyms - dysymlc->iundefsym;1261 dysymlc->nundefsym = symlc->nsyms - dysymlc->iundefsym;
738 dysymlc->indirectsymoff = mo->indirsyms->sh_offset;1262 dysymlc->indirectsymoff = mo->indirsyms->sh_offset;
739 dysymlc->nindirectsyms = mo->indirsyms->data_offset / sizeof(uint32_t);1263 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 }
740}1281}
741 1282
742static void macho_write(TCCState *s1, struct macho *mo, FILE *fp)1283static 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
745 uint64_t fileofs = 0;1286 uint64_t fileofs = 0;
746 Section *s;1287 Section *s;
747 mo->mh.mh.magic = MH_MAGIC_64;1288 mo->mh.mh.magic = MH_MAGIC_64;
748 mo->mh.mh.cputype = 0x1000007; // x86_641289#ifdef TCC_TARGET_X86_64
749 mo->mh.mh.cpusubtype = 0x80000003;// all | CPU_SUBTYPE_LIB641290 mo->mh.mh.cputype = CPU_TYPE_X86_64;
750 mo->mh.mh.filetype = 2; // MH_EXECUTE1291 mo->mh.mh.cpusubtype = CPU_SUBTYPE_LIB64 | CPU_SUBTYPE_X86_ALL;
751 mo->mh.mh.flags = 4; // DYLDLINK1292#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;
752 mo->mh.mh.ncmds = mo->nlc;1298 mo->mh.mh.ncmds = mo->nlc;
753 mo->mh.mh.sizeofcmds = 0;1299 mo->mh.mh.sizeofcmds = 0;
754 for (i = 0; i < mo->nlc; i++)1300 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
803 printf("<- %s\n", filename);1349 printf("<- %s\n", filename);
804 1350
805 tcc_add_runtime(s1);1351 tcc_add_runtime(s1);
1352 tcc_macho_add_destructor(s1);
806 resolve_common_syms(s1);1353 resolve_common_syms(s1);
807 create_symtab(s1, &mo);1354 create_symtab(s1, &mo);
808 check_relocs(s1, &mo);1355 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
959 fh.nfat_arch * sizeof(*fa));1506 fh.nfat_arch * sizeof(*fa));
960 swap = fh.magic == FAT_CIGAM;1507 swap = fh.magic == FAT_CIGAM;
961 for (i = 0; i < SWAP(fh.nfat_arch); i++)1508 for (i = 0; i < SWAP(fh.nfat_arch); i++)
962 if (SWAP(fa[i].cputype) == 0x01000007 /* CPU_TYPE_X86_64 */1509#ifdef TCC_TARGET_X86_64
963 && SWAP(fa[i].cpusubtype) == 3) /* CPU_SUBTYPE_X86_ALL */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
964 break;1516 break;
965 if (i == SWAP(fh.nfat_arch)) {1517 if (i == SWAP(fh.nfat_arch)) {
966 tcc_free(fa);1518 tcc_free(fa);
tests/tcctest.c+3−5
@@ -3648,7 +3648,7 @@ void test_asm_dead_code(void) · 3647 unmodified lines
3648 3648
3649void test_asm_call(void)3649void test_asm_call(void)
3650{3650{
3651#if defined __x86_64__ && !defined _WIN643651#if defined __x86_64__ && !defined _WIN64 && !defined(__APPLE__)
3652 static char str[] = "PATH";3652 static char str[] = "PATH";
3653 char *s;3653 char *s;
3654 /* This tests if a reference to an undefined symbol from an asm3654 /* This tests if a reference to an undefined symbol from an asm
@@ -3660,10 +3660,8 @@ void test_asm_call(void) · 5 unmodified lines
3660 tested here). */3660 tested here). */
3661 /* two pushes so stack remains aligned */3661 /* two pushes so stack remains aligned */
3662 asm volatile ("push %%rdi; push %%rdi; mov %0, %%rdi;"3662 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__))
3664 "call getenv@plt;"3664 "call getenv@plt;"
3665#elif defined(__APPLE__)
3666 "call _getenv;"
3667#else3665#else
3668 "call getenv;"3666 "call getenv;"
3669#endif3667#endif
@@ -3892,7 +3890,7 @@ void builtin_test(void) · 222 unmodified lines
3892 //printf("bera: %p\n", __builtin_extract_return_addr((void*)43));3890 //printf("bera: %p\n", __builtin_extract_return_addr((void*)43));
3893}3891}
3894 3892
3895#ifdef _WIN323893#if defined _WIN32 || defined __APPLE__
3896void weak_test(void) {}3894void weak_test(void) {}
3897#else3895#else
3898extern int __attribute__((weak)) weak_f1(void);3896extern int __attribute__((weak)) weak_f1(void);
tests/tests2/124_atomic_counter.c+2−0
@@ -14,9 +14,11 @@ · 13 unmodified lines
14 abort(); \14 abort(); \
15 } while (0)15 } while (0)
16 16
17#ifndef __APPLE__
17#if defined __x86_64__ || defined __aarch64__ || defined __riscv18#if defined __x86_64__ || defined __aarch64__ || defined __riscv
18#define HAS_64BITS19#define HAS_64BITS
19#endif20#endif
21#endif
20 22
21typedef struct {23typedef struct {
22 atomic_flag flag;24 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