fixed VT_LLOCAL dereferencing

This commit is contained in:
bellard 2002-01-05 00:40:47 +00:00
parent 4124f1a1c1
commit 9eab1030f7

36
tcc.c
View file

@ -29,6 +29,7 @@
#include <sys/mman.h> #include <sys/mman.h>
#include <elf.h> #include <elf.h>
#include <stab.h> #include <stab.h>
#include <malloc.h>
#ifndef CONFIG_TCC_STATIC #ifndef CONFIG_TCC_STATIC
#include <dlfcn.h> #include <dlfcn.h>
#endif #endif
@ -218,8 +219,8 @@ int tcc_ext = 1;
#define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */ #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
#define VT_LVAL 0x0100 /* var is an lvalue */ #define VT_LVAL 0x0100 /* var is an lvalue */
#define VT_FORWARD 0x0200 /* value is forward reference */ #define VT_FORWARD 0x0200 /* value is forward reference */
#define VT_MUSTCAST 0x0400 /* value must be casted to be correct (user for #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
bool/char/short stored in int registers) */ char/short stored in integer registers) */
/* types */ /* types */
#define VT_STRUCT_SHIFT 16 /* structure/enum name shift (16 bits left) */ #define VT_STRUCT_SHIFT 16 /* structure/enum name shift (16 bits left) */
@ -2329,6 +2330,15 @@ void move_reg(int r, int s)
} }
} }
/* get address of vtop (vtop MUST BE an lvalue) */
void gaddrof(void)
{
vtop->r &= ~VT_LVAL;
/* tricky: if saved lvalue, then we can go back to lvalue */
if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
vtop->r = (vtop->r & ~VT_VALMASK) | VT_LOCAL | VT_LVAL;
}
/* store vtop a register belonging to class 'rc'. lvalues are /* store vtop a register belonging to class 'rc'. lvalues are
converted to values. Cannot be used if cannot be converted to converted to values. Cannot be used if cannot be converted to
register value (such as structures). */ register value (such as structures). */
@ -2396,7 +2406,7 @@ int gv(int rc)
vtop[-1].r = r; /* save register value */ vtop[-1].r = r; /* save register value */
/* increment pointer to get second word */ /* increment pointer to get second word */
vtop->t = VT_INT; vtop->t = VT_INT;
vtop->r &= ~VT_LVAL; gaddrof();
vpushi(4); vpushi(4);
gen_op('+'); gen_op('+');
vtop->r |= VT_LVAL; vtop->r |= VT_LVAL;
@ -3457,12 +3467,12 @@ void vstore(void)
gfunc_param(&gf); gfunc_param(&gf);
/* source */ /* source */
vtop->t = VT_INT; vtop->t = VT_INT;
vtop->r &= ~VT_LVAL; gaddrof();
gfunc_param(&gf); gfunc_param(&gf);
/* destination */ /* destination */
vswap(); vswap();
vtop->t = VT_INT; vtop->t = VT_INT;
vtop->r &= ~VT_LVAL; gaddrof();
gfunc_param(&gf); gfunc_param(&gf);
save_regs(); save_regs();
@ -3513,7 +3523,7 @@ void vstore(void)
vswap(); vswap();
/* convert to int to increment easily */ /* convert to int to increment easily */
vtop->t = VT_INT; vtop->t = VT_INT;
vtop->r &= ~VT_LVAL; gaddrof();
vpushi(4); vpushi(4);
gen_op('+'); gen_op('+');
vtop->r |= VT_LVAL; vtop->r |= VT_LVAL;
@ -4151,7 +4161,7 @@ void unary(void)
if ((vtop->t & VT_BTYPE) != VT_FUNC) if ((vtop->t & VT_BTYPE) != VT_FUNC)
test_lvalue(); test_lvalue();
vtop->t = mk_pointer(vtop->t); vtop->t = mk_pointer(vtop->t);
vtop->r &= ~VT_LVAL; gaddrof();
} else } else
if (t == '!') { if (t == '!') {
unary(); unary();
@ -4227,7 +4237,7 @@ void unary(void)
if (tok == TOK_ARROW) if (tok == TOK_ARROW)
indir(); indir();
test_lvalue(); test_lvalue();
vtop->r &= ~VT_LVAL; gaddrof();
next(); next();
/* expect pointer on structure */ /* expect pointer on structure */
if ((vtop->t & VT_BTYPE) != VT_STRUCT) if ((vtop->t & VT_BTYPE) != VT_STRUCT)
@ -5660,6 +5670,10 @@ static void put_stabd(int type, int other, int desc)
} }
/* output an ELF file (currently, only for testing) */ /* output an ELF file (currently, only for testing) */
/* XXX: better program header generation */
/* XXX: handle realloc'ed sections (instead of mmaping them) */
/* XXX: generate dynamic reloc info + DLL tables */
/* XXX: generate startup code */
void build_exe(char *filename) void build_exe(char *filename)
{ {
Elf32_Ehdr ehdr; Elf32_Ehdr ehdr;
@ -5866,7 +5880,7 @@ static void rt_printline(unsigned long wanted_pc)
sym++; sym++;
} }
/* did not find line number info: */ /* did not find line number info: */
fprintf(stderr, "(no debug info, pc=0x%08lx) ", wanted_pc); fprintf(stderr, "(no debug info, pc=0x%08lx): ", wanted_pc);
return; return;
found: found:
for(i = 0; i < incl_index - 1; i++) for(i = 0; i < incl_index - 1; i++)
@ -5919,7 +5933,7 @@ static void sig_error(int signum, siginfo_t *siginf, void *puc)
fprintf(stderr, "abort() called\n"); fprintf(stderr, "abort() called\n");
break; break;
default: default:
fprintf(stderr, "signal %d\n", signum); fprintf(stderr, "caught signal %d\n", signum);
break; break;
} }
exit(255); exit(255);
@ -5976,7 +5990,7 @@ void help(void)
"-Dsym[=val] : define 'sym' with value 'val'\n" "-Dsym[=val] : define 'sym' with value 'val'\n"
"-Usym : undefine 'sym'\n" "-Usym : undefine 'sym'\n"
"-llib : link with dynamic library 'lib'\n" "-llib : link with dynamic library 'lib'\n"
"-g : generate debug info\n" "-g : generate runtime debug info\n"
"-b : compile with built-in memory and bounds checker (implies -g)\n" "-b : compile with built-in memory and bounds checker (implies -g)\n"
"-i infile : compile infile\n" "-i infile : compile infile\n"
); );