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
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
1399/* generate function prolog of type 't' */1413/* generate function prolog of type 't' */
1400void gfunc_prolog(Sym *func_sym)1414void gfunc_prolog(Sym *func_sym)
1401{1415{
arm64-gen.c+19−0
@@ -1167,6 +1167,25 @@ 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
1170static unsigned long arm64_func_va_list_stack;1189static unsigned long arm64_func_va_list_stack;
1171static int arm64_func_va_list_gr_offs;1190static int arm64_func_va_list_gr_offs;
1172static int arm64_func_va_list_vr_offs;1191static 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
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
507#ifdef TCC_TARGET_PE525#ifdef TCC_TARGET_PE
508#define FUNC_PROLOG_SIZE (10 + USE_EBX)526#define FUNC_PROLOG_SIZE (10 + USE_EBX)
509#else527#else
riscv64-gen.c+14−0
@@ -769,6 +769,20 @@ 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
772static int func_sub_sp_offset, num_va_regs, func_va_list_ofs;786static int func_sub_sp_offset, num_va_regs, func_va_list_ofs;
773 787
774ST_FUNC void gfunc_prolog(Sym *func_sym)788ST_FUNC void gfunc_prolog(Sym *func_sym)
tcc.h+1−0
@@ -1797,6 +1797,7 @@ 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);
1800#endif1801#endif
1801 1802
1802/* ------------ tcctools.c ----------------- */1803/* ------------ tcctools.c ----------------- */
tccrun.c+24−2
@@ -249,8 +249,30 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) · 248 unmodified lines
249 fflush(stderr);249 fflush(stderr);
250 250
251 ret = tcc_setjmp(s1, main_jb, tcc_get_symbol(s1, top_sym));251 ret = tcc_setjmp(s1, main_jb, tcc_get_symbol(s1, top_sym));
252 if (0 == ret)252 if (0 == ret) {
253 ret = prog_main(argc, argv, envp);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 }
254 else if (RT_EXIT_ZERO == ret)276 else if (RT_EXIT_ZERO == ret)
255 ret = 0;277 ret = 0;
256 278
x86_64-gen.c+18−0
@@ -933,6 +933,10 @@ 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}
936 940
937#define FUNC_PROLOG_SIZE 11941#define FUNC_PROLOG_SIZE 11
938 942
@@ -1434,6 +1438,20 @@ void gfunc_call(int nb_args) · 495 unmodified lines
1434 vtop--;1438 vtop--;
1435}1439}
1436 1440
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
1437#define FUNC_PROLOG_SIZE 111455#define FUNC_PROLOG_SIZE 11
1438 1456
1439static void push_arg_reg(int i) {1457static 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