Skip to content

Commit 8569427

Browse files
committed
Move -run -nostdlib code to lib directory
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
1 parent 829c848 commit 8569427

File tree

11 files changed

+263
-109
lines changed

11 files changed

+263
-109
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ IR = $(IM) mkdir -p $2 && cp -r $1/. $2
367367
IM = @echo "-> $2 : $1" ;
368368
BINCHECK = $(if $(wildcard $(PROGS) *-tcc$(EXESUF)),,@echo "Makefile: nothing found to install" && exit 1)
369369

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
371371

372372
# install progs & libs
373373
install-unx:

arm-gen.c

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1396,20 +1396,6 @@ void gfunc_call(int nb_args)
13961396
float_abi = def_float_abi;
13971397
}
13981398

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-
14131399
/* generate function prolog of type 't' */
14141400
void gfunc_prolog(Sym *func_sym)
14151401
{

arm64-gen.c

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1167,25 +1167,6 @@ ST_FUNC void gfunc_call(int nb_args)
11671167
tcc_free(t);
11681168
}
11691169

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-
11891170
static unsigned long arm64_func_va_list_stack;
11901171
static int arm64_func_va_list_gr_offs;
11911172
static int arm64_func_va_list_vr_offs;

i386-gen.c

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -504,24 +504,6 @@ ST_FUNC void gfunc_call(int nb_args)
504504
vtop--;
505505
}
506506

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-
525507
#ifdef TCC_TARGET_PE
526508
#define FUNC_PROLOG_SIZE (10 + USE_EBX)
527509
#else

lib/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,13 @@ Nat = $(if $X,no,)
5050
Cbt = $(Nat)$(subst yes,,$(CONFIG_backtrace))
5151
Cbc = $(Cbt)$(subst yes,,$(CONFIG_bcheck))
5252

53-
$(Nat)COMMON_O += runmain.o tcov.o
53+
$(Nat)COMMON_O += runmain.o run_nostdlib.o tcov.o
5454
$(Cbt)COMMON_O += bt-exe.o bt-log.o
5555
$(Cbt)WIN_O += bt-dll.o
5656
$(Cbc)COMMON_O += bcheck.o
5757

5858
# 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
6060

6161
OBJ-i386 = $(I386_O) $(LIN_O)
6262
OBJ-x86_64 = $(X86_64_O) $(LIN_O)

lib/run_nostdlib.c

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
}

riscv64-gen.c

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -769,20 +769,6 @@ ST_FUNC void gfunc_call(int nb_args)
769769
tcc_free(info);
770770
}
771771

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-
786772
static int func_sub_sp_offset, num_va_regs, func_va_list_ofs;
787773

788774
ST_FUNC void gfunc_prolog(Sym *func_sym)

tcc.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1797,7 +1797,6 @@ ST_FUNC const char *dlerror(void);
17971797
ST_FUNC void *dlsym(void *handle, const char *symbol);
17981798
#endif
17991799
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);
18011800
#endif
18021801

18031802
/* ------------ tcctools.c ----------------- */

tccrun.c

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -206,9 +206,10 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
206206
const char *top_sym;
207207
jmp_buf main_jb;
208208

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__)
212213
extern char **environ;
213214
char **envp = environ;
214215
#else
@@ -221,6 +222,7 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
221222

222223
tcc_add_symbol(s1, "__rt_exit", rt_exit);
223224
if (s1->nostdlib) {
225+
tcc_add_support(s1, "run_nostdlib.o");
224226
s1->run_main = top_sym = s1->elf_entryname ? s1->elf_entryname : "_start";
225227
} else {
226228
tcc_add_support(s1, "runmain.o");
@@ -251,24 +253,12 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
251253
ret = tcc_setjmp(s1, main_jb, tcc_get_symbol(s1, top_sym));
252254
if (0 == ret) {
253255
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 */
272262
}
273263
else
274264
ret = prog_main(argc, argv, envp);

0 commit comments

Comments
 (0)