Ignore:
File:
1 edited

Legend:

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

    r5035ba05 r17341d4  
    112112 * @param name          Name of the symbol to search for.
    113113 * @param start         Module in which to start the search..
     114 * @param flags         @c ssf_none or @c ssf_noroot to not look for the symbol
     115 *                      in @a start
    114116 * @param mod           (output) Will be filled with a pointer to the module
    115117 *                      that contains the symbol.
    116118 */
    117119elf_symbol_t *symbol_bfs_find(const char *name, module_t *start,
    118     module_t **mod)
     120    symbol_search_flags_t flags, module_t **mod)
    119121{
    120122        module_t *m, *dm;
     
    148150
    149151                /* If ssf_noroot is specified, do not look in start module */
    150                 s = def_find_in_module(name, m);
    151                 if (s != NULL) {
    152                         /* Symbol found */
    153                         sym = s;
    154                         *mod = m;
    155                         break;
     152                if (m != start || (flags & ssf_noroot) == 0) {
     153                        s = def_find_in_module(name, m);
     154                        if (s != NULL) {
     155                                /* Symbol found */
     156                                sym = s;
     157                                *mod = m;
     158                                break;
     159                        }
    156160                }
    157161
     
    185189 *
    186190 * 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.
     191 * origin is searched first. Otherwise, or if the symbol hasn't been found,
     192 * the module dependency graph is searched breadth-first, beginning
     193 * from the executable program.
    189194 *
    190195 * @param name          Name of the symbol to search for.
    191196 * @param origin        Module in which the dependency originates.
    192  * @param flags         @c ssf_none or @c ssf_noexec to not look for the symbol
     197 * @param flags         @c ssf_none or @c ssf_noroot to not look for the symbol
    193198 *                      in the executable program.
    194199 * @param mod           (output) Will be filled with a pointer to the module
     
    200205        elf_symbol_t *s;
    201206
    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                 /*
     207        if (origin->dyn.symbolic) {
     208                /*
    207209                 * Origin module has a DT_SYMBOLIC flag.
    208210                 * Try this module first
    209211                 */
    210                 s = def_find_in_module(name, origin);
    211                 if (s != NULL) {
     212                 s = def_find_in_module(name, origin);
     213                 if (s != NULL) {
    212214                        /* Found */
    213215                        *mod = origin;
    214216                        return s;
    215                 }
     217                 }
    216218        }
    217219
    218220        /* Not DT_SYMBOLIC or no match. Now try other locations. */
    219221
    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;
     222        if (origin->rtld->program) {
     223                /* Program is dynamic -- start with program as root. */
     224                return symbol_bfs_find(name, origin->rtld->program, flags, mod);
     225        } else {
     226                /* Program is static -- start with @a origin as root. */
     227                return symbol_bfs_find(name, origin, ssf_none, mod);
     228        }
    249229}
    250230
Note: See TracChangeset for help on using the changeset viewer.