lotsa debug printing
This commit is contained in:
parent
a41c019ff7
commit
bb0a641cab
|
@ -225,12 +225,20 @@ void o(uint32_t i)
|
||||||
if (ind1 > cur_text_section->data_allocated)
|
if (ind1 > cur_text_section->data_allocated)
|
||||||
section_realloc(cur_text_section, ind1);
|
section_realloc(cur_text_section, ind1);
|
||||||
cur_text_section->data[ind++] = i&255;
|
cur_text_section->data[ind++] = i&255;
|
||||||
|
trace ("o "); eputs (itoa (i&255)); eputs ("\n");
|
||||||
|
trace ("o "); eputs (itoa (cur_text_section->data[ind-1])); eputs ("\n");
|
||||||
i>>=8;
|
i>>=8;
|
||||||
cur_text_section->data[ind++] = i&255;
|
cur_text_section->data[ind++] = i&255;
|
||||||
|
trace ("o "); eputs (itoa (i&255)); eputs ("\n");
|
||||||
|
trace ("o "); eputs (itoa (cur_text_section->data[ind-1])); eputs ("\n");
|
||||||
i>>=8;
|
i>>=8;
|
||||||
cur_text_section->data[ind++] = i&255;
|
cur_text_section->data[ind++] = i&255;
|
||||||
|
trace ("o "); eputs (itoa (i&255)); eputs ("\n");
|
||||||
|
trace ("o "); eputs (itoa (cur_text_section->data[ind-1])); eputs ("\n");
|
||||||
i>>=8;
|
i>>=8;
|
||||||
cur_text_section->data[ind++] = i;
|
cur_text_section->data[ind++] = i;
|
||||||
|
trace ("o "); eputs (itoa (i)); eputs ("\n");
|
||||||
|
trace ("o "); eputs (itoa (cur_text_section->data[ind-1])); eputs ("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t stuff_const(uint32_t op, uint32_t c)
|
static uint32_t stuff_const(uint32_t op, uint32_t c)
|
||||||
|
|
|
@ -1599,6 +1599,7 @@ ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands,
|
||||||
ASMOperand *op;
|
ASMOperand *op;
|
||||||
int i, reg;
|
int i, reg;
|
||||||
|
|
||||||
|
trace_enter ("asm_gen_code");
|
||||||
/* Strictly speaking %Xbp and %Xsp should be included in the
|
/* Strictly speaking %Xbp and %Xsp should be included in the
|
||||||
call-preserved registers, but currently it doesn't matter. */
|
call-preserved registers, but currently it doesn't matter. */
|
||||||
#ifdef TCC_TARGET_X86_64
|
#ifdef TCC_TARGET_X86_64
|
||||||
|
@ -1692,6 +1693,7 @@ ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
trace_exit ("asm_gen_code");
|
||||||
}
|
}
|
||||||
|
|
||||||
ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str)
|
ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str)
|
||||||
|
|
46
i386-gen.c
46
i386-gen.c
|
@ -99,6 +99,8 @@ static unsigned long func_bound_ind;
|
||||||
/* XXX: make it faster ? */
|
/* XXX: make it faster ? */
|
||||||
ST_FUNC void g(int c)
|
ST_FUNC void g(int c)
|
||||||
{
|
{
|
||||||
|
trace_enter ("g");
|
||||||
|
trace ("gen o c="); eputs (itoa (c)); eputs ("\n");
|
||||||
int ind1;
|
int ind1;
|
||||||
if (nocode_wanted)
|
if (nocode_wanted)
|
||||||
return;
|
return;
|
||||||
|
@ -106,7 +108,9 @@ ST_FUNC void g(int c)
|
||||||
if (ind1 > cur_text_section->data_allocated)
|
if (ind1 > cur_text_section->data_allocated)
|
||||||
section_realloc(cur_text_section, ind1);
|
section_realloc(cur_text_section, ind1);
|
||||||
cur_text_section->data[ind] = c;
|
cur_text_section->data[ind] = c;
|
||||||
|
trace ("gen o data="); eputs (itoa (cur_text_section->data[ind])); eputs ("\n");
|
||||||
ind = ind1;
|
ind = ind1;
|
||||||
|
trace_exit ("g");
|
||||||
}
|
}
|
||||||
|
|
||||||
ST_FUNC void o(unsigned int c)
|
ST_FUNC void o(unsigned int c)
|
||||||
|
@ -206,6 +210,7 @@ ST_FUNC void load(int r, SValue *sv)
|
||||||
int v, t, ft, fc, fr;
|
int v, t, ft, fc, fr;
|
||||||
SValue v1;
|
SValue v1;
|
||||||
|
|
||||||
|
trace_enter ("load");
|
||||||
#ifdef TCC_TARGET_PE
|
#ifdef TCC_TARGET_PE
|
||||||
SValue v2;
|
SValue v2;
|
||||||
sv = pe_getimport(sv, &v2);
|
sv = pe_getimport(sv, &v2);
|
||||||
|
@ -277,6 +282,7 @@ ST_FUNC void load(int r, SValue *sv)
|
||||||
o(0xc0 + r + v * 8); /* mov v, r */
|
o(0xc0 + r + v * 8); /* mov v, r */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
trace_exit ("load");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* store register 'r' in lvalue 'v' */
|
/* store register 'r' in lvalue 'v' */
|
||||||
|
@ -284,6 +290,7 @@ ST_FUNC void store(int r, SValue *v)
|
||||||
{
|
{
|
||||||
int fr, bt, ft, fc;
|
int fr, bt, ft, fc;
|
||||||
|
|
||||||
|
trace_enter ("store");
|
||||||
#ifdef TCC_TARGET_PE
|
#ifdef TCC_TARGET_PE
|
||||||
SValue v2;
|
SValue v2;
|
||||||
v = pe_getimport(v, &v2);
|
v = pe_getimport(v, &v2);
|
||||||
|
@ -320,6 +327,7 @@ ST_FUNC void store(int r, SValue *v)
|
||||||
} else if (fr != r) {
|
} else if (fr != r) {
|
||||||
o(0xc0 + fr + r * 8); /* mov r, fr */
|
o(0xc0 + fr + r * 8); /* mov r, fr */
|
||||||
}
|
}
|
||||||
|
trace_exit ("store");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gadd_sp(int val)
|
static void gadd_sp(int val)
|
||||||
|
@ -424,6 +432,7 @@ ST_FUNC void gfunc_call(int nb_args)
|
||||||
int size, align, r, args_size, i, func_call;
|
int size, align, r, args_size, i, func_call;
|
||||||
Sym *func_sym;
|
Sym *func_sym;
|
||||||
|
|
||||||
|
trace_enter ("gfunc_call");
|
||||||
args_size = 0;
|
args_size = 0;
|
||||||
for(i = 0;i < nb_args; i++) {
|
for(i = 0;i < nb_args; i++) {
|
||||||
if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
|
if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
|
||||||
|
@ -503,6 +512,7 @@ ST_FUNC void gfunc_call(int nb_args)
|
||||||
if (args_size && func_call != FUNC_STDCALL && func_call != FUNC_FASTCALLW)
|
if (args_size && func_call != FUNC_STDCALL && func_call != FUNC_FASTCALLW)
|
||||||
gadd_sp(args_size);
|
gadd_sp(args_size);
|
||||||
vtop--;
|
vtop--;
|
||||||
|
trace_exit ("gfunc_call");
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TCC_TARGET_PE
|
#ifdef TCC_TARGET_PE
|
||||||
|
@ -520,30 +530,40 @@ ST_FUNC void gfunc_prolog(CType *func_type)
|
||||||
Sym *sym;
|
Sym *sym;
|
||||||
CType *type;
|
CType *type;
|
||||||
|
|
||||||
|
trace_enter ("gfunc_prolog");
|
||||||
sym = func_type->ref;
|
sym = func_type->ref;
|
||||||
func_call = sym->f.func_call;
|
func_call = sym->f.func_call;
|
||||||
addr = 8;
|
addr = 8;
|
||||||
loc = 0;
|
loc = 0;
|
||||||
func_vc = 0;
|
func_vc = 0;
|
||||||
|
|
||||||
|
trace ("gfunc_prolog 10\n");
|
||||||
if (func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) {
|
if (func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) {
|
||||||
|
trace ("gfunc_prolog 11\n");
|
||||||
fastcall_nb_regs = func_call - FUNC_FASTCALL1 + 1;
|
fastcall_nb_regs = func_call - FUNC_FASTCALL1 + 1;
|
||||||
fastcall_regs_ptr = fastcall_regs;
|
fastcall_regs_ptr = fastcall_regs;
|
||||||
} else if (func_call == FUNC_FASTCALLW) {
|
} else if (func_call == FUNC_FASTCALLW) {
|
||||||
|
trace ("gfunc_prolog 15\n");
|
||||||
fastcall_nb_regs = 2;
|
fastcall_nb_regs = 2;
|
||||||
fastcall_regs_ptr = fastcallw_regs;
|
fastcall_regs_ptr = fastcallw_regs;
|
||||||
} else {
|
} else {
|
||||||
|
trace ("gfunc_prolog 18\n");
|
||||||
fastcall_nb_regs = 0;
|
fastcall_nb_regs = 0;
|
||||||
fastcall_regs_ptr = NULL;
|
fastcall_regs_ptr = NULL;
|
||||||
}
|
}
|
||||||
param_index = 0;
|
param_index = 0;
|
||||||
|
|
||||||
|
trace ("gfunc_prolog 20\n");
|
||||||
ind += FUNC_PROLOG_SIZE;
|
ind += FUNC_PROLOG_SIZE;
|
||||||
|
trace ("gfunc_prolog 21\n");
|
||||||
func_sub_sp_offset = ind;
|
func_sub_sp_offset = ind;
|
||||||
|
trace ("gfunc_prolog 22\n");
|
||||||
/* if the function returns a structure, then add an
|
/* if the function returns a structure, then add an
|
||||||
implicit pointer parameter */
|
implicit pointer parameter */
|
||||||
func_vt = sym->type;
|
func_vt = sym->type;
|
||||||
|
trace ("gfunc_prolog 23\n");
|
||||||
func_var = (sym->f.func_type == FUNC_ELLIPSIS);
|
func_var = (sym->f.func_type == FUNC_ELLIPSIS);
|
||||||
|
trace ("gfunc_prolog 24\n");
|
||||||
#ifdef TCC_TARGET_PE
|
#ifdef TCC_TARGET_PE
|
||||||
size = type_size(&func_vt,&align);
|
size = type_size(&func_vt,&align);
|
||||||
if (((func_vt.t & VT_BTYPE) == VT_STRUCT)
|
if (((func_vt.t & VT_BTYPE) == VT_STRUCT)
|
||||||
|
@ -551,29 +571,35 @@ ST_FUNC void gfunc_prolog(CType *func_type)
|
||||||
#else
|
#else
|
||||||
if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
|
if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
|
||||||
#endif
|
#endif
|
||||||
|
trace ("gfunc_prolog 25\n");
|
||||||
/* XXX: fastcall case ? */
|
/* XXX: fastcall case ? */
|
||||||
func_vc = addr;
|
func_vc = addr;
|
||||||
addr += 4;
|
addr += 4;
|
||||||
param_index++;
|
param_index++;
|
||||||
}
|
}
|
||||||
|
trace ("gfunc_prolog 30\n");
|
||||||
/* define parameters */
|
/* define parameters */
|
||||||
while ((sym = sym->next) != NULL) {
|
while ((sym = sym->next) != NULL) {
|
||||||
|
trace ("gfunc_prolog 31 param_index="); eputs (itoa (param_index)); eputs ("\n");
|
||||||
type = &sym->type;
|
type = &sym->type;
|
||||||
size = type_size(type, &align);
|
size = type_size(type, &align);
|
||||||
size = (size + 3) & ~3;
|
size = (size + 3) & ~3;
|
||||||
#ifdef FUNC_STRUCT_PARAM_AS_PTR
|
#ifdef FUNC_STRUCT_PARAM_AS_PTR
|
||||||
/* structs are passed as pointer */
|
/* structs are passed as pointer */
|
||||||
if ((type->t & VT_BTYPE) == VT_STRUCT) {
|
if ((type->t & VT_BTYPE) == VT_STRUCT) {
|
||||||
|
trace ("gfunc_prolog 36\n");
|
||||||
size = 4;
|
size = 4;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (param_index < fastcall_nb_regs) {
|
if (param_index < fastcall_nb_regs) {
|
||||||
|
trace ("gfunc_prolog 38\n");
|
||||||
/* save FASTCALL register */
|
/* save FASTCALL register */
|
||||||
loc -= 4;
|
loc -= 4;
|
||||||
o(0x89); /* movl */
|
o(0x89); /* movl */
|
||||||
gen_modrm(fastcall_regs_ptr[param_index], VT_LOCAL, NULL, loc);
|
gen_modrm(fastcall_regs_ptr[param_index], VT_LOCAL, NULL, loc);
|
||||||
param_addr = loc;
|
param_addr = loc;
|
||||||
} else {
|
} else {
|
||||||
|
trace ("gfunc_prolog 39\n");
|
||||||
param_addr = addr;
|
param_addr = addr;
|
||||||
addr += size;
|
addr += size;
|
||||||
}
|
}
|
||||||
|
@ -582,6 +608,7 @@ ST_FUNC void gfunc_prolog(CType *func_type)
|
||||||
param_index++;
|
param_index++;
|
||||||
}
|
}
|
||||||
func_ret_sub = 0;
|
func_ret_sub = 0;
|
||||||
|
trace ("gfunc_prolog 50\n");
|
||||||
/* pascal type call or fastcall ? */
|
/* pascal type call or fastcall ? */
|
||||||
if (func_call == FUNC_STDCALL || func_call == FUNC_FASTCALLW)
|
if (func_call == FUNC_STDCALL || func_call == FUNC_FASTCALLW)
|
||||||
func_ret_sub = addr - 8;
|
func_ret_sub = addr - 8;
|
||||||
|
@ -590,15 +617,18 @@ ST_FUNC void gfunc_prolog(CType *func_type)
|
||||||
func_ret_sub = 4;
|
func_ret_sub = 4;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
trace ("gfunc_prolog 60\n");
|
||||||
#ifdef CONFIG_TCC_BCHECK
|
#ifdef CONFIG_TCC_BCHECK
|
||||||
/* leave some room for bound checking code */
|
/* leave some room for bound checking code */
|
||||||
if (tcc_state->do_bounds_check) {
|
if (tcc_state->do_bounds_check) {
|
||||||
|
trace ("gfunc_prolog 61\n");
|
||||||
func_bound_offset = lbounds_section->data_offset;
|
func_bound_offset = lbounds_section->data_offset;
|
||||||
func_bound_ind = ind;
|
func_bound_ind = ind;
|
||||||
oad(0xb8, 0); /* lbound section pointer */
|
oad(0xb8, 0); /* lbound section pointer */
|
||||||
oad(0xb8, 0); /* call to function */
|
oad(0xb8, 0); /* call to function */
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
trace_exit ("gfunc_prolog");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* generate function epilog */
|
/* generate function epilog */
|
||||||
|
@ -606,9 +636,11 @@ ST_FUNC void gfunc_epilog(void)
|
||||||
{
|
{
|
||||||
addr_t v, saved_ind;
|
addr_t v, saved_ind;
|
||||||
|
|
||||||
|
trace ("gfunc_epilog\n");
|
||||||
#ifdef CONFIG_TCC_BCHECK
|
#ifdef CONFIG_TCC_BCHECK
|
||||||
if (tcc_state->do_bounds_check
|
if (tcc_state->do_bounds_check
|
||||||
&& func_bound_offset != lbounds_section->data_offset) {
|
&& func_bound_offset != lbounds_section->data_offset) {
|
||||||
|
trace ("gfunc_epilog 01\n");
|
||||||
addr_t saved_ind;
|
addr_t saved_ind;
|
||||||
addr_t *bounds_ptr;
|
addr_t *bounds_ptr;
|
||||||
Sym *sym_data;
|
Sym *sym_data;
|
||||||
|
@ -637,18 +669,22 @@ ST_FUNC void gfunc_epilog(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
trace ("gfunc_epilog 20\n");
|
||||||
/* align local size to word & save local variables */
|
/* align local size to word & save local variables */
|
||||||
v = (-loc + 3) & -4;
|
v = (-loc + 3) & -4;
|
||||||
|
|
||||||
#if USE_EBX
|
#if USE_EBX
|
||||||
|
trace ("gfunc_epilog 21\n");
|
||||||
o(0x8b);
|
o(0x8b);
|
||||||
gen_modrm(TREG_EBX, VT_LOCAL, NULL, -(v+4));
|
gen_modrm(TREG_EBX, VT_LOCAL, NULL, -(v+4));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
o(0xc9); /* leave */
|
o(0xc9); /* leave */
|
||||||
if (func_ret_sub == 0) {
|
if (func_ret_sub == 0) {
|
||||||
|
trace ("gfunc_epilog 23\n");
|
||||||
o(0xc3); /* ret */
|
o(0xc3); /* ret */
|
||||||
} else {
|
} else {
|
||||||
|
trace ("gfunc_epilog 24\n");
|
||||||
o(0xc2); /* ret n */
|
o(0xc2); /* ret n */
|
||||||
g(func_ret_sub);
|
g(func_ret_sub);
|
||||||
g(func_ret_sub >> 8);
|
g(func_ret_sub >> 8);
|
||||||
|
@ -662,6 +698,7 @@ ST_FUNC void gfunc_epilog(void)
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
trace ("gfunc_epilog 30\n");
|
||||||
o(0xe58955); /* push %ebp, mov %esp, %ebp */
|
o(0xe58955); /* push %ebp, mov %esp, %ebp */
|
||||||
o(0xec81); /* sub esp, stacksize */
|
o(0xec81); /* sub esp, stacksize */
|
||||||
gen_le32(v);
|
gen_le32(v);
|
||||||
|
@ -753,6 +790,8 @@ ST_FUNC void gen_opi(int op)
|
||||||
{
|
{
|
||||||
int r, fr, opc, c;
|
int r, fr, opc, c;
|
||||||
|
|
||||||
|
trace_enter ("gen_opi");
|
||||||
|
trace ("gen_opi op="); eputs (itoa (op)); eputs ("\n");
|
||||||
switch(op) {
|
switch(op) {
|
||||||
case '+':
|
case '+':
|
||||||
case TOK_ADDC1: /* add with carry generation */
|
case TOK_ADDC1: /* add with carry generation */
|
||||||
|
@ -764,7 +803,13 @@ ST_FUNC void gen_opi(int op)
|
||||||
r = gv(RC_INT);
|
r = gv(RC_INT);
|
||||||
vswap();
|
vswap();
|
||||||
c = vtop->c.i;
|
c = vtop->c.i;
|
||||||
|
trace ("gen_opi 14 c ="); eputs (itoa (c)); eputs ("\n");
|
||||||
|
#if __MESC__
|
||||||
|
char ch = c;
|
||||||
|
if (c == ch && ((ch >= 0 && ch < 128) || c < 0)) {
|
||||||
|
#else
|
||||||
if (c == (char)c) {
|
if (c == (char)c) {
|
||||||
|
#endif
|
||||||
/* generate inc and dec for smaller code */
|
/* generate inc and dec for smaller code */
|
||||||
if (c==1 && opc==0 && op != TOK_ADDC1) {
|
if (c==1 && opc==0 && op != TOK_ADDC1) {
|
||||||
o (0x40 | r); // inc
|
o (0x40 | r); // inc
|
||||||
|
@ -776,6 +821,7 @@ ST_FUNC void gen_opi(int op)
|
||||||
g(c);
|
g(c);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
trace ("gen_opi 20\n");
|
||||||
o(0x81);
|
o(0x81);
|
||||||
oad(0xc0 | (opc << 3) | r, c);
|
oad(0xc0 | (opc << 3) | r, c);
|
||||||
}
|
}
|
||||||
|
|
149
libtcc.c
149
libtcc.c
|
@ -222,10 +222,14 @@ PUB_FUNC void *tcc_mallocz(unsigned long size)
|
||||||
|
|
||||||
PUB_FUNC void *tcc_realloc(void *ptr, unsigned long size)
|
PUB_FUNC void *tcc_realloc(void *ptr, unsigned long size)
|
||||||
{
|
{
|
||||||
|
trace_enter ("tcc_realloc");
|
||||||
|
trace ("tcc_realloc size="); eputs (itoa (size)); eputs ("\n");
|
||||||
|
|
||||||
void *ptr1;
|
void *ptr1;
|
||||||
ptr1 = realloc(ptr, size);
|
ptr1 = realloc(ptr, size);
|
||||||
if (!ptr1 && size)
|
if (!ptr1 && size)
|
||||||
tcc_error("memory full (realloc)");
|
tcc_error("memory full (realloc)");
|
||||||
|
trace_exit ("tcc_realloc");
|
||||||
return ptr1;
|
return ptr1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -435,11 +439,16 @@ ST_FUNC void dynarray_reset(void *pp, int *n)
|
||||||
static void tcc_split_path(TCCState *s, void *p_ary, int *p_nb_ary, const char *in)
|
static void tcc_split_path(TCCState *s, void *p_ary, int *p_nb_ary, const char *in)
|
||||||
{
|
{
|
||||||
const char *p;
|
const char *p;
|
||||||
|
//eputs ("sp in="); //eputs (in); //eputs ("\n");
|
||||||
do {
|
do {
|
||||||
int c;
|
int c;
|
||||||
CString str;
|
CString str;
|
||||||
|
//eputs ("sp in="); //eputs (in); //eputs ("\n");
|
||||||
|
//if (s->nb_files) {struct filespec *f = s->files[0]; //eputs ("sp 01 file[0]="); //eputs (f->name); //eputs ("\n");}
|
||||||
|
|
||||||
|
|
||||||
cstr_new(&str);
|
cstr_new(&str);
|
||||||
|
//if (s->nb_files) {struct filespec *f = s->files[0]; //eputs ("sp 02 file[0]="); //eputs (f->name); //eputs ("\n");}
|
||||||
for (p = in; c = *p, c != '\0' && c != PATHSEP[0]; ++p) {
|
for (p = in; c = *p, c != '\0' && c != PATHSEP[0]; ++p) {
|
||||||
if (c == '{' && p[1] && p[2] == '}') {
|
if (c == '{' && p[1] && p[2] == '}') {
|
||||||
c = p[1], p += 2;
|
c = p[1], p += 2;
|
||||||
|
@ -451,11 +460,15 @@ static void tcc_split_path(TCCState *s, void *p_ary, int *p_nb_ary, const char *
|
||||||
}
|
}
|
||||||
if (str.size) {
|
if (str.size) {
|
||||||
cstr_ccat(&str, '\0');
|
cstr_ccat(&str, '\0');
|
||||||
|
//if (s->nb_files) {struct filespec *f = s->files[0]; //eputs ("sp 14 file[0]="); //eputs (f->name); //eputs ("\n");}
|
||||||
dynarray_add(p_ary, p_nb_ary, tcc_strdup(str.data));
|
dynarray_add(p_ary, p_nb_ary, tcc_strdup(str.data));
|
||||||
}
|
}
|
||||||
|
//if (s->nb_files) {struct filespec *f = s->files[0]; //eputs ("sp 15 file[0]="); //eputs (f->name); //eputs ("\n");}
|
||||||
cstr_free(&str);
|
cstr_free(&str);
|
||||||
|
//if (s->nb_files) {struct filespec *f = s->files[0]; //eputs ("sp 16 file[0]="); //eputs (f->name); //eputs ("\n");}
|
||||||
in = p+1;
|
in = p+1;
|
||||||
} while (*p);
|
} while (*p);
|
||||||
|
//eputs ("sp 99\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************/
|
/********************************************************/
|
||||||
|
@ -572,53 +585,78 @@ PUB_FUNC void tcc_warning(const char *fmt, ...)
|
||||||
|
|
||||||
ST_FUNC void tcc_open_bf(TCCState *s1, const char *filename, int initlen)
|
ST_FUNC void tcc_open_bf(TCCState *s1, const char *filename, int initlen)
|
||||||
{
|
{
|
||||||
|
trace_enter ("tcc_open_bf");
|
||||||
BufferedFile *bf;
|
BufferedFile *bf;
|
||||||
int buflen = initlen ? initlen : IO_BUF_SIZE;
|
int buflen = initlen ? initlen : IO_BUF_SIZE;
|
||||||
|
|
||||||
bf = tcc_mallocz(sizeof(BufferedFile) + buflen);
|
bf = tcc_mallocz(sizeof(BufferedFile) + buflen);
|
||||||
|
trace ("tcc_open_bf buflen="); eputs (itoa (buflen)); eputs ("\n");
|
||||||
|
//eputs ("tcc_open_bf bf size="); //eputs (itoa (sizeof (BufferedFile) + buflen)); //eputs ("\n");
|
||||||
|
|
||||||
|
trace ("tcc_open_bf 10\n");
|
||||||
bf->buf_ptr = bf->buffer;
|
bf->buf_ptr = bf->buffer;
|
||||||
|
trace ("tcc_open_bf 11\n");
|
||||||
bf->buf_end = bf->buffer + initlen;
|
bf->buf_end = bf->buffer + initlen;
|
||||||
|
trace ("tcc_open_bf 12\n");
|
||||||
bf->buf_end[0] = CH_EOB; /* put eob symbol */
|
bf->buf_end[0] = CH_EOB; /* put eob symbol */
|
||||||
|
trace ("tcc_open_bf 13\n");
|
||||||
pstrcpy(bf->filename, sizeof(bf->filename), filename);
|
pstrcpy(bf->filename, sizeof(bf->filename), filename);
|
||||||
|
trace ("tcc_open_bf 14\n");
|
||||||
bf->true_filename = bf->filename;
|
bf->true_filename = bf->filename;
|
||||||
|
trace ("tcc_open_bf 15\n");
|
||||||
bf->line_num = 1;
|
bf->line_num = 1;
|
||||||
bf->ifdef_stack_ptr = s1->ifdef_stack_ptr;
|
bf->ifdef_stack_ptr = s1->ifdef_stack_ptr;
|
||||||
bf->fd = -1;
|
bf->fd = -1;
|
||||||
bf->prev = file;
|
bf->prev = file;
|
||||||
file = bf;
|
file = bf;
|
||||||
tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
|
tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
|
||||||
|
trace_exit ("tcc_open_bf");
|
||||||
}
|
}
|
||||||
|
|
||||||
ST_FUNC void tcc_close(void)
|
ST_FUNC void tcc_close(void)
|
||||||
{
|
{
|
||||||
|
trace_enter ("tcc_close");
|
||||||
BufferedFile *bf = file;
|
BufferedFile *bf = file;
|
||||||
|
//eputs ("tcc_close file:"); //eputs (itoa (file)); //eputs ("\n");
|
||||||
|
//eputs ("tcc_close bf->fd:"); //eputs (itoa (bf->fd)); //eputs ("\n");
|
||||||
|
//eputs ("tcc_close bf->prev:"); //eputs (itoa (bf->prev)); //eputs ("\n");
|
||||||
if (bf->fd > 0) {
|
if (bf->fd > 0) {
|
||||||
|
//eputs ("tcc_close bf->filename:"); //eputs (bf->filename); //eputs ("\n");
|
||||||
close(bf->fd);
|
close(bf->fd);
|
||||||
total_lines += bf->line_num;
|
total_lines += bf->line_num;
|
||||||
}
|
}
|
||||||
if (bf->true_filename != bf->filename)
|
if (bf->true_filename != bf->filename)
|
||||||
tcc_free(bf->true_filename);
|
tcc_free(bf->true_filename);
|
||||||
|
trace ("tcc_close file->buf_ptr="); eputs (file->buf_ptr); eputs ("\n");
|
||||||
file = bf->prev;
|
file = bf->prev;
|
||||||
tcc_free(bf);
|
tcc_free(bf);
|
||||||
|
trace_exit ("tcc_close");
|
||||||
}
|
}
|
||||||
|
|
||||||
ST_FUNC int tcc_open(TCCState *s1, const char *filename)
|
ST_FUNC int tcc_open(TCCState *s1, const char *filename)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
|
trace_enter ("tcc_open");
|
||||||
|
trace ("tcc_open file-name="); eputs (filename); eputs ("\n");
|
||||||
if (strcmp(filename, "-") == 0)
|
if (strcmp(filename, "-") == 0)
|
||||||
fd = 0, filename = "<stdin>";
|
fd = 0, filename = "<stdin>";
|
||||||
else
|
else
|
||||||
fd = open(filename, O_RDONLY | O_BINARY);
|
fd = open(filename, O_RDONLY | O_BINARY);
|
||||||
|
trace ("tcc_open fd="); eputs (itoa (fd)); eputs ("\n");
|
||||||
if ((s1->verbose == 2 && fd >= 0) || s1->verbose == 3)
|
if ((s1->verbose == 2 && fd >= 0) || s1->verbose == 3)
|
||||||
printf("%s %*s%s\n", fd < 0 ? "nf":"->",
|
printf("%s %*s%s\n", fd < 0 ? "nf":"->",
|
||||||
(int)(s1->include_stack_ptr - s1->include_stack), "", filename);
|
(int)(s1->include_stack_ptr - s1->include_stack), "", filename);
|
||||||
if (fd < 0)
|
if (fd < 0) {
|
||||||
|
trace_exit ("tcc_open");
|
||||||
return -1;
|
return -1;
|
||||||
|
eputs ("tcc_open 10\n");
|
||||||
tcc_open_bf(s1, filename, 0);
|
tcc_open_bf(s1, filename, 0);
|
||||||
|
eputs ("tcc_open 11\n");
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
normalize_slashes(file->filename);
|
normalize_slashes(file->filename);
|
||||||
#endif
|
#endif
|
||||||
file->fd = fd;
|
file->fd = fd;
|
||||||
|
trace_exit ("tcc_open");
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -628,6 +666,7 @@ static int tcc_compile(TCCState *s1)
|
||||||
Sym *define_start;
|
Sym *define_start;
|
||||||
int filetype, is_asm;
|
int filetype, is_asm;
|
||||||
|
|
||||||
|
trace_enter ("tcc_compile");
|
||||||
define_start = define_stack;
|
define_start = define_stack;
|
||||||
filetype = s1->filetype;
|
filetype = s1->filetype;
|
||||||
is_asm = filetype == AFF_TYPE_ASM || filetype == AFF_TYPE_ASMPP;
|
is_asm = filetype == AFF_TYPE_ASM || filetype == AFF_TYPE_ASMPP;
|
||||||
|
@ -637,7 +676,9 @@ static int tcc_compile(TCCState *s1)
|
||||||
s1->nb_errors = 0;
|
s1->nb_errors = 0;
|
||||||
s1->error_set_jmp_enabled = 1;
|
s1->error_set_jmp_enabled = 1;
|
||||||
|
|
||||||
|
trace ("tcc_compile 05 nb_errors="); eputs (itoa (s1->nb_errors)); eputs ("\n");
|
||||||
preprocess_start(s1, is_asm);
|
preprocess_start(s1, is_asm);
|
||||||
|
trace ("tcc_compile 06 nb_errors="); eputs (itoa (s1->nb_errors)); eputs ("\n");
|
||||||
if (s1->output_type == TCC_OUTPUT_PREPROCESS) {
|
if (s1->output_type == TCC_OUTPUT_PREPROCESS) {
|
||||||
tcc_preprocess(s1);
|
tcc_preprocess(s1);
|
||||||
} else if (is_asm) {
|
} else if (is_asm) {
|
||||||
|
@ -647,7 +688,9 @@ static int tcc_compile(TCCState *s1)
|
||||||
tcc_error_noabort("asm not supported");
|
tcc_error_noabort("asm not supported");
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
|
trace ("tcc_compile 13 nb_errors="); eputs (itoa (s1->nb_errors)); eputs ("\n");
|
||||||
tccgen_compile(s1);
|
tccgen_compile(s1);
|
||||||
|
trace ("tcc_compile 14 nb_errors="); eputs (itoa (s1->nb_errors)); eputs ("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s1->error_set_jmp_enabled = 0;
|
s1->error_set_jmp_enabled = 0;
|
||||||
|
@ -659,6 +702,7 @@ static int tcc_compile(TCCState *s1)
|
||||||
sym_pop(&global_stack, NULL, 0);
|
sym_pop(&global_stack, NULL, 0);
|
||||||
sym_pop(&local_stack, NULL, 0);
|
sym_pop(&local_stack, NULL, 0);
|
||||||
tccelf_end_file(s1);
|
tccelf_end_file(s1);
|
||||||
|
trace_exit ("tcc_compile");
|
||||||
return s1->nb_errors != 0 ? -1 : 0;
|
return s1->nb_errors != 0 ? -1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -677,23 +721,35 @@ LIBTCCAPI int tcc_compile_string(TCCState *s, const char *str)
|
||||||
/* define a preprocessor symbol. A value can also be provided with the '=' operator */
|
/* define a preprocessor symbol. A value can also be provided with the '=' operator */
|
||||||
LIBTCCAPI void tcc_define_symbol(TCCState *s1, const char *sym, const char *value)
|
LIBTCCAPI void tcc_define_symbol(TCCState *s1, const char *sym, const char *value)
|
||||||
{
|
{
|
||||||
|
trace_enter ("tcc_define_symbol");
|
||||||
|
trace ("tcc_define_symbol value="); eputs (itoa (value)); eputs ("\n");
|
||||||
|
|
||||||
int len1, len2;
|
int len1, len2;
|
||||||
/* default value */
|
/* default value */
|
||||||
if (!value)
|
if (!value)
|
||||||
value = "1";
|
value = "1";
|
||||||
|
trace ("tcc_define_symbol 01\n");
|
||||||
len1 = strlen(sym);
|
len1 = strlen(sym);
|
||||||
|
trace ("tcc_define_symbol 02\n");
|
||||||
len2 = strlen(value);
|
len2 = strlen(value);
|
||||||
|
trace ("tcc_define_symbol 03\n");
|
||||||
|
|
||||||
/* init file structure */
|
/* init file structure */
|
||||||
tcc_open_bf(s1, "<define>", len1 + len2 + 1);
|
tcc_open_bf(s1, "<define>", len1 + len2 + 1);
|
||||||
|
trace ("tcc_define_symbol 04\n");
|
||||||
memcpy(file->buffer, sym, len1);
|
memcpy(file->buffer, sym, len1);
|
||||||
file->buffer[len1] = ' ';
|
file->buffer[len1] = ' ';
|
||||||
memcpy(file->buffer + len1 + 1, value, len2);
|
memcpy(file->buffer + len1 + 1, value, len2);
|
||||||
|
|
||||||
|
trace ("tcc_define_symbol X="); //eputs (file->buffer); //eputs ("\n");
|
||||||
/* parse with define parser */
|
/* parse with define parser */
|
||||||
next_nomacro();
|
next_nomacro();
|
||||||
|
trace ("tcc_define_symbol 09\n");
|
||||||
parse_define();
|
parse_define();
|
||||||
|
trace ("tcc_define_symbol 10\n");
|
||||||
|
|
||||||
tcc_close();
|
tcc_close();
|
||||||
|
trace_exit ("tcc_define_symbol");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* undefine a preprocessor symbol */
|
/* undefine a preprocessor symbol */
|
||||||
|
@ -711,14 +767,17 @@ LIBTCCAPI void tcc_undefine_symbol(TCCState *s1, const char *sym)
|
||||||
/* cleanup all static data used during compilation */
|
/* cleanup all static data used during compilation */
|
||||||
static void tcc_cleanup(void)
|
static void tcc_cleanup(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (NULL == tcc_state)
|
if (NULL == tcc_state)
|
||||||
return;
|
return;
|
||||||
while (file)
|
while (file)
|
||||||
tcc_close();
|
tcc_close();
|
||||||
tccpp_delete(tcc_state);
|
tccpp_delete(tcc_state);
|
||||||
|
//eputs ("tcc_cleanup01\n");
|
||||||
tcc_state = NULL;
|
tcc_state = NULL;
|
||||||
/* free sym_pools */
|
/* free sym_pools */
|
||||||
dynarray_reset(&sym_pools, &nb_sym_pools);
|
dynarray_reset(&sym_pools, &nb_sym_pools);
|
||||||
|
//eputs ("tcc_cleanup02\n");
|
||||||
/* reset symbol stack */
|
/* reset symbol stack */
|
||||||
sym_free_first = NULL;
|
sym_free_first = NULL;
|
||||||
}
|
}
|
||||||
|
@ -727,17 +786,28 @@ LIBTCCAPI TCCState *tcc_new(void)
|
||||||
{
|
{
|
||||||
TCCState *s;
|
TCCState *s;
|
||||||
|
|
||||||
|
//eputs ("tcc_new\n");
|
||||||
tcc_cleanup();
|
tcc_cleanup();
|
||||||
|
//eputs ("tcc_new01\n");
|
||||||
|
|
||||||
s = tcc_mallocz(sizeof(TCCState));
|
s = tcc_mallocz(sizeof(TCCState));
|
||||||
|
//eputs ("size:"); //eputs (itoa (sizeof(TCCState))); //eputs ("\n");
|
||||||
|
//eputs ("tcc_new02\n");
|
||||||
|
//eputs ("s="); //eputs (itoa (s)); //eputs ("\n");
|
||||||
|
|
||||||
if (!s)
|
if (!s)
|
||||||
return NULL;
|
return NULL;
|
||||||
tcc_state = s;
|
tcc_state = s;
|
||||||
|
|
||||||
|
trace ("tccnew include_stack="); eputs (itoa (&s->include_stack[0])); eputs ("\n");
|
||||||
|
|
||||||
++nb_states;
|
++nb_states;
|
||||||
|
|
||||||
#if BOOTSTRAP
|
#if BOOTSTRAP
|
||||||
s->static_link = 1;
|
s->static_link = 1;
|
||||||
#endif
|
#endif
|
||||||
|
eputs ("tcc_new03\n");
|
||||||
|
|
||||||
s->alacarte_link = 1;
|
s->alacarte_link = 1;
|
||||||
s->nocommon = 1;
|
s->nocommon = 1;
|
||||||
s->warn_implicit_function_declaration = 1;
|
s->warn_implicit_function_declaration = 1;
|
||||||
|
@ -894,6 +964,8 @@ LIBTCCAPI TCCState *tcc_new(void)
|
||||||
/* Some GCC builtins that are simple to express as macros. */
|
/* Some GCC builtins that are simple to express as macros. */
|
||||||
tcc_define_symbol(s, "__builtin_extract_return_addr(x)", "x");
|
tcc_define_symbol(s, "__builtin_extract_return_addr(x)", "x");
|
||||||
#endif /* ndef TCC_TARGET_PE */
|
#endif /* ndef TCC_TARGET_PE */
|
||||||
|
//eputs ("tcc_new99\n");
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -999,12 +1071,35 @@ LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !__x86_64__
|
||||||
|
#undef eputs
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !BOOTSTRAP // MESC
|
||||||
|
#define for_each_elem(sec, startoff, elem, type) \
|
||||||
|
for (elem = (type *) sec->data + startoff; \
|
||||||
|
elem < (type *) (sec->data + sec->data_offset); elem++)
|
||||||
|
#else
|
||||||
|
#define for_each_elem(sec, startoff, elem, type) \
|
||||||
|
elem = sec->data + sizeof (type) * startoff; \
|
||||||
|
for (;elem < ((type *) (sec->data + sec->data_offset)); elem++)
|
||||||
|
#endif
|
||||||
|
|
||||||
ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
|
ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* open the file */
|
/* open the file */
|
||||||
|
trace ("tcc_add_file_internal filename="); eputs (filename); eputs ("\n");
|
||||||
ret = tcc_open(s1, filename);
|
ret = tcc_open(s1, filename);
|
||||||
|
trace ("tcc_add_file_internal 20 ret="); eputs (itoa (ret));; eputs ("\n");
|
||||||
|
|
||||||
|
for_each_elem(symtab_section, 1, esym, ElfW(Sym)) {
|
||||||
|
trace ("tcc_add_file_internal num="); eputs (itoa (esym->st_shndx)); eputs ("\n");
|
||||||
|
name = (char *) strtab_section->data + esym->st_name;
|
||||||
|
trace ("tcc_add_file_internal name="); eputs (name); eputs ("\n");
|
||||||
|
}
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
if (flags & AFF_PRINT_ERROR)
|
if (flags & AFF_PRINT_ERROR)
|
||||||
tcc_error_noabort("file '%s' not found", filename);
|
tcc_error_noabort("file '%s' not found", filename);
|
||||||
|
@ -1030,45 +1125,62 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
|
||||||
|
|
||||||
switch (obj_type) {
|
switch (obj_type) {
|
||||||
case AFF_BINTYPE_REL:
|
case AFF_BINTYPE_REL:
|
||||||
|
{
|
||||||
ret = tcc_load_object_file(s1, fd, 0);
|
ret = tcc_load_object_file(s1, fd, 0);
|
||||||
|
trace ("tcc_add_file_internal 41 ret="); eputs (itoa (ret));; eputs ("\n");
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
#ifndef TCC_TARGET_PE
|
#ifndef TCC_TARGET_PE
|
||||||
case AFF_BINTYPE_DYN:
|
case AFF_BINTYPE_DYN:
|
||||||
|
{
|
||||||
if (s1->output_type == TCC_OUTPUT_MEMORY) {
|
if (s1->output_type == TCC_OUTPUT_MEMORY) {
|
||||||
ret = 0;
|
ret = 0;
|
||||||
#ifdef TCC_IS_NATIVE
|
#ifdef TCC_IS_NATIVE
|
||||||
if (NULL == dlopen(filename, RTLD_GLOBAL | RTLD_LAZY))
|
if (NULL == dlopen(filename, RTLD_GLOBAL | RTLD_LAZY))
|
||||||
ret = -1;
|
ret = -1;
|
||||||
#endif
|
#endif
|
||||||
|
trace ("tcc_add_file_internal 42 ret="); eputs (itoa (ret));; eputs ("\n");
|
||||||
} else {
|
} else {
|
||||||
ret = tcc_load_dll(s1, fd, filename,
|
ret = tcc_load_dll(s1, fd, filename,
|
||||||
(flags & AFF_REFERENCED_DLL) != 0);
|
(flags & AFF_REFERENCED_DLL) != 0);
|
||||||
|
trace ("tcc_add_file_internal 43 ret="); eputs (itoa (ret));; eputs ("\n");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
case AFF_BINTYPE_AR:
|
case AFF_BINTYPE_AR:
|
||||||
|
{
|
||||||
ret = tcc_load_archive(s1, fd);
|
ret = tcc_load_archive(s1, fd);
|
||||||
|
trace ("tcc_add_file_internal 51 ret="); eputs (itoa (ret));; eputs ("\n");
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
#ifdef TCC_TARGET_COFF
|
#ifdef TCC_TARGET_COFF
|
||||||
case AFF_BINTYPE_C67:
|
case AFF_BINTYPE_C67:
|
||||||
ret = tcc_load_coff(s1, fd);
|
ret = tcc_load_coff(s1, fd);
|
||||||
|
trace ("tcc_add_file_internal 52 ret="); eputs (itoa (ret));; eputs ("\n");
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
|
{
|
||||||
#ifdef TCC_TARGET_PE
|
#ifdef TCC_TARGET_PE
|
||||||
ret = pe_load_file(s1, filename, fd);
|
ret = pe_load_file(s1, filename, fd);
|
||||||
#else
|
#else
|
||||||
/* as GNU ld, consider it is an ld script if not recognized */
|
/* as GNU ld, consider it is an ld script if not recognized */
|
||||||
ret = tcc_load_ldscript(s1);
|
ret = tcc_load_ldscript(s1);
|
||||||
|
trace ("tcc_add_file_internal 61 ret="); eputs (itoa (ret));; eputs ("\n");
|
||||||
#endif
|
#endif
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
tcc_error_noabort("unrecognized file type");
|
tcc_error_noabort("unrecognized file type");
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ret = tcc_compile(s1);
|
ret = tcc_compile(s1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trace ("tcc_add_file_internal 90\n");
|
||||||
tcc_close();
|
tcc_close();
|
||||||
|
trace_exit ("tcc_add_file_internal");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1099,7 +1211,11 @@ LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename)
|
||||||
|
|
||||||
LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname)
|
LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname)
|
||||||
{
|
{
|
||||||
|
trace ("tcc_add_library_path path="); eputs (pathname); eputs ("\n");
|
||||||
tcc_split_path(s, &s->library_paths, &s->nb_library_paths, pathname);
|
tcc_split_path(s, &s->library_paths, &s->nb_library_paths, pathname);
|
||||||
|
for(int i = 0; i < s->nb_library_paths; i++) {
|
||||||
|
trace ("tcc_add_library_path dir="); eputs (s->library_paths[i]); eputs ("\n");
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1109,8 +1225,11 @@ static int tcc_add_library_internal(TCCState *s, const char *fmt,
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
trace ("tcc_add_library_internal file-name="); eputs (filename); eputs ("\n");
|
||||||
|
trace ("tcc_add_library_internal nb_paths="); eputs (itoa (nb_paths)); eputs ("\n");
|
||||||
for(i = 0; i < nb_paths; i++) {
|
for(i = 0; i < nb_paths; i++) {
|
||||||
snprintf(buf, sizeof(buf), fmt, paths[i], filename);
|
snprintf(buf, sizeof(buf), fmt, paths[i], filename);
|
||||||
|
trace ("tcc_add_library_internal buf="); eputs (buf); eputs ("\n");
|
||||||
if (tcc_add_file_internal(s, buf, flags | AFF_TYPE_BIN) == 0)
|
if (tcc_add_file_internal(s, buf, flags | AFF_TYPE_BIN) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1127,6 +1246,7 @@ ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags)
|
||||||
|
|
||||||
ST_FUNC int tcc_add_crt(TCCState *s, const char *filename)
|
ST_FUNC int tcc_add_crt(TCCState *s, const char *filename)
|
||||||
{
|
{
|
||||||
|
trace ("tcc_add_crt file name="); eputs (filename); eputs ("\n");
|
||||||
if (-1 == tcc_add_library_internal(s, "%s/%s",
|
if (-1 == tcc_add_library_internal(s, "%s/%s",
|
||||||
filename, 0, s->crt_paths, s->nb_crt_paths))
|
filename, 0, s->crt_paths, s->nb_crt_paths))
|
||||||
tcc_error_noabort("file '%s' not found", filename);
|
tcc_error_noabort("file '%s' not found", filename);
|
||||||
|
@ -1157,6 +1277,7 @@ LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname)
|
||||||
|
|
||||||
PUB_FUNC int tcc_add_library_err(TCCState *s, const char *libname)
|
PUB_FUNC int tcc_add_library_err(TCCState *s, const char *libname)
|
||||||
{
|
{
|
||||||
|
trace ("tcc_add_library_err libname="); eputs (libname); eputs ("\n");
|
||||||
int ret = tcc_add_library(s, libname);
|
int ret = tcc_add_library(s, libname);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
tcc_error_noabort("library '%s' not found", libname);
|
tcc_error_noabort("library '%s' not found", libname);
|
||||||
|
@ -1178,6 +1299,7 @@ LIBTCCAPI int tcc_add_symbol(TCCState *s, const char *name, const void *val)
|
||||||
So it is handled here as if it were in a DLL. */
|
So it is handled here as if it were in a DLL. */
|
||||||
pe_putimport(s, 0, name, (uintptr_t)val);
|
pe_putimport(s, 0, name, (uintptr_t)val);
|
||||||
#else
|
#else
|
||||||
|
trace ("tcc_add_symbol name="); eputs (name); eputs ("\n");
|
||||||
set_elf_sym(symtab_section, (uintptr_t)val, 0,
|
set_elf_sym(symtab_section, (uintptr_t)val, 0,
|
||||||
ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
|
ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
|
||||||
SHN_ABS, name);
|
SHN_ABS, name);
|
||||||
|
@ -1242,10 +1364,13 @@ ST_FUNC int set_flag(TCCState *s, const FlagDef *flags, const char *name)
|
||||||
|
|
||||||
static int strstart(const char *val, const char **str)
|
static int strstart(const char *val, const char **str)
|
||||||
{
|
{
|
||||||
|
//eputs ("strstart val:"); //eputs (val); //eputs ("\n");
|
||||||
|
//eputs ("strstart *str:"); //eputs (*str); //eputs ("\n");
|
||||||
const char *p, *q;
|
const char *p, *q;
|
||||||
p = *str;
|
p = *str;
|
||||||
q = val;
|
q = val;
|
||||||
while (*q) {
|
while (*q) {
|
||||||
|
//eputs ("*q:"); //eputc (*q); //eputs ("\n");
|
||||||
if (*p != *q)
|
if (*p != *q)
|
||||||
return 0;
|
return 0;
|
||||||
p++;
|
p++;
|
||||||
|
@ -1604,10 +1729,16 @@ static void parse_option_D(TCCState *s1, const char *optarg)
|
||||||
static void args_parser_add_file(TCCState *s, const char* filename, int filetype)
|
static void args_parser_add_file(TCCState *s, const char* filename, int filetype)
|
||||||
{
|
{
|
||||||
struct filespec *f = tcc_malloc(sizeof *f + strlen(filename));
|
struct filespec *f = tcc_malloc(sizeof *f + strlen(filename));
|
||||||
|
trace ("arg_parser_add file name="); eputs (filename); eputs ("\n");
|
||||||
f->type = filetype;
|
f->type = filetype;
|
||||||
f->alacarte = s->alacarte_link;
|
f->alacarte = s->alacarte_link;
|
||||||
strcpy(f->name, filename);
|
strcpy(f->name, filename);
|
||||||
|
trace ("arg_parser_add file f->name="); //eputs (f->name); //eputs ("\n");
|
||||||
|
trace ("arg_parser_add nb_files="); //eputs (itoa (s->nb_files)); //eputs ("\n");
|
||||||
dynarray_add(&s->files, &s->nb_files, f);
|
dynarray_add(&s->files, &s->nb_files, f);
|
||||||
|
//struct filespec *= s->files[s->nb_files - 1];
|
||||||
|
struct filespec * fs = s->files[0];
|
||||||
|
//eputs ("arg_parser_add file fs->name="); //eputs (fs->name); //eputs ("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int args_parser_make_argv(const char *r, int *argc, char ***argv)
|
static int args_parser_make_argv(const char *r, int *argc, char ***argv)
|
||||||
|
@ -1652,6 +1783,7 @@ static void args_parser_listfile(TCCState *s,
|
||||||
int argc = 0;
|
int argc = 0;
|
||||||
char **argv = NULL;
|
char **argv = NULL;
|
||||||
|
|
||||||
|
trace ("arg_parser_listfile filename="); eputs (filename); eputs ("\n");
|
||||||
fd = open(filename, O_RDONLY | O_BINARY);
|
fd = open(filename, O_RDONLY | O_BINARY);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
tcc_error("listfile '%s' not found", filename);
|
tcc_error("listfile '%s' not found", filename);
|
||||||
|
@ -1673,6 +1805,8 @@ static void args_parser_listfile(TCCState *s,
|
||||||
|
|
||||||
PUB_FUNC int tcc_parse_args(TCCState *s, int *pargc, char ***pargv, int optind)
|
PUB_FUNC int tcc_parse_args(TCCState *s, int *pargc, char ***pargv, int optind)
|
||||||
{
|
{
|
||||||
|
trace ("tcc_parse_args\n");
|
||||||
|
|
||||||
const TCCOption *popt;
|
const TCCOption *popt;
|
||||||
const char *optarg, *r;
|
const char *optarg, *r;
|
||||||
const char *run = NULL;
|
const char *run = NULL;
|
||||||
|
@ -1686,7 +1820,11 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int *pargc, char ***pargv, int optind)
|
||||||
cstr_new(&linker_arg);
|
cstr_new(&linker_arg);
|
||||||
|
|
||||||
while (optind < argc) {
|
while (optind < argc) {
|
||||||
|
trace ("tcc_parse_args 02 arg:"); eputs (itoa (optind)); eputs ("\n");
|
||||||
|
|
||||||
r = argv[optind];
|
r = argv[optind];
|
||||||
|
trace ("tcc_parse_args 03 r:"); eputs (r); eputs ("\n");
|
||||||
|
|
||||||
if (r[0] == '@' && r[1] != '\0') {
|
if (r[0] == '@' && r[1] != '\0') {
|
||||||
args_parser_listfile(s, r + 1, optind, &argc, &argv);
|
args_parser_listfile(s, r + 1, optind, &argc, &argv);
|
||||||
continue;
|
continue;
|
||||||
|
@ -1709,10 +1847,17 @@ reparse:
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trace ("tcc_parse_args 20\n");
|
||||||
|
|
||||||
|
trace ("tcc_parse_args 20 opt0="); eputs (tcc_options[0].name); eputs ("\n");
|
||||||
|
trace ("tcc_parse_args 20 opt1="); eputs (tcc_options[1].name); eputs ("\n");
|
||||||
/* find option in table */
|
/* find option in table */
|
||||||
for(popt = tcc_options; ; ++popt) {
|
for(popt = tcc_options; ; ++popt) {
|
||||||
|
trace ("tcc_parse_args 21\n");
|
||||||
|
trace ("tcc_parse_args 22 popt:"); eputs (popt->name); eputs ("\n");
|
||||||
const char *p1 = popt->name;
|
const char *p1 = popt->name;
|
||||||
const char *r1 = r + 1;
|
const char *r1 = r + 1;
|
||||||
|
trace ("tcc_parse_args 23 r1:"); eputs (r1); eputs ("\n");
|
||||||
if (p1 == NULL)
|
if (p1 == NULL)
|
||||||
tcc_error("invalid option -- '%s'", r);
|
tcc_error("invalid option -- '%s'", r);
|
||||||
if (!strstart(p1, &r1))
|
if (!strstart(p1, &r1))
|
||||||
|
@ -1730,6 +1875,8 @@ reparse:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trace ("pars_arg 2\n");
|
||||||
|
|
||||||
switch(popt->index) {
|
switch(popt->index) {
|
||||||
case TCC_OPTION_HELP:
|
case TCC_OPTION_HELP:
|
||||||
return OPT_HELP;
|
return OPT_HELP;
|
||||||
|
|
29
tcc.c
29
tcc.c
|
@ -252,10 +252,22 @@ int main(int argc0, char **argv0)
|
||||||
int argc; char **argv;
|
int argc; char **argv;
|
||||||
FILE *ppfp = stdout;
|
FILE *ppfp = stdout;
|
||||||
|
|
||||||
|
trace_enter ("main");
|
||||||
redo:
|
redo:
|
||||||
argc = argc0, argv = argv0;
|
argc = argc0, argv = argv0;
|
||||||
|
trace ("main 01\n");
|
||||||
s = tcc_new();
|
s = tcc_new();
|
||||||
|
trace ("main 02\n");
|
||||||
opt = tcc_parse_args(s, &argc, &argv, 1);
|
opt = tcc_parse_args(s, &argc, &argv, 1);
|
||||||
|
trace ("main 03\n");
|
||||||
|
|
||||||
|
|
||||||
|
if (s->nb_files) {
|
||||||
|
struct filespec *f = s->files[0];
|
||||||
|
trace ("main 05 file[0]="); eputs (f->name); eputs ("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
trace ("main 06\n");
|
||||||
|
|
||||||
if ((n | t) == 0) {
|
if ((n | t) == 0) {
|
||||||
if (opt == OPT_HELP)
|
if (opt == OPT_HELP)
|
||||||
|
@ -306,7 +318,10 @@ redo:
|
||||||
start_time = getclock_ms();
|
start_time = getclock_ms();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trace ("main 20\n");
|
||||||
set_environment(s);
|
set_environment(s);
|
||||||
|
trace ("main 21\n");
|
||||||
|
|
||||||
if (s->output_type == 0)
|
if (s->output_type == 0)
|
||||||
s->output_type = TCC_OUTPUT_EXE;
|
s->output_type = TCC_OUTPUT_EXE;
|
||||||
tcc_set_output_type(s, s->output_type);
|
tcc_set_output_type(s, s->output_type);
|
||||||
|
@ -316,14 +331,20 @@ redo:
|
||||||
|| s->output_type == TCC_OUTPUT_PREPROCESS) && (s->dflag & 16))
|
|| s->output_type == TCC_OUTPUT_PREPROCESS) && (s->dflag & 16))
|
||||||
s->dflag |= t ? 32 : 0, s->run_test = ++t, n = s->nb_files;
|
s->dflag |= t ? 32 : 0, s->run_test = ++t, n = s->nb_files;
|
||||||
|
|
||||||
|
trace ("main 23\n");
|
||||||
|
|
||||||
/* compile or add each files or library */
|
/* compile or add each files or library */
|
||||||
for (first_file = NULL, ret = 0;;) {
|
for (first_file = NULL, ret = 0;;) {
|
||||||
|
trace ("main 24 nb-files="); eputs (itoa (s->nb_files)); eputs ("\n");
|
||||||
|
trace ("main 24 n="); eputs (itoa (n)); eputs ("\n");
|
||||||
struct filespec *f = s->files[s->nb_files - n];
|
struct filespec *f = s->files[s->nb_files - n];
|
||||||
|
trace ("for f->name="); eputs (f->name); eputs ("\n");
|
||||||
s->filetype = f->type;
|
s->filetype = f->type;
|
||||||
s->alacarte_link = f->alacarte;
|
s->alacarte_link = f->alacarte;
|
||||||
if (f->type == AFF_TYPE_LIB) {
|
if (f->type == AFF_TYPE_LIB) {
|
||||||
if (tcc_add_library_err(s, f->name) < 0)
|
if (tcc_add_library_err(s, f->name) < 0)
|
||||||
ret = 1;
|
ret = 1;
|
||||||
|
trace ("main 32 ret="); eputs (itoa (ret)); eputs ("\n");
|
||||||
} else {
|
} else {
|
||||||
if (1 == s->verbose)
|
if (1 == s->verbose)
|
||||||
printf("-> %s\n", f->name);
|
printf("-> %s\n", f->name);
|
||||||
|
@ -331,7 +352,9 @@ redo:
|
||||||
first_file = f->name;
|
first_file = f->name;
|
||||||
if (tcc_add_file(s, f->name) < 0)
|
if (tcc_add_file(s, f->name) < 0)
|
||||||
ret = 1;
|
ret = 1;
|
||||||
|
trace ("main 33 ret="); eputs (itoa (ret)); eputs ("\n");
|
||||||
}
|
}
|
||||||
|
trace ("ret="); eputs (itoa (ret)); eputs ("\n");
|
||||||
s->filetype = 0;
|
s->filetype = 0;
|
||||||
s->alacarte_link = 1;
|
s->alacarte_link = 1;
|
||||||
if (--n == 0 || ret
|
if (--n == 0 || ret
|
||||||
|
@ -339,18 +362,23 @@ redo:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trace ("main 40\n");
|
||||||
if (s->run_test) {
|
if (s->run_test) {
|
||||||
t = 0;
|
t = 0;
|
||||||
} else if (s->output_type == TCC_OUTPUT_PREPROCESS) {
|
} else if (s->output_type == TCC_OUTPUT_PREPROCESS) {
|
||||||
;
|
;
|
||||||
} else if (0 == ret) {
|
} else if (0 == ret) {
|
||||||
|
trace ("main 42 ret == 0\n");
|
||||||
if (s->output_type == TCC_OUTPUT_MEMORY) {
|
if (s->output_type == TCC_OUTPUT_MEMORY) {
|
||||||
|
trace ("main RUN\n");
|
||||||
#ifdef TCC_IS_NATIVE
|
#ifdef TCC_IS_NATIVE
|
||||||
ret = tcc_run(s, argc, argv);
|
ret = tcc_run(s, argc, argv);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
|
trace ("main 44 gonna output_file\n");
|
||||||
if (!s->outfile)
|
if (!s->outfile)
|
||||||
s->outfile = default_outputfile(s, first_file);
|
s->outfile = default_outputfile(s, first_file);
|
||||||
|
trace ("main 45 output_file\n");
|
||||||
if (tcc_output_file(s, s->outfile))
|
if (tcc_output_file(s, s->outfile))
|
||||||
ret = 1;
|
ret = 1;
|
||||||
else if (s->gen_deps)
|
else if (s->gen_deps)
|
||||||
|
@ -367,5 +395,6 @@ redo:
|
||||||
goto redo; /* run more tests with -dt -run */
|
goto redo; /* run more tests with -dt -run */
|
||||||
if (ppfp && ppfp != stdout)
|
if (ppfp && ppfp != stdout)
|
||||||
fclose(ppfp);
|
fclose(ppfp);
|
||||||
|
trace_exit ("main");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
12
tccasm.c
12
tccasm.c
|
@ -1111,9 +1111,12 @@ static void parse_asm_operands(ASMOperand *operands, int *nb_operands_ptr,
|
||||||
next();
|
next();
|
||||||
skip(']');
|
skip(']');
|
||||||
}
|
}
|
||||||
parse_mult_str(&astr, "string constant");
|
parse_mult_str(&astr, "parse_asm_operands string constant");
|
||||||
|
trace ("parse arm_operands tokc.str.data="); eputs (tokc.str.data); eputs ("\n");
|
||||||
op->constraint = tcc_malloc(astr.size);
|
op->constraint = tcc_malloc(astr.size);
|
||||||
|
trace ("parse arm_operands tokc.str.data="); eputs (tokc.str.data); eputs ("\n");
|
||||||
strcpy(op->constraint, astr.data);
|
strcpy(op->constraint, astr.data);
|
||||||
|
trace ("parse arm_operands tokc.str.data="); eputs (tokc.str.data); eputs ("\n");
|
||||||
cstr_free(&astr);
|
cstr_free(&astr);
|
||||||
skip('(');
|
skip('(');
|
||||||
gexpr();
|
gexpr();
|
||||||
|
@ -1152,13 +1155,17 @@ ST_FUNC void asm_instr(void)
|
||||||
int nb_outputs, nb_operands, i, must_subst, out_reg;
|
int nb_outputs, nb_operands, i, must_subst, out_reg;
|
||||||
uint8_t clobber_regs[NB_ASM_REGS];
|
uint8_t clobber_regs[NB_ASM_REGS];
|
||||||
|
|
||||||
|
trace_enter ("asm_instr");
|
||||||
next();
|
next();
|
||||||
|
trace ("asm_instr 01\n");
|
||||||
/* since we always generate the asm() instruction, we can ignore
|
/* since we always generate the asm() instruction, we can ignore
|
||||||
volatile */
|
volatile */
|
||||||
if (tok == TOK_VOLATILE1 || tok == TOK_VOLATILE2 || tok == TOK_VOLATILE3) {
|
if (tok == TOK_VOLATILE1 || tok == TOK_VOLATILE2 || tok == TOK_VOLATILE3) {
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
|
trace ("asm_instr 02\n");
|
||||||
parse_asm_str(&astr);
|
parse_asm_str(&astr);
|
||||||
|
trace ("asm_instr astr.data="); eputs (astr.data); eputs ("\n");
|
||||||
nb_operands = 0;
|
nb_operands = 0;
|
||||||
nb_outputs = 0;
|
nb_outputs = 0;
|
||||||
must_subst = 0;
|
must_subst = 0;
|
||||||
|
@ -1211,6 +1218,7 @@ ST_FUNC void asm_instr(void)
|
||||||
#ifdef ASM_DEBUG
|
#ifdef ASM_DEBUG
|
||||||
printf("asm: \"%s\"\n", (char *)astr.data);
|
printf("asm: \"%s\"\n", (char *)astr.data);
|
||||||
#endif
|
#endif
|
||||||
|
trace ("asm_instr asm:"); eputs (astr.data); eputs ("\n");
|
||||||
if (must_subst) {
|
if (must_subst) {
|
||||||
subst_asm_operands(operands, nb_operands, &astr1, &astr);
|
subst_asm_operands(operands, nb_operands, &astr1, &astr);
|
||||||
cstr_free(&astr);
|
cstr_free(&astr);
|
||||||
|
@ -1220,6 +1228,7 @@ ST_FUNC void asm_instr(void)
|
||||||
#ifdef ASM_DEBUG
|
#ifdef ASM_DEBUG
|
||||||
printf("subst_asm: \"%s\"\n", (char *)astr1.data);
|
printf("subst_asm: \"%s\"\n", (char *)astr1.data);
|
||||||
#endif
|
#endif
|
||||||
|
trace ("asm_instr subst:"); eputs (astr1.data); eputs ("\n");
|
||||||
|
|
||||||
/* generate loads */
|
/* generate loads */
|
||||||
asm_gen_code(operands, nb_operands, nb_outputs, 0,
|
asm_gen_code(operands, nb_operands, nb_outputs, 0,
|
||||||
|
@ -1243,6 +1252,7 @@ ST_FUNC void asm_instr(void)
|
||||||
vpop();
|
vpop();
|
||||||
}
|
}
|
||||||
cstr_free(&astr1);
|
cstr_free(&astr1);
|
||||||
|
trace_exit ("asm_instr");
|
||||||
}
|
}
|
||||||
|
|
||||||
ST_FUNC void asm_global_instr(void)
|
ST_FUNC void asm_global_instr(void)
|
||||||
|
|
290
tccelf.c
290
tccelf.c
|
@ -56,27 +56,41 @@ static int new_undef_sym = 0; /* Is there a new undefined sym since last new_und
|
||||||
|
|
||||||
ST_FUNC void tccelf_new(TCCState *s)
|
ST_FUNC void tccelf_new(TCCState *s)
|
||||||
{
|
{
|
||||||
|
//eputs ("tccelf_new00\n");
|
||||||
/* no section zero */
|
/* no section zero */
|
||||||
|
//eputs ("tccelf_new00 nb_sections="); //eputs (itoa (s->nb_sections)); //eputs ("\n");
|
||||||
dynarray_add(&s->sections, &s->nb_sections, NULL);
|
dynarray_add(&s->sections, &s->nb_sections, NULL);
|
||||||
|
//eputs ("tccelf_new01\n");
|
||||||
|
|
||||||
/* create standard sections */
|
/* create standard sections */
|
||||||
text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
|
text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
|
||||||
|
//eputs ("tccelf_new02\n");
|
||||||
data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
|
data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
|
||||||
|
//eputs ("tccelf_new3\n");
|
||||||
bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
|
bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
|
||||||
|
//eputs ("tccelf_new04\n");
|
||||||
common_section = new_section(s, ".common", SHT_NOBITS, SHF_PRIVATE);
|
common_section = new_section(s, ".common", SHT_NOBITS, SHF_PRIVATE);
|
||||||
|
//eputs ("tccelf_new05\n");
|
||||||
common_section->sh_num = SHN_COMMON;
|
common_section->sh_num = SHN_COMMON;
|
||||||
|
|
||||||
|
//eputs ("tccelf_new06\n");
|
||||||
|
|
||||||
/* symbols are always generated for linking stage */
|
/* symbols are always generated for linking stage */
|
||||||
symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
|
symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
|
||||||
".strtab",
|
".strtab",
|
||||||
".hashtab", SHF_PRIVATE);
|
".hashtab", SHF_PRIVATE);
|
||||||
|
//eputs ("tccelf_new07\n");
|
||||||
s->symtab = symtab_section;
|
s->symtab = symtab_section;
|
||||||
|
//eputs ("tccelf_new08\n");
|
||||||
|
|
||||||
|
//eputs ("tccelf_new09\n");
|
||||||
/* private symbol table for dynamic symbols */
|
/* private symbol table for dynamic symbols */
|
||||||
s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE|SHF_DYNSYM,
|
s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE|SHF_DYNSYM,
|
||||||
".dynstrtab",
|
".dynstrtab",
|
||||||
".dynhashtab", SHF_PRIVATE);
|
".dynhashtab", SHF_PRIVATE);
|
||||||
|
//eputs ("tccelf_new10\n");
|
||||||
get_sym_attr(s, 0, 1);
|
get_sym_attr(s, 0, 1);
|
||||||
|
//eputs ("tccelf_new99\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_TCC_BCHECK
|
#ifdef CONFIG_TCC_BCHECK
|
||||||
|
@ -197,10 +211,16 @@ ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh
|
||||||
{
|
{
|
||||||
Section *sec;
|
Section *sec;
|
||||||
|
|
||||||
|
trace_enter ("new_section");
|
||||||
sec = tcc_mallocz(sizeof(Section) + strlen(name));
|
sec = tcc_mallocz(sizeof(Section) + strlen(name));
|
||||||
|
trace ("size:"); eputs (itoa (sizeof(Section) + strlen (name))); eputs ("\n");
|
||||||
|
trace ("new_section 01\n");
|
||||||
|
trace ("name="); eputs (name); eputs ("\n");
|
||||||
strcpy(sec->name, name);
|
strcpy(sec->name, name);
|
||||||
|
trace ("new_section 02\n");
|
||||||
sec->sh_type = sh_type;
|
sec->sh_type = sh_type;
|
||||||
sec->sh_flags = sh_flags;
|
sec->sh_flags = sh_flags;
|
||||||
|
trace ("new_section 05\n");
|
||||||
switch(sh_type) {
|
switch(sh_type) {
|
||||||
case SHT_HASH:
|
case SHT_HASH:
|
||||||
case SHT_REL:
|
case SHT_REL:
|
||||||
|
@ -218,13 +238,29 @@ ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trace ("new_section 10\n");
|
||||||
if (sh_flags & SHF_PRIVATE) {
|
if (sh_flags & SHF_PRIVATE) {
|
||||||
|
trace ("new_section 11\n");
|
||||||
dynarray_add(&s1->priv_sections, &s1->nb_priv_sections, sec);
|
dynarray_add(&s1->priv_sections, &s1->nb_priv_sections, sec);
|
||||||
} else {
|
} else {
|
||||||
|
trace ("new_section 12\n");
|
||||||
sec->sh_num = s1->nb_sections;
|
sec->sh_num = s1->nb_sections;
|
||||||
dynarray_add(&s1->sections, &s1->nb_sections, sec);
|
dynarray_add(&s1->sections, &s1->nb_sections, sec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i = 1; i < s1->nb_sections; i++) {
|
||||||
|
trace ("new_section i= "); eputs (itoa (i)); eputs ("\n");
|
||||||
|
Section *s;
|
||||||
|
#if !BOOTSTRAP
|
||||||
|
s = s1->sections[i];
|
||||||
|
#else
|
||||||
|
Section **ps = s1->sections;
|
||||||
|
s = ps[i];
|
||||||
|
#endif
|
||||||
|
trace ("new_section name="); eputs (s->name); eputs ("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
trace_exit ("new_section");
|
||||||
return sec;
|
return sec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,16 +272,26 @@ ST_FUNC Section *new_symtab(TCCState *s1,
|
||||||
Section *symtab, *strtab, *hash;
|
Section *symtab, *strtab, *hash;
|
||||||
int *ptr, nb_buckets;
|
int *ptr, nb_buckets;
|
||||||
|
|
||||||
|
//eputs ("new_symtab00\n");
|
||||||
symtab = new_section(s1, symtab_name, sh_type, sh_flags);
|
symtab = new_section(s1, symtab_name, sh_type, sh_flags);
|
||||||
|
//eputs ("new_symtab01\n");
|
||||||
|
//eputs ("s->hash="); //eputs (itoa (symtab->hash)); //eputs ("\n");
|
||||||
symtab->sh_entsize = sizeof(ElfW(Sym));
|
symtab->sh_entsize = sizeof(ElfW(Sym));
|
||||||
|
//eputs ("new_symtab02\n");
|
||||||
strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
|
strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
|
||||||
|
//eputs ("new_symtab03\n");
|
||||||
put_elf_str(strtab, "");
|
put_elf_str(strtab, "");
|
||||||
|
//eputs ("new_symtab04\n");
|
||||||
symtab->link = strtab;
|
symtab->link = strtab;
|
||||||
|
//eputs ("new_symtab05\n");
|
||||||
put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
|
put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
|
||||||
|
//eputs ("new_symtab06\n");
|
||||||
|
|
||||||
nb_buckets = 1;
|
nb_buckets = 1;
|
||||||
|
|
||||||
|
//eputs ("new_symtab10\n");
|
||||||
hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
|
hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
|
||||||
|
//eputs ("new_symtab11\n");
|
||||||
hash->sh_entsize = sizeof(int);
|
hash->sh_entsize = sizeof(int);
|
||||||
symtab->hash = hash;
|
symtab->hash = hash;
|
||||||
hash->link = symtab;
|
hash->link = symtab;
|
||||||
|
@ -280,13 +326,19 @@ ST_FUNC size_t section_add(Section *sec, addr_t size, int align)
|
||||||
{
|
{
|
||||||
size_t offset, offset1;
|
size_t offset, offset1;
|
||||||
|
|
||||||
|
trace_enter ("section_add");
|
||||||
offset = (sec->data_offset + align - 1) & -align;
|
offset = (sec->data_offset + align - 1) & -align;
|
||||||
|
trace ("section_add 01 offset="); eputs (itoa (offset)); eputs ("\n");
|
||||||
offset1 = offset + size;
|
offset1 = offset + size;
|
||||||
if (sec->sh_type != SHT_NOBITS && offset1 > sec->data_allocated)
|
if (sec->sh_type != SHT_NOBITS && offset1 > sec->data_allocated) {
|
||||||
|
trace ("section_add 05\n");
|
||||||
section_realloc(sec, offset1);
|
section_realloc(sec, offset1);
|
||||||
|
}
|
||||||
sec->data_offset = offset1;
|
sec->data_offset = offset1;
|
||||||
|
trace ("section_add 08 offset1="); eputs (itoa (offset1)); eputs ("\n");
|
||||||
if (align > sec->sh_addralign)
|
if (align > sec->sh_addralign)
|
||||||
sec->sh_addralign = align;
|
sec->sh_addralign = align;
|
||||||
|
trace_exit ("section_add");
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,7 +346,9 @@ ST_FUNC size_t section_add(Section *sec, addr_t size, int align)
|
||||||
sec->data_offset. */
|
sec->data_offset. */
|
||||||
ST_FUNC void *section_ptr_add(Section *sec, addr_t size)
|
ST_FUNC void *section_ptr_add(Section *sec, addr_t size)
|
||||||
{
|
{
|
||||||
|
trace_enter ("section_ptr_add");
|
||||||
size_t offset = section_add(sec, size, 1);
|
size_t offset = section_add(sec, size, 1);
|
||||||
|
trace_exit ("section_ptr_add");
|
||||||
return sec->data + offset;
|
return sec->data + offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -329,6 +383,7 @@ ST_FUNC int put_elf_str(Section *s, const char *sym)
|
||||||
int offset, len;
|
int offset, len;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
|
|
||||||
|
trace ("put_elf_str\n");
|
||||||
len = strlen(sym) + 1;
|
len = strlen(sym) + 1;
|
||||||
offset = s->data_offset;
|
offset = s->data_offset;
|
||||||
ptr = section_ptr_add(s, len);
|
ptr = section_ptr_add(s, len);
|
||||||
|
@ -397,6 +452,10 @@ ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size,
|
||||||
ElfW(Sym) *sym;
|
ElfW(Sym) *sym;
|
||||||
Section *hs;
|
Section *hs;
|
||||||
|
|
||||||
|
trace_enter ("put_elf_sym");
|
||||||
|
if (name) {
|
||||||
|
trace ("put_elf_sym 00 name="); eputs (name); eputs ("\n");
|
||||||
|
}
|
||||||
sym = section_ptr_add(s, sizeof(ElfW(Sym)));
|
sym = section_ptr_add(s, sizeof(ElfW(Sym)));
|
||||||
if (name && name[0])
|
if (name && name[0])
|
||||||
name_offset = put_elf_str(s->link, name);
|
name_offset = put_elf_str(s->link, name);
|
||||||
|
@ -411,12 +470,16 @@ ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size,
|
||||||
sym->st_shndx = shndx;
|
sym->st_shndx = shndx;
|
||||||
sym_index = sym - (ElfW(Sym) *)s->data;
|
sym_index = sym - (ElfW(Sym) *)s->data;
|
||||||
hs = s->hash;
|
hs = s->hash;
|
||||||
|
trace ("put_elf_sym20 size="); eputs (itoa (sizeof (ElfW(Sym)))); eputs ("\n");
|
||||||
|
trace ("put_elf_sym21 sym_index="); eputs (itoa (sym_index)); eputs ("\n");
|
||||||
if (hs) {
|
if (hs) {
|
||||||
int *ptr, *base;
|
int *ptr, *base;
|
||||||
|
trace ("put_elf_sym 21\n");
|
||||||
ptr = section_ptr_add(hs, sizeof(int));
|
ptr = section_ptr_add(hs, sizeof(int));
|
||||||
base = (int *)hs->data;
|
base = (int *)hs->data;
|
||||||
/* only add global or weak symbols. */
|
/* only add global or weak symbols. */
|
||||||
if (ELFW(ST_BIND)(info) != STB_LOCAL) {
|
if (ELFW(ST_BIND)(info) != STB_LOCAL) {
|
||||||
|
trace ("put_elf_sym 25\n");
|
||||||
/* add another hashing entry */
|
/* add another hashing entry */
|
||||||
nbuckets = base[0];
|
nbuckets = base[0];
|
||||||
h = elf_hash((unsigned char *)s->link->data + name_offset) % nbuckets;
|
h = elf_hash((unsigned char *)s->link->data + name_offset) % nbuckets;
|
||||||
|
@ -429,10 +492,12 @@ ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size,
|
||||||
rebuild_hash(s, 2 * nbuckets);
|
rebuild_hash(s, 2 * nbuckets);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
trace ("put_elf_sym 40\n");
|
||||||
*ptr = 0;
|
*ptr = 0;
|
||||||
base[1]++;
|
base[1]++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
trace_exit ("put_elf_sym");
|
||||||
return sym_index;
|
return sym_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -443,19 +508,37 @@ ST_FUNC int find_elf_sym(Section *s, const char *name)
|
||||||
int nbuckets, sym_index, h;
|
int nbuckets, sym_index, h;
|
||||||
const char *name1;
|
const char *name1;
|
||||||
|
|
||||||
|
trace_enter ("find_elf_sym");
|
||||||
|
trace ("find_elf_sym name="); eputs (name); eputs ("\n");
|
||||||
hs = s->hash;
|
hs = s->hash;
|
||||||
if (!hs)
|
trace ("find_elf_sym 01\n");
|
||||||
|
if (!hs) {
|
||||||
|
trace_exit ("find_elf_sym");
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
nbuckets = ((int *)hs->data)[0];
|
nbuckets = ((int *)hs->data)[0];
|
||||||
|
trace ("find_elf_sym 10 nbuckets="); eputs (itoa (nbuckets)); eputs ("\n");
|
||||||
h = elf_hash((unsigned char *) name) % nbuckets;
|
h = elf_hash((unsigned char *) name) % nbuckets;
|
||||||
|
trace ("find_elf_sym 11 h="); eputs (itoa (h)); eputs ("\n");
|
||||||
sym_index = ((int *)hs->data)[2 + h];
|
sym_index = ((int *)hs->data)[2 + h];
|
||||||
|
trace ("find_elf_sym 12 sym_index="); eputs (itoa (sym_index)); eputs ("\n");
|
||||||
while (sym_index != 0) {
|
while (sym_index != 0) {
|
||||||
sym = &((ElfW(Sym) *)s->data)[sym_index];
|
sym = &((ElfW(Sym) *)s->data)[sym_index];
|
||||||
name1 = (char *) s->link->data + sym->st_name;
|
name1 = (char *) s->link->data + sym->st_name;
|
||||||
if (!strcmp(name, name1))
|
trace ("find_elf_sym 13 sym->st_name="); eputs (itoa (sym->st_name)); eputs ("\n");
|
||||||
|
trace ("find_elf_sym 14 name1= "); eputs (itoa ((int)name1 - (int)s->link->data)); eputs ("\n");
|
||||||
|
//trace ("find_elf_sym 15 name= "); eputs (itoa (name)); eputs ("\n");
|
||||||
|
trace ("find_elf_sym 16 *name= "); eputs (itoa (*name)); eputs ("\n");
|
||||||
|
trace ("find_elf_sym 17 *name1="); eputs (itoa (name1 && sym->st_name >=0 && sym->st_name < 1000 ? *name1 : 0)); eputs ("\n");
|
||||||
|
//trace ("find_elf_sym 19 name= "); eputs (name); eputs ("\n");
|
||||||
|
//trace ("find_elf_sym 18 name1= "); eputs (name1); eputs ("\n");
|
||||||
|
if (!strcmp(name, name1)) {
|
||||||
|
trace_exit ("find_elf_sym 20");
|
||||||
return sym_index;
|
return sym_index;
|
||||||
|
}
|
||||||
sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
|
sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
|
||||||
}
|
}
|
||||||
|
trace_exit ("find_elf_sym");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -489,20 +572,35 @@ ST_FUNC void* tcc_get_symbol_err(TCCState *s, const char *name)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !BOOTSTRAP // MESC
|
||||||
|
#define for_each_elem(sec, startoff, elem, type) \
|
||||||
|
for (elem = (type *) sec->data + startoff; \
|
||||||
|
elem < (type *) (sec->data + sec->data_offset); elem++)
|
||||||
|
#else
|
||||||
|
#define for_each_elem(sec, startoff, elem, type) \
|
||||||
|
elem = sec->data + sizeof (type) * startoff; \
|
||||||
|
for (;elem < ((type *) (sec->data + sec->data_offset)); elem++)
|
||||||
|
#endif
|
||||||
|
|
||||||
/* add an elf symbol : check if it is already defined and patch
|
/* add an elf symbol : check if it is already defined and patch
|
||||||
it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
|
it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
|
||||||
ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size,
|
ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size,
|
||||||
int info, int other, int shndx, const char *name)
|
int info, int other, int shndx, const char *name)
|
||||||
{
|
{
|
||||||
|
trace_enter ("set_elf_sym");
|
||||||
ElfW(Sym) *esym;
|
ElfW(Sym) *esym;
|
||||||
|
trace ("set_elf_sym 01 name="); eputs (name); eputs ("\n");
|
||||||
int sym_bind, sym_index, sym_type, esym_bind;
|
int sym_bind, sym_index, sym_type, esym_bind;
|
||||||
unsigned char sym_vis, esym_vis, new_vis;
|
unsigned char sym_vis, esym_vis, new_vis;
|
||||||
|
|
||||||
sym_bind = ELFW(ST_BIND)(info);
|
sym_bind = ELFW(ST_BIND)(info);
|
||||||
|
trace ("set_elf_sym 02\n");
|
||||||
sym_type = ELFW(ST_TYPE)(info);
|
sym_type = ELFW(ST_TYPE)(info);
|
||||||
|
trace ("set_elf_sym 03\n");
|
||||||
sym_vis = ELFW(ST_VISIBILITY)(other);
|
sym_vis = ELFW(ST_VISIBILITY)(other);
|
||||||
|
|
||||||
if (sym_bind != STB_LOCAL) {
|
if (sym_bind != STB_LOCAL) {
|
||||||
|
trace ("set_elf_sym 13\n");
|
||||||
/* we search global or weak symbols */
|
/* we search global or weak symbols */
|
||||||
sym_index = find_elf_sym(s, name);
|
sym_index = find_elf_sym(s, name);
|
||||||
if (!sym_index)
|
if (!sym_index)
|
||||||
|
@ -512,6 +610,7 @@ ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size,
|
||||||
&& esym->st_other == other && esym->st_shndx == shndx)
|
&& esym->st_other == other && esym->st_shndx == shndx)
|
||||||
return sym_index;
|
return sym_index;
|
||||||
if (esym->st_shndx != SHN_UNDEF) {
|
if (esym->st_shndx != SHN_UNDEF) {
|
||||||
|
trace ("set_elf_sym 16\n");
|
||||||
esym_bind = ELFW(ST_BIND)(esym->st_info);
|
esym_bind = ELFW(ST_BIND)(esym->st_info);
|
||||||
/* propagate the most constraining visibility */
|
/* propagate the most constraining visibility */
|
||||||
/* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
|
/* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
|
||||||
|
@ -561,6 +660,7 @@ ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
do_patch:
|
do_patch:
|
||||||
|
trace ("set_elf_sym 40\n");
|
||||||
esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
|
esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
|
||||||
esym->st_shndx = shndx;
|
esym->st_shndx = shndx;
|
||||||
new_undef_sym = 1;
|
new_undef_sym = 1;
|
||||||
|
@ -570,10 +670,31 @@ ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
do_def:
|
do_def:
|
||||||
|
trace ("set_elf_sym 50\n");
|
||||||
sym_index = put_elf_sym(s, value, size,
|
sym_index = put_elf_sym(s, value, size,
|
||||||
ELFW(ST_INFO)(sym_bind, sym_type), other,
|
ELFW(ST_INFO)(sym_bind, sym_type), other,
|
||||||
shndx, name);
|
shndx, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trace ("set_elf_sym 90 name="); eputs (name); eputs ("\n");
|
||||||
|
ElfW(Sym) *sym;
|
||||||
|
#if 1
|
||||||
|
for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
|
||||||
|
trace ("set_elf_sym num="); eputs (itoa (sym->st_shndx)); eputs ("\n");
|
||||||
|
name = (char *) strtab_section->data + sym->st_name;
|
||||||
|
trace ("set_elf_sym name="); eputs (name); eputs ("\n");
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
for (sym = symtab_section->data; sym < (symtab_section->data + symtab_section->data_offset); sym++) {
|
||||||
|
trace ("set_elf_sym num="); eputs (itoa (sym->st_shndx)); eputs ("\n");
|
||||||
|
name = strtab_section->data;
|
||||||
|
name += sym->st_name;
|
||||||
|
//name = ((char *) strtab_section->data) + sym->st_name;
|
||||||
|
trace ("set_elf_sym name="); eputs (name); eputs ("\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
trace_exit ("set_elf_sym");
|
||||||
return sym_index;
|
return sym_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -734,27 +855,40 @@ static void sort_syms(TCCState *s1, Section *s)
|
||||||
Section *sr;
|
Section *sr;
|
||||||
int type, sym_index;
|
int type, sym_index;
|
||||||
|
|
||||||
|
trace_enter ("sort_syms\n");
|
||||||
nb_syms = s->data_offset / sizeof(ElfW(Sym));
|
nb_syms = s->data_offset / sizeof(ElfW(Sym));
|
||||||
new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
|
new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
|
||||||
old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
|
old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
|
||||||
|
|
||||||
|
trace ("sort_syms 05\n");
|
||||||
/* first pass for local symbols */
|
/* first pass for local symbols */
|
||||||
p = (ElfW(Sym) *)s->data;
|
p = (ElfW(Sym) *)s->data;
|
||||||
q = new_syms;
|
q = new_syms;
|
||||||
|
trace ("sort_syms 10\n");
|
||||||
for(i = 0; i < nb_syms; i++) {
|
for(i = 0; i < nb_syms; i++) {
|
||||||
|
trace ("sort_syms 11 i="); eputs (itoa (i)); eputs ("\n");
|
||||||
|
unsigned char val = p->st_info;
|
||||||
|
trace ("val="); eputs (itoa (val)); eputs ("\n");
|
||||||
|
val >>= 4;
|
||||||
|
trace ("val="); eputs (itoa (val)); eputs ("\n");
|
||||||
if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
|
if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
|
||||||
|
trace ("sort_syms 12\n");
|
||||||
old_to_new_syms[i] = q - new_syms;
|
old_to_new_syms[i] = q - new_syms;
|
||||||
*q++ = *p;
|
*q++ = *p;
|
||||||
|
trace ("sort_syms 13\n");
|
||||||
}
|
}
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
|
trace ("sort_syms 20\n");
|
||||||
/* save the number of local symbols in section header */
|
/* save the number of local symbols in section header */
|
||||||
if( s->sh_size ) /* this 'if' makes IDA happy */
|
if( s->sh_size ) /* this 'if' makes IDA happy */
|
||||||
s->sh_info = q - new_syms;
|
s->sh_info = q - new_syms;
|
||||||
|
|
||||||
/* then second pass for non local symbols */
|
/* then second pass for non local symbols */
|
||||||
p = (ElfW(Sym) *)s->data;
|
p = (ElfW(Sym) *)s->data;
|
||||||
|
trace ("sort_syms 25\n");
|
||||||
for(i = 0; i < nb_syms; i++) {
|
for(i = 0; i < nb_syms; i++) {
|
||||||
|
trace ("sort_syms 31 i="); eputs (itoa (i)); eputs ("\n");
|
||||||
if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
|
if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
|
||||||
old_to_new_syms[i] = q - new_syms;
|
old_to_new_syms[i] = q - new_syms;
|
||||||
*q++ = *p;
|
*q++ = *p;
|
||||||
|
@ -762,12 +896,15 @@ static void sort_syms(TCCState *s1, Section *s)
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trace ("sort_syms40\n");
|
||||||
/* we copy the new symbols to the old */
|
/* we copy the new symbols to the old */
|
||||||
memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
|
memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
|
||||||
tcc_free(new_syms);
|
tcc_free(new_syms);
|
||||||
|
|
||||||
|
trace ("sort_syms43\n");
|
||||||
/* now we modify all the relocations */
|
/* now we modify all the relocations */
|
||||||
for(i = 1; i < s1->nb_sections; i++) {
|
for(i = 1; i < s1->nb_sections; i++) {
|
||||||
|
trace ("sort_syms 43 i="); eputs (itoa (i)); eputs ("\n");
|
||||||
sr = s1->sections[i];
|
sr = s1->sections[i];
|
||||||
if (sr->sh_type == SHT_RELX && sr->link == s) {
|
if (sr->sh_type == SHT_RELX && sr->link == s) {
|
||||||
for_each_elem(sr, 0, rel, ElfW_Rel) {
|
for_each_elem(sr, 0, rel, ElfW_Rel) {
|
||||||
|
@ -780,6 +917,7 @@ static void sort_syms(TCCState *s1, Section *s)
|
||||||
}
|
}
|
||||||
|
|
||||||
tcc_free(old_to_new_syms);
|
tcc_free(old_to_new_syms);
|
||||||
|
trace_exit ("sort_syms\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* relocate symbol table, resolve undefined symbols if do_resolve is
|
/* relocate symbol table, resolve undefined symbols if do_resolve is
|
||||||
|
@ -792,10 +930,13 @@ ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve)
|
||||||
|
|
||||||
for_each_elem(symtab, 1, sym, ElfW(Sym)) {
|
for_each_elem(symtab, 1, sym, ElfW(Sym)) {
|
||||||
sh_num = sym->st_shndx;
|
sh_num = sym->st_shndx;
|
||||||
|
trace ("relocate_syms 01 num="); eputs (itoa (sh_num)); eputs ("\n");
|
||||||
if (sh_num == SHN_UNDEF) {
|
if (sh_num == SHN_UNDEF) {
|
||||||
name = (char *) s1->symtab->link->data + sym->st_name;
|
name = (char *) s1->symtab->link->data + sym->st_name;
|
||||||
|
trace ("relocate_syms 02 name="); eputs (name); eputs ("\n");
|
||||||
/* Use ld.so to resolve symbol for us (for tcc -run) */
|
/* Use ld.so to resolve symbol for us (for tcc -run) */
|
||||||
if (do_resolve) {
|
if (do_resolve) {
|
||||||
|
trace ("relocate_syms 03\n");
|
||||||
#if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
|
#if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
|
||||||
void *addr = dlsym(RTLD_DEFAULT, name);
|
void *addr = dlsym(RTLD_DEFAULT, name);
|
||||||
if (addr) {
|
if (addr) {
|
||||||
|
@ -807,25 +948,36 @@ ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* if dynamic symbol exist, it will be used in relocate_section */
|
/* if dynamic symbol exist, it will be used in relocate_section */
|
||||||
} else if (s1->dynsym && find_elf_sym(s1->dynsym, name))
|
} else if (s1->dynsym && find_elf_sym(s1->dynsym, name)) {
|
||||||
|
trace ("relocate_syms 04\n");
|
||||||
goto found;
|
goto found;
|
||||||
|
}
|
||||||
/* XXX: _fp_hw seems to be part of the ABI, so we ignore
|
/* XXX: _fp_hw seems to be part of the ABI, so we ignore
|
||||||
it */
|
it */
|
||||||
if (!strcmp(name, "_fp_hw"))
|
trace ("relocate_syms 05\n");
|
||||||
|
if (!strcmp(name, "_fp_hw")) {
|
||||||
|
trace ("relocate_syms 06\n");
|
||||||
goto found;
|
goto found;
|
||||||
|
}
|
||||||
/* only weak symbols are accepted to be undefined. Their
|
/* only weak symbols are accepted to be undefined. Their
|
||||||
value is zero */
|
value is zero */
|
||||||
sym_bind = ELFW(ST_BIND)(sym->st_info);
|
sym_bind = ELFW(ST_BIND)(sym->st_info);
|
||||||
|
trace ("relocate_syms 08\n");
|
||||||
if (sym_bind == STB_WEAK)
|
if (sym_bind == STB_WEAK)
|
||||||
sym->st_value = 0;
|
sym->st_value = 0;
|
||||||
else
|
else
|
||||||
tcc_error_noabort("undefined symbol '%s'", name);
|
tcc_error_noabort("undefined symbol '%s'", name);
|
||||||
} else if (sh_num < SHN_LORESERVE) {
|
} else if (sh_num < SHN_LORESERVE) {
|
||||||
|
trace ("relocate_syms 20\n");
|
||||||
|
name = (char *) strtab_section->data + sym->st_name;
|
||||||
|
trace ("relocate_syms 02 name="); eputs (name); eputs ("\n");
|
||||||
/* add section base */
|
/* add section base */
|
||||||
sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
|
sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
|
||||||
|
trace ("relocate_syms 22\n");
|
||||||
}
|
}
|
||||||
found: ;
|
found: ;
|
||||||
}
|
}
|
||||||
|
trace_exit ("relocate_syms");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* relocate a given section (CPU dependent) by applying the relocations
|
/* relocate a given section (CPU dependent) by applying the relocations
|
||||||
|
@ -1226,18 +1378,37 @@ static void tcc_add_linker_symbols(TCCState *s1)
|
||||||
int i;
|
int i;
|
||||||
Section *s;
|
Section *s;
|
||||||
|
|
||||||
|
trace_enter ("tcc_add_linker_symbols");
|
||||||
set_elf_sym(symtab_section,
|
set_elf_sym(symtab_section,
|
||||||
text_section->data_offset, 0,
|
text_section->data_offset, 0,
|
||||||
ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
|
ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
|
||||||
text_section->sh_num, "_etext");
|
text_section->sh_num, "_etext");
|
||||||
|
|
||||||
|
ElfW(Sym) *sym;
|
||||||
|
char *name;
|
||||||
|
for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
|
||||||
|
trace ("tcc_add_linker_symbols num="); eputs (itoa (sym->st_shndx)); eputs ("\n");
|
||||||
|
name = (char *) strtab_section->data + sym->st_name;
|
||||||
|
trace ("tcc_add_linker_symbols name="); eputs (name); eputs ("\n");
|
||||||
|
}
|
||||||
set_elf_sym(symtab_section,
|
set_elf_sym(symtab_section,
|
||||||
data_section->data_offset, 0,
|
data_section->data_offset, 0,
|
||||||
ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
|
ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
|
||||||
data_section->sh_num, "_edata");
|
data_section->sh_num, "_edata");
|
||||||
|
for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
|
||||||
|
trace ("tcc_add_linker_symbols num="); eputs (itoa (sym->st_shndx)); eputs ("\n");
|
||||||
|
name = (char *) strtab_section->data + sym->st_name;
|
||||||
|
trace ("tcc_add_linker_symbols name="); eputs (name); eputs ("\n");
|
||||||
|
}
|
||||||
set_elf_sym(symtab_section,
|
set_elf_sym(symtab_section,
|
||||||
bss_section->data_offset, 0,
|
bss_section->data_offset, 0,
|
||||||
ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
|
ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
|
||||||
bss_section->sh_num, "_end");
|
bss_section->sh_num, "_end");
|
||||||
|
for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
|
||||||
|
trace ("tcc_add_linker_symbols num="); eputs (itoa (sym->st_shndx)); eputs ("\n");
|
||||||
|
name = (char *) strtab_section->data + sym->st_name;
|
||||||
|
trace ("tcc_add_linker_symbols name="); eputs (name); eputs ("\n");
|
||||||
|
}
|
||||||
#ifndef TCC_TARGET_PE
|
#ifndef TCC_TARGET_PE
|
||||||
/* horrible new standard ldscript defines */
|
/* horrible new standard ldscript defines */
|
||||||
add_init_array_defines(s1, ".preinit_array");
|
add_init_array_defines(s1, ".preinit_array");
|
||||||
|
@ -1277,6 +1448,12 @@ static void tcc_add_linker_symbols(TCCState *s1)
|
||||||
}
|
}
|
||||||
next_sec: ;
|
next_sec: ;
|
||||||
}
|
}
|
||||||
|
for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
|
||||||
|
trace ("set_elf_sym num="); eputs (itoa (sym->st_shndx)); eputs ("\n");
|
||||||
|
name = (char *) strtab_section->data + sym->st_name;
|
||||||
|
trace ("set_elf_sym name="); eputs (name); eputs ("\n");
|
||||||
|
}
|
||||||
|
trace_exit ("tcc_add_linker_symbols");
|
||||||
}
|
}
|
||||||
|
|
||||||
ST_FUNC void resolve_common_syms(TCCState *s1)
|
ST_FUNC void resolve_common_syms(TCCState *s1)
|
||||||
|
@ -1343,6 +1520,7 @@ ST_FUNC void fill_got(TCCState *s1)
|
||||||
ElfW_Rel *rel;
|
ElfW_Rel *rel;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
trace_enter ("fill_got");
|
||||||
for(i = 1; i < s1->nb_sections; i++) {
|
for(i = 1; i < s1->nb_sections; i++) {
|
||||||
s = s1->sections[i];
|
s = s1->sections[i];
|
||||||
if (s->sh_type != SHT_RELX)
|
if (s->sh_type != SHT_RELX)
|
||||||
|
@ -1362,6 +1540,7 @@ ST_FUNC void fill_got(TCCState *s1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
trace_exit ("fill_got");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See put_got_entry for a description. This is the second stage
|
/* See put_got_entry for a description. This is the second stage
|
||||||
|
@ -1370,6 +1549,7 @@ static void fill_local_got_entries(TCCState *s1)
|
||||||
{
|
{
|
||||||
ElfW_Rel *rel;
|
ElfW_Rel *rel;
|
||||||
for_each_elem(s1->got->reloc, 0, rel, ElfW_Rel) {
|
for_each_elem(s1->got->reloc, 0, rel, ElfW_Rel) {
|
||||||
|
trace_enter ("fill_local_got_entries");
|
||||||
if (ELFW(R_TYPE)(rel->r_info) == R_RELATIVE) {
|
if (ELFW(R_TYPE)(rel->r_info) == R_RELATIVE) {
|
||||||
int sym_index = ELFW(R_SYM) (rel->r_info);
|
int sym_index = ELFW(R_SYM) (rel->r_info);
|
||||||
ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
|
ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
|
||||||
|
@ -1386,6 +1566,7 @@ static void fill_local_got_entries(TCCState *s1)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
trace_exit ("fill_local_got_entries");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Bind symbols of executable: resolve undefined symbols from exported symbols
|
/* Bind symbols of executable: resolve undefined symbols from exported symbols
|
||||||
|
@ -1529,9 +1710,13 @@ static int alloc_sec_names(TCCState *s1, int file_type, Section *strsec)
|
||||||
Section *s;
|
Section *s;
|
||||||
int textrel = 0;
|
int textrel = 0;
|
||||||
|
|
||||||
|
trace_enter ("alloc_sec_names");
|
||||||
/* Allocate strings for section names */
|
/* Allocate strings for section names */
|
||||||
for(i = 1; i < s1->nb_sections; i++) {
|
for(i = 1; i < s1->nb_sections; i++) {
|
||||||
|
trace ("alloc_sec_names i="); eputs (itoa (i)); eputs ("\n");
|
||||||
s = s1->sections[i];
|
s = s1->sections[i];
|
||||||
|
trace ("alloc_sec_names 02\n");
|
||||||
|
trace ("alloc_sec_names name="); eputs (s->name); eputs ("\n");
|
||||||
/* when generating a DLL, we include relocations but we may
|
/* when generating a DLL, we include relocations but we may
|
||||||
patch them */
|
patch them */
|
||||||
if (file_type == TCC_OUTPUT_DLL &&
|
if (file_type == TCC_OUTPUT_DLL &&
|
||||||
|
@ -1545,13 +1730,19 @@ static int alloc_sec_names(TCCState *s1, int file_type, Section *strsec)
|
||||||
file_type == TCC_OUTPUT_OBJ ||
|
file_type == TCC_OUTPUT_OBJ ||
|
||||||
(s->sh_flags & SHF_ALLOC) ||
|
(s->sh_flags & SHF_ALLOC) ||
|
||||||
i == (s1->nb_sections - 1)) {
|
i == (s1->nb_sections - 1)) {
|
||||||
|
trace ("alloc_sec_names 10\n");
|
||||||
/* we output all sections if debug or object file */
|
/* we output all sections if debug or object file */
|
||||||
s->sh_size = s->data_offset;
|
s->sh_size = s->data_offset;
|
||||||
|
trace ("alloc_sec_names 11\n");
|
||||||
}
|
}
|
||||||
if (s->sh_size || (s->sh_flags & SHF_ALLOC))
|
trace ("alloc_sec_names 12\n");
|
||||||
|
if (s->sh_size || (s->sh_flags & SHF_ALLOC)) {
|
||||||
|
trace ("alloc_sec_names 13\n");
|
||||||
s->sh_name = put_elf_str(strsec, s->name);
|
s->sh_name = put_elf_str(strsec, s->name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
strsec->sh_size = strsec->data_offset;
|
strsec->sh_size = strsec->data_offset;
|
||||||
|
trace_exit ("alloc_sec_names");
|
||||||
return textrel;
|
return textrel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1581,6 +1772,7 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
|
||||||
ElfW(Phdr) *ph;
|
ElfW(Phdr) *ph;
|
||||||
Section *s;
|
Section *s;
|
||||||
|
|
||||||
|
trace_enter ("layout_sections");
|
||||||
file_type = s1->output_type;
|
file_type = s1->output_type;
|
||||||
sh_order_index = 1;
|
sh_order_index = 1;
|
||||||
file_offset = 0;
|
file_offset = 0;
|
||||||
|
@ -1590,8 +1782,11 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
|
||||||
if (s1->section_align)
|
if (s1->section_align)
|
||||||
s_align = s1->section_align;
|
s_align = s1->section_align;
|
||||||
|
|
||||||
|
trace ("layout_sections 10\n");
|
||||||
if (phnum > 0) {
|
if (phnum > 0) {
|
||||||
|
trace ("layout_sections 11\n");
|
||||||
if (s1->has_text_addr) {
|
if (s1->has_text_addr) {
|
||||||
|
trace ("layout_sections 12\n");
|
||||||
int a_offset, p_offset;
|
int a_offset, p_offset;
|
||||||
addr = s1->text_addr;
|
addr = s1->text_addr;
|
||||||
/* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
|
/* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
|
||||||
|
@ -1602,6 +1797,7 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
|
||||||
a_offset += s_align;
|
a_offset += s_align;
|
||||||
file_offset += (a_offset - p_offset);
|
file_offset += (a_offset - p_offset);
|
||||||
} else {
|
} else {
|
||||||
|
trace ("layout_sections 20\n");
|
||||||
if (file_type == TCC_OUTPUT_DLL)
|
if (file_type == TCC_OUTPUT_DLL)
|
||||||
addr = 0;
|
addr = 0;
|
||||||
else
|
else
|
||||||
|
@ -1610,6 +1806,7 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
|
||||||
addr += (file_offset & (s_align - 1));
|
addr += (file_offset & (s_align - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trace ("layout_sections 30\n");
|
||||||
ph = &phdr[0];
|
ph = &phdr[0];
|
||||||
/* Leave one program headers for the program interpreter and one for
|
/* Leave one program headers for the program interpreter and one for
|
||||||
the program header table itself if needed. These are done later as
|
the program header table itself if needed. These are done later as
|
||||||
|
@ -1624,6 +1821,7 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for(j = 0; j < 2; j++) {
|
for(j = 0; j < 2; j++) {
|
||||||
|
trace ("layout_sections j="); eputs (itoa (j)); eputs ("\n");
|
||||||
ph->p_type = PT_LOAD;
|
ph->p_type = PT_LOAD;
|
||||||
if (j == 0)
|
if (j == 0)
|
||||||
ph->p_flags = PF_R | PF_X;
|
ph->p_flags = PF_R | PF_X;
|
||||||
|
@ -1637,8 +1835,10 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
|
||||||
symbol tables, relocations, progbits, nobits */
|
symbol tables, relocations, progbits, nobits */
|
||||||
/* XXX: do faster and simpler sorting */
|
/* XXX: do faster and simpler sorting */
|
||||||
for(k = 0; k < 5; k++) {
|
for(k = 0; k < 5; k++) {
|
||||||
|
trace ("layout_sections k="); eputs (itoa (k)); eputs ("\n");
|
||||||
for(i = 1; i < s1->nb_sections; i++) {
|
for(i = 1; i < s1->nb_sections; i++) {
|
||||||
s = s1->sections[i];
|
s = s1->sections[i];
|
||||||
|
trace ("layout_sections i="); eputs (itoa (i)); eputs ("\n");
|
||||||
/* compute if section should be included */
|
/* compute if section should be included */
|
||||||
if (j == 0) {
|
if (j == 0) {
|
||||||
if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
|
if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
|
||||||
|
@ -1731,8 +1931,10 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trace ("layout_sections 80\n");
|
||||||
/* all other sections come after */
|
/* all other sections come after */
|
||||||
for(i = 1; i < s1->nb_sections; i++) {
|
for(i = 1; i < s1->nb_sections; i++) {
|
||||||
|
trace ("layout_sections 80 i="); eputs (itoa (i)); eputs ("\n");
|
||||||
s = s1->sections[i];
|
s = s1->sections[i];
|
||||||
if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
|
if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
|
||||||
continue;
|
continue;
|
||||||
|
@ -1740,11 +1942,14 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
|
||||||
|
|
||||||
file_offset = (file_offset + s->sh_addralign - 1) &
|
file_offset = (file_offset + s->sh_addralign - 1) &
|
||||||
~(s->sh_addralign - 1);
|
~(s->sh_addralign - 1);
|
||||||
|
trace ("layout_sections file_offset="); eputs (itoa (file_offset)); eputs ("\n");
|
||||||
s->sh_offset = file_offset;
|
s->sh_offset = file_offset;
|
||||||
if (s->sh_type != SHT_NOBITS)
|
if (s->sh_type != SHT_NOBITS)
|
||||||
file_offset += s->sh_size;
|
file_offset += s->sh_size;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trace_exit ("layout_sections");
|
||||||
return file_offset;
|
return file_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1833,14 +2038,20 @@ static int final_sections_reloc(TCCState *s1)
|
||||||
int i;
|
int i;
|
||||||
Section *s;
|
Section *s;
|
||||||
|
|
||||||
|
trace_enter ("final_sections_reloc");
|
||||||
relocate_syms(s1, s1->symtab, 0);
|
relocate_syms(s1, s1->symtab, 0);
|
||||||
|
trace ("final_sections_reloc 01\n");
|
||||||
|
|
||||||
if (s1->nb_errors != 0)
|
if (s1->nb_errors != 0) {
|
||||||
|
trace_exit ("final_sections_reloc");
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
trace ("final_sections_reloc 02\n");
|
||||||
|
|
||||||
/* relocate sections */
|
/* relocate sections */
|
||||||
/* XXX: ignore sections with allocated relocations ? */
|
/* XXX: ignore sections with allocated relocations ? */
|
||||||
for(i = 1; i < s1->nb_sections; i++) {
|
for(i = 1; i < s1->nb_sections; i++) {
|
||||||
|
trace ("final_sections_reloc 21\n");
|
||||||
s = s1->sections[i];
|
s = s1->sections[i];
|
||||||
#if defined(TCC_TARGET_I386) || defined(TCC_MUSL)
|
#if defined(TCC_TARGET_I386) || defined(TCC_MUSL)
|
||||||
if (s->reloc && s != s1->got && (s->sh_flags & SHF_ALLOC)) //gr
|
if (s->reloc && s != s1->got && (s->sh_flags & SHF_ALLOC)) //gr
|
||||||
|
@ -1853,15 +2064,19 @@ static int final_sections_reloc(TCCState *s1)
|
||||||
relocate_section(s1, s);
|
relocate_section(s1, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trace ("final_sections_reloc 80\n");
|
||||||
/* relocate relocation entries if the relocation tables are
|
/* relocate relocation entries if the relocation tables are
|
||||||
allocated in the executable */
|
allocated in the executable */
|
||||||
for(i = 1; i < s1->nb_sections; i++) {
|
for(i = 1; i < s1->nb_sections; i++) {
|
||||||
|
trace ("final_sections_reloc 81\n");
|
||||||
s = s1->sections[i];
|
s = s1->sections[i];
|
||||||
if ((s->sh_flags & SHF_ALLOC) &&
|
if ((s->sh_flags & SHF_ALLOC) &&
|
||||||
s->sh_type == SHT_RELX) {
|
s->sh_type == SHT_RELX) {
|
||||||
relocate_rel(s1, s);
|
relocate_rel(s1, s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trace_exit ("final_sections_reloc");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1875,6 +2090,7 @@ static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
|
||||||
ElfW(Ehdr) ehdr;
|
ElfW(Ehdr) ehdr;
|
||||||
ElfW(Shdr) shdr, *sh;
|
ElfW(Shdr) shdr, *sh;
|
||||||
|
|
||||||
|
trace_enter ("tcc_output_elf");
|
||||||
file_type = s1->output_type;
|
file_type = s1->output_type;
|
||||||
shnum = s1->nb_sections;
|
shnum = s1->nb_sections;
|
||||||
|
|
||||||
|
@ -1886,6 +2102,8 @@ static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
|
||||||
ehdr.e_phoff = sizeof(ElfW(Ehdr));
|
ehdr.e_phoff = sizeof(ElfW(Ehdr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trace ("tcc_output_elf 10\n");
|
||||||
|
|
||||||
/* align to 4 */
|
/* align to 4 */
|
||||||
file_offset = (file_offset + 3) & -4;
|
file_offset = (file_offset + 3) & -4;
|
||||||
|
|
||||||
|
@ -1915,6 +2133,7 @@ static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
|
||||||
ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
|
ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
trace ("tcc_output_elf 20\n");
|
||||||
switch(file_type) {
|
switch(file_type) {
|
||||||
default:
|
default:
|
||||||
case TCC_OUTPUT_EXE:
|
case TCC_OUTPUT_EXE:
|
||||||
|
@ -1937,6 +2156,15 @@ static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
|
||||||
ehdr.e_shnum = shnum;
|
ehdr.e_shnum = shnum;
|
||||||
ehdr.e_shstrndx = shnum - 1;
|
ehdr.e_shstrndx = shnum - 1;
|
||||||
|
|
||||||
|
trace ("tcc_output_elf 50\n");
|
||||||
|
trace ("tcc_output_elf ehdr.size="); eputs (itoa (sizeof(ElfW(Ehdr)))); eputs ("\n");
|
||||||
|
trace ("tcc_output_elf ehdr.e_machine="); eputs (itoa (ehdr.e_machine)); eputs ("\n");
|
||||||
|
trace ("tcc_output_elf ehdr.e_version="); eputs (itoa (ehdr.e_version)); eputs ("\n");
|
||||||
|
unsigned char *p = &ehdr;
|
||||||
|
for (int i = 0; i < sizeof(ElfW(Ehdr)); i++) {
|
||||||
|
if (i < 10) eputs (" ");
|
||||||
|
trace (itoa (i)); eputs (": "); eputs (itoa (p[i])); eputs ("\n");
|
||||||
|
}
|
||||||
fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
|
fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
|
||||||
fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
|
fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
|
||||||
offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
|
offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
|
||||||
|
@ -1944,6 +2172,7 @@ static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
|
||||||
sort_syms(s1, symtab_section);
|
sort_syms(s1, symtab_section);
|
||||||
for(i = 1; i < s1->nb_sections; i++) {
|
for(i = 1; i < s1->nb_sections; i++) {
|
||||||
s = s1->sections[sec_order[i]];
|
s = s1->sections[sec_order[i]];
|
||||||
|
trace ("tcc_output_elf 50 name="); eputs (s->name); eputs ("\n");
|
||||||
if (s->sh_type != SHT_NOBITS) {
|
if (s->sh_type != SHT_NOBITS) {
|
||||||
while (offset < s->sh_offset) {
|
while (offset < s->sh_offset) {
|
||||||
fputc(0, f);
|
fputc(0, f);
|
||||||
|
@ -1956,31 +2185,44 @@ static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trace ("tcc_output_elf 60\n");
|
||||||
/* output section headers */
|
/* output section headers */
|
||||||
while (offset < ehdr.e_shoff) {
|
while (offset < ehdr.e_shoff) {
|
||||||
fputc(0, f);
|
fputc(0, f);
|
||||||
offset++;
|
offset++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trace ("tcc_output_elf 70\n");
|
||||||
for(i = 0; i < s1->nb_sections; i++) {
|
for(i = 0; i < s1->nb_sections; i++) {
|
||||||
|
trace ("tcc_output_elf 70 i="); eputs (itoa (i)); eputs ("\n");
|
||||||
sh = &shdr;
|
sh = &shdr;
|
||||||
memset(sh, 0, sizeof(ElfW(Shdr)));
|
memset(sh, 0, sizeof(ElfW(Shdr)));
|
||||||
|
trace ("tcc_output_elf 72\n");
|
||||||
s = s1->sections[i];
|
s = s1->sections[i];
|
||||||
if (s) {
|
if (s) {
|
||||||
|
trace ("tcc_output_elf 80\n");
|
||||||
|
trace ("tcc_output_elf 80 name="); eputs (s->name ? s->name : "<null>"); eputs ("\n");
|
||||||
sh->sh_name = s->sh_name;
|
sh->sh_name = s->sh_name;
|
||||||
sh->sh_type = s->sh_type;
|
sh->sh_type = s->sh_type;
|
||||||
sh->sh_flags = s->sh_flags;
|
sh->sh_flags = s->sh_flags;
|
||||||
sh->sh_entsize = s->sh_entsize;
|
sh->sh_entsize = s->sh_entsize;
|
||||||
sh->sh_info = s->sh_info;
|
sh->sh_info = s->sh_info;
|
||||||
if (s->link)
|
trace ("tcc_output_elf 85\n");
|
||||||
|
if (s->link) {
|
||||||
sh->sh_link = s->link->sh_num;
|
sh->sh_link = s->link->sh_num;
|
||||||
|
trace ("tcc_output_elf 86 sh_num="); eputs (itoa (s->link->sh_num)); eputs ("\n");
|
||||||
|
}
|
||||||
|
trace ("tcc_output_elf 87\n");
|
||||||
sh->sh_addralign = s->sh_addralign;
|
sh->sh_addralign = s->sh_addralign;
|
||||||
sh->sh_addr = s->sh_addr;
|
sh->sh_addr = s->sh_addr;
|
||||||
sh->sh_offset = s->sh_offset;
|
sh->sh_offset = s->sh_offset;
|
||||||
sh->sh_size = s->sh_size;
|
sh->sh_size = s->sh_size;
|
||||||
}
|
}
|
||||||
|
trace ("tcc_output_elf 90\n");
|
||||||
fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
|
fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
|
||||||
|
trace ("tcc_output_elf 91\n");
|
||||||
}
|
}
|
||||||
|
trace_exit ("tcc_output_elf");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write an elf, coff or "binary" file */
|
/* Write an elf, coff or "binary" file */
|
||||||
|
@ -1990,18 +2232,24 @@ static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
|
||||||
int fd, mode, file_type;
|
int fd, mode, file_type;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
|
|
||||||
|
trace_enter ("tcc_write_elf_file");
|
||||||
file_type = s1->output_type;
|
file_type = s1->output_type;
|
||||||
if (file_type == TCC_OUTPUT_OBJ)
|
if (file_type == TCC_OUTPUT_OBJ)
|
||||||
mode = 0666;
|
mode = 0666;
|
||||||
else
|
else
|
||||||
mode = 0777;
|
mode = 0777;
|
||||||
unlink(filename);
|
unlink(filename);
|
||||||
|
trace ("tcc_write_elf_file 06\n");
|
||||||
fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
|
fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
|
||||||
|
trace ("tcc_write_elf_file 07\n");
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
|
trace ("tcc_write_elf_file fd < 0\n");
|
||||||
tcc_error_noabort("could not write '%s'", filename);
|
tcc_error_noabort("could not write '%s'", filename);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
trace ("tcc_write_elf_file 09\n");
|
||||||
f = fdopen(fd, "wb");
|
f = fdopen(fd, "wb");
|
||||||
|
trace ("tcc_write_elf_file 10\n");
|
||||||
if (s1->verbose)
|
if (s1->verbose)
|
||||||
printf("<- %s\n", filename);
|
printf("<- %s\n", filename);
|
||||||
|
|
||||||
|
@ -2016,6 +2264,7 @@ static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
|
||||||
tcc_output_binary(s1, f, sec_order);
|
tcc_output_binary(s1, f, sec_order);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
|
trace_exit ("tcc_write_elf_file");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2027,6 +2276,7 @@ static void tidy_section_headers(TCCState *s1, int *sec_order)
|
||||||
Section **snew, *s;
|
Section **snew, *s;
|
||||||
ElfW(Sym) *sym;
|
ElfW(Sym) *sym;
|
||||||
|
|
||||||
|
trace_enter ("tidy_section_headers");
|
||||||
snew = tcc_malloc(s1->nb_sections * sizeof(snew[0]));
|
snew = tcc_malloc(s1->nb_sections * sizeof(snew[0]));
|
||||||
backmap = tcc_malloc(s1->nb_sections * sizeof(backmap[0]));
|
backmap = tcc_malloc(s1->nb_sections * sizeof(backmap[0]));
|
||||||
for (i = 0, nnew = 0, l = s1->nb_sections; i < s1->nb_sections; i++) {
|
for (i = 0, nnew = 0, l = s1->nb_sections; i < s1->nb_sections; i++) {
|
||||||
|
@ -2063,6 +2313,7 @@ static void tidy_section_headers(TCCState *s1, int *sec_order)
|
||||||
s1->sections = snew;
|
s1->sections = snew;
|
||||||
s1->nb_sections = nnew;
|
s1->nb_sections = nnew;
|
||||||
tcc_free(backmap);
|
tcc_free(backmap);
|
||||||
|
trace_exit ("tidy_section_headers");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Output an elf, coff or binary file */
|
/* Output an elf, coff or binary file */
|
||||||
|
@ -2076,6 +2327,7 @@ static int elf_output_file(TCCState *s1, const char *filename)
|
||||||
Section *strsec, *interp, *dynamic, *dynstr;
|
Section *strsec, *interp, *dynamic, *dynstr;
|
||||||
int textrel;
|
int textrel;
|
||||||
|
|
||||||
|
trace_enter ("elf_output_file");
|
||||||
file_type = s1->output_type;
|
file_type = s1->output_type;
|
||||||
s1->nb_errors = 0;
|
s1->nb_errors = 0;
|
||||||
ret = -1;
|
ret = -1;
|
||||||
|
@ -2089,8 +2341,17 @@ static int elf_output_file(TCCState *s1, const char *filename)
|
||||||
tcc_add_runtime(s1);
|
tcc_add_runtime(s1);
|
||||||
resolve_common_syms(s1);
|
resolve_common_syms(s1);
|
||||||
|
|
||||||
|
trace ("elf_output_file 12\n");
|
||||||
|
for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
|
||||||
|
trace ("elf_output_file num="); eputs (itoa (sym->st_shndx)); eputs ("\n");
|
||||||
|
name = (char *) strtab_section->data + sym->st_name;
|
||||||
|
trace ("elf_output_file name="); eputs (name); eputs ("\n");
|
||||||
|
}
|
||||||
|
|
||||||
if (!s1->static_link) {
|
if (!s1->static_link) {
|
||||||
|
trace ("elf_output_file 13\n");
|
||||||
if (file_type == TCC_OUTPUT_EXE) {
|
if (file_type == TCC_OUTPUT_EXE) {
|
||||||
|
trace ("elf_output_file 14\n");
|
||||||
char *ptr;
|
char *ptr;
|
||||||
/* allow override the dynamic loader */
|
/* allow override the dynamic loader */
|
||||||
const char *elfint = getenv("LD_SO");
|
const char *elfint = getenv("LD_SO");
|
||||||
|
@ -2102,6 +2363,7 @@ static int elf_output_file(TCCState *s1, const char *filename)
|
||||||
ptr = section_ptr_add(interp, 1 + strlen(elfint));
|
ptr = section_ptr_add(interp, 1 + strlen(elfint));
|
||||||
strcpy(ptr, elfint);
|
strcpy(ptr, elfint);
|
||||||
}
|
}
|
||||||
|
trace ("elf_output_file 20\n");
|
||||||
|
|
||||||
/* add dynamic symbol table */
|
/* add dynamic symbol table */
|
||||||
s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
|
s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
|
||||||
|
@ -2117,7 +2379,9 @@ static int elf_output_file(TCCState *s1, const char *filename)
|
||||||
|
|
||||||
build_got(s1);
|
build_got(s1);
|
||||||
|
|
||||||
|
trace ("elf_output_file 30\n");
|
||||||
if (file_type == TCC_OUTPUT_EXE) {
|
if (file_type == TCC_OUTPUT_EXE) {
|
||||||
|
trace ("elf_output_file 31\n");
|
||||||
bind_exe_dynsyms(s1);
|
bind_exe_dynsyms(s1);
|
||||||
if (s1->nb_errors)
|
if (s1->nb_errors)
|
||||||
goto the_end;
|
goto the_end;
|
||||||
|
@ -2169,6 +2433,7 @@ static int elf_output_file(TCCState *s1, const char *filename)
|
||||||
dynamic->sh_size = dynamic->data_offset;
|
dynamic->sh_size = dynamic->data_offset;
|
||||||
dynstr->sh_size = dynstr->data_offset;
|
dynstr->sh_size = dynstr->data_offset;
|
||||||
}
|
}
|
||||||
|
trace ("elf_output_file 50\n");
|
||||||
|
|
||||||
/* compute number of program headers */
|
/* compute number of program headers */
|
||||||
if (file_type == TCC_OUTPUT_OBJ)
|
if (file_type == TCC_OUTPUT_OBJ)
|
||||||
|
@ -2194,6 +2459,7 @@ static int elf_output_file(TCCState *s1, const char *filename)
|
||||||
file_offset = layout_sections(s1, phdr, phnum, interp, strsec, &dyninf,
|
file_offset = layout_sections(s1, phdr, phnum, interp, strsec, &dyninf,
|
||||||
sec_order);
|
sec_order);
|
||||||
|
|
||||||
|
trace ("elf_output_file 63\n");
|
||||||
/* Fill remaining program header and finalize relocation related to dynamic
|
/* Fill remaining program header and finalize relocation related to dynamic
|
||||||
linking. */
|
linking. */
|
||||||
if (file_type != TCC_OUTPUT_OBJ) {
|
if (file_type != TCC_OUTPUT_OBJ) {
|
||||||
|
@ -2220,10 +2486,13 @@ static int elf_output_file(TCCState *s1, const char *filename)
|
||||||
/* if building executable or DLL, then relocate each section
|
/* if building executable or DLL, then relocate each section
|
||||||
except the GOT which is already relocated */
|
except the GOT which is already relocated */
|
||||||
ret = final_sections_reloc(s1);
|
ret = final_sections_reloc(s1);
|
||||||
|
trace ("elf_output_file 82\n");
|
||||||
if (ret)
|
if (ret)
|
||||||
goto the_end;
|
goto the_end;
|
||||||
#if !BOOTSTRAP
|
#if !BOOTSTRAP
|
||||||
|
trace ("elf_output_file 83\n");
|
||||||
tidy_section_headers(s1, sec_order);
|
tidy_section_headers(s1, sec_order);
|
||||||
|
trace ("elf_output_file 84\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Perform relocation to GOT or PLT entries */
|
/* Perform relocation to GOT or PLT entries */
|
||||||
|
@ -2233,12 +2502,17 @@ static int elf_output_file(TCCState *s1, const char *filename)
|
||||||
fill_local_got_entries(s1);
|
fill_local_got_entries(s1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trace ("elf_output_file 90\n");
|
||||||
/* Create the ELF file with name 'filename' */
|
/* Create the ELF file with name 'filename' */
|
||||||
ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
|
ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
|
||||||
|
trace ("elf_output_file 91\n");
|
||||||
s1->nb_sections = shnum;
|
s1->nb_sections = shnum;
|
||||||
the_end:
|
the_end:
|
||||||
|
trace ("elf_output_file 92\n");
|
||||||
tcc_free(sec_order);
|
tcc_free(sec_order);
|
||||||
|
trace ("elf_output_file 93\n");
|
||||||
tcc_free(phdr);
|
tcc_free(phdr);
|
||||||
|
trace_exit ("elf_output_file");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue