Skip to content

Commit

Permalink
* sysdeps/generic/ldsodefs.h (rtld_global): Reorder some elements
Browse files Browse the repository at this point in the history
	to fill in holes
	(rtld_global_ro): Likewise.

	* elf/dl-addr.c (_dl_addr): Skip PT_LOAD checking if l_contiguous.
	Move PT_LOAD checking to...
	(_dl_addr_inside_object): ... here, new function.
	* elf/dl-sym.c (do_sym): If not l_contiguous,
	call _dl_addr_inside_object.
	* elf/dl-iteratephdr.c (__dl_iterate_phdr): Likewise.
	* dlfcn/dlinfo.c (dlinfo_doit): Likewise.
	* elf/dl-open.c (dl_open_worker): Likewise.
	(_dl_addr_inside_object): New function if IS_IN_rtld.
	* elf/dl-load.c (_dl_map_object_from_fd): Set l_contiguous if no
	holes are present or are PROT_NONE protected.
	* include/link.h (struct link_map): Add l_contiguous field.
	* sysdeps/generic/ldsodefs.h (_dl_addr_inside_object): New prototype.
  • Loading branch information
Jakub Jelinek committed Jul 7, 2007
1 parent 5daa061 commit a1ce84f
Show file tree
Hide file tree
Showing 9 changed files with 90 additions and 38 deletions.
22 changes: 22 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,25 @@
2007-06-19 Ulrich Drepper <drepper@redhat.com>

* sysdeps/generic/ldsodefs.h (rtld_global): Reorder some elements
to fill in holes
(rtld_global_ro): Likewise.

2007-06-18 Jakub Jelinek <jakub@redhat.com>

* elf/dl-addr.c (_dl_addr): Skip PT_LOAD checking if l_contiguous.
Move PT_LOAD checking to...
(_dl_addr_inside_object): ... here, new function.
* elf/dl-sym.c (do_sym): If not l_contiguous,
call _dl_addr_inside_object.
* elf/dl-iteratephdr.c (__dl_iterate_phdr): Likewise.
* dlfcn/dlinfo.c (dlinfo_doit): Likewise.
* elf/dl-open.c (dl_open_worker): Likewise.
(_dl_addr_inside_object): New function if IS_IN_rtld.
* elf/dl-load.c (_dl_map_object_from_fd): Set l_contiguous if no
holes are present or are PROT_NONE protected.
* include/link.h (struct link_map): Add l_contiguous field.
* sysdeps/generic/ldsodefs.h (_dl_addr_inside_object): New prototype.

2007-06-18 Jakub Jelinek <jakub@redhat.com>

* elf/rtld.c (dl_main): Don't call init_tls more than once.
Expand Down
5 changes: 2 additions & 3 deletions dlfcn/dlinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,8 @@ dlinfo_doit (void *argsblock)
/* Find the highest-addressed object that CALLER is not below. */
for (nsid = 0; nsid < DL_NNS; ++nsid)
for (l = GL(dl_ns)[nsid]._ns_loaded; l != NULL; l = l->l_next)
if (caller >= l->l_map_start && caller < l->l_map_end)
/* There must be exactly one DSO for the range of the virtual
memory. Otherwise something is really broken. */
if (caller >= l->l_map_start && caller < l->l_map_end
&& (l->l_contiguous || _dl_addr_inside_object (l, caller)))
break;

if (l == NULL)
Expand Down
36 changes: 21 additions & 15 deletions elf/dl-addr.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,22 +134,12 @@ _dl_addr (const void *address, Dl_info *info,
/* Find the highest-addressed object that ADDRESS is not below. */
for (Lmid_t ns = 0; ns < DL_NNS; ++ns)
for (struct link_map *l = GL(dl_ns)[ns]._ns_loaded; l; l = l->l_next)
if (addr >= l->l_map_start && addr < l->l_map_end)
if (addr >= l->l_map_start && addr < l->l_map_end
&& (l->l_contiguous || _dl_addr_inside_object (l, addr)))
{
/* Make sure it lies within one of L's segments. */
int n = l->l_phnum;
const ElfW(Addr) reladdr = addr - l->l_addr;
while (--n >= 0)
if (l->l_phdr[n].p_type == PT_LOAD)
{
if (reladdr - l->l_phdr[n].p_vaddr >= 0
&& reladdr - l->l_phdr[n].p_vaddr < l->l_phdr[n].p_memsz)
{
determine_info (addr, l, info, mapp, symbolp);
result = 1;
goto out;
}
}
determine_info (addr, l, info, mapp, symbolp);
result = 1;
goto out;
}

out:
Expand All @@ -158,3 +148,19 @@ _dl_addr (const void *address, Dl_info *info,
return result;
}
libc_hidden_def (_dl_addr)

/* Return non-zero if ADDR lies within one of L's segments. */
int
internal_function
_dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr)
{
int n = l->l_phnum;
const ElfW(Addr) reladdr = addr - l->l_addr;

while (--n >= 0)
if (l->l_phdr[n].p_type == PT_LOAD
&& reladdr - l->l_phdr[n].p_vaddr >= 0
&& reladdr - l->l_phdr[n].p_vaddr < l->l_phdr[n].p_memsz)
return 1;
return 0;
}
6 changes: 3 additions & 3 deletions elf/dl-iteratephdr.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ __dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info,
nloaded += GL(dl_ns)[cnt]._ns_nloaded;

if (caller >= (const void *) l->l_map_start
&& caller < (const void *) l->l_map_end)
/* There must be exactly one DSO for the range of the virtual
memory. Otherwise something is really broken. */
&& caller < (const void *) l->l_map_end
&& (l->l_contiguous
|| _dl_addr_inside_object (l, (ElfW(Addr)) caller)))
ns = cnt;
}

Expand Down
3 changes: 3 additions & 0 deletions elf/dl-load.c
Original file line number Diff line number Diff line change
Expand Up @@ -1223,6 +1223,8 @@ cannot allocate TLS data structures for initial thread");
loadcmds[nloadcmds - 1].mapstart - c->mapend,
PROT_NONE);

l->l_contiguous = 1;

goto postmap;
}

Expand All @@ -1242,6 +1244,7 @@ cannot allocate TLS data structures for initial thread");
/* Remember which part of the address space this object uses. */
l->l_map_start = c->mapstart + l->l_addr;
l->l_map_end = l->l_map_start + maplength;
l->l_contiguous = !has_holes;

while (c < &loadcmds[nloadcmds])
{
Expand Down
24 changes: 21 additions & 3 deletions elf/dl-open.c
Original file line number Diff line number Diff line change
Expand Up @@ -235,10 +235,10 @@ dl_open_worker (void *a)
for (Lmid_t ns = 0; ns < DL_NNS; ++ns)
for (l = GL(dl_ns)[ns]._ns_loaded; l != NULL; l = l->l_next)
if (caller_dlopen >= (const void *) l->l_map_start
&& caller_dlopen < (const void *) l->l_map_end)
&& caller_dlopen < (const void *) l->l_map_end
&& (l->l_contiguous
|| _dl_addr_inside_object (l, (ElfW(Addr)) caller_dlopen)))
{
/* There must be exactly one DSO for the range of the virtual
memory. Otherwise something is really broken. */
assert (ns == l->l_ns);
call_map = l;
goto found_caller;
Expand Down Expand Up @@ -689,3 +689,21 @@ show_scope (struct link_map *new)
}
}
#endif

#ifdef IS_IN_rtld
/* Return non-zero if ADDR lies within one of L's segments. */
int
internal_function
_dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr)
{
int n = l->l_phnum;
const ElfW(Addr) reladdr = addr - l->l_addr;

while (--n >= 0)
if (l->l_phdr[n].p_type == PT_LOAD
&& reladdr - l->l_phdr[n].p_vaddr >= 0
&& reladdr - l->l_phdr[n].p_vaddr < l->l_phdr[n].p_memsz)
return 1;
return 0;
}
#endif
5 changes: 2 additions & 3 deletions elf/dl-sym.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,9 @@ do_sym (void *handle, const char *name, void *who,
for (Lmid_t ns = 0; ns < DL_NNS; ++ns)
for (struct link_map *l = GL(dl_ns)[ns]._ns_loaded; l != NULL;
l = l->l_next)
if (caller >= l->l_map_start && caller < l->l_map_end)
if (caller >= l->l_map_start && caller < l->l_map_end
&& (l->l_contiguous || _dl_addr_inside_object (l, caller)))
{
/* There must be exactly one DSO for the range of the virtual
memory. Otherwise something is really broken. */
match = l;
break;
}
Expand Down
3 changes: 3 additions & 0 deletions include/link.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,9 @@ struct link_map
is interested in the PLT interception.*/
unsigned int l_removed:1; /* Nozero if the object cannot be used anymore
since it is removed. */
unsigned int l_contiguous:1; /* Nonzero if inter-segment holes are
mprotected or if no holes are present at
all. */

/* Collected information about own RPATH directories. */
struct r_search_path_struct l_rpath_dirs;
Expand Down
24 changes: 13 additions & 11 deletions sysdeps/generic/ldsodefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -438,18 +438,18 @@ struct rtld_global
EXTERN void (*_dl_rtld_unlock_recursive) (void *);
#endif

/* Prevailing state of the stack, PF_X indicating it's executable. */
EXTERN ElfW(Word) _dl_stack_flags;

/* If loading a shared object requires that we make the stack executable
when it was not, we do it by calling this function.
It returns an errno code or zero on success. */
EXTERN int (*_dl_make_stack_executable_hook) (void **) internal_function;

/* Highest dtv index currently needed. */
EXTERN size_t _dl_tls_max_dtv_idx;
/* Prevailing state of the stack, PF_X indicating it's executable. */
EXTERN ElfW(Word) _dl_stack_flags;

/* Flag signalling whether there are gaps in the module ID allocation. */
EXTERN bool _dl_tls_dtv_gaps;
/* Highest dtv index currently needed. */
EXTERN size_t _dl_tls_max_dtv_idx;
/* Information about the dtv slots. */
EXTERN struct dtv_slotinfo_list
{
Expand Down Expand Up @@ -539,15 +539,15 @@ struct rtld_global_ro
#define DL_DEBUG_HELP (1 << 9)
#define DL_DEBUG_PRELINK (1 << 10)

/* Cached value of `getpagesize ()'. */
EXTERN size_t _dl_pagesize;

/* OS version. */
EXTERN unsigned int _dl_osversion;
/* Platform name. */
EXTERN const char *_dl_platform;
EXTERN size_t _dl_platformlen;

/* Cached value of `getpagesize ()'. */
EXTERN size_t _dl_pagesize;

/* Copy of the content of `_dl_main_searchlist' at startup time. */
EXTERN struct r_scope_elem _dl_initial_searchlist;

Expand Down Expand Up @@ -576,9 +576,6 @@ struct rtld_global_ro
/* Expected cache ID. */
EXTERN int _dl_correct_cache_id;

/* 0 if internal pointer values should not be guarded, 1 if they should. */
EXTERN int _dl_pointer_guard;

/* Mask for hardware capabilities that are available. */
EXTERN uint64_t _dl_hwcap;

Expand Down Expand Up @@ -662,6 +659,9 @@ struct rtld_global_ro
/* List of auditing interfaces. */
struct audit_ifaces *_dl_audit;
unsigned int _dl_naudit;

/* 0 if internal pointer values should not be guarded, 1 if they should. */
EXTERN int _dl_pointer_guard;
};
# define __rtld_global_attribute__
# ifdef IS_IN_rtld
Expand Down Expand Up @@ -1069,6 +1069,8 @@ extern struct link_map *_dl_update_slotinfo (unsigned long int req_modid);
but never touch anything. Return null if it's not allocated yet. */
extern void *_dl_tls_get_addr_soft (struct link_map *l) internal_function;

extern int _dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr)
internal_function attribute_hidden;

__END_DECLS

Expand Down

0 comments on commit a1ce84f

Please sign in to comment.