mirror of
git://repo.or.cz/tinycc.git
synced 2026-07-05 02:48:40 +08:00
Allow -nostdlib -run
Some checks are pending
build and test / test-x86_64-linux (push) Waiting to run
build and test / test-x86_64-osx (push) Waiting to run
build and test / test-aarch64-osx (push) Waiting to run
build and test / test-x86_64-win32 (push) Waiting to run
build and test / test-i386-win32 (push) Waiting to run
build and test / test-armv7-linux (push) Waiting to run
build and test / test-aarch64-linux (push) Waiting to run
build and test / test-riscv64-linux (push) Waiting to run
Some checks are pending
build and test / test-x86_64-linux (push) Waiting to run
build and test / test-x86_64-osx (push) Waiting to run
build and test / test-aarch64-osx (push) Waiting to run
build and test / test-x86_64-win32 (push) Waiting to run
build and test / test-i386-win32 (push) Waiting to run
build and test / test-armv7-linux (push) Waiting to run
build and test / test-aarch64-linux (push) Waiting to run
build and test / test-riscv64-linux (push) Waiting to 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
This commit is contained in:
parent
d9ec17d334
commit
c52b96cf85
14
arm-gen.c
14
arm-gen.c
@ -1396,6 +1396,20 @@ void gfunc_call(int nb_args)
|
|||||||
float_abi = def_float_abi;
|
float_abi = def_float_abi;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tcc_run_start(int (*prog_main)(int, char **, char **), int cnt, char **var)
|
||||||
|
{
|
||||||
|
#ifdef __arm__
|
||||||
|
void *sp;
|
||||||
|
|
||||||
|
asm("sub sp, sp, %1\n"
|
||||||
|
"\tmov %0, sp"
|
||||||
|
: "=r" (sp)
|
||||||
|
: "r" ((((size_t) cnt + 1) & -2) * sizeof(char *)));
|
||||||
|
memcpy(sp, var, cnt * sizeof(char *));
|
||||||
|
asm("mov pc, %0" : : "r" (prog_main));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/* generate function prolog of type 't' */
|
/* generate function prolog of type 't' */
|
||||||
void gfunc_prolog(Sym *func_sym)
|
void gfunc_prolog(Sym *func_sym)
|
||||||
{
|
{
|
||||||
|
|||||||
19
arm64-gen.c
19
arm64-gen.c
@ -1167,6 +1167,25 @@ ST_FUNC void gfunc_call(int nb_args)
|
|||||||
tcc_free(t);
|
tcc_free(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tcc_run_start(int (*prog_main)(int, char **, char **), int cnt, char **var)
|
||||||
|
{
|
||||||
|
#if defined(__aarch64__)
|
||||||
|
#if defined(__TINYC__)
|
||||||
|
// FIXME: immplement arm64 assembler
|
||||||
|
fprintf(stderr, "tcc -nostdlib -run not implement for arm64\n");
|
||||||
|
#else
|
||||||
|
void *sp;
|
||||||
|
|
||||||
|
asm("sub sp, sp, %1\n"
|
||||||
|
"\tmov %0, sp"
|
||||||
|
: "=r" (sp)
|
||||||
|
: "r" ((((size_t) cnt + 1) & -2) * sizeof(char *)));
|
||||||
|
memcpy(sp, var, cnt * sizeof(char *));
|
||||||
|
asm("br %0" : : "r" (prog_main));
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static unsigned long arm64_func_va_list_stack;
|
static unsigned long arm64_func_va_list_stack;
|
||||||
static int arm64_func_va_list_gr_offs;
|
static int arm64_func_va_list_gr_offs;
|
||||||
static int arm64_func_va_list_vr_offs;
|
static int arm64_func_va_list_vr_offs;
|
||||||
|
|||||||
18
i386-gen.c
18
i386-gen.c
@ -504,6 +504,24 @@ ST_FUNC void gfunc_call(int nb_args)
|
|||||||
vtop--;
|
vtop--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tcc_run_start(int (*prog_main)(int, char **, char **), int cnt, char **var)
|
||||||
|
{
|
||||||
|
#ifdef __i386__
|
||||||
|
#ifdef TCC_TARGET_PE
|
||||||
|
fprintf(stderr, "tcc -nostdlib -run not implement for TCC_TARGET_PE\n");
|
||||||
|
#else
|
||||||
|
void *sp;
|
||||||
|
|
||||||
|
asm("sub %1, %%esp\n"
|
||||||
|
"\tmov %%esp, %0"
|
||||||
|
: "=r" (sp)
|
||||||
|
: "r" ((((size_t) cnt + 1) & -2) * sizeof(char *)));
|
||||||
|
memcpy(sp, var, cnt * sizeof(char *));
|
||||||
|
asm("jmp *%0" : : "r" (prog_main));
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef TCC_TARGET_PE
|
#ifdef TCC_TARGET_PE
|
||||||
#define FUNC_PROLOG_SIZE (10 + USE_EBX)
|
#define FUNC_PROLOG_SIZE (10 + USE_EBX)
|
||||||
#else
|
#else
|
||||||
|
|||||||
@ -769,6 +769,20 @@ done:
|
|||||||
tcc_free(info);
|
tcc_free(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tcc_run_start(int (*prog_main)(int, char **, char **), int cnt, char **var)
|
||||||
|
{
|
||||||
|
#ifdef __riscv
|
||||||
|
void *sp;
|
||||||
|
|
||||||
|
asm("sub sp, sp, %1\n"
|
||||||
|
"\tmv %0, sp"
|
||||||
|
: "=r" (sp)
|
||||||
|
: "r" ((((size_t) cnt + 1) & -2) * sizeof(char *)));
|
||||||
|
memcpy(sp, var, cnt * sizeof(char *));
|
||||||
|
asm("jalr %0" : : "r" (prog_main));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static int func_sub_sp_offset, num_va_regs, func_va_list_ofs;
|
static int func_sub_sp_offset, num_va_regs, func_va_list_ofs;
|
||||||
|
|
||||||
ST_FUNC void gfunc_prolog(Sym *func_sym)
|
ST_FUNC void gfunc_prolog(Sym *func_sym)
|
||||||
|
|||||||
1
tcc.h
1
tcc.h
@ -1797,6 +1797,7 @@ ST_FUNC const char *dlerror(void);
|
|||||||
ST_FUNC void *dlsym(void *handle, const char *symbol);
|
ST_FUNC void *dlsym(void *handle, const char *symbol);
|
||||||
#endif
|
#endif
|
||||||
ST_FUNC void tcc_run_free(TCCState *s1);
|
ST_FUNC void tcc_run_free(TCCState *s1);
|
||||||
|
ST_FUNC void tcc_run_start(int (*prog_main)(int, char **, char **), int cnt, char **var);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ------------ tcctools.c ----------------- */
|
/* ------------ tcctools.c ----------------- */
|
||||||
|
|||||||
26
tccrun.c
26
tccrun.c
@ -249,8 +249,30 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
|
|||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
|
|
||||||
ret = tcc_setjmp(s1, main_jb, tcc_get_symbol(s1, top_sym));
|
ret = tcc_setjmp(s1, main_jb, tcc_get_symbol(s1, top_sym));
|
||||||
if (0 == ret)
|
if (0 == ret) {
|
||||||
ret = prog_main(argc, argv, envp);
|
if (s1->nostdlib) {
|
||||||
|
int n = 1;
|
||||||
|
char **p, **e = envp;
|
||||||
|
|
||||||
|
/* create sysv memory layout: argc, argv[], NULL, envp[], NULL */
|
||||||
|
if (envp)
|
||||||
|
while (*e++)
|
||||||
|
n++;
|
||||||
|
p = tcc_malloc((argc + n + 2) * sizeof(char **));
|
||||||
|
p[0] = (char *) (size_t) argc;
|
||||||
|
memcpy(p + 1, argv, argc * sizeof(char *));
|
||||||
|
p[argc + 1] = NULL;
|
||||||
|
if (envp)
|
||||||
|
memcpy(p + argc + 2, envp, n * sizeof(char *));
|
||||||
|
else
|
||||||
|
p[argc + 2] = NULL;
|
||||||
|
/* Probably never returns */
|
||||||
|
tcc_run_start(prog_main, argc + n + 2, p);
|
||||||
|
tcc_free(p);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ret = prog_main(argc, argv, envp);
|
||||||
|
}
|
||||||
else if (RT_EXIT_ZERO == ret)
|
else if (RT_EXIT_ZERO == ret)
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
|
|||||||
18
x86_64-gen.c
18
x86_64-gen.c
@ -933,6 +933,10 @@ void gfunc_call(int nb_args)
|
|||||||
vtop--;
|
vtop--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tcc_run_start(int (*prog_main)(int, char **, char **), int cnt, char **var)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "tcc -nostdlib -run not implement for TCC_TARGET_PE\n");
|
||||||
|
}
|
||||||
|
|
||||||
#define FUNC_PROLOG_SIZE 11
|
#define FUNC_PROLOG_SIZE 11
|
||||||
|
|
||||||
@ -1434,6 +1438,20 @@ void gfunc_call(int nb_args)
|
|||||||
vtop--;
|
vtop--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tcc_run_start(int (*prog_main)(int, char **, char **), int cnt, char **var)
|
||||||
|
{
|
||||||
|
#ifdef __x86_64__
|
||||||
|
void *sp;
|
||||||
|
|
||||||
|
asm("subq %1, %%rsp\n"
|
||||||
|
"\tmovq %%rsp, %0"
|
||||||
|
: "=r" (sp)
|
||||||
|
: "r" ((((size_t) cnt + 1) & -2) * sizeof(char *)));
|
||||||
|
memcpy(sp, var, cnt * sizeof(char *));
|
||||||
|
asm("jmp *%0" : : "r" (prog_main));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#define FUNC_PROLOG_SIZE 11
|
#define FUNC_PROLOG_SIZE 11
|
||||||
|
|
||||||
static void push_arg_reg(int i) {
|
static void push_arg_reg(int i) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user