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


Ignore:
Timestamp:
2016-05-02T19:49:51Z (9 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
32573ff, 9a08e6b
Parents:
634e020
Message:

Default symbol search vs. dlsym's BFS search.

Location:
uspace/lib/c/generic/rtld
Files:
3 edited

Legend:

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

    r634e020 r5035ba05  
    117117                }
    118118        }
    119        
     119
    120120        return NULL; /* Not found */
    121121}
     
    127127 * Currently this trivially tries to load '/<name>'.
    128128 */
    129 module_t *module_load(rtld_t *rtld, const char *name)
     129module_t *module_load(rtld_t *rtld, const char *name, mlflags_t flags)
    130130{
    131131        elf_finfo_t info;
     
    133133        module_t *m;
    134134        int rc;
    135        
    136         m = malloc(sizeof(module_t));
     135
     136        m = calloc(1, sizeof(module_t));
    137137        if (!m) {
    138138                printf("malloc failed\n");
     
    141141
    142142        m->rtld = rtld;
     143        if ((flags & mlf_local) != 0)
     144                m->local = true;
    143145
    144146        if (str_size(name) > NAME_BUF_SIZE - 2) {
     
    185187/** Load all modules on which m (transitively) depends.
    186188 */
    187 void module_load_deps(module_t *m)
     189void module_load_deps(module_t *m, mlflags_t flags)
    188190{
    189191        elf_dyn_t *dp;
     
    230232                        dm = module_find(m->rtld, dep_name);
    231233                        if (!dm) {
    232                                 dm = module_load(m->rtld, dep_name);
    233                                 module_load_deps(dm);
     234                                dm = module_load(m->rtld, dep_name, flags);
     235                                module_load_deps(dm, flags);
    234236                        }
    235237
  • uspace/lib/c/generic/rtld/rtld.c

    r634e020 r5035ba05  
    8080        prog_mod.dyn.soname = "[program]";
    8181        prog_mod.rtld = env;
     82        prog_mod.exec = true;
     83        prog_mod.local = false;
    8284
    8385        /* Initialize list of loaded modules */
     
    9698
    9799        DPRINTF("Load all program dependencies\n");
    98         module_load_deps(&prog_mod);
     100        module_load_deps(&prog_mod, 0);
    99101
    100102        /*
  • 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.