diff options
| author | bellard <bellard> | 2002-07-22 23:37:39 +0000 |
|---|---|---|
| committer | bellard <bellard> | 2002-07-22 23:37:39 +0000 |
| commit | 6cdecbe4e622194c5ba311d0e944a1b33a0e18a3 (patch) | |
| tree | 5404af2f8e171a1079c06b090d375fdff214b7e8 /tcc.c | |
| parent | 3d902af1a912f85968d3a94aa4a831dd9765be9b (diff) | |
| download | tinycc-6cdecbe4e622194c5ba311d0e944a1b33a0e18a3.tar.gz tinycc-6cdecbe4e622194c5ba311d0e944a1b33a0e18a3.tar.bz2 | |
added runtime library - fixed more relocations
Diffstat (limited to 'tcc.c')
| -rw-r--r-- | tcc.c | 174 |
1 files changed, 57 insertions, 117 deletions
@@ -100,6 +100,7 @@ typedef union CValue { unsigned long long ull; struct TokenSym *ts; struct Sym *sym; + void *ptr; int tab[1]; } CValue; @@ -284,6 +285,7 @@ int ifdef_stack[IFDEF_STACK_SIZE], *ifdef_stack_ptr; char **include_paths; int nb_include_paths; int char_pointer_type; +int func_old_type; /* compile with debug symbol (and use them if error during execution) */ int do_debug = 0; @@ -493,21 +495,9 @@ enum { /* special identifiers */ TOK___FUNC__, TOK_MAIN, - /* attribute identifiers */ - TOK_SECTION, - TOK___SECTION__, - TOK_ALIGNED, - TOK___ALIGNED__, - TOK_UNUSED, - TOK___UNUSED__, - TOK_CDECL, - TOK___CDECL, - TOK___CDECL__, - TOK_STDCALL, - TOK___STDCALL, - TOK___STDCALL__, - TOK_NORETURN, - TOK___NORETURN__, +#define DEF(id, str) id, +#include "tcctok.h" +#undef DEF }; char *tcc_keywords = @@ -521,10 +511,10 @@ char *tcc_keywords = "defined\0undef\0error\0line\0" "__LINE__\0__FILE__\0__DATE__\0__TIME__\0__VA_ARGS__\0" "__func__\0main\0" -/* attributes */ -"section\0__section__\0aligned\0__aligned__\0unused\0__unused__\0" -"cdecl\0__cdecl\0__cdecl__\0stdcall\0__stdcall\0__stdcall__\0" -"noreturn\0__noreturn__\0" +/* builtin functions */ +#define DEF(id, str) str "\0" +#include "tcctok.h" +#undef DEF ; #ifdef WIN32 @@ -595,6 +585,7 @@ void vset(int t, int r, int v); void type_to_str(char *buf, int buf_size, int t, const char *varstr); char *get_tok_str(int v, CValue *cv); +Sym *external_sym(int v, int u, int r); /* section generation */ void put_extern_sym(Sym *sym, Section *section, unsigned long value); @@ -681,77 +672,6 @@ void *dlsym(void *handle, const char *symbol) #endif /********************************************************/ -/* runtime library is there */ -/* XXX: we suppose that the host compiler handles 'long long'. It - would not be difficult to suppress this assumption */ - -long long __divll(long long a, long long b) -{ - return a / b; -} - -long long __modll(long long a, long long b) -{ - return a % b; -} - -unsigned long long __divull(unsigned long long a, unsigned long long b) -{ - return a / b; -} - -unsigned long long __modull(unsigned long long a, unsigned long long b) -{ - return a % b; -} - -long long __sardi3(long long a, int b) -{ - return a >> b; -} - -unsigned long long __shrdi3(unsigned long long a, int b) -{ - return a >> b; -} - -long long __shldi3(long long a, int b) -{ - return a << b; -} - -float __ulltof(unsigned long long a) -{ - return (float)a; -} - -double __ulltod(unsigned long long a) -{ - return (double)a; -} - -long double __ulltold(unsigned long long a) -{ - return (long double)a; -} - -unsigned long long __ftoull(float a) -{ - return (unsigned long long)a; -} - -unsigned long long __dtoull(double a) -{ - return (unsigned long long)a; -} - -unsigned long long __ldtoull(long double a) -{ - return (unsigned long long)a; -} - - -/********************************************************/ /* we use our own 'finite' function to avoid potential problems with non standard math libs */ @@ -2589,6 +2509,17 @@ void vpush_ref(int t, Section *sec, unsigned long offset) vsetc(t, VT_CONST | VT_SYM, &cval); } +/* push a reference to symbol v */ +void vpush_sym(int t, int v) +{ + Sym *sym; + CValue cval; + + sym = external_sym(v, t, 0); + cval.sym = sym; + vsetc(t, VT_CONST | VT_SYM, &cval); +} + void vset(int t, int r, int v) { CValue cval; @@ -3019,29 +2950,29 @@ void gv_dup(void) void gen_opl(int op) { int t, a, b, op1, c, i; - void *func; + int func; GFuncContext gf; SValue tmp; switch(op) { case '/': case TOK_PDIV: - func = __divll; + func = TOK___divdi3; goto gen_func; case TOK_UDIV: - func = __divull; + func = TOK___udivdi3; goto gen_func; case '%': - func = __modll; + func = TOK___moddi3; goto gen_func; case TOK_UMOD: - func = __modull; + func = TOK___umoddi3; gen_func: /* call generic long long function */ gfunc_start(&gf, FUNC_CDECL); gfunc_param(&gf); gfunc_param(&gf); - vpushi((int)func); + vpush_sym(func_old_type, func); gfunc_call(&gf); vpushi(0); vtop->r = REG_IRET; @@ -3166,13 +3097,13 @@ void gen_opl(int op) /* XXX: should provide a faster fallback on x86 ? */ switch(op) { case TOK_SAR: - func = __sardi3; + func = TOK___sardi3; goto gen_func; case TOK_SHR: - func = __shrdi3; + func = TOK___shrdi3; goto gen_func; case TOK_SHL: - func = __shldi3; + func = TOK___shldi3; goto gen_func; } } @@ -3561,11 +3492,11 @@ void gen_cvt_itof1(int t) gfunc_start(&gf, FUNC_CDECL); gfunc_param(&gf); if (t == VT_FLOAT) - vpushi((int)&__ulltof); + vpush_sym(func_old_type, TOK___ulltof); else if (t == VT_DOUBLE) - vpushi((int)&__ulltod); + vpush_sym(func_old_type, TOK___ulltod); else - vpushi((int)&__ulltold); + vpush_sym(func_old_type, TOK___ulltold); gfunc_call(&gf); vpushi(0); vtop->r = REG_FRET; @@ -3586,11 +3517,11 @@ void gen_cvt_ftoi1(int t) st = vtop->t & VT_BTYPE; gfunc_param(&gf); if (st == VT_FLOAT) - vpushi((int)&__ftoull); + vpush_sym(func_old_type, TOK___fixunssfdi); else if (st == VT_DOUBLE) - vpushi((int)&__dtoull); + vpush_sym(func_old_type, TOK___fixunsdfdi); else - vpushi((int)&__ldtoull); + vpush_sym(func_old_type, TOK___fixunsxfdi); gfunc_call(&gf); vpushi(0); vtop->r = REG_IRET; @@ -4049,7 +3980,7 @@ void vstore(void) gfunc_param(&gf); save_regs(0); - vpushi((int)&memcpy); + vpush_sym(func_old_type, TOK_memcpy); gfunc_call(&gf); /* leave source on stack */ } else if (ft & VT_BITFIELD) { @@ -4697,7 +4628,7 @@ void gfunc_param_typed(GFuncContext *gf, Sym *func, Sym *arg) void unary(void) { - int n, t, ft, fc, p, align, size, r, data_offset; + int n, t, ft, fc, align, size, r, data_offset; Sym *s; GFuncContext gf; AttributeDef ad; @@ -4847,11 +4778,8 @@ void unary(void) if (tok != '(') error("'%s' undeclared", get_tok_str(t, NULL)); /* for simple function calls, we tolerate undeclared - external reference */ - p = anon_sym++; - sym_push1(&global_stack, p, 0, FUNC_OLD); - /* int() function */ - s = external_sym(t, VT_FUNC | (p << VT_STRUCT_SHIFT), 0); + external reference to int() function */ + s = external_sym(t, func_old_type, 0); } vset(s->t, s->r, s->c); /* if forward reference, we must point to s */ @@ -5633,7 +5561,7 @@ void init_putz(int t, Section *sec, unsigned long c, int size) gfunc_param(&gf); vset(VT_INT, VT_LOCAL, c); gfunc_param(&gf); - vpushi((int)&memset); + vpush_sym(func_old_type, TOK_memset); gfunc_call(&gf); } } @@ -6190,7 +6118,8 @@ static int tcc_compile(TCCState *s) { Sym *define_start; char buf[512]; - + int p; + funcname = ""; include_stack_ptr = include_stack; ifdef_stack_ptr = ifdef_stack; @@ -6215,6 +6144,10 @@ static int tcc_compile(TCCState *s) /* define common 'char *' type because it is often used internally for arrays and struct dereference */ char_pointer_type = mk_pointer(VT_BYTE); + /* define an old type function 'int func()' */ + p = anon_sym++; + sym_push1(&global_stack, p, 0, FUNC_OLD); + func_old_type = VT_FUNC | (p << VT_STRUCT_SHIFT); define_start = define_stack.top; inp(); @@ -6807,8 +6740,6 @@ static void put32(unsigned char *p, unsigned int val) static void build_got(void) { /* if no got, then create it */ - /* a got is needed even if static link for the symbol - _GLOBAL_OFFSET_TABLE_ */ got = new_section(".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE); got->sh_entsize = 4; add_elf_sym(symtab_section, 0, 4, ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT), @@ -6933,6 +6864,12 @@ static void put_dt(Section *dynamic, int dt, unsigned long val) dynamic->data_ptr += sizeof(Elf32_Dyn); } +/* add tcc runtime libraries */ +static void tcc_add_runtime(TCCState *s1) +{ + tcc_add_file(s1, CONFIG_TCC_PREFIX "/lib/tcc/libtcc1.o"); +} + /* add dynamic sections so that the executable is dynamically linked */ static char elf_interp[] = "/lib/ld-linux.so.2"; @@ -6963,8 +6900,9 @@ int tcc_output_file(TCCState *s1, const char *filename) /* add libc crtn object */ if (file_type != TCC_OUTPUT_OBJ) { - tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o"); + tcc_add_runtime(s1); tcc_add_library(s1, "c"); + tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o"); } interp = NULL; @@ -8076,6 +8014,8 @@ int tcc_run(TCCState *s1, int argc, char **argv) int (*prog_main)(int, char **); int i; + tcc_add_runtime(s1); + relocate_common_syms(); /* compute relocation address : section are relocated in place */ |
