aboutsummaryrefslogtreecommitdiff
path: root/elf
diff options
context:
space:
mode:
Diffstat (limited to 'elf')
-rw-r--r--elf/dl-close.c1
-rw-r--r--elf/dl-iteratephdr.c4
-rw-r--r--elf/dl-support.c2
-rw-r--r--elf/link.h2
-rw-r--r--elf/rtld.c35
5 files changed, 26 insertions, 18 deletions
diff --git a/elf/dl-close.c b/elf/dl-close.c
index 519d3d316f..c7424c5ffb 100644
--- a/elf/dl-close.c
+++ b/elf/dl-close.c
@@ -319,7 +319,6 @@ _dl_close (void *_map)
/* Notify the debugger we are about to remove some loaded objects. */
_r_debug.r_state = RT_DELETE;
_dl_debug_state ();
- ++GL(dl_load_subs);
#ifdef USE_TLS
size_t tls_free_start;
diff --git a/elf/dl-iteratephdr.c b/elf/dl-iteratephdr.c
index a6df7f21e8..d615cd6312 100644
--- a/elf/dl-iteratephdr.c
+++ b/elf/dl-iteratephdr.c
@@ -49,7 +49,7 @@ __dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info,
info.dlpi_phdr = l->l_phdr;
info.dlpi_phnum = l->l_phnum;
info.dlpi_adds = GL(dl_load_adds);
- info.dlpi_subs = GL(dl_load_subs);
+ info.dlpi_subs = GL(dl_load_adds) - GL(dl_nloaded);
ret = callback (&info, sizeof (struct dl_phdr_info), data);
if (ret)
break;
@@ -87,7 +87,7 @@ dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info,
info.dlpi_phdr = _dl_phdr;
info.dlpi_phnum = _dl_phnum;
info.dlpi_adds = GL(dl_load_adds);
- info.dlpi_subs = GL(dl_load_subs);
+ info.dlpi_subs = GL(dl_load_adds) - GL(dl_nloaded);
ret = (*callback) (&info, sizeof (struct dl_phdr_info), data);
if (ret)
return ret;
diff --git a/elf/dl-support.c b/elf/dl-support.c
index 8e5c905566..aeebf3c5e2 100644
--- a/elf/dl-support.c
+++ b/elf/dl-support.c
@@ -73,8 +73,6 @@ unsigned int _dl_nloaded;
/* Incremented whenever something may have been added to dl_loaded. */
unsigned long long _dl_load_adds;
-/* Incremented whenever something may have been removed from dl_loaded. */
-unsigned long long _dl_load_subs;
/* Fake scope. In dynamically linked binaries this is the scope of the
main application but here we don't have something like this. So
diff --git a/elf/link.h b/elf/link.h
index f6d76bdf35..6d5ad9d98c 100644
--- a/elf/link.h
+++ b/elf/link.h
@@ -103,7 +103,7 @@ struct dl_phdr_info
/* Note: the next two members were introduced after the first
version of this structure was available. Check the SIZE
- argument pass to the dl_iterate_phdr() callback to determine
+ argument passed to the dl_iterate_phdr() callback to determine
whether or not they are provided. */
/* Incremented when a new object may have been added. */
diff --git a/elf/rtld.c b/elf/rtld.c
index 3a8ede8579..e0f9f28944 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -224,8 +224,6 @@ _dl_start_final (void *arg, struct dl_start_final_info *info)
memcpy (GL(dl_rtld_map).l_info, info->l.l_info,
sizeof GL(dl_rtld_map).l_info);
GL(dl_rtld_map).l_mach = info->l.l_mach;
- GL(dl_rtld_map).l_relro_addr = info->l.l_relro_addr;
- GL(dl_rtld_map).l_relro_size = info->l.l_relro_size;
#endif
_dl_setup_hash (&GL(dl_rtld_map));
GL(dl_rtld_map).l_opencount = 1;
@@ -351,17 +349,16 @@ _dl_start (void *arg)
on the `l_addr' value, which is not the value we want when prelinked. */
#if USE___THREAD
dtv_t initdtv[3];
-#endif /* USE___THREAD */
ElfW(Ehdr) *ehdr
# ifdef DONT_USE_BOOTSTRAP_MAP
= (ElfW(Ehdr) *) &_begin;
# else
+# error This will not work with prelink.
= (ElfW(Ehdr) *) bootstrap_map.l_addr;
# endif
ElfW(Phdr) *phdr = (ElfW(Phdr) *) ((void *) ehdr + ehdr->e_phoff);
size_t cnt = ehdr->e_phnum; /* PT_TLS is usually the last phdr. */
while (cnt-- > 0)
-#if USE___THREAD
if (phdr[cnt].p_type == PT_TLS)
{
void *tlsblock;
@@ -456,14 +453,11 @@ _dl_start (void *arg)
/* So far this is module number one. */
bootstrap_map.l_tls_modid = 1;
+
+ /* There can only be one PT_TLS entry. */
+ break;
}
- else
#endif /* USE___THREAD */
- if (phdr[cnt].p_type == PT_GNU_RELRO)
- {
- bootstrap_map.l_relro_addr = phdr[cnt].p_vaddr;
- bootstrap_map.l_relro_size = phdr[cnt].p_memsz;
- }
#ifdef ELF_MACHINE_BEFORE_RTLD_RELOC
ELF_MACHINE_BEFORE_RTLD_RELOC (bootstrap_map.l_info);
@@ -958,6 +952,11 @@ of this helper program; chances are you did not intend to run this program.\n\
case PT_GNU_STACK:
GL(dl_stack_flags) = ph->p_flags;
break;
+
+ case PT_GNU_RELRO:
+ GL(dl_loaded)->l_relro_addr = ph->p_vaddr;
+ GL(dl_loaded)->l_relro_size = ph->p_memsz;
+ break;
}
#ifdef USE_TLS
/* Adjust the address of the TLS initialization image in case
@@ -1020,6 +1019,7 @@ of this helper program; chances are you did not intend to run this program.\n\
GL(dl_loaded)->l_next = &GL(dl_rtld_map);
GL(dl_rtld_map).l_prev = GL(dl_loaded);
++GL(dl_nloaded);
+ ++GL(dl_load_adds);
/* If LD_USE_LOAD_BIAS env variable has not been seen, default
to not using bias for non-prelinked PIEs and libraries
@@ -1030,10 +1030,21 @@ of this helper program; chances are you did not intend to run this program.\n\
/* Set up the program header information for the dynamic linker
itself. It is needed in the dl_iterate_phdr() callbacks. */
ElfW(Ehdr) *rtld_ehdr = (ElfW(Ehdr) *) GL(dl_rtld_map).l_map_start;
- GL(dl_rtld_map).l_phdr = (ElfW(Phdr) *) (GL(dl_rtld_map).l_map_start
- + rtld_ehdr->e_phoff);
+ ElfW(Phdr) *rtld_phdr = (ElfW(Phdr) *) (GL(dl_rtld_map).l_map_start
+ + rtld_ehdr->e_phoff);
+ GL(dl_rtld_map).l_phdr = rtld_phdr;
GL(dl_rtld_map).l_phnum = rtld_ehdr->e_phnum;
+ /* PT_GNU_RELRO is usually the last phdr. */
+ size_t cnt = rtld_ehdr->e_phnum;
+ while (cnt-- > 0)
+ if (rtld_phdr[cnt].p_type == PT_GNU_RELRO)
+ {
+ GL(dl_rtld_map).l_relro_addr = rtld_phdr[cnt].p_vaddr;
+ GL(dl_rtld_map).l_relro_size = rtld_phdr[cnt].p_memsz;
+ break;
+ }
+
/* We have two ways to specify objects to preload: via environment
variable and via the file /etc/ld.so.preload. The latter can also
be used when security is enabled. */