]> rtime.felk.cvut.cz Git - l4.git/blobdiff - l4/pkg/uclibc/lib/contrib/uclibc/ldso/include/dl-elf.h
update
[l4.git] / l4 / pkg / uclibc / lib / contrib / uclibc / ldso / include / dl-elf.h
index 076678cfc461eb82235753db4bb6df8cb3822ad1..7fbb373b4fd5f93bb4e08fb62f6df29c7c55bb3b 100644 (file)
@@ -104,13 +104,15 @@ extern void _dl_protect_relro (struct elf_resolve *l);
 # define DT_GNU_HASH_IDX (DT_RELCONT_IDX + 1)
 #endif
 
-extern void _dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info[],
-                                   void *debug_addr, DL_LOADADDR_TYPE load_off);
+extern unsigned int _dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info[],
+                                           void *debug_addr, DL_LOADADDR_TYPE load_off);
 
 static __always_inline
-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)
 {
+       unsigned int rtld_flags = 0;
+
        for (; dpnt->d_tag; dpnt++) {
                if (dpnt->d_tag < DT_NUM) {
                        dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
@@ -138,9 +140,12 @@ void __dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info[],
                } else if (dpnt->d_tag < DT_LOPROC) {
                        if (dpnt->d_tag == DT_RELOCCOUNT)
                                dynamic_info[DT_RELCONT_IDX] = dpnt->d_un.d_val;
-                       if (dpnt->d_tag == DT_FLAGS_1 &&
-                           (dpnt->d_un.d_val & DF_1_NOW))
-                               dynamic_info[DT_BIND_NOW] = 1;
+                       if (dpnt->d_tag == DT_FLAGS_1) {
+                               if (dpnt->d_un.d_val & DF_1_NOW)
+                                       dynamic_info[DT_BIND_NOW] = 1;
+                               if (dpnt->d_un.d_val & DF_1_NODELETE)
+                                       rtld_flags |= RTLD_NODELETE;
+                       }
 #ifdef __LDSO_GNU_HASH_SUPPORT__
                        if (dpnt->d_tag == DT_GNU_HASH)
                                dynamic_info[DT_GNU_HASH_IDX] = dpnt->d_un.d_ptr;
@@ -157,16 +162,34 @@ void __dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info[],
                if (dynamic_info[tag]) \
                        dynamic_info[tag] = (unsigned long) DL_RELOC_ADDR(load_off, dynamic_info[tag]); \
        } while (0)
-       ADJUST_DYN_INFO(DT_HASH, load_off);
-       ADJUST_DYN_INFO(DT_PLTGOT, load_off);
-       ADJUST_DYN_INFO(DT_STRTAB, load_off);
-       ADJUST_DYN_INFO(DT_SYMTAB, load_off);
-       ADJUST_DYN_INFO(DT_RELOC_TABLE_ADDR, load_off);
-       ADJUST_DYN_INFO(DT_JMPREL, load_off);
+       /* Don't adjust .dynamic unnecessarily.  For FDPIC targets,
+          we'd have to walk all the loadsegs to find out if it was
+          actually unnecessary, so skip this optimization.  */
+#if !defined __FDPIC__ && !defined __DSBT__
+       if (load_off != 0)
+#endif
+       {
+               ADJUST_DYN_INFO(DT_HASH, load_off);
+               ADJUST_DYN_INFO(DT_PLTGOT, load_off);
+               ADJUST_DYN_INFO(DT_STRTAB, load_off);
+               ADJUST_DYN_INFO(DT_SYMTAB, load_off);
+               ADJUST_DYN_INFO(DT_RELOC_TABLE_ADDR, load_off);
+               ADJUST_DYN_INFO(DT_JMPREL, load_off);
 #ifdef __LDSO_GNU_HASH_SUPPORT__
-       ADJUST_DYN_INFO(DT_GNU_HASH_IDX, load_off);
+               ADJUST_DYN_INFO(DT_GNU_HASH_IDX, load_off);
+#endif
+       }
+#ifdef __DSBT__
+       /* Get the mapped address of the DSBT base.  */
+       ADJUST_DYN_INFO(DT_DSBT_BASE_IDX, load_off);
+
+       /* Initialize loadmap dsbt info.  */
+       load_off.map->dsbt_table = dynamic_info[DT_DSBT_BASE_IDX];
+       load_off.map->dsbt_size = dynamic_info[DT_DSBT_SIZE_IDX];
+       load_off.map->dsbt_index = dynamic_info[DT_DSBT_INDEX_IDX];
 #endif
 #undef ADJUST_DYN_INFO
+       return rtld_flags;
 }
 
 /* Reloc type classes as returned by elf_machine_type_class().