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 | 367 | IM = @echo "-> $2 : $1" ; |
| 368 | 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 | 372 | # install progs & libs |
| 373 | 373 | install-unx: |
| @@ -1396,20 +1396,6 @@ void gfunc_call(int nb_args) · 1395 unmodified lines | ||
| 1396 | 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 | 1399 | /* generate function prolog of type 't' */ |
| 1414 | 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 | 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 | 1170 | static unsigned long arm64_func_va_list_stack; |
| 1190 | 1171 | static int arm64_func_va_list_gr_offs; |
| 1191 | 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 | 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 | 507 | #ifdef TCC_TARGET_PE |
| 526 | 508 | #define FUNC_PROLOG_SIZE (10 + USE_EBX) |
| 527 | 509 | #else |
| @@ -50,13 +50,13 @@ Nat = $(if $X,no,) · 49 unmodified lines | ||
| 50 | 50 | Cbt = $(Nat)$(subst yes,,$(CONFIG_backtrace)) |
| 51 | 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 | 54 | $(Cbt)COMMON_O += bt-exe.o bt-log.o |
| 55 | 55 | $(Cbt)WIN_O += bt-dll.o |
| 56 | 56 | $(Cbc)COMMON_O += bcheck.o |
| 57 | 57 | |
| 58 | 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 | 61 | OBJ-i386 = $(I386_O) $(LIN_O) |
| 62 | 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 | 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 | 772 | static int func_sub_sp_offset, num_va_regs, func_va_list_ofs; |
| 787 | 773 | |
| 788 | 774 | ST_FUNC void gfunc_prolog(Sym *func_sym) |
| @@ -1797,7 +1797,6 @@ ST_FUNC const char *dlerror(void); · 1796 unmodified lines | ||
| 1797 | 1797 | ST_FUNC void *dlsym(void *handle, const char *symbol); |
| 1798 | 1798 | #endif |
| 1799 | 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 | 1800 | #endif |
| 1802 | 1801 | |
| 1803 | 1802 | /* ------------ tcctools.c ----------------- */ |
| @@ -206,9 +206,10 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) · 205 unmodified lines | ||
| 206 | 206 | const char *top_sym; |
| 207 | 207 | jmp_buf main_jb; |
| 208 | 208 | |
| 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__) | |
| 212 | 213 | extern char **environ; |
| 213 | 214 | char **envp = environ; |
| 214 | 215 | #else |
| @@ -221,6 +222,7 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) · 6 unmodified lines | ||
| 221 | 222 | |
| 222 | 223 | tcc_add_symbol(s1, "__rt_exit", rt_exit); |
| 223 | 224 | if (s1->nostdlib) { |
| 225 | + tcc_add_support(s1, "run_nostdlib.o"); | |
| 224 | 226 | s1->run_main = top_sym = s1->elf_entryname ? s1->elf_entryname : "_start"; |
| 225 | 227 | } else { |
| 226 | 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 | 253 | ret = tcc_setjmp(s1, main_jb, tcc_get_symbol(s1, top_sym)); |
| 252 | 254 | if (0 == ret) { |
| 253 | 255 | 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 */ | |
| 272 | 262 | } |
| 273 | 263 | else |
| 274 | 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 | 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 | 936 | #define FUNC_PROLOG_SIZE 11 |
| 942 | 937 | |
| 943 | 938 | /* generate function prolog of type 't' */ |
| @@ -1438,20 +1433,6 @@ void gfunc_call(int nb_args) · 494 unmodified lines | ||
| 1438 | 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 | 1436 | #define FUNC_PROLOG_SIZE 11 |
| 1456 | 1437 | |
| 1457 | 1438 | static void push_arg_reg(int i) { |