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 )