Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 5035ba05 in mainline for uspace/lib/c/generic/rtld/symbol.c


Ignore:
Timestamp:
2016-05-02T19:49:51Z (5 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master
Children:
32573ff, 9a08e6b
Parents:
634e020
Message:

Default symbol search vs. dlsym's BFS search.

File:
1 edited

Legend:

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

    r634e020 r5035ba05  
    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
    116114 * @param mod           (output) Will be filled with a pointer to the module
    117115 *                      that contains the symbol.
    118116 */
    119117elf_symbol_t *symbol_bfs_find(const char *name, module_t *start,
    120     symbol_search_flags_t flags, module_t **mod)
     118    module_t **mod)
    121119{
    122120        module_t *m, *dm;
     
    150148
    151149                /* If ssf_noroot is specified, do not look in start module */
    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                         }
     150                s = def_find_in_module(name, m);
     151                if (s != NULL) {
     152                        /* Symbol found */
     153                        sym = s;
     154                        *mod = m;
     155                        break;
    160156                }
    161157
     
    189185 *
    190186 * By definition in System V ABI, if module origin has the flag DT_SYMBOLIC,
    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.
     187 * origin is searched first. Otherwise, search global modules in the default
     188 * order.
    194189 *
    195190 * @param name          Name of the symbol to search for.
    196191 * @param origin        Module in which the dependency originates.
    197  * @param flags         @c ssf_none or @c ssf_noroot to not look for the symbol
     192 * @param flags         @c ssf_none or @c ssf_noexec to not look for the symbol
    198193 *                      in the executable program.
    199194 * @param mod           (output) Will be filled with a pointer to the module
     
    205200        elf_symbol_t *s;
    206201
    207         if (origin->dyn.symbolic) {
    208                 /*
     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                /*
    209207                 * Origin module has a DT_SYMBOLIC flag.
    210208                 * Try this module first
    211209                 */
    212                  s = def_find_in_module(name, origin);
    213                  if (s != NULL) {
     210                s = def_find_in_module(name, origin);
     211                if (s != NULL) {
    214212                        /* Found */
    215213                        *mod = origin;
    216214                        return s;
    217                  }
     215                }
    218216        }
    219217
    220218        /* Not DT_SYMBOLIC or no match. Now try other locations. */
    221219
    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         }
     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;
    229249}
    230250
Note: See TracChangeset for help on using the changeset viewer.