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;
DL_CHECK_LIB_TYPE (epnt, piclib, _dl_progname, libname);
maxvma = (maxvma + ADDR_ALIGN) & PAGE_ALIGN;
- minvma = minvma & ~0xffffU;
+ minvma = minvma & ~ADDR_ALIGN;
flags = MAP_PRIVATE /*| MAP_DENYWRITE */ ;
if (!piclib)
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. */
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 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)
/* 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
INIT_GOT(lpnt, tpnt);
}
+#ifdef __DSBT__
+ /* Handle DSBT initialization */
+ {
+ struct elf_resolve *t, *ref = NULL;
+ int idx = tpnt->loadaddr.map->dsbt_index;
+ unsigned *dsbt = tpnt->loadaddr.map->dsbt_table;
+
+ if (idx == 0) {
+ /* This DSO has not been assigned an index */
+ _dl_dprintf(2, "%s: '%s' is missing a dsbt index assignment!\n",
+ _dl_progname, libname);
+ _dl_exit(1);
+ }
+
+ /*
+ * Setup dsbt slot for this module in dsbt of all modules.
+ */
+ 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 *));
+ }
+#endif
_dl_if_debug_dprint("\n\tfile='%s'; generating link map\n", libname);
_dl_if_debug_dprint("\t\tdynamic: %x base: %x\n", dynamic_addr, DL_LOADADDR_BASE(lib_loadaddr));
_dl_if_debug_dprint("\t\t entry: %x phdr: %x phnum: %x\n\n",
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);
}