OSDN Git Service

ldso: silence warnings in debug code
[uclinux-h8/uClibc.git] / ldso / ldso / dl-elf.c
index b9de199..1b06bc1 100644 (file)
@@ -174,8 +174,11 @@ search_for_named_library(const char *name, unsigned rflags, const char *path_lis
                                _dl_strcpy(mylibname, "."); /* Assume current dir if empty path */
                        _dl_strcat(mylibname, "/");
                        _dl_strcat(mylibname, name);
-                       if ((tpnt = _dl_load_elf_shared_library(rflags, rpnt, mylibname)) != NULL)
-                               return tpnt;
+#ifdef __LDSO_SAFE_RUNPATH__
+                       if (*mylibname == '/')
+#endif
+                               if ((tpnt = _dl_load_elf_shared_library(rflags, rpnt, mylibname)) != NULL)
+                                       return tpnt;
                        path_n = path+1;
                }
                path++;
@@ -315,6 +318,9 @@ goof:
        return NULL;
 }
 
+/* Define the _dl_library_offset for the architectures that need it */
+DL_DEF_LIB_OFFSET;
+
 /*
  * Make a writeable mapping of a segment, regardless of whether PF_W is
  * set or not.
@@ -357,7 +363,7 @@ map_writeable (int infile, ElfW(Phdr) *ppnt, int piclib, int flags,
        }
 
        tryaddr = piclib == 2 ? piclib2map
-               : ((char*) (piclib ? libaddr : 0) +
+               : ((char *) (piclib ? libaddr : DL_GET_LIB_OFFSET()) +
                   (ppnt->p_vaddr & PAGE_ALIGN));
 
        size = (ppnt->p_vaddr & ADDR_ALIGN) + ppnt->p_filesz;
@@ -459,7 +465,7 @@ struct elf_resolve *_dl_load_elf_shared_library(unsigned rflags,
        size_t relro_size = 0;
        struct stat st;
        uint32_t *p32;
-       DL_LOADADDR_TYPE lib_loadaddr = 0;
+       DL_LOADADDR_TYPE lib_loadaddr;
        DL_INIT_LOADADDR_EXTRA_DECLS
 
        libaddr = 0;
@@ -497,7 +503,7 @@ struct elf_resolve *_dl_load_elf_shared_library(unsigned rflags,
                return NULL;
        }
        header = _dl_mmap((void *) 0, _dl_pagesize, PROT_READ | PROT_WRITE,
-                       MAP_PRIVATE | MAP_ANONYMOUS | MAP_UNINITIALIZE, -1, 0);
+                       MAP_PRIVATE | MAP_ANONYMOUS | MAP_UNINITIALIZED, -1, 0);
        if (_dl_mmap_check_error(header)) {
                _dl_dprintf(2, "%s:%i: can't map '%s'\n", _dl_progname, __LINE__, libname);
                _dl_internal_error_number = LD_ERROR_MMAP_FAILED;
@@ -617,6 +623,8 @@ struct elf_resolve *_dl_load_elf_shared_library(unsigned rflags,
        ppnt = (ElfW(Phdr) *)(intptr_t) & header[epnt->e_phoff];
 
        DL_INIT_LOADADDR(lib_loadaddr, libaddr - minvma, ppnt, epnt->e_phnum);
+       /* Set _dl_library_offset to lib_loadaddr or 0. */
+       DL_SET_LIB_OFFSET(lib_loadaddr);
 
        for (i = 0; i < epnt->e_phnum; i++) {
                if (DL_IS_SPECIAL_SEGMENT (epnt, ppnt)) {
@@ -648,7 +656,7 @@ struct elf_resolve *_dl_load_elf_shared_library(unsigned rflags,
                        } else {
                                tryaddr = (piclib == 2 ? 0
                                           : (char *) (ppnt->p_vaddr & PAGE_ALIGN)
-                                          + (piclib ? libaddr : lib_loadaddr));
+                                          + (piclib ? libaddr : DL_GET_LIB_OFFSET()));
                                size = (ppnt->p_vaddr & ADDR_ALIGN) + ppnt->p_filesz;
                                status = (char *) _dl_mmap
                                           (tryaddr, size, LXFLAGS(ppnt->p_flags),
@@ -675,7 +683,11 @@ struct elf_resolve *_dl_load_elf_shared_library(unsigned rflags,
         * The dynamic_addr must be take into acount lib_loadaddr value, to note
         * it is zero when the SO has been mapped to the elf's physical addr
         */
-       if (lib_loadaddr) {
+#ifdef __LDSO_PRELINK_SUPPORT__
+       if (DL_GET_LIB_OFFSET()) {
+#else
+       if (piclib) {
+#endif
                dynamic_addr = (unsigned long) DL_RELOC_ADDR(lib_loadaddr, dynamic_addr);
        }
 
@@ -708,7 +720,7 @@ struct elf_resolve *_dl_load_elf_shared_library(unsigned rflags,
                for (i = 0; i < epnt->e_phnum; i++, ppnt++) {
                        if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W)) {
 #ifdef __ARCH_USE_MMU__
-                               _dl_mprotect((void *) ((piclib ? libaddr : lib_loadaddr) +
+                               _dl_mprotect((void *) ((piclib ? libaddr : DL_GET_LIB_OFFSET()) +
                                                        (ppnt->p_vaddr & PAGE_ALIGN)),
                                                (ppnt->p_vaddr & ADDR_ALIGN) + (unsigned long) ppnt->p_filesz,
                                                PROT_READ | PROT_WRITE | PROT_EXEC);
@@ -730,7 +742,7 @@ struct elf_resolve *_dl_load_elf_shared_library(unsigned rflags,
                        }
                }
 #else
-               _dl_dprintf(_dl_debug_file, "Can't modify %s's text section."
+               _dl_dprintf(2, "Can't modify %s's text section."
                        " Use GCC option -fPIC for shared objects, please.\n",
                        libname);
                _dl_exit(1);
@@ -746,7 +758,9 @@ struct elf_resolve *_dl_load_elf_shared_library(unsigned rflags,
        tpnt->relro_size = relro_size;
        tpnt->st_dev = st.st_dev;
        tpnt->st_ino = st.st_ino;
-       tpnt->ppnt = (ElfW(Phdr) *) DL_RELOC_ADDR(tpnt->mapaddr, epnt->e_phoff);
+       tpnt->ppnt = (ElfW(Phdr) *)
+               DL_RELOC_ADDR(DL_GET_RUN_ADDR(tpnt->loadaddr, tpnt->mapaddr),
+               epnt->e_phoff);
        tpnt->n_phent = epnt->e_phnum;
        tpnt->rtld_flags |= rtld_flags;
 #ifdef __LDSO_STANDALONE_SUPPORT__
@@ -780,7 +794,7 @@ struct elf_resolve *_dl_load_elf_shared_library(unsigned rflags,
 #endif
                {
 # ifdef __SUPPORT_LD_DEBUG_EARLY__
-                       unsigned int tmp = (unsigned int) tpnt->l_tls_initimage;
+                       char *tmp = (char *) tpnt->l_tls_initimage;
                        tpnt->l_tls_initimage = (char *) tlsppnt->p_vaddr + tpnt->loadaddr;
                        _dl_debug_early("Relocated TLS initial image from %x to %x (size = %x)\n", tmp, tpnt->l_tls_initimage, tpnt->l_tls_initimage_size);
                        tmp = 0;
@@ -840,10 +854,15 @@ struct elf_resolve *_dl_load_elf_shared_library(unsigned rflags,
        /* Handle DSBT initialization */
        {
                struct elf_resolve *t, *ref;
-               int idx = tpnt->loadaddr.map->dsbt_index;
-               unsigned *dsbt = tpnt->loadaddr.map->dsbt_table;
+               int idx = tpnt->dsbt_index;
+               void **dsbt = tpnt->dsbt_table;
 
-               if (idx == 0) {
+               /*
+                * It is okay (required actually) to have zero idx for an executable.
+                * This is the case when running ldso standalone and the program
+                * is being mapped in via _dl_load_shared_library().
+                */
+               if (idx == 0 && tpnt->libtype != elf_executable) {
                        if (!dynamic_info[DT_TEXTREL]) {
                                /* This DSO has not been assigned an index. */
                                _dl_dprintf(2, "%s: '%s' is missing a dsbt index assignment!\n",
@@ -858,9 +877,9 @@ struct elf_resolve *_dl_load_elf_shared_library(unsigned rflags,
                                        break;
                                }
                        }
-                       idx = tpnt->loadaddr.map->dsbt_size;
+                       idx = tpnt->dsbt_size;
                        while (idx-- > 0)
-                               if (!ref || ref->loadaddr.map->dsbt_table[idx] == NULL)
+                               if (!ref || ref->dsbt_table[idx] == NULL)
                                        break;
                        if (idx <= 0) {
                                _dl_dprintf(2, "%s: '%s' caused DSBT table overflow!\n",
@@ -869,43 +888,36 @@ struct elf_resolve *_dl_load_elf_shared_library(unsigned rflags,
                        }
                        _dl_if_debug_dprint("\n\tfile='%s';  assigned index %d\n",
                                            libname, idx);
-                       tpnt->loadaddr.map->dsbt_index = idx;
+                       tpnt->dsbt_index = idx;
+               }
+
+               /* make sure index is not already used */
+               if (_dl_ldso_dsbt[idx]) {
+                       struct elf_resolve *dup;
+                       const char *dup_name;
 
+                       for (dup = _dl_loaded_modules; dup; dup = dup->next)
+                               if (dup != tpnt && dup->dsbt_index == idx)
+                                       break;
+                       if (dup)
+                               dup_name = dup->libname;
+                       else if (idx == 1)
+                               dup_name = "runtime linker";
+                       else
+                               dup_name = "unknown library";
+                       _dl_dprintf(2, "%s: '%s' dsbt index %d already used by %s!\n",
+                                   _dl_progname, libname, idx, dup_name);
+                       _dl_exit(1);
                }
 
                /*
                 * Setup dsbt slot for this module in dsbt of all modules.
                 */
-               ref = NULL;
-               for (t = _dl_loaded_modules; t; t = t->next) {
-                       /* find a dsbt table from another module */
-                       if (ref == NULL && t != tpnt) {
-                               ref = t;
-
-                               /* make sure index is not already used */
-                               if (t->loadaddr.map->dsbt_table[idx]) {
-                                       struct elf_resolve *dup;
-                                       char *dup_name;
-
-                                       for (dup = _dl_loaded_modules; dup; dup = dup->next)
-                                               if (dup != tpnt && dup->loadaddr.map->dsbt_index == idx)
-                                                       break;
-                                       if (dup)
-                                               dup_name = dup->libname;
-                                       else if (idx == 1)
-                                               dup_name = "runtime linker";
-                                       else
-                                               dup_name = "unknown library";
-                                       _dl_dprintf(2, "%s: '%s' dsbt index %d already used by %s!\n",
-                                                   _dl_progname, libname, idx, dup_name);
-                                       _dl_exit(1);
-                               }
-                       }
-                       t->loadaddr.map->dsbt_table[idx] = (unsigned)dsbt;
-               }
-               if (ref)
-                       _dl_memcpy(dsbt, ref->loadaddr.map->dsbt_table,
-                                  tpnt->loadaddr.map->dsbt_size * sizeof(unsigned *));
+               for (t = _dl_loaded_modules; t; t = t->next)
+                       t->dsbt_table[idx] = dsbt;
+               _dl_ldso_dsbt[idx] = dsbt;
+               _dl_memcpy(dsbt, _dl_ldso_dsbt,
+                          tpnt->dsbt_size * sizeof(tpnt->dsbt_table[0]));
        }
 #endif
        _dl_if_debug_dprint("\n\tfile='%s';  generating link map\n", libname);
@@ -954,11 +966,9 @@ int _dl_fixup(struct dyn_elf *rpnt, struct r_scope_elem *scope, int now_flag)
                relative_count = tpnt->dynamic_info[DT_RELCONT_IDX];
                if (relative_count) { /* Optimize the XX_RELATIVE relocations if possible */
                        reloc_size -= relative_count * sizeof(ELF_RELOC);
-                       if (tpnt->loadaddr
 #ifdef __LDSO_PRELINK_SUPPORT__
-                               || (!tpnt->dynamic_info[DT_GNU_PRELINKED_IDX])
+                       if (tpnt->loadaddr || (!tpnt->dynamic_info[DT_GNU_PRELINKED_IDX]))
 #endif
-                               )
                                elf_machine_relative(tpnt->loadaddr, reloc_addr, relative_count);
                        reloc_addr += relative_count * sizeof(ELF_RELOC);
                }
@@ -997,6 +1007,7 @@ int _dl_fixup(struct dyn_elf *rpnt, struct r_scope_elem *scope, int now_flag)
        return goof;
 }
 
+#ifdef IS_IN_rtld
 /* Minimal printf which handles only %s, %d, and %x */
 void _dl_dprintf(int fd, const char *fmt, ...)
 {
@@ -1062,7 +1073,7 @@ void _dl_dprintf(int fd, const char *fmt, ...)
                                                break;
                                        }
                                case 'x':
-                               case 'X':
+                               case 'p':
                                        {
                                                char tmp[22];
 #if __WORDSIZE > 32
@@ -1099,6 +1110,7 @@ char *_dl_strdup(const char *string)
        _dl_strcpy(retval, string);
        return retval;
 }
+#endif
 
 unsigned int _dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info[],
                                     void *debug_addr, DL_LOADADDR_TYPE load_off)