From 0d23a5c1b1908700d25b7e3c6cece148e19dded4 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Fri, 31 Jan 2014 17:51:31 +0000 Subject: [BZ #16046] Static dlopen correction fallout fixes. Fixes to address issues from BZ #15022 resolution, as follows: * TLS updates to csu/libc-tls.c -- we now have a proper main map, so there's no longer a need to create a separate fake one to keep TLS structures, * random updates to elf/dl-close.c -- LM_ID_BASE is now a valid name space ID for static executables as well, so assert that we don't unload the main map. Similarly dl_nns isn't supposed to be 0 for static executables anymore, * actual BZ #16046 fix to elf/dl-iteratephdr.c -- the dl_iterate_phdr special function for static executables isn't needed anymore, provided that l_phdr and l_phnum members of the main map have been properly initialized (done in _dl_non_dynamic_init in elf/dl-support.c now), * ld.so.cache loader update to elf/dl-load.c -- GL(dl_ns)[LM_ID_BASE]._ns_loaded is now always initialized in static executables so can become the fallback loader map to check for DF_1_NODEFLIB, provided that the l_flags_1 member of the main map has been properly initialized (done in elf/dl-support.c now); this also ensures previous semantics elsewhere in elf/dl-load.c, * matching updates to elf/dl-support.c -- to complement the two fixes above. --- csu/libc-tls.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) (limited to 'csu/libc-tls.c') diff --git a/csu/libc-tls.c b/csu/libc-tls.c index 5aec47d54c..c18b888b31 100644 --- a/csu/libc-tls.c +++ b/csu/libc-tls.c @@ -42,9 +42,6 @@ static struct struct dtv_slotinfo info[2 + TLS_SLOTINFO_SURPLUS]; } static_slotinfo; -/* Fake link map for the application. */ -static struct link_map static_map; - /* Highest dtv index currently needed. */ size_t _dl_tls_max_dtv_idx; @@ -162,14 +159,16 @@ __libc_setup_tls (size_t tcbsize, size_t tcbalign) _dl_static_dtv[0].counter = (sizeof (_dl_static_dtv) / sizeof (_dl_static_dtv[0])) - 2; // _dl_static_dtv[1].counter = 0; would be needed if not already done + struct link_map *main_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded; + /* Initialize the TLS block. */ #if TLS_TCB_AT_TP _dl_static_dtv[2].pointer.val = ((char *) tlsblock + tcb_offset - roundup (memsz, align ?: 1)); - static_map.l_tls_offset = roundup (memsz, align ?: 1); + main_map->l_tls_offset = roundup (memsz, align ?: 1); #elif TLS_DTV_AT_TP _dl_static_dtv[2].pointer.val = (char *) tlsblock + tcb_offset; - static_map.l_tls_offset = tcb_offset; + main_map->l_tls_offset = tcb_offset; #else # error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined" #endif @@ -193,19 +192,17 @@ __libc_setup_tls (size_t tcbsize, size_t tcbalign) if (__builtin_expect (lossage != NULL, 0)) __libc_fatal (lossage); - /* We have to create a fake link map which normally would be created - by the dynamic linker. It just has to have enough information to - make the TLS routines happy. */ - static_map.l_tls_align = align; - static_map.l_tls_blocksize = memsz; - static_map.l_tls_initimage = initimage; - static_map.l_tls_initimage_size = filesz; - static_map.l_type = lt_executable; - static_map.l_tls_modid = 1; + /* Update the executable's link map with enough information to make + the TLS routines happy. */ + main_map->l_tls_align = align; + main_map->l_tls_blocksize = memsz; + main_map->l_tls_initimage = initimage; + main_map->l_tls_initimage_size = filesz; + main_map->l_tls_modid = 1; init_slotinfo (); // static_slotinfo.si.slotinfo[1].gen = 0; already zero - static_slotinfo.si.slotinfo[1].map = &static_map; + static_slotinfo.si.slotinfo[1].map = main_map; memsz = roundup (memsz, align ?: 1); -- cgit v1.2.3