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
367367 IM = @echo "-> $2 : $1" ;
368368 BINCHECK = $(if $(wildcard $(PROGS) *-tcc$(EXESUF)),,@echo "Makefile: nothing found to install" && exit 1)
369369
370−EXTRA_O = runmain.o bt-exe.o bt-dll.o bt-log.o bcheck.o
370+EXTRA_O = runmain.o run_nostdlib.o bt-exe.o bt-dll.o bt-log.o bcheck.o
371371
372372 # install progs & libs
373373 install-unx:
arm-gen.c+0−14
@@ -1396,20 +1396,6 @@ void gfunc_call(int nb_args) · 1395 unmodified lines
13961396 float_abi = def_float_abi;
13971397 }
13981398
1399−void 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−
14131399 /* generate function prolog of type 't' */
14141400 void gfunc_prolog(Sym *func_sym)
14151401 {
arm64-gen.c+0−19
@@ -1167,25 +1167,6 @@ ST_FUNC void gfunc_call(int nb_args) · 1166 unmodified lines
11671167 tcc_free(t);
11681168 }
11691169
1170−void 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−
11891170 static unsigned long arm64_func_va_list_stack;
11901171 static int arm64_func_va_list_gr_offs;
11911172 static 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
504504 vtop--;
505505 }
506506
507−void 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−
525507 #ifdef TCC_TARGET_PE
526508 #define FUNC_PROLOG_SIZE (10 + USE_EBX)
527509 #else
lib/Makefile+2−2
@@ -50,13 +50,13 @@ Nat = $(if $X,no,) · 49 unmodified lines
5050 Cbt = $(Nat)$(subst yes,,$(CONFIG_backtrace))
5151 Cbc = $(Cbt)$(subst yes,,$(CONFIG_bcheck))
5252
53−$(Nat)COMMON_O += runmain.o tcov.o
53+$(Nat)COMMON_O += runmain.o run_nostdlib.o tcov.o
5454 $(Cbt)COMMON_O += bt-exe.o bt-log.o
5555 $(Cbt)WIN_O += bt-dll.o
5656 $(Cbc)COMMON_O += bcheck.o
5757
5858 # not in libtcc1.a
59−EXTRA_O = runmain.o bt-exe.o bt-dll.o bt-log.o bcheck.o
59+EXTRA_O = runmain.o run_nostdlib.o bt-exe.o bt-dll.o bt-log.o bcheck.o
6060
6161 OBJ-i386 = $(I386_O) $(LIN_O)
6262 OBJ-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
7+static 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+);
20+static 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+
31+void _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
769769 tcc_free(info);
770770 }
771771
772−void 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−
786772 static int func_sub_sp_offset, num_va_regs, func_va_list_ofs;
787773
788774 ST_FUNC void gfunc_prolog(Sym *func_sym)
tcc.h+0−1
@@ -1797,7 +1797,6 @@ ST_FUNC const char *dlerror(void); · 1796 unmodified lines
17971797 ST_FUNC void *dlsym(void *handle, const char *symbol);
17981798 #endif
17991799 ST_FUNC void tcc_run_free(TCCState *s1);
1800−ST_FUNC void tcc_run_start(int (*prog_main)(int, char **, char **), int cnt, char **var);
18011800 #endif
18021801
18031802 /* ------------ tcctools.c ----------------- */
tccrun.c+11−21
@@ -206,9 +206,10 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) · 205 unmodified lines
206206 const char *top_sym;
207207 jmp_buf main_jb;
208208
209−#if defined(__APPLE__) || defined(__FreeBSD__)
210− char **envp = NULL;
211−#elif defined(__OpenBSD__) || defined(__NetBSD__)
209+#if defined(__APPLE__)
210+ extern char ***_NSGetEnviron(void);
211+ char **envp = *_NSGetEnviron();
212+#elif defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__)
212213 extern char **environ;
213214 char **envp = environ;
214215 #else
@@ -221,6 +222,7 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) · 6 unmodified lines
221222
222223 tcc_add_symbol(s1, "__rt_exit", rt_exit);
223224 if (s1->nostdlib) {
225+ tcc_add_support(s1, "run_nostdlib.o");
224226 s1->run_main = top_sym = s1->elf_entryname ? s1->elf_entryname : "_start";
225227 } else {
226228 tcc_add_support(s1, "runmain.o");
@@ -251,24 +253,12 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) · 24 unmodified lines
251253 ret = tcc_setjmp(s1, main_jb, tcc_get_symbol(s1, top_sym));
252254 if (0 == ret) {
253255 if (s1->nostdlib) {
254− int n = 1;
255− char **p, **e = envp;
256−
257− /* create sysv memory layout: argc, argv[], NULL, envp[], NULL */
258− if (envp)
259− while (*e++)
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);
256+ void (*run_nostdlib)(void *start, int argc, char **argv, char **envp);
257+
258+ run_nostdlib = (void *)get_sym_addr(s1, "_run_nostdlib", 1, 1);
259+ if ((addr_t)-1 == (addr_t)run_nostdlib)
260+ return -1;
261+ run_nostdlib(prog_main, argc, argv, envp); /* never returns */
272262 }
273263 else
274264 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
105+unsigned long strlen(const char *s)
106+{
107+ unsigned long len = 0;
108+
109+ while (*s++)
110+ len++;
111+ return len;
112+}
113+
114+static 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+
132+static 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+
140+void 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
933933 vtop--;
934934 }
935935
936−void 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−
941936 #define FUNC_PROLOG_SIZE 11
942937
943938 /* generate function prolog of type 't' */
@@ -1438,20 +1433,6 @@ void gfunc_call(int nb_args) · 494 unmodified lines
14381433 vtop--;
14391434 }
14401435
1441−void 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−
14551436 #define FUNC_PROLOG_SIZE 11
14561437
14571438 static 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