suppressed some buffer overflows - moved function generation to cpu specific code (XXX: should have less cpu specific code for that)
This commit is contained in:
parent
8b41bc57e1
commit
14799da838
2 changed files with 105 additions and 83 deletions
44
i386-gen.c
44
i386-gen.c
|
@ -72,6 +72,8 @@ typedef struct GFuncContext {
|
||||||
|
|
||||||
/******************************************************/
|
/******************************************************/
|
||||||
|
|
||||||
|
static int *func_sub_sp_ptr;
|
||||||
|
|
||||||
void g(int c)
|
void g(int c)
|
||||||
{
|
{
|
||||||
*(char *)ind++ = c;
|
*(char *)ind++ = c;
|
||||||
|
@ -355,6 +357,48 @@ void gfunc_call(GFuncContext *c)
|
||||||
vtop--;
|
vtop--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* generate function prolog of type 't' */
|
||||||
|
void gfunc_prolog(int t)
|
||||||
|
{
|
||||||
|
int addr, align, size, u;
|
||||||
|
Sym *sym;
|
||||||
|
|
||||||
|
sym = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
|
||||||
|
addr = 8;
|
||||||
|
/* if the function returns a structure, then add an
|
||||||
|
implicit pointer parameter */
|
||||||
|
func_vt = sym->t;
|
||||||
|
if ((func_vt & VT_BTYPE) == VT_STRUCT) {
|
||||||
|
func_vc = addr;
|
||||||
|
addr += 4;
|
||||||
|
}
|
||||||
|
/* define parameters */
|
||||||
|
while ((sym = sym->next) != NULL) {
|
||||||
|
u = sym->t;
|
||||||
|
sym_push(sym->v & ~SYM_FIELD, u,
|
||||||
|
VT_LOCAL | VT_LVAL, addr);
|
||||||
|
size = type_size(u, &align);
|
||||||
|
size = (size + 3) & ~3;
|
||||||
|
#ifdef FUNC_STRUCT_PARAM_AS_PTR
|
||||||
|
/* structs are passed as pointer */
|
||||||
|
if ((u & VT_BTYPE) == VT_STRUCT) {
|
||||||
|
size = 4;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
addr += size;
|
||||||
|
}
|
||||||
|
o(0xe58955); /* push %ebp, mov %esp, %ebp */
|
||||||
|
func_sub_sp_ptr = (int *)oad(0xec81, 0); /* sub $xxx, %esp */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* generate function epilog */
|
||||||
|
void gfunc_epilog(void)
|
||||||
|
{
|
||||||
|
o(0xc3c9); /* leave, ret */
|
||||||
|
*func_sub_sp_ptr = (-loc + 3) & -4; /* align local size to word &
|
||||||
|
save local variables */
|
||||||
|
}
|
||||||
|
|
||||||
int gjmp(int t)
|
int gjmp(int t)
|
||||||
{
|
{
|
||||||
return psym(0xe9, t);
|
return psym(0xe9, t);
|
||||||
|
|
144
tcc.c
144
tcc.c
|
@ -32,11 +32,6 @@
|
||||||
/* preprocessor debug */
|
/* preprocessor debug */
|
||||||
//#define PP_DEBUG
|
//#define PP_DEBUG
|
||||||
|
|
||||||
/* these sizes are dummy for unix, because malloc() does not use
|
|
||||||
memory when the pages are not used */
|
|
||||||
#define TEXT_SIZE (4*1024*1024)
|
|
||||||
#define DATA_SIZE (4*1024*1024)
|
|
||||||
|
|
||||||
/* amount of virtual memory associate to a section (currently, we do
|
/* amount of virtual memory associate to a section (currently, we do
|
||||||
not realloc them) */
|
not realloc them) */
|
||||||
#define SECTION_VSIZE (1024 * 1024)
|
#define SECTION_VSIZE (1024 * 1024)
|
||||||
|
@ -398,6 +393,8 @@ void gen_op(int op);
|
||||||
void force_charshort_cast(int t);
|
void force_charshort_cast(int t);
|
||||||
void gen_cast(int t);
|
void gen_cast(int t);
|
||||||
void vstore(void);
|
void vstore(void);
|
||||||
|
Sym *sym_find(int v);
|
||||||
|
Sym *sym_push(int v, int t, int r, int c);
|
||||||
|
|
||||||
/* type handling */
|
/* type handling */
|
||||||
int type_size(int t, int *a);
|
int type_size(int t, int *a);
|
||||||
|
@ -546,7 +543,7 @@ unsigned long long __ldtoull(long double a)
|
||||||
|
|
||||||
/********************************************************/
|
/********************************************************/
|
||||||
|
|
||||||
/* copy a string and trucate it */
|
/* copy a string and truncate it */
|
||||||
char *pstrcpy(char *buf, int buf_size, const char *s)
|
char *pstrcpy(char *buf, int buf_size, const char *s)
|
||||||
{
|
{
|
||||||
char *q, *q_end;
|
char *q, *q_end;
|
||||||
|
@ -564,6 +561,16 @@ char *pstrcpy(char *buf, int buf_size, const char *s)
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* strcat and truncate */
|
||||||
|
char *pstrcat(char *buf, int buf_size, const char *s)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
len = strlen(buf);
|
||||||
|
if (len < buf_size)
|
||||||
|
pstrcpy(buf + len, buf_size - len, s);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
Section *new_section(const char *name)
|
Section *new_section(const char *name)
|
||||||
{
|
{
|
||||||
Section *sec, **psec;
|
Section *sec, **psec;
|
||||||
|
@ -1235,8 +1242,7 @@ void preprocess(void)
|
||||||
next();
|
next();
|
||||||
if (tok != TOK_STR)
|
if (tok != TOK_STR)
|
||||||
error("#include syntax error");
|
error("#include syntax error");
|
||||||
/* XXX: buffer overflow */
|
pstrcpy(buf, sizeof(buf), get_tok_str(tok, &tokc));
|
||||||
strcpy(buf, get_tok_str(tok, &tokc));
|
|
||||||
c = '\"';
|
c = '\"';
|
||||||
}
|
}
|
||||||
/* eat all spaces and comments after include */
|
/* eat all spaces and comments after include */
|
||||||
|
@ -1248,14 +1254,15 @@ void preprocess(void)
|
||||||
error("memory full");
|
error("memory full");
|
||||||
if (c == '\"') {
|
if (c == '\"') {
|
||||||
/* first search in current dir if "header.h" */
|
/* first search in current dir if "header.h" */
|
||||||
/* XXX: buffer overflow */
|
|
||||||
size = 0;
|
size = 0;
|
||||||
p = strrchr(filename, '/');
|
p = strrchr(filename, '/');
|
||||||
if (p)
|
if (p)
|
||||||
size = p + 1 - filename;
|
size = p + 1 - filename;
|
||||||
|
if (size > sizeof(buf1) - 1)
|
||||||
|
size = sizeof(buf1) - 1;
|
||||||
memcpy(buf1, filename, size);
|
memcpy(buf1, filename, size);
|
||||||
buf1[size] = '\0';
|
buf1[size] = '\0';
|
||||||
strcat(buf1, buf);
|
pstrcat(buf1, sizeof(buf1), buf);
|
||||||
f = fopen(buf1, "r");
|
f = fopen(buf1, "r");
|
||||||
if (f)
|
if (f)
|
||||||
goto found;
|
goto found;
|
||||||
|
@ -1850,13 +1857,12 @@ int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args)
|
||||||
if (s) {
|
if (s) {
|
||||||
token_buf[0] = '\0';
|
token_buf[0] = '\0';
|
||||||
st = (int *)s->c;
|
st = (int *)s->c;
|
||||||
/* XXX: buffer overflow */
|
|
||||||
notfirst = 0;
|
notfirst = 0;
|
||||||
while (*st) {
|
while (*st) {
|
||||||
if (notfirst)
|
if (notfirst)
|
||||||
strcat(token_buf, " ");
|
pstrcat(token_buf, sizeof(token_buf), " ");
|
||||||
t = tok_get(&st, &cval);
|
t = tok_get(&st, &cval);
|
||||||
strcat(token_buf, get_tok_str(t, &cval));
|
pstrcat(token_buf, sizeof(token_buf), get_tok_str(t, &cval));
|
||||||
notfirst = 1;
|
notfirst = 1;
|
||||||
}
|
}
|
||||||
#ifdef PP_DEBUG
|
#ifdef PP_DEBUG
|
||||||
|
@ -1918,11 +1924,10 @@ int *macro_twosharps(int *macro_str)
|
||||||
ident + ident or ident + number */
|
ident + ident or ident + number */
|
||||||
if (tok >= TOK_IDENT &&
|
if (tok >= TOK_IDENT &&
|
||||||
(t >= TOK_IDENT || t == TOK_CINT)) {
|
(t >= TOK_IDENT || t == TOK_CINT)) {
|
||||||
/* XXX: buffer overflow */
|
|
||||||
p = get_tok_str(tok, &tokc);
|
p = get_tok_str(tok, &tokc);
|
||||||
strcpy(token_buf, p);
|
pstrcpy(token_buf, sizeof(token_buf), p);
|
||||||
p = get_tok_str(t, &cval);
|
p = get_tok_str(t, &cval);
|
||||||
strcat(token_buf, p);
|
pstrcat(token_buf, sizeof(token_buf), p);
|
||||||
ts = tok_alloc(token_buf, 0);
|
ts = tok_alloc(token_buf, 0);
|
||||||
tok = ts->tok; /* modify current token */
|
tok = ts->tok; /* modify current token */
|
||||||
} else {
|
} else {
|
||||||
|
@ -3241,87 +3246,90 @@ int is_compatible_types(int t1, int t2)
|
||||||
printed in the type */
|
printed in the type */
|
||||||
/* XXX: union */
|
/* XXX: union */
|
||||||
/* XXX: add array and function pointers */
|
/* XXX: add array and function pointers */
|
||||||
/* XXX: buffer overflows */
|
|
||||||
void type_to_str(char *buf, int buf_size,
|
void type_to_str(char *buf, int buf_size,
|
||||||
int t, const char *varstr)
|
int t, const char *varstr)
|
||||||
{
|
{
|
||||||
int bt, v;
|
int bt, v;
|
||||||
Sym *s, *sa;
|
Sym *s, *sa;
|
||||||
char buf1[256];
|
char buf1[256];
|
||||||
|
const char *tstr;
|
||||||
|
|
||||||
t = t & VT_TYPE;
|
t = t & VT_TYPE;
|
||||||
bt = t & VT_BTYPE;
|
bt = t & VT_BTYPE;
|
||||||
buf[0] = '\0';
|
buf[0] = '\0';
|
||||||
if (t & VT_UNSIGNED)
|
if (t & VT_UNSIGNED)
|
||||||
strcat(buf, "unsigned ");
|
pstrcat(buf, buf_size, "unsigned ");
|
||||||
switch(bt) {
|
switch(bt) {
|
||||||
case VT_VOID:
|
case VT_VOID:
|
||||||
strcat(buf, "void");
|
tstr = "void";
|
||||||
break;
|
goto add_tstr;
|
||||||
case VT_BOOL:
|
case VT_BOOL:
|
||||||
strcat(buf, "_Bool");
|
tstr = "_Bool";
|
||||||
break;
|
goto add_tstr;
|
||||||
case VT_BYTE:
|
case VT_BYTE:
|
||||||
strcat(buf, "char");
|
tstr = "char";
|
||||||
break;
|
goto add_tstr;
|
||||||
case VT_SHORT:
|
case VT_SHORT:
|
||||||
strcat(buf, "short");
|
tstr = "short";
|
||||||
break;
|
goto add_tstr;
|
||||||
case VT_INT:
|
case VT_INT:
|
||||||
strcat(buf, "int");
|
tstr = "int";
|
||||||
break;
|
goto add_tstr;
|
||||||
case VT_LONG:
|
case VT_LONG:
|
||||||
strcat(buf, "long");
|
tstr = "long";
|
||||||
break;
|
goto add_tstr;
|
||||||
case VT_LLONG:
|
case VT_LLONG:
|
||||||
strcat(buf, "long long");
|
tstr = "long long";
|
||||||
break;
|
goto add_tstr;
|
||||||
case VT_FLOAT:
|
case VT_FLOAT:
|
||||||
strcat(buf, "float");
|
tstr = "float";
|
||||||
break;
|
goto add_tstr;
|
||||||
case VT_DOUBLE:
|
case VT_DOUBLE:
|
||||||
strcat(buf, "double");
|
tstr = "double";
|
||||||
break;
|
goto add_tstr;
|
||||||
case VT_LDOUBLE:
|
case VT_LDOUBLE:
|
||||||
strcat(buf, "long double");
|
tstr = "long double";
|
||||||
|
add_tstr:
|
||||||
|
pstrcat(buf, buf_size, tstr);
|
||||||
break;
|
break;
|
||||||
case VT_ENUM:
|
case VT_ENUM:
|
||||||
case VT_STRUCT:
|
case VT_STRUCT:
|
||||||
if (bt == VT_STRUCT)
|
if (bt == VT_STRUCT)
|
||||||
strcat(buf, "struct ");
|
tstr = "struct ";
|
||||||
else
|
else
|
||||||
strcat(buf, "enum ");
|
tstr = "enum ";
|
||||||
|
pstrcat(buf, buf_size, tstr);
|
||||||
v = (unsigned)t >> VT_STRUCT_SHIFT;
|
v = (unsigned)t >> VT_STRUCT_SHIFT;
|
||||||
if (v >= SYM_FIRST_ANOM)
|
if (v >= SYM_FIRST_ANOM)
|
||||||
strcat(buf, "<anonymous>");
|
pstrcat(buf, buf_size, "<anonymous>");
|
||||||
else
|
else
|
||||||
strcat(buf, get_tok_str(v, NULL));
|
pstrcat(buf, buf_size, get_tok_str(v, NULL));
|
||||||
break;
|
break;
|
||||||
case VT_FUNC:
|
case VT_FUNC:
|
||||||
s = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
|
s = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
|
||||||
type_to_str(buf, buf_size, s->t, varstr);
|
type_to_str(buf, buf_size, s->t, varstr);
|
||||||
strcat(buf, "(");
|
pstrcat(buf, buf_size, "(");
|
||||||
sa = s->next;
|
sa = s->next;
|
||||||
while (sa != NULL) {
|
while (sa != NULL) {
|
||||||
type_to_str(buf1, sizeof(buf1), sa->t, NULL);
|
type_to_str(buf1, sizeof(buf1), sa->t, NULL);
|
||||||
strcat(buf, buf1);
|
pstrcat(buf, buf_size, buf1);
|
||||||
sa = sa->next;
|
sa = sa->next;
|
||||||
if (sa)
|
if (sa)
|
||||||
strcat(buf, ", ");
|
pstrcat(buf, buf_size, ", ");
|
||||||
}
|
}
|
||||||
strcat(buf, ")");
|
pstrcat(buf, buf_size, ")");
|
||||||
goto no_var;
|
goto no_var;
|
||||||
case VT_PTR:
|
case VT_PTR:
|
||||||
s = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
|
s = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
|
||||||
strcpy(buf1, "*");
|
pstrcpy(buf1, sizeof(buf1), "*");
|
||||||
if (varstr)
|
if (varstr)
|
||||||
strcat(buf1, varstr);
|
pstrcat(buf1, sizeof(buf1), varstr);
|
||||||
type_to_str(buf, buf_size, s->t, buf1);
|
type_to_str(buf, buf_size, s->t, buf1);
|
||||||
goto no_var;
|
goto no_var;
|
||||||
}
|
}
|
||||||
if (varstr) {
|
if (varstr) {
|
||||||
strcat(buf, " ");
|
pstrcat(buf, buf_size, " ");
|
||||||
strcat(buf, varstr);
|
pstrcat(buf, buf_size, varstr);
|
||||||
}
|
}
|
||||||
no_var: ;
|
no_var: ;
|
||||||
}
|
}
|
||||||
|
@ -5147,7 +5155,7 @@ int decl_initializer_alloc(int t, AttributeDef *ad, int r, int has_init)
|
||||||
/* 'l' is VT_LOCAL or VT_CONST to define default storage type */
|
/* 'l' is VT_LOCAL or VT_CONST to define default storage type */
|
||||||
void decl(int l)
|
void decl(int l)
|
||||||
{
|
{
|
||||||
int *a, t, b, v, addr, has_init, size, align, r, u;
|
int t, b, v, addr, has_init, r;
|
||||||
Sym *sym;
|
Sym *sym;
|
||||||
AttributeDef ad;
|
AttributeDef ad;
|
||||||
|
|
||||||
|
@ -5207,41 +5215,12 @@ void decl(int l)
|
||||||
funcname = get_tok_str(v, NULL);
|
funcname = get_tok_str(v, NULL);
|
||||||
/* push a dummy symbol to enable local sym storage */
|
/* push a dummy symbol to enable local sym storage */
|
||||||
sym_push1(&local_stack, 0, 0, 0);
|
sym_push1(&local_stack, 0, 0, 0);
|
||||||
/* define parameters */
|
gfunc_prolog(t);
|
||||||
sym = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
|
|
||||||
/* XXX: the following is x86 dependant -> move it to
|
|
||||||
x86 code gen */
|
|
||||||
addr = 8;
|
|
||||||
/* if the function returns a structure, then add an
|
|
||||||
implicit pointer parameter */
|
|
||||||
func_vt = sym->t;
|
|
||||||
if ((func_vt & VT_BTYPE) == VT_STRUCT) {
|
|
||||||
func_vc = addr;
|
|
||||||
addr += 4;
|
|
||||||
}
|
|
||||||
while ((sym = sym->next) != NULL) {
|
|
||||||
u = sym->t;
|
|
||||||
sym_push(sym->v & ~SYM_FIELD, u,
|
|
||||||
VT_LOCAL | VT_LVAL, addr);
|
|
||||||
size = type_size(u, &align);
|
|
||||||
size = (size + 3) & ~3;
|
|
||||||
#ifdef FUNC_STRUCT_PARAM_AS_PTR
|
|
||||||
/* structs are passed as pointer */
|
|
||||||
if ((u & VT_BTYPE) == VT_STRUCT) {
|
|
||||||
size = 4;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
addr += size;
|
|
||||||
}
|
|
||||||
loc = 0;
|
loc = 0;
|
||||||
o(0xe58955); /* push %ebp, mov %esp, %ebp */
|
|
||||||
a = (int *)oad(0xec81, 0); /* sub $xxx, %esp */
|
|
||||||
rsym = 0;
|
rsym = 0;
|
||||||
block(NULL, NULL, NULL, NULL, 0);
|
block(NULL, NULL, NULL, NULL, 0);
|
||||||
gsym(rsym);
|
gsym(rsym);
|
||||||
o(0xc3c9); /* leave, ret */
|
gfunc_epilog();
|
||||||
*a = (-loc + 3) & -4; /* align local size to word &
|
|
||||||
save local variables */
|
|
||||||
cur_text_section->data_ptr = (unsigned char *)ind;
|
cur_text_section->data_ptr = (unsigned char *)ind;
|
||||||
sym_pop(&label_stack, NULL); /* reset label stack */
|
sym_pop(&label_stack, NULL); /* reset label stack */
|
||||||
sym_pop(&local_stack, NULL); /* reset local stack */
|
sym_pop(&local_stack, NULL); /* reset local stack */
|
||||||
|
@ -5398,8 +5377,7 @@ void define_symbol(const char *sym)
|
||||||
|
|
||||||
p = strchr(sym, '=');
|
p = strchr(sym, '=');
|
||||||
if (!p) {
|
if (!p) {
|
||||||
/* XXX: buffer overflow */
|
pstrcpy(buf, sizeof(buf), sym);
|
||||||
strcpy(buf, sym);
|
|
||||||
p = "1";
|
p = "1";
|
||||||
} else {
|
} else {
|
||||||
len = p - sym;
|
len = p - sym;
|
||||||
|
|
Loading…
Reference in a new issue