History

Allow -nostdlib -run

The -run option did not support -nostdlib correctly. The argc/argc/envp are now passed on stack according to sysv. This implementation does not work for TCC_TARGET_PE. Also arm64 does not work when running tcc compiled with itself. This is because arm64 assembly is not implemented yet. The following test code is used to check the code: #include <unistd.h> #include <sys/syscall.h> void _start() { syscall(SYS_write, 1, "hello world\n", 12); syscall(SYS_exit, 0); } Run this with: ./tcc -nostdlib -lc -run a.c make tcc_c ./tcc_c -nostdlib -lc -run a.c

herman ten brugge committed 12 months ago

Commit c52b96c1 parent d9ec17d7 files · +108 −2Browse files

Unified · Split

7 files
  1. arm-gen.c +14 −0
  2. arm64-gen.c +19 −0
  3. i386-gen.c +18 −0
  4. riscv64-gen.c +14 −0
  5. tcc.h +1 −0
  6. tccrun.c +24 −2
  7. x86_64-gen.c +18 −0
arm-gen.c+14−0
@@ -1396,6 +1396,20 @@ 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+
13991413 /* generate function prolog of type 't' */
14001414 void gfunc_prolog(Sym *func_sym)
14011415 {
arm64-gen.c+19−0
@@ -1167,6 +1167,25 @@ 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+
11701189 static unsigned long arm64_func_va_list_stack;
11711190 static int arm64_func_va_list_gr_offs;
11721191 static int arm64_func_va_list_vr_offs;
i386-gen.c+18−0
@@ -504,6 +504,24 @@ 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+
507525 #ifdef TCC_TARGET_PE
508526 #define FUNC_PROLOG_SIZE (10 + USE_EBX)
509527 #else
riscv64-gen.c+14−0
@@ -769,6 +769,20 @@ 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+
772786 static int func_sub_sp_offset, num_va_regs, func_va_list_ofs;
773787
774788 ST_FUNC void gfunc_prolog(Sym *func_sym)
tcc.h+1−0
@@ -1797,6 +1797,7 @@ 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);
18001801 #endif
18011802
18021803 /* ------------ tcctools.c ----------------- */
tccrun.c+24−2
@@ -249,8 +249,30 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) · 248 unmodified lines
249249 fflush(stderr);
250250
251251 ret = tcc_setjmp(s1, main_jb, tcc_get_symbol(s1, top_sym));
252− if (0 == ret)
253− ret = prog_main(argc, argv, envp);
252+ if (0 == ret) {
253+ 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);
272+ }
273+ else
274+ ret = prog_main(argc, argv, envp);
275+ }
254276 else if (RT_EXIT_ZERO == ret)
255277 ret = 0;
256278
x86_64-gen.c+18−0
@@ -933,6 +933,10 @@ 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+}
936940
937941 #define FUNC_PROLOG_SIZE 11
938942
@@ -1434,6 +1438,20 @@ void gfunc_call(int nb_args) · 495 unmodified lines
14341438 vtop--;
14351439 }
14361440
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+
14371455 #define FUNC_PROLOG_SIZE 11
14381456
14391457 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