Alien-TinyCCx
view release on metacpan or search on metacpan
src/tccexsymtab.c view on Meta::CPAN
name = s->link->data + sym->st_name;
while (strcmp("_etext", name) != 0) {
if (name[0] == 'L' && name[1] == '.') {
/* Skip constants */
}
else {
/* Copy the symbol's pointer into the hash_next field of the TokenSym */
TokenSym * ts = tcc_get_extended_tokensym(exsymtab, name);
if (ts == NULL) {
tcc_warning("Global symbol %s does not exist in extended symbol table; not copying\n",
name);
}
else {
ts->hash_next = (void*)sym->st_value;
}
}
/* Next iteration */
sym_index++;
sym = &((ElfW(Sym) *)s->data)[sym_index];
name = s->link->data + sym->st_name;
}
}
/* A value of NULL for exsymtab means that the extended symtab was not supposed
* to be generated in the first place. A value of 1 means that it is supposed to
* be created, but the state hasn't compiled yet. Otherwise, we have a fully
* formed extended symbol table, which we can return. In that case, we assume
* that the user takes responsibility for cleaning it up. */
LIBTCCAPI extended_symtab * tcc_get_extended_symbol_table(TCCState * s)
{
extended_symtab * to_return;
if (s->exsymtab <= (extended_symtab*)1) return NULL;
/* clear the pointer value; otherwise we would free it, leading to a
* double-free situation when the user also frees it. */
to_return = s->exsymtab;
s->exsymtab = (extended_symtab*)1;
return to_return;
}
LIBTCCAPI TokenSym* tcc_get_extended_tokensym(extended_symtab* symtab, const char * name)
{
/* delegate to the symtab's trie */
return (TokenSym*)(*token_string_hash_get_ref(symtab->tsh, name));
}
LIBTCCAPI void * tcc_get_extended_symbol(extended_symtab * symtab, const char * name)
{
TokenSym * ts = tcc_get_extended_tokensym(symtab, name);
if (ts == NULL) return NULL;
return (void*) ts->hash_next;
}
/******************************************************************************/
/* extended symtab copy */
/******************************************************************************/
/* The user may want fine-grained control over the order of symbol table lookup.
* Thus, I provide a set of callbacks to look for names, add symbols to compiler
* contexts, and prep the compiler state before things get started. */
LIBTCCAPI void tcc_set_extended_symtab_callbacks (
TCCState * s,
extended_symtab_lookup_by_name_callback new_name_callback,
extended_symtab_sym_used_callback new_sym_used_callback,
extended_symtab_prep_callback new_prep_callback,
void * data
) {
s->symtab_name_callback = new_name_callback;
s->symtab_sym_used_callback = new_sym_used_callback;
s->symtab_prep_callback = new_prep_callback;
s->symtab_callback_data = data;
}
LIBTCCAPI void tcc_save_extended_symtab(TCCState * s) {
if (s->exsymtab == NULL) s->exsymtab = (extended_symtab*)1;
}
Sym * get_new_symtab_pointer (Sym * old, ram_hash * rh)
{
void ** Sym_ref;
Sym * to_return;
int btype;
/* Handle the null case up-front */
if (old == NULL) return NULL;
/* Check the global symbol stack. */
Sym_ref = ram_hash_get_ref(rh, old);
to_return = *Sym_ref;
if (NULL != to_return) return to_return;
/* Create new sym. Note that mallocz sets lots of things to null
* for me. :-) */
to_return = *Sym_ref = tcc_mallocz(sizeof(Sym));
/* See tcc.h around line 425 for descriptions of some of the fields.
* See also tccgen.c line 5987 to see what needs to happen for function
* declarations to work properly (and, in turn, line 446 for how to
* push a forward reference). */
/* Copy the v value (token id). This will not be copied later, so keep
* things simple for now and simply strip out the extended flag. */
to_return->v = old->v & ~SYM_EXTENDED;
/* Copy the assembler label token id. Just like the v field, we copy
* this unmodified. */
/* XXX do we need to strip out SYM_EXTENDED? It seems unlikely. */
to_return->asm_label = old->asm_label;
/* associated register. For variables, I believe that the low bits
* specify the register size that can hold the value while high bits
* indicate storage details (VT_SYM, VT_LVAL, etc). For function types,
* however, this gets cast as an AttributeDef and queried for function
* attributes; so far, I have only seen the .r field queried for the
* FUNC_CALL field. It matters little; copying the whole long is easy
* and it seems that everything works fine when it is the same for
* consuming contexts as for the original compilation context. */
to_return->r = old->r;
/* Set the type. Judging by the constants in tcc.h and code that
* uses this field, I'm pretty sure that the low bits in the .t field
( run in 0.587 second using v1.01-cache-2.11-cpan-d7f47b0818f )