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

Changeset 5035ba05 in mainline


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

Default symbol search vs. dlsym's BFS search.

Location:
uspace/lib/c
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/arch/ia32/src/rtld/reloc.c

    r634e020 r5035ba05  
    144144
    145145                        sym_def = symbol_def_find(str_tab + sym->st_name,
    146                             m, ssf_noroot, &dest);
     146                            m, ssf_noexec, &dest);
    147147
    148148                        if (sym_def) {
  • uspace/lib/c/generic/dlfcn.c

    r634e020 r5035ba05  
    6060        if (m == NULL) {
    6161                printf("NULL. module_load('%s')\n", path);
    62                 m = module_load(runtime_env, path);
     62                m = module_load(runtime_env, path, mlf_local);
    6363                printf("module_load_deps(m)\n");
    64                 module_load_deps(m);
     64                module_load_deps(m, mlf_local);
    6565                /* Now relocate. */
    6666                printf("module_process_relocs(m)\n");
     
    8282
    8383        printf("dlsym(0x%lx, \"%s\")\n", (long)mod, sym_name);
    84         sd = symbol_bfs_find(sym_name, (module_t *) mod, ssf_none, &sm);
     84        sd = symbol_bfs_find(sym_name, (module_t *) mod, &sm);
    8585        if (sd != NULL) {
    8686                return symbol_get_addr(sd, sm);
  • 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
  • uspace/lib/c/include/rtld/module.h

    r634e020 r5035ba05  
    4444extern void module_process_relocs(module_t *);
    4545extern module_t *module_find(rtld_t *, const char *);
    46 extern module_t *module_load(rtld_t *, const char *);
    47 extern void module_load_deps(module_t *);
     46extern module_t *module_load(rtld_t *, const char *, mlflags_t);
     47extern void module_load_deps(module_t *, mlflags_t);
    4848
    4949extern void modules_process_relocs(rtld_t *, module_t *);
  • uspace/lib/c/include/rtld/symbol.h

    r634e020 r5035ba05  
    4343        /** No flags */
    4444        ssf_none = 0,
    45         /** Do not search tree root */
    46         ssf_noroot = 0x1
     45        /** Do not search in the executable */
     46        ssf_noexec = 0x1
    4747} symbol_search_flags_t;
    4848
    49 extern elf_symbol_t *symbol_bfs_find(const char *, module_t *,
    50     symbol_search_flags_t, module_t **);
     49extern elf_symbol_t *symbol_bfs_find(const char *, module_t *, module_t **);
    5150extern elf_symbol_t *symbol_def_find(const char *, module_t *,
    5251    symbol_search_flags_t, module_t **);
  • uspace/lib/c/include/types/rtld/module.h

    r634e020 r5035ba05  
    3939#include <sys/types.h>
    4040
     41typedef enum {
     42        /** Do not export symbols to global namespace */
     43        mlf_local = 0x1
     44} mlflags_t;
     45
     46/** Dynamically linked module */
    4147typedef struct module {
    4248        dyn_info_t dyn;
     
    6066        /** Tag for modules already processed during a BFS */
    6167        bool bfs_tag;
     68        /** If @c true, does not export symbols to global namespace */
     69        bool local;
     70        /** This is the dynamically linked executable */
     71        bool exec;
    6272} module_t;
    6373
Note: See TracChangeset for help on using the changeset viewer.