History

Move -run -nostdlib code to lib directory

tcc.h, arm-gen.c, arm64-gen.c, i386-gen.c, riscv64-gen.c, x86_64-gen.c: - remove old code tccrun.c: - update to use lib/run_nostdlib.c Makefile, lib/Makefile, lib/run_nostdlib.c: - new code tests/nostdlib_test.c: - testcode

herman ten brugge committed 11 months ago

Commit 85694271 parent 829c84811 files · +263 −109Browse files

Unified · Split

11 files
  1. Makefile +1 −1
  2. arm-gen.c +0 −14
  3. arm64-gen.c +0 −19
  4. i386-gen.c +0 −18
  5. lib/Makefile +2 −2
  6. lib/run_nostdlib.c +94 −0
  7. riscv64-gen.c +0 −14
  8. tcc.h +0 −1
  9. tccrun.c +11 −21
  10. tests/nostdlib_test.c +155 −0
  11. x86_64-gen.c +0 −19
Makefile+1−1
@@ -367,7 +367,7 @@ IR = $(IM) mkdir -p $2 && cp -r $1/. $2 · 366 unmodified lines
367IM = @echo "-> $2 : $1" ;367IM = @echo "-> $2 : $1" ;
368BINCHECK = $(if $(wildcard $(PROGS) *-tcc$(EXESUF)),,@echo "Makefile: nothing found to install" && exit 1)368BINCHECK = $(if $(wildcard $(PROGS) *-tcc$(EXESUF)),,@echo "Makefile: nothing found to install" && exit 1)
369 369
370EXTRA_O = runmain.o bt-exe.o bt-dll.o bt-log.o bcheck.o370EXTRA_O = runmain.o run_nostdlib.o bt-exe.o bt-dll.o bt-log.o bcheck.o
371 371
372# install progs & libs372# install progs & libs
373install-unx:373install-unx:
arm-gen.c+0−14
@@ -1396,20 +1396,6 @@ void gfunc_call(int nb_args) · 1395 unmodified lines
1396 float_abi = def_float_abi;1396 float_abi = def_float_abi;
1397}1397}
1398 1398
1399void tcc_run_start(int (*prog_main)(int, char **, char **), int cnt, char **var)
1400{
1401#ifdef __arm__
1402 void *sp;
1403
1404 __asm__("sub sp, sp, %1\n"
1405 "\tmov %0, sp"
1406 : "=r" (sp)
1407 : "r" ((((size_t) cnt + 1) & -2) * sizeof(char *)));
1408 memcpy(sp, var, cnt * sizeof(char *));
1409 __asm__("mov pc, %0" : : "r" (prog_main));
1410#endif
1411}
1412
1413/* generate function prolog of type 't' */1399/* generate function prolog of type 't' */
1414void gfunc_prolog(Sym *func_sym)1400void gfunc_prolog(Sym *func_sym)
1415{1401{
arm64-gen.c+0−19
@@ -1167,25 +1167,6 @@ ST_FUNC void gfunc_call(int nb_args) · 1166 unmodified lines
1167 tcc_free(t);1167 tcc_free(t);
1168}1168}
1169 1169
1170void tcc_run_start(int (*prog_main)(int, char **, char **), int cnt, char **var)
1171{
1172#if defined(__aarch64__)
1173#if defined(__TINYC__)
1174 // FIXME: immplement arm64 assembler
1175 fprintf(stderr, "tcc -nostdlib -run not implement for arm64\n");
1176#else
1177 void *sp;
1178
1179 __asm__("sub sp, sp, %1\n"
1180 "\tmov %0, sp"
1181 : "=r" (sp)
1182 : "r" ((((size_t) cnt + 1) & -2) * sizeof(char *)));
1183 memcpy(sp, var, cnt * sizeof(char *));
1184 __asm__("br %0" : : "r" (prog_main));
1185#endif
1186#endif
1187}
1188
1189static unsigned long arm64_func_va_list_stack;1170static unsigned long arm64_func_va_list_stack;
1190static int arm64_func_va_list_gr_offs;1171static int arm64_func_va_list_gr_offs;
1191static int arm64_func_va_list_vr_offs;1172static int arm64_func_va_list_vr_offs;
i386-gen.c+0−18
@@ -504,24 +504,6 @@ ST_FUNC void gfunc_call(int nb_args) · 503 unmodified lines
504 vtop--;504 vtop--;
505}505}
506 506
507void tcc_run_start(int (*prog_main)(int, char **, char **), int cnt, char **var)
508{
509#ifdef __i386__
510#ifdef TCC_TARGET_PE
511 fprintf(stderr, "tcc -nostdlib -run not implement for TCC_TARGET_PE\n");
512#else
513 void *sp;
514
515 __asm("sub %1, %%esp\n"
516 "\tmov %%esp, %0"
517 : "=r" (sp)
518 : "r" ((((size_t) cnt + 1) & -2) * sizeof(char *)));
519 memcpy(sp, var, cnt * sizeof(char *));
520 __asm__("jmp *%0" : : "r" (prog_main));
521#endif
522#endif
523}
524
525#ifdef TCC_TARGET_PE507#ifdef TCC_TARGET_PE
526#define FUNC_PROLOG_SIZE (10 + USE_EBX)508#define FUNC_PROLOG_SIZE (10 + USE_EBX)
527#else509#else
lib/Makefile+2−2
@@ -50,13 +50,13 @@ Nat = $(if $X,no,) · 49 unmodified lines
50Cbt = $(Nat)$(subst yes,,$(CONFIG_backtrace))50Cbt = $(Nat)$(subst yes,,$(CONFIG_backtrace))
51Cbc = $(Cbt)$(subst yes,,$(CONFIG_bcheck))51Cbc = $(Cbt)$(subst yes,,$(CONFIG_bcheck))
52 52
53$(Nat)COMMON_O += runmain.o tcov.o53$(Nat)COMMON_O += runmain.o run_nostdlib.o tcov.o
54$(Cbt)COMMON_O += bt-exe.o bt-log.o54$(Cbt)COMMON_O += bt-exe.o bt-log.o
55$(Cbt)WIN_O += bt-dll.o55$(Cbt)WIN_O += bt-dll.o
56$(Cbc)COMMON_O += bcheck.o56$(Cbc)COMMON_O += bcheck.o
57 57
58# not in libtcc1.a58# not in libtcc1.a
59EXTRA_O = runmain.o bt-exe.o bt-dll.o bt-log.o bcheck.o59EXTRA_O = runmain.o run_nostdlib.o bt-exe.o bt-dll.o bt-log.o bcheck.o
60 60
61OBJ-i386 = $(I386_O) $(LIN_O)61OBJ-i386 = $(I386_O) $(LIN_O)
62OBJ-x86_64 = $(X86_64_O) $(LIN_O)62OBJ-x86_64 = $(X86_64_O) $(LIN_O)
lib/run_nostdlib.c+94−0
@@ -0,0 +1,94 @@
1/* ------------------------------------------------------------- */
2/* support for run_nostdlib() */
3
4// FIXME: implement arm64 assembler
5#if defined(__aarch64__)
6#define USE_ARM64_ASM
7static void *alloca_arm64(unsigned long);
8__asm__(
9#ifdef __leading_underscore
10 "_alloca_arm64:\n\t"
11#else
12 "alloca_arm64:\n\t"
13#endif
14 ".int 0x91003c00\n\t" // add x0, x0, #15
15 ".int 0x927cec00\n\t" // and x0, x0, #-16
16 ".int 0xcb2063ff\n\t" // sub sp, sp, x0
17 ".int 0x910003e0\n\t" // mov x0, sp
18 ".int 0xd65f03c0" // ret
19);
20static void goto_arm64(void *start);
21__asm__(
22#ifdef __leading_underscore
23 "_goto_arm64:\n\t"
24#else
25 "goto_arm64:\n\t"
26#endif
27 ".int 0xd61f0000" // br x0
28);
29#endif
30
31void _run_nostdlib(void *start, int argc, char **argv, char **envp)
32{
33#if !defined(_WIN32)
34 int i, n = 1;
35 unsigned long l;
36 char **sp, **e = envp;
37
38 if (envp)
39 while (*e++)
40 n++;
41 l = (((unsigned long) argc + n + 2 + 1) & -2) * sizeof(char *);
42 /* nostdlib so avoid alloca() */
43 /* also code below will be removed because compiler detects dead store */
44#if defined(USE_ARM64_ASM)
45 sp = alloca_arm64(l);
46#else
47#if defined(__aarch64__)
48 __asm__("sub sp, sp, %1\n"
49 "\tmov %0, sp"
50#elif defined(__arm__)
51 __asm__("sub sp, sp, %1\n"
52 "\tmov %0, sp"
53#elif defined(__i386__)
54 __asm("sub %1, %%esp\n"
55 "\tmov %%esp, %0"
56#elif defined(__riscv)
57 __asm__("sub sp, sp, %1\n"
58 "\tmv %0, sp"
59#elif defined(__x86_64__)
60 __asm__("subq %1, %%rsp\n"
61 "\tmovq %%rsp, %0"
62#endif
63 : "=r" (sp)
64 : "r" (l));
65#endif
66 /* create sysv memory layout: argc, argv[], NULL, envp[], NULL */
67 sp[0] = (char *) (__SIZE_TYPE__) argc;
68 for (i = 0; i < argc; i++)
69 sp[i + 1] = argv[i];
70 sp[argc + 1] = (char *) 0;
71 if (envp)
72 for (i = 0; i < n; i++)
73 sp[i + argc + 2] = envp[i];
74 else
75 sp[argc + 2] = (char *) 0;
76#endif
77
78 /* goto *start does not work for clang. Use assembly. */
79#if defined(USE_ARM64_ASM)
80 goto_arm64(start);
81#else
82#if defined(__aarch64__)
83 __asm__("br %0" : : "r" (start));
84#elif defined(__arm__)
85 __asm__("mov pc, %0" : : "r" (start));
86#elif defined(__i386__)
87 __asm__("jmp *%0" : : "r" (start));
88#elif defined(__riscv)
89 __asm__("jalr %0" : : "r" (start));
90#elif defined(__x86_64__)
91 __asm__("jmp *%0" : : "r" (start));
92#endif
93#endif
94}
riscv64-gen.c+0−14
@@ -769,20 +769,6 @@ done: · 768 unmodified lines
769 tcc_free(info);769 tcc_free(info);
770}770}
771 771
772void tcc_run_start(int (*prog_main)(int, char **, char **), int cnt, char **var)
773{
774#ifdef __riscv
775 void *sp;
776
777 __asm__("sub sp, sp, %1\n"
778 "\tmv %0, sp"
779 : "=r" (sp)
780 : "r" ((((size_t) cnt + 1) & -2) * sizeof(char *)));
781 memcpy(sp, var, cnt * sizeof(char *));
782 __asm__("jalr %0" : : "r" (prog_main));
783#endif
784}
785
786static int func_sub_sp_offset, num_va_regs, func_va_list_ofs;772static int func_sub_sp_offset, num_va_regs, func_va_list_ofs;
787 773
788ST_FUNC void gfunc_prolog(Sym *func_sym)774ST_FUNC void gfunc_prolog(Sym *func_sym)
tcc.h+0−1
@@ -1797,7 +1797,6 @@ ST_FUNC const char *dlerror(void); · 1796 unmodified lines
1797ST_FUNC void *dlsym(void *handle, const char *symbol);1797ST_FUNC void *dlsym(void *handle, const char *symbol);
1798#endif1798#endif
1799ST_FUNC void tcc_run_free(TCCState *s1);1799ST_FUNC void tcc_run_free(TCCState *s1);
1800ST_FUNC void tcc_run_start(int (*prog_main)(int, char **, char **), int cnt, char **var);
1801#endif1800#endif
1802 1801
1803/* ------------ tcctools.c ----------------- */1802/* ------------ tcctools.c ----------------- */
tccrun.c+11−21
@@ -206,9 +206,10 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) · 205 unmodified lines
206 const char *top_sym;206 const char *top_sym;
207 jmp_buf main_jb;207 jmp_buf main_jb;
208 208
209#if defined(__APPLE__) || defined(__FreeBSD__)209#if defined(__APPLE__)
210 char **envp = NULL;210 extern char ***_NSGetEnviron(void);
211#elif defined(__OpenBSD__) || defined(__NetBSD__)211 char **envp = *_NSGetEnviron();
212#elif defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__)
212 extern char **environ;213 extern char **environ;
213 char **envp = environ;214 char **envp = environ;
214#else215#else
@@ -221,6 +222,7 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) · 6 unmodified lines
221 222
222 tcc_add_symbol(s1, "__rt_exit", rt_exit);223 tcc_add_symbol(s1, "__rt_exit", rt_exit);
223 if (s1->nostdlib) {224 if (s1->nostdlib) {
225 tcc_add_support(s1, "run_nostdlib.o");
224 s1->run_main = top_sym = s1->elf_entryname ? s1->elf_entryname : "_start";226 s1->run_main = top_sym = s1->elf_entryname ? s1->elf_entryname : "_start";
225 } else {227 } else {
226 tcc_add_support(s1, "runmain.o");228 tcc_add_support(s1, "runmain.o");
@@ -251,24 +253,12 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) · 24 unmodified lines
251 ret = tcc_setjmp(s1, main_jb, tcc_get_symbol(s1, top_sym));253 ret = tcc_setjmp(s1, main_jb, tcc_get_symbol(s1, top_sym));
252 if (0 == ret) {254 if (0 == ret) {
253 if (s1->nostdlib) {255 if (s1->nostdlib) {
254 int n = 1;256 void (*run_nostdlib)(void *start, int argc, char **argv, char **envp);
255 char **p, **e = envp;257
256 258 run_nostdlib = (void *)get_sym_addr(s1, "_run_nostdlib", 1, 1);
257 /* create sysv memory layout: argc, argv[], NULL, envp[], NULL */259 if ((addr_t)-1 == (addr_t)run_nostdlib)
258 if (envp)260 return -1;
259 while (*e++)261 run_nostdlib(prog_main, argc, argv, envp); /* never returns */
260 n++;
261 p = tcc_malloc((argc + n + 2) * sizeof(char *));
262 p[0] = (char *) (size_t) argc;
263 memcpy(p + 1, argv, argc * sizeof(char *));
264 p[argc + 1] = NULL;
265 if (envp)
266 memcpy(p + argc + 2, envp, n * sizeof(char *));
267 else
268 p[argc + 2] = NULL;
269 /* Probably never returns */
270 tcc_run_start(prog_main, argc + n + 2, p);
271 tcc_free(p);
272 }262 }
273 else263 else
274 ret = prog_main(argc, argv, envp);264 ret = prog_main(argc, argv, envp);
tests/nostdlib_test.c+155−0
@@ -0,0 +1,155 @@
1#!/usr/local/bin/tcc -run -nostdlib
2
3// Not working on windows and apple because of different API.
4
5#include <unistd.h>
6#include <sys/syscall.h>
7#if defined __x86_64__
8__asm__ ("syscall:\n\t"
9 "mov %rdi,%rax\n\t"
10 "mov %rsi,%rdi\n\t"
11 "mov %rdx,%rsi\n\t"
12 "mov %rcx,%rdx\n\t"
13 "mov %r8,%r10\n\t"
14 "mov %r9,%r8\n\t"
15 "mov 0x8(%rsp),%r9\n\t"
16 "syscall\n\t"
17 "ret");
18__asm__ (".global _start\n\t"
19 "_start:\n\t"
20 "mov 0(%rsp), %rdi\n\t"
21 "lea 8(%rsp), %rsi\n\t"
22 "jmp print");
23#elif defined __i386__
24__asm__ ("syscall:\n\t"
25 "push %ebp\n\t"
26 "push %edi\n\t"
27 "push %esi\n\t"
28 "push %ebx\n\t"
29 "mov 0x2c(%esp),%ebp\n\t"
30 "mov 0x28(%esp),%edi\n\t"
31 "mov 0x24(%esp),%esi\n\t"
32 "mov 0x20(%esp),%edx\n\t"
33 "mov 0x1c(%esp),%ecx\n\t"
34 "mov 0x18(%esp),%ebx\n\t"
35 "mov 0x14(%esp),%eax\n\t"
36 // "call *%gs:0x10\n\t"
37 ".byte 0x65,0xff,0x15,0x10,0x00,0x00,0x00\n\t"
38 "pop %ebx\n\t"
39 "pop %esi\n\t"
40 "pop %edi\n\t"
41 "pop %ebp\n\t"
42 "ret");
43__asm__ (".global _start\n\t"
44 "_start:\n\t"
45 "pop %esi\n\t"
46 "mov %esp, %ecx\n\t"
47 "and $0xfffffff0,%esp\n\t"
48 "push %ecx\n\t"
49 "push %esi\n\t"
50 "call print");
51#elif defined __arm__
52__asm__ ("syscall:\n\t"
53 "mov r12, sp\n\t"
54 "push {r4, r5, r6, r7}\n\t"
55 "mov r7, r0\n\t"
56 "mov r0, r1\n\t"
57 "mov r1, r2\n\t"
58 "mov r2, r3\n\t"
59 "ldm r12, {r3, r4, r5, r6}\n\t"
60 "svc 0x00000000\n\t"
61 "pop {r4, r5, r6, r7}\n\t"
62 "mov pc, lr");
63__asm__ (".global _start\n\t"
64 "_start:\n\t"
65 "pop {r0}\n\t"
66 "mov r1, sp\n\t"
67 "bl print");
68#elif defined __aarch64__
69__asm__ ("syscall:\n\t"
70 ".int 0x2a0003e8\n\t" // mov w8, w0
71 ".int 0xaa0103e0\n\t" // x0, x1
72 ".int 0xaa0203e1\n\t" // mov x1, x2
73 ".int 0xaa0303e2\n\t" // mov x2, x3
74 ".int 0xaa0403e3\n\t" // mov x3, x4
75 ".int 0xaa0503e4\n\t" // mov x4, x5
76 ".int 0xaa0603e5\n\t" // mov x5, x6
77 ".int 0xaa0703e6\n\t" // mov x6, x7
78 ".int 0xd4000001\n\t" // svc #0x0
79 ".int 0xd65f03c0"); // ret
80__asm__ (".global _start\n\t"
81 "_start:\n\t"
82 ".int 0xf94003e0\n\t" // ldr x0, [sp]
83 ".int 0x910023e1\n\t" // add x1, sp, #08
84 ".reloc .,R_AARCH64_CALL26,print\n\t"
85 ".int 0x94000000"); // bl print
86#elif defined __riscv
87__asm__ ("syscall:\n\t"
88 "mv t1,a0\n\t"
89 "mv a0,a1\n\t"
90 "mv a1,a2\n\t"
91 "mv a2,a3\n\t"
92 "mv a3,a4\n\t"
93 "mv a4,a5\n\t"
94 "mv a5,a6\n\t"
95 "mv a6,a7\n\t"
96 "mv a7,t1\n\t"
97 "ecall\n\t"
98 "ret");
99__asm__ (".global _start\n\t"
100 "_start:\n\t"
101 "ld a0,0(sp)\n\t"
102 "addi a1,sp,8\n\t"
103 "jal print");
104#endif
105unsigned long strlen(const char *s)
106{
107 unsigned long len = 0;
108
109 while (*s++)
110 len++;
111 return len;
112}
113
114static void pr_num(int num)
115{
116 char val[20], *p = &val[20];
117
118 *--p = '\0';
119 do {
120 int a = num, b = 0;
121
122 while (a >= 10) {
123 a -= 10;
124 b++;
125 }
126 *--p = a + '0';
127 num = b;
128 } while (num);
129 syscall(SYS_write, 1, p, strlen(p));
130}
131
132static void pr_str(int n, char *s)
133{
134 pr_num(n);
135 syscall(SYS_write, 1, ": ", 2);
136 syscall(SYS_write, 1, s, strlen(s));
137 syscall(SYS_write, 1, "\n", 1);
138}
139
140void print(int argc, char **argv) {
141 int i;
142 char **envp = &argv[argc + 1];
143
144 syscall(SYS_write, 1, "argc: ", 6);
145 pr_num(argc);
146 syscall(SYS_write, 1, "\n", 1);
147 syscall(SYS_write, 1, "argv[]\n", 7);
148 for (i = 0; i < argc; i++)
149 pr_str(i, argv[i]);
150 syscall(SYS_write, 1, "envp[]\n", 7);
151 i = 0;
152 while (*envp)
153 pr_str(i++, *envp++);
154 syscall(SYS_exit, 0);
155}
x86_64-gen.c+0−19
@@ -933,11 +933,6 @@ void gfunc_call(int nb_args) · 932 unmodified lines
933 vtop--;933 vtop--;
934}934}
935 935
936void tcc_run_start(int (*prog_main)(int, char **, char **), int cnt, char **var)
937{
938 fprintf(stderr, "tcc -nostdlib -run not implement for TCC_TARGET_PE\n");
939}
940
941#define FUNC_PROLOG_SIZE 11936#define FUNC_PROLOG_SIZE 11
942 937
943/* generate function prolog of type 't' */938/* generate function prolog of type 't' */
@@ -1438,20 +1433,6 @@ void gfunc_call(int nb_args) · 494 unmodified lines
1438 vtop--;1433 vtop--;
1439}1434}
1440 1435
1441void tcc_run_start(int (*prog_main)(int, char **, char **), int cnt, char **var)
1442{
1443#ifdef __x86_64__
1444 void *sp;
1445
1446 __asm__("subq %1, %%rsp\n"
1447 "\tmovq %%rsp, %0"
1448 : "=r" (sp)
1449 : "r" ((((size_t) cnt + 1) & -2) * sizeof(char *)));
1450 memcpy(sp, var, cnt * sizeof(char *));
1451 __asm__("jmp *%0" : : "r" (prog_main));
1452#endif
1453}
1454
1455#define FUNC_PROLOG_SIZE 111436#define FUNC_PROLOG_SIZE 11
1456 1437
1457static void push_arg_reg(int i) {1438static void push_arg_reg(int i) {

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