Files
tinycc/lib/run_nostdlib.c
herman ten brugge 8569427459 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
2025-12-15 14:45:11 +01:00

95 lines
2.4 KiB
C

/* ------------------------------------------------------------- */
/* support for run_nostdlib() */
// FIXME: implement arm64 assembler
#if defined(__aarch64__)
#define USE_ARM64_ASM
static void *alloca_arm64(unsigned long);
__asm__(
#ifdef __leading_underscore
"_alloca_arm64:\n\t"
#else
"alloca_arm64:\n\t"
#endif
".int 0x91003c00\n\t" // add x0, x0, #15
".int 0x927cec00\n\t" // and x0, x0, #-16
".int 0xcb2063ff\n\t" // sub sp, sp, x0
".int 0x910003e0\n\t" // mov x0, sp
".int 0xd65f03c0" // ret
);
static void goto_arm64(void *start);
__asm__(
#ifdef __leading_underscore
"_goto_arm64:\n\t"
#else
"goto_arm64:\n\t"
#endif
".int 0xd61f0000" // br x0
);
#endif
void _run_nostdlib(void *start, int argc, char **argv, char **envp)
{
#if !defined(_WIN32)
int i, n = 1;
unsigned long l;
char **sp, **e = envp;
if (envp)
while (*e++)
n++;
l = (((unsigned long) argc + n + 2 + 1) & -2) * sizeof(char *);
/* nostdlib so avoid alloca() */
/* also code below will be removed because compiler detects dead store */
#if defined(USE_ARM64_ASM)
sp = alloca_arm64(l);
#else
#if defined(__aarch64__)
__asm__("sub sp, sp, %1\n"
"\tmov %0, sp"
#elif defined(__arm__)
__asm__("sub sp, sp, %1\n"
"\tmov %0, sp"
#elif defined(__i386__)
__asm("sub %1, %%esp\n"
"\tmov %%esp, %0"
#elif defined(__riscv)
__asm__("sub sp, sp, %1\n"
"\tmv %0, sp"
#elif defined(__x86_64__)
__asm__("subq %1, %%rsp\n"
"\tmovq %%rsp, %0"
#endif
: "=r" (sp)
: "r" (l));
#endif
/* create sysv memory layout: argc, argv[], NULL, envp[], NULL */
sp[0] = (char *) (__SIZE_TYPE__) argc;
for (i = 0; i < argc; i++)
sp[i + 1] = argv[i];
sp[argc + 1] = (char *) 0;
if (envp)
for (i = 0; i < n; i++)
sp[i + argc + 2] = envp[i];
else
sp[argc + 2] = (char *) 0;
#endif
/* goto *start does not work for clang. Use assembly. */
#if defined(USE_ARM64_ASM)
goto_arm64(start);
#else
#if defined(__aarch64__)
__asm__("br %0" : : "r" (start));
#elif defined(__arm__)
__asm__("mov pc, %0" : : "r" (start));
#elif defined(__i386__)
__asm__("jmp *%0" : : "r" (start));
#elif defined(__riscv)
__asm__("jalr %0" : : "r" (start));
#elif defined(__x86_64__)
__asm__("jmp *%0" : : "r" (start));
#endif
#endif
}