Ticket #658: r_i386_copy.patch

File r_i386_copy.patch, 5.0 KB (added by Jakub Jermář, 8 years ago)

Suggested fix

  • uspace/lib/c/arch/ia32/src/rtld/reloc.c

    === modified file 'uspace/lib/c/arch/ia32/src/rtld/reloc.c'
     
    7070        char *str_tab;
    7171       
    7272        elf_symbol_t *sym_def;
     73        module_t *src;
    7374        module_t *dest;
    7475
    7576        DPRINTF("parse relocation table\n");
     
    99100                if (sym->st_name != 0) {
    100101//                      DPRINTF("rel_type: %x, rel_offset: 0x%x\n", rel_type, r_offset);
    101102                        sym_def = symbol_def_find(str_tab + sym->st_name,
    102                             m, &dest);
     103                            m, &dest, NULL);
    103104//                      DPRINTF("dest name: '%s'\n", dest->dyn.soname);
    104105//                      DPRINTF("dest bias: 0x%x\n", dest->bias);
    105106                        if (sym_def) {
     
    138139                         * Copy symbol data from shared object to specified
    139140                         * location.
    140141                         */
    141                         DPRINTF("fixup R_386_COPY (s)\n");
    142142                        sym_size = sym->st_size;
    143143                        if (sym_size != sym_def->st_size) {
    144144                                printf("Warning: Mismatched symbol sizes.\n");
     
    146146                                if (sym_size > sym_def->st_size)
    147147                                        sym_size = sym_def->st_size;
    148148                        }
    149                         memcpy(r_ptr, (const void *)sym_addr, sym_size);
     149
     150                        /*
     151                         * Look for the source symbol definition in all other
     152                         * modules.
     153                         */
     154                        elf_symbol_t *sdef;
     155                        sdef = symbol_def_find(str_tab + sym->st_name, m, &src, m);
     156                        if (sdef) {
     157                                uint32_t saddr;
     158
     159                                saddr = (uint32_t) symbol_get_addr(sdef, src);
     160                                memcpy(r_ptr, (const void *) saddr, sym_size);
     161                        } else {
     162                                printf("Source definition of '%s' not found.\n",
     163                                    str_tab + sym->st_name);
     164                        }
     165
    150166                        break;
    151167                       
    152168                case R_386_RELATIVE:
  • uspace/lib/c/generic/dlfcn.c

    === modified file 'uspace/lib/c/generic/dlfcn.c'
     
    8080        module_t *sm;
    8181
    8282        printf("dlsym(0x%lx, \"%s\")\n", (long)mod, sym_name);
    83         sd = symbol_bfs_find(sym_name, (module_t *) mod, &sm);
     83        sd = symbol_bfs_find(sym_name, (module_t *) mod, &sm, NULL);
    8484        if (sd != NULL) {
    8585                return symbol_get_addr(sd, sm);
    8686        }
  • uspace/lib/c/generic/rtld/symbol.c

    === modified file 'uspace/lib/c/generic/rtld/symbol.c'
     
    112112 * @param start         Module in which to start the search..
    113113 * @param mod           (output) Will be filled with a pointer to the module
    114114 *                      that contains the symbol.
     115 * @param avoid         Module to exclude from the symbol search or NULL.
    115116 */
    116 elf_symbol_t *symbol_bfs_find(const char *name, module_t *start, module_t **mod)
     117elf_symbol_t *
     118symbol_bfs_find(const char *name, module_t *start, module_t **mod,
     119    module_t *avoid)
    117120{
    118121        module_t *m, *dm;
    119122        elf_symbol_t *sym, *s;
     
    144147                m = list_get_instance(list_first(&queue), module_t, queue_link);
    145148                list_remove(&m->queue_link);
    146149
    147                 s = def_find_in_module(name, m);
    148                 if (s != NULL) {
    149                         /* Symbol found */
    150                         sym = s;
    151                         *mod = m;
    152                         break;
     150                if (m != avoid) {
     151                        s = def_find_in_module(name, m);
     152                        if (s != NULL) {
     153                                /* Symbol found */
     154                                sym = s;
     155                                *mod = m;
     156                                break;
     157                        }
    153158                }
    154159
    155160                /*
     
    178183}
    179184
    180185
    181 /** Find the definition of a symbol..
     186/** Find the definition of a symbol.
    182187 *
    183188 * By definition in System V ABI, if module origin has the flag DT_SYMBOLIC,
    184189 * origin is searched first. Otherwise, or if the symbol hasn't been found,
     
    189194 * @param origin        Module in which the dependency originates.
    190195 * @param mod           (output) Will be filled with a pointer to the module
    191196 *                      that contains the symbol.
     197 * @param avoid         Module to exclude from the symbol search or NULL.
    192198 */
    193 elf_symbol_t *symbol_def_find(const char *name, module_t *origin, module_t **mod)
     199elf_symbol_t *
     200symbol_def_find(const char *name, module_t *origin, module_t **mod,
     201    module_t *avoid)
    194202{
    195203        elf_symbol_t *s;
    196204
    197         if (origin->dyn.symbolic) {
     205        if ((origin != avoid) && origin->dyn.symbolic) {
    198206                /*
    199207                 * Origin module has a DT_SYMBOLIC flag.
    200208                 * Try this module first
     
    211219
    212220        if (runtime_env->program) {
    213221                /* Program is dynamic -- start with program as root. */
    214                 return symbol_bfs_find(name, runtime_env->program, mod);
     222                return symbol_bfs_find(name, runtime_env->program, mod, avoid);
    215223        } else {
    216224                /* Program is static -- start with @a origin as root. */
    217                 return symbol_bfs_find(name, origin, mod);
     225                return symbol_bfs_find(name, origin, mod, avoid);
    218226        }
    219227}
    220228
  • uspace/lib/c/include/rtld/symbol.h

    === modified file 'uspace/lib/c/include/rtld/symbol.h'
     
    3838#include <elf/elf.h>
    3939#include <rtld/rtld.h>
    4040
    41 elf_symbol_t *symbol_bfs_find(const char *name, module_t *start, module_t **mod);
    42 elf_symbol_t *symbol_def_find(const char *name, module_t *origin, module_t **mod);
     41elf_symbol_t *symbol_bfs_find(const char *name, module_t *start, module_t **mod,
     42    module_t *avoid);
     43elf_symbol_t *symbol_def_find(const char *name, module_t *origin, module_t **mod,
     44    module_t *avoid);
    4345void *symbol_get_addr(elf_symbol_t *sym, module_t *m);
    4446
    4547#endif