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
Unified · Split
| @@ -367,7 +367,7 @@ IR = $(IM) mkdir -p $2 && cp -r $1/. $2 · 366 unmodified lines | |||
| 367 | IM = @echo "-> $2 : $1" ; | 367 | IM = @echo "-> $2 : $1" ; |
| 368 | BINCHECK = $(if $(wildcard $(PROGS) *-tcc$(EXESUF)),,@echo "Makefile: nothing found to install" && exit 1) | 368 | BINCHECK = $(if $(wildcard $(PROGS) *-tcc$(EXESUF)),,@echo "Makefile: nothing found to install" && exit 1) |
| 369 | 369 | ||
| 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 |
| 371 | 371 | ||
| 372 | # install progs & libs | 372 | # install progs & libs |
| 373 | install-unx: | 373 | install-unx: |
| @@ -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 | ||
| 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 | |||
| 1413 | /* generate function prolog of type 't' */ | 1399 | /* generate function prolog of type 't' */ |
| 1414 | void gfunc_prolog(Sym *func_sym) | 1400 | void gfunc_prolog(Sym *func_sym) |
| 1415 | { | 1401 | { |
| @@ -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 | ||
| 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 | |||
| 1189 | static unsigned long arm64_func_va_list_stack; | 1170 | static unsigned long arm64_func_va_list_stack; |
| 1190 | static int arm64_func_va_list_gr_offs; | 1171 | static int arm64_func_va_list_gr_offs; |
| 1191 | static int arm64_func_va_list_vr_offs; | 1172 | static int arm64_func_va_list_vr_offs; |
| @@ -504,24 +504,6 @@ ST_FUNC void gfunc_call(int nb_args) · 503 unmodified lines | |||
| 504 | vtop--; | 504 | vtop--; |
| 505 | } | 505 | } |
| 506 | 506 | ||
| 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 | |||
| 525 | #ifdef TCC_TARGET_PE | 507 | #ifdef TCC_TARGET_PE |
| 526 | #define FUNC_PROLOG_SIZE (10 + USE_EBX) | 508 | #define FUNC_PROLOG_SIZE (10 + USE_EBX) |
| 527 | #else | 509 | #else |
| @@ -50,13 +50,13 @@ Nat = $(if $X,no,) · 49 unmodified lines | |||
| 50 | Cbt = $(Nat)$(subst yes,,$(CONFIG_backtrace)) | 50 | Cbt = $(Nat)$(subst yes,,$(CONFIG_backtrace)) |
| 51 | Cbc = $(Cbt)$(subst yes,,$(CONFIG_bcheck)) | 51 | Cbc = $(Cbt)$(subst yes,,$(CONFIG_bcheck)) |
| 52 | 52 | ||
| 53 | $(Nat)COMMON_O += runmain.o tcov.o | 53 | $(Nat)COMMON_O += runmain.o run_nostdlib.o tcov.o |
| 54 | $(Cbt)COMMON_O += bt-exe.o bt-log.o | 54 | $(Cbt)COMMON_O += bt-exe.o bt-log.o |
| 55 | $(Cbt)WIN_O += bt-dll.o | 55 | $(Cbt)WIN_O += bt-dll.o |
| 56 | $(Cbc)COMMON_O += bcheck.o | 56 | $(Cbc)COMMON_O += bcheck.o |
| 57 | 57 | ||
| 58 | # not in libtcc1.a | 58 | # 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 |
| 60 | 60 | ||
| 61 | OBJ-i386 = $(I386_O) $(LIN_O) | 61 | OBJ-i386 = $(I386_O) $(LIN_O) |
| 62 | OBJ-x86_64 = $(X86_64_O) $(LIN_O) | 62 | OBJ-x86_64 = $(X86_64_O) $(LIN_O) |
| @@ -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 | } | ||
| @@ -769,20 +769,6 @@ done: · 768 unmodified lines | |||
| 769 | tcc_free(info); | 769 | tcc_free(info); |
| 770 | } | 770 | } |
| 771 | 771 | ||
| 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 | |||
| 786 | static int func_sub_sp_offset, num_va_regs, func_va_list_ofs; | 772 | static int func_sub_sp_offset, num_va_regs, func_va_list_ofs; |
| 787 | 773 | ||
| 788 | ST_FUNC void gfunc_prolog(Sym *func_sym) | 774 | ST_FUNC void gfunc_prolog(Sym *func_sym) |
| @@ -1797,7 +1797,6 @@ ST_FUNC const char *dlerror(void); · 1796 unmodified lines | |||
| 1797 | ST_FUNC void *dlsym(void *handle, const char *symbol); | 1797 | ST_FUNC void *dlsym(void *handle, const char *symbol); |
| 1798 | #endif | 1798 | #endif |
| 1799 | ST_FUNC void tcc_run_free(TCCState *s1); | 1799 | 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); | ||
| 1801 | #endif | 1800 | #endif |
| 1802 | 1801 | ||
| 1803 | /* ------------ tcctools.c ----------------- */ | 1802 | /* ------------ tcctools.c ----------------- */ |
| @@ -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 | #else | 215 | #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 | else | 263 | else |
| 274 | ret = prog_main(argc, argv, envp); | 264 | ret = prog_main(argc, argv, envp); |
| @@ -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 | } | ||
| @@ -933,11 +933,6 @@ void gfunc_call(int nb_args) · 932 unmodified lines | |||
| 933 | vtop--; | 933 | vtop--; |
| 934 | } | 934 | } |
| 935 | 935 | ||
| 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 | |||
| 941 | #define FUNC_PROLOG_SIZE 11 | 936 | #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 | ||
| 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 | |||
| 1455 | #define FUNC_PROLOG_SIZE 11 | 1436 | #define FUNC_PROLOG_SIZE 11 |
| 1456 | 1437 | ||
| 1457 | static void push_arg_reg(int i) { | 1438 | static void push_arg_reg(int i) { |