mirror of
git://repo.or.cz/tinycc.git
synced 2026-06-17 15:44:18 +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;
|
||||
}
|
||||
|
||||
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' */
|
||||
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);
|
||||
}
|
||||
|
||||
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 int arm64_func_va_list_gr_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--;
|
||||
}
|
||||
|
||||
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
|
||||
#define FUNC_PROLOG_SIZE (10 + USE_EBX)
|
||||
#else
|
||||
|
||||
@ -769,6 +769,20 @@ done:
|
||||
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;
|
||||
|
||||
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);
|
||||
#endif
|
||||
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
|
||||
|
||||
/* ------------ tcctools.c ----------------- */
|
||||
|
||||
24
tccrun.c
24
tccrun.c
@ -249,8 +249,30 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
|
||||
fflush(stderr);
|
||||
|
||||
ret = tcc_setjmp(s1, main_jb, tcc_get_symbol(s1, top_sym));
|
||||
if (0 == ret)
|
||||
if (0 == ret) {
|
||||
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)
|
||||
ret = 0;
|
||||
|
||||
|
||||
18
x86_64-gen.c
18
x86_64-gen.c
@ -933,6 +933,10 @@ void gfunc_call(int nb_args)
|
||||
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
|
||||
|
||||
@ -1434,6 +1438,20 @@ void gfunc_call(int nb_args)
|
||||
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
|
||||
|
||||
static void push_arg_reg(int i) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user