Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/rtld/symbol.c

    rd2bb25e7 r9d58539  
    3939
    4040#include <elf/elf.h>
    41 #include <rtld/module.h>
    4241#include <rtld/rtld.h>
    4342#include <rtld/rtld_debug.h>
     
    115114 *                      that contains the symbol.
    116115 */
    117 elf_symbol_t *symbol_bfs_find(const char *name, module_t *start,
    118     module_t **mod)
     116elf_symbol_t *symbol_bfs_find(const char *name, module_t *start, module_t **mod)
    119117{
    120118        module_t *m, *dm;
     
    131129
    132130        /* Mark all vertices (modules) as unvisited */ 
    133         modules_untag(start->rtld);
     131        modules_untag();
    134132
    135133        /* Insert root (the program) into the queue and tag it */
     
    147145                list_remove(&m->queue_link);
    148146
    149                 /* If ssf_noroot is specified, do not look in start module */
    150147                s = def_find_in_module(name, m);
    151148                if (s != NULL) {
     
    182179
    183180
    184 /** Find the definition of a symbol.
     181/** Find the definition of a symbol..
    185182 *
    186183 * By definition in System V ABI, if module origin has the flag DT_SYMBOLIC,
    187  * origin is searched first. Otherwise, search global modules in the default
    188  * order.
     184 * origin is searched first. Otherwise, or if the symbol hasn't been found,
     185 * the module dependency graph is searched breadth-first, beginning
     186 * from the executable program.
    189187 *
    190188 * @param name          Name of the symbol to search for.
    191189 * @param origin        Module in which the dependency originates.
    192  * @param flags         @c ssf_none or @c ssf_noexec to not look for the symbol
    193  *                      in the executable program.
    194190 * @param mod           (output) Will be filled with a pointer to the module
    195191 *                      that contains the symbol.
    196192 */
    197 elf_symbol_t *symbol_def_find(const char *name, module_t *origin,
    198     symbol_search_flags_t flags, module_t **mod)
     193elf_symbol_t *symbol_def_find(const char *name, module_t *origin, module_t **mod)
    199194{
    200195        elf_symbol_t *s;
    201196
    202         DPRINTF("symbol_def_find('%s', origin='%s'\n",
    203             name, origin->dyn.soname);
    204         if (origin->dyn.symbolic && (!origin->exec || (flags & ssf_noexec) == 0)) {
    205                 DPRINTF("symbolic->find '%s' in module '%s'\n", name, origin->dyn.soname);
    206                 /*
     197        if (origin->dyn.symbolic) {
     198                /*
    207199                 * Origin module has a DT_SYMBOLIC flag.
    208200                 * Try this module first
    209201                 */
    210                 s = def_find_in_module(name, origin);
    211                 if (s != NULL) {
     202                 s = def_find_in_module(name, origin);
     203                 if (s != NULL) {
    212204                        /* Found */
    213205                        *mod = origin;
    214206                        return s;
    215                 }
     207                 }
    216208        }
    217209
    218210        /* Not DT_SYMBOLIC or no match. Now try other locations. */
    219211
    220         list_foreach(origin->rtld->modules, modules_link, module_t, m) {
    221                 DPRINTF("module '%s' local?\n", m->dyn.soname);
    222                 if (!m->local && (!m->exec || (flags & ssf_noexec) == 0)) {
    223                         DPRINTF("!local->find '%s' in module '%s'\n", name, m->dyn.soname);
    224                         s = def_find_in_module(name, m);
    225                         if (s != NULL) {
    226                                 /* Found */
    227                                 *mod = m;
    228                                 return s;
    229                         }
    230                 }
    231         }
    232 
    233         /* Finally, try origin. */
    234 
    235         DPRINTF("try finding '%s' in origin '%s'\n", name,
    236             origin->dyn.soname);
    237 
    238         if (!origin->exec || (flags & ssf_noexec) == 0) {
    239                 s = def_find_in_module(name, origin);
    240                 if (s != NULL) {
    241                         /* Found */
    242                         *mod = origin;
    243                         return s;
    244                 }
    245         }
    246 
    247         DPRINTF("'%s' not found\n", name);
    248         return NULL;
    249 }
    250 
    251 /** Get symbol address.
    252  *
    253  * @param sym Symbol
    254  * @param m Module contaning the symbol
    255  * @param tcb TCB of the thread whose thread-local variable instance should
    256  *            be returned. If @a tcb is @c NULL then @c NULL is returned for
    257  *            thread-local variables.
    258  *
    259  * @return Symbol address
    260  */
    261 void *symbol_get_addr(elf_symbol_t *sym, module_t *m, tcb_t *tcb)
    262 {
    263         if (ELF_ST_TYPE(sym->st_info) == STT_TLS) {
    264                 if (tcb == NULL)
    265                         return NULL;
    266                 return rtld_tls_get_addr(m->rtld, tcb, m->id, sym->st_value);
    267         } else if (sym->st_shndx == SHN_ABS) {
     212        if (runtime_env->program) {
     213                /* Program is dynamic -- start with program as root. */
     214                return symbol_bfs_find(name, runtime_env->program, mod);
     215        } else {
     216                /* Program is static -- start with @a origin as root. */
     217                return symbol_bfs_find(name, origin, mod);
     218        }
     219}
     220
     221void *symbol_get_addr(elf_symbol_t *sym, module_t *m)
     222{
     223        if (sym->st_shndx == SHN_ABS) {
    268224                /* Do not add bias to absolute symbols */
    269225                return (void *) sym->st_value;
Note: See TracChangeset for help on using the changeset viewer.