tccgen/tccelf: move code from libtcc.c
This commit is contained in:
228
tccgen.c
228
tccgen.c
@ -30,20 +30,6 @@
|
||||
*/
|
||||
ST_DATA int rsym, anon_sym, ind, loc;
|
||||
|
||||
ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */
|
||||
ST_DATA Section *cur_text_section; /* current section where function code is generated */
|
||||
#ifdef CONFIG_TCC_ASM
|
||||
ST_DATA Section *last_text_section; /* to handle .previous asm directive */
|
||||
#endif
|
||||
#ifdef CONFIG_TCC_BCHECK
|
||||
/* bound check related sections */
|
||||
ST_DATA Section *bounds_section; /* contains global data bound description */
|
||||
ST_DATA Section *lbounds_section; /* contains local data bound description */
|
||||
#endif
|
||||
/* symbol sections */
|
||||
ST_DATA Section *symtab_section, *strtab_section;
|
||||
/* debug sections */
|
||||
ST_DATA Section *stab_section, *stabstr_section;
|
||||
ST_DATA Sym *sym_free_first;
|
||||
ST_DATA void **sym_pools;
|
||||
ST_DATA int nb_sym_pools;
|
||||
@ -55,6 +41,7 @@ ST_DATA Sym *global_label_stack;
|
||||
ST_DATA Sym *local_label_stack;
|
||||
static int local_scope;
|
||||
static int in_sizeof;
|
||||
static int section_sym;
|
||||
|
||||
ST_DATA int vlas_in_scope; /* number of VLAs that are currently in scope */
|
||||
ST_DATA int vla_sp_root_loc; /* vla_sp_loc for SP before any VLAs were pushed */
|
||||
@ -148,6 +135,217 @@ void pv (const char *lbl, int a, int b)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
ST_FUNC void tccgen_start(TCCState *s1)
|
||||
{
|
||||
cur_text_section = NULL;
|
||||
funcname = "";
|
||||
anon_sym = SYM_FIRST_ANOM;
|
||||
section_sym = 0;
|
||||
nocode_wanted = 1;
|
||||
|
||||
/* define some often used types */
|
||||
int_type.t = VT_INT;
|
||||
char_pointer_type.t = VT_BYTE;
|
||||
mk_pointer(&char_pointer_type);
|
||||
#if PTR_SIZE == 4
|
||||
size_type.t = VT_INT;
|
||||
#else
|
||||
size_type.t = VT_LLONG;
|
||||
#endif
|
||||
func_old_type.t = VT_FUNC;
|
||||
func_old_type.ref = sym_push(SYM_FIELD, &int_type, FUNC_CDECL, FUNC_OLD);
|
||||
|
||||
if (s1->do_debug) {
|
||||
char buf[512];
|
||||
|
||||
/* file info: full path + filename */
|
||||
section_sym = put_elf_sym(symtab_section, 0, 0,
|
||||
ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0,
|
||||
text_section->sh_num, NULL);
|
||||
getcwd(buf, sizeof(buf));
|
||||
#ifdef _WIN32
|
||||
normalize_slashes(buf);
|
||||
#endif
|
||||
pstrcat(buf, sizeof(buf), "/");
|
||||
put_stabs_r(buf, N_SO, 0, 0,
|
||||
text_section->data_offset, text_section, section_sym);
|
||||
put_stabs_r(file->filename, N_SO, 0, 0,
|
||||
text_section->data_offset, text_section, section_sym);
|
||||
}
|
||||
/* an elf symbol of type STT_FILE must be put so that STB_LOCAL
|
||||
symbols can be safely used */
|
||||
put_elf_sym(symtab_section, 0, 0,
|
||||
ELFW(ST_INFO)(STB_LOCAL, STT_FILE), 0,
|
||||
SHN_ABS, file->filename);
|
||||
|
||||
#ifdef TCC_TARGET_ARM
|
||||
arm_init(s1);
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/* define 'void *alloca(unsigned int)' builtin function */
|
||||
{
|
||||
Sym *s1;
|
||||
|
||||
p = anon_sym++;
|
||||
sym = sym_push(p, mk_pointer(VT_VOID), FUNC_CDECL, FUNC_NEW);
|
||||
s1 = sym_push(SYM_FIELD, VT_UNSIGNED | VT_INT, 0, 0);
|
||||
s1->next = NULL;
|
||||
sym->next = s1;
|
||||
sym_push(TOK_alloca, VT_FUNC | (p << VT_STRUCT_SHIFT), VT_CONST, 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
ST_FUNC void tccgen_end(TCCState *s1)
|
||||
{
|
||||
check_vstack();
|
||||
/* end of translation unit info */
|
||||
if (s1->do_debug) {
|
||||
put_stabs_r(NULL, N_SO, 0, 0,
|
||||
text_section->data_offset, text_section, section_sym);
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* update sym->c so that it points to an external symbol in section
|
||||
'section' with value 'value' */
|
||||
|
||||
ST_FUNC void put_extern_sym2(Sym *sym, Section *section,
|
||||
addr_t value, unsigned long size,
|
||||
int can_add_underscore)
|
||||
{
|
||||
int sym_type, sym_bind, sh_num, info, other;
|
||||
ElfW(Sym) *esym;
|
||||
const char *name;
|
||||
char buf1[256];
|
||||
|
||||
#ifdef CONFIG_TCC_BCHECK
|
||||
char buf[32];
|
||||
#endif
|
||||
|
||||
if (section == NULL)
|
||||
sh_num = SHN_UNDEF;
|
||||
else if (section == SECTION_ABS)
|
||||
sh_num = SHN_ABS;
|
||||
else
|
||||
sh_num = section->sh_num;
|
||||
|
||||
if ((sym->type.t & VT_BTYPE) == VT_FUNC) {
|
||||
sym_type = STT_FUNC;
|
||||
} else if ((sym->type.t & VT_BTYPE) == VT_VOID) {
|
||||
sym_type = STT_NOTYPE;
|
||||
} else {
|
||||
sym_type = STT_OBJECT;
|
||||
}
|
||||
|
||||
if (sym->type.t & VT_STATIC)
|
||||
sym_bind = STB_LOCAL;
|
||||
else {
|
||||
if (sym->type.t & VT_WEAK)
|
||||
sym_bind = STB_WEAK;
|
||||
else
|
||||
sym_bind = STB_GLOBAL;
|
||||
}
|
||||
|
||||
if (!sym->c) {
|
||||
name = get_tok_str(sym->v, NULL);
|
||||
#ifdef CONFIG_TCC_BCHECK
|
||||
if (tcc_state->do_bounds_check) {
|
||||
/* XXX: avoid doing that for statics ? */
|
||||
/* if bound checking is activated, we change some function
|
||||
names by adding the "__bound" prefix */
|
||||
switch(sym->v) {
|
||||
#ifdef TCC_TARGET_PE
|
||||
/* XXX: we rely only on malloc hooks */
|
||||
case TOK_malloc:
|
||||
case TOK_free:
|
||||
case TOK_realloc:
|
||||
case TOK_memalign:
|
||||
case TOK_calloc:
|
||||
#endif
|
||||
case TOK_memcpy:
|
||||
case TOK_memmove:
|
||||
case TOK_memset:
|
||||
case TOK_strlen:
|
||||
case TOK_strcpy:
|
||||
case TOK_alloca:
|
||||
strcpy(buf, "__bound_");
|
||||
strcat(buf, name);
|
||||
name = buf;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
other = 0;
|
||||
|
||||
#ifdef TCC_TARGET_PE
|
||||
if (sym->type.t & VT_EXPORT)
|
||||
other |= ST_PE_EXPORT;
|
||||
if (sym_type == STT_FUNC && sym->type.ref) {
|
||||
Sym *ref = sym->type.ref;
|
||||
if (ref->a.func_export)
|
||||
other |= ST_PE_EXPORT;
|
||||
if (ref->a.func_call == FUNC_STDCALL && can_add_underscore) {
|
||||
sprintf(buf1, "_%s@%d", name, ref->a.func_args * PTR_SIZE);
|
||||
name = buf1;
|
||||
other |= ST_PE_STDCALL;
|
||||
can_add_underscore = 0;
|
||||
}
|
||||
} else {
|
||||
if (find_elf_sym(tcc_state->dynsymtab_section, name))
|
||||
other |= ST_PE_IMPORT;
|
||||
if (sym->type.t & VT_IMPORT)
|
||||
other |= ST_PE_IMPORT;
|
||||
}
|
||||
#else
|
||||
if (! (sym->type.t & VT_STATIC))
|
||||
other = (sym->type.t & VT_VIS_MASK) >> VT_VIS_SHIFT;
|
||||
#endif
|
||||
if (tcc_state->leading_underscore && can_add_underscore) {
|
||||
buf1[0] = '_';
|
||||
pstrcpy(buf1 + 1, sizeof(buf1) - 1, name);
|
||||
name = buf1;
|
||||
}
|
||||
if (sym->asm_label) {
|
||||
name = get_tok_str(sym->asm_label, NULL);
|
||||
}
|
||||
info = ELFW(ST_INFO)(sym_bind, sym_type);
|
||||
sym->c = add_elf_sym(symtab_section, value, size, info, other, sh_num, name);
|
||||
} else {
|
||||
esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
|
||||
esym->st_value = value;
|
||||
esym->st_size = size;
|
||||
esym->st_shndx = sh_num;
|
||||
}
|
||||
}
|
||||
|
||||
ST_FUNC void put_extern_sym(Sym *sym, Section *section,
|
||||
addr_t value, unsigned long size)
|
||||
{
|
||||
put_extern_sym2(sym, section, value, size, 1);
|
||||
}
|
||||
|
||||
/* add a new relocation entry to symbol 'sym' in section 's' */
|
||||
ST_FUNC void greloca(Section *s, Sym *sym, unsigned long offset, int type,
|
||||
addr_t addend)
|
||||
{
|
||||
int c = 0;
|
||||
if (sym) {
|
||||
if (0 == sym->c)
|
||||
put_extern_sym(sym, NULL, 0, 0);
|
||||
c = sym->c;
|
||||
}
|
||||
/* now we can add ELF relocation info */
|
||||
put_elf_reloca(symtab_section, s, offset, type, c, addend);
|
||||
}
|
||||
|
||||
ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type)
|
||||
{
|
||||
greloca(s, sym, offset, type, 0);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* symbol allocator */
|
||||
static Sym *__sym_malloc(void)
|
||||
@ -6607,3 +6805,5 @@ ST_FUNC void decl(int l)
|
||||
{
|
||||
decl0(l, 0);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
Reference in New Issue
Block a user