OSDN Git Service

ldso/mips: Fix relocation parsing so that they work on both mips32/mips64
[uclinux-h8/uClibc.git] / ldso / ldso / dl-elf.c
index 75e8f71..5562e07 100644 (file)
@@ -45,14 +45,14 @@ int _dl_map_cache(void)
        libentry_t *libent;
        int i, strtabsize;
 
-       if (_dl_cache_addr == (caddr_t) - 1)
+       if (_dl_cache_addr == MAP_FAILED)
                return -1;
        else if (_dl_cache_addr != NULL)
                return 0;
 
        if (_dl_stat(LDSO_CACHE, &st)
-           || (fd = _dl_open(LDSO_CACHE, O_RDONLY, 0)) < 0) {
-               _dl_cache_addr = (caddr_t) - 1; /* so we won't try again */
+           || (fd = _dl_open(LDSO_CACHE, O_RDONLY|O_CLOEXEC, 0)) < 0) {
+               _dl_cache_addr = MAP_FAILED;    /* so we won't try again */
                return -1;
        }
 
@@ -96,13 +96,13 @@ int _dl_map_cache(void)
 
 fail:
        _dl_munmap(_dl_cache_addr, _dl_cache_size);
-       _dl_cache_addr = (caddr_t) - 1;
+       _dl_cache_addr = MAP_FAILED;
        return -1;
 }
 
 int _dl_unmap_cache(void)
 {
-       if (_dl_cache_addr == NULL || _dl_cache_addr == (caddr_t) - 1)
+       if (_dl_cache_addr == NULL || _dl_cache_addr == MAP_FAILED)
                return -1;
 
 #if 1
@@ -264,7 +264,7 @@ struct elf_resolve *_dl_load_shared_library(int secure, struct dyn_elf **rpnt,
         * the hard coded paths that follow (i.e before /lib and /usr/lib).
         */
 #ifdef __LDSO_CACHE_SUPPORT__
-       if (_dl_cache_addr != NULL && _dl_cache_addr != (caddr_t) - 1) {
+       if (_dl_cache_addr != NULL && _dl_cache_addr != MAP_FAILED) {
                int i;
                header_t *header = (header_t *) _dl_cache_addr;
                libentry_t *libent = (libentry_t *) & header[1];
@@ -329,7 +329,7 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
        ElfW(Dyn) *dpnt;
        struct elf_resolve *tpnt;
        ElfW(Phdr) *ppnt;
-#if USE_TLS
+#if defined(USE_TLS) && USE_TLS
        ElfW(Phdr) *tlsppnt = NULL;
 #endif
        char *status, *header;
@@ -337,6 +337,7 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
        unsigned long *lpnt;
        unsigned long libaddr;
        unsigned long minvma = 0xffffffff, maxvma = 0;
+       unsigned int rtld_flags;
        int i, flags, piclib, infile;
        ElfW(Addr) relro_addr = 0;
        size_t relro_size = 0;
@@ -376,7 +377,7 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
                }
        }
        header = _dl_mmap((void *) 0, _dl_pagesize, PROT_READ | PROT_WRITE,
-                       MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+                       MAP_PRIVATE | MAP_ANONYMOUS | MAP_UNINITIALIZE, -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;
@@ -436,9 +437,8 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
                                maxvma = ppnt->p_vaddr + ppnt->p_memsz;
                        }
                }
-               if (ppnt->p_type == PT_TLS)
-               {
-#if USE_TLS
+               if (ppnt->p_type == PT_TLS) {
+#if defined(USE_TLS) && USE_TLS
                        if (ppnt->p_memsz == 0)
                                /* Nothing to do for an empty segment.  */
                                continue;
@@ -701,7 +701,7 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
 
        dpnt = (ElfW(Dyn) *) dynamic_addr;
        _dl_memset(dynamic_info, 0, sizeof(dynamic_info));
-       _dl_parse_dynamic_info(dpnt, dynamic_info, NULL, lib_loadaddr);
+       rtld_flags = _dl_parse_dynamic_info(dpnt, dynamic_info, NULL, lib_loadaddr);
        /* If the TEXTREL is set, this means that we need to make the pages
           writable before we perform relocations.  Do this now. They get set
           back again later. */
@@ -733,14 +733,14 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
        tpnt->st_ino = st.st_ino;
        tpnt->ppnt = (ElfW(Phdr) *) DL_RELOC_ADDR(tpnt->loadaddr, epnt->e_phoff);
        tpnt->n_phent = epnt->e_phnum;
+       tpnt->rtld_flags |= rtld_flags;
 
-#if USE_TLS
-       if (tlsppnt)
-       {
+#if defined(USE_TLS) && USE_TLS
+       if (tlsppnt) {
                _dl_debug_early("Found TLS header for %s\n", libname);
-#if NO_TLS_OFFSET != 0
+# if NO_TLS_OFFSET != 0
                tpnt->l_tls_offset = NO_TLS_OFFSET;
-#endif
+# endif
                tpnt->l_tls_blocksize = tlsppnt->p_memsz;
                tpnt->l_tls_align = tlsppnt->p_align;
                if (tlsppnt->p_align == 0)
@@ -757,10 +757,14 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
                /* We know the load address, so add it to the offset. */
                if (tpnt->l_tls_initimage != NULL)
                {
+# ifdef __SUPPORT_LD_DEBUG_EARLY__
                        unsigned int tmp = (unsigned int) 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;
+# else
+                       tpnt->l_tls_initimage = (char *) tlsppnt->p_vaddr + tpnt->loadaddr;
+# endif
                }
        }
 #endif
@@ -875,9 +879,9 @@ int _dl_fixup(struct dyn_elf *rpnt, int now_flag)
        }
 
 #if 0
-/* _dl_add_to_slotinfo is called by init_tls() for initial DSO 
+/* _dl_add_to_slotinfo is called by init_tls() for initial DSO
    or by dlopen() for dynamically loaded DSO. */
-#if USE_TLS
+#if defined(USE_TLS) && USE_TLS
        /* Add object to slot information data if necessasy. */
        if (tpnt->l_tls_blocksize != 0 && tls_init_tp_called)
                _dl_add_to_slotinfo ((struct link_map *) tpnt);
@@ -896,7 +900,7 @@ void _dl_dprintf(int fd, const char *fmt, ...)
 #endif
        va_list args;
        char *start, *ptr, *string;
-       static char *buf;
+       char *buf;
 
        if (!fmt)
                return;
@@ -989,8 +993,8 @@ char *_dl_strdup(const char *string)
        return retval;
 }
 
-void _dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info[],
-                            void *debug_addr, DL_LOADADDR_TYPE load_off)
+unsigned int _dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info[],
+                                    void *debug_addr, DL_LOADADDR_TYPE load_off)
 {
-       __dl_parse_dynamic_info(dpnt, dynamic_info, debug_addr, load_off);
+       return __dl_parse_dynamic_info(dpnt, dynamic_info, debug_addr, load_off);
 }