lotsa debug printing

This commit is contained in:
Jan Nieuwenhuizen 2017-11-16 07:48:49 +01:00
parent a41c019ff7
commit bb0a641cab
No known key found for this signature in database
GPG Key ID: F3C1A0D9C1D65273
9 changed files with 1442 additions and 60 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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
View File

@ -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
View File

@ -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;
} }

View File

@ -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
View File

@ -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;
} }

533
tccgen.c

File diff suppressed because it is too large Load Diff

433
tccpp.c

File diff suppressed because it is too large Load Diff