mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-30 22:43:12 +03:00
* 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.
This commit is contained in:
22
ChangeLog
22
ChangeLog
@ -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>
|
2007-06-18 Jakub Jelinek <jakub@redhat.com>
|
||||||
Tomas Janousek <tjanouse@redhat.com>
|
Tomas Janousek <tjanouse@redhat.com>
|
||||||
Ulrich Drepper <drepper@redhat.com>
|
Ulrich Drepper <drepper@redhat.com>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* dlinfo -- Get information from the dynamic linker.
|
/* dlinfo -- Get information from the dynamic linker.
|
||||||
Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
|
Copyright (C) 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it and/or
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
@ -56,9 +56,8 @@ dlinfo_doit (void *argsblock)
|
|||||||
/* Find the highest-addressed object that CALLER is not below. */
|
/* Find the highest-addressed object that CALLER is not below. */
|
||||||
for (nsid = 0; nsid < DL_NNS; ++nsid)
|
for (nsid = 0; nsid < DL_NNS; ++nsid)
|
||||||
for (l = GL(dl_ns)[nsid]._ns_loaded; l != NULL; l = l->l_next)
|
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)
|
if (caller >= l->l_map_start && caller < l->l_map_end
|
||||||
/* There must be exactly one DSO for the range of the virtual
|
&& (l->l_contiguous || _dl_addr_inside_object (l, caller)))
|
||||||
memory. Otherwise something is really broken. */
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (l == NULL)
|
if (l == NULL)
|
||||||
|
@ -134,22 +134,12 @@ _dl_addr (const void *address, Dl_info *info,
|
|||||||
/* Find the highest-addressed object that ADDRESS is not below. */
|
/* Find the highest-addressed object that ADDRESS is not below. */
|
||||||
for (Lmid_t ns = 0; ns < DL_NNS; ++ns)
|
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)
|
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. */
|
determine_info (addr, l, info, mapp, symbolp);
|
||||||
int n = l->l_phnum;
|
result = 1;
|
||||||
const ElfW(Addr) reladdr = addr - l->l_addr;
|
goto out;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
@ -158,3 +148,19 @@ _dl_addr (const void *address, Dl_info *info,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
libc_hidden_def (_dl_addr)
|
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;
|
||||||
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* Get loaded objects program headers.
|
/* Get loaded objects program headers.
|
||||||
Copyright (C) 2001,2002,2003,2004,2006 Free Software Foundation, Inc.
|
Copyright (C) 2001,2002,2003,2004,2006,2007 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
Contributed by Jakub Jelinek <jakub@redhat.com>, 2001.
|
Contributed by Jakub Jelinek <jakub@redhat.com>, 2001.
|
||||||
|
|
||||||
@ -54,9 +54,9 @@ __dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info,
|
|||||||
nloaded += GL(dl_ns)[cnt]._ns_nloaded;
|
nloaded += GL(dl_ns)[cnt]._ns_nloaded;
|
||||||
|
|
||||||
if (caller >= (const void *) l->l_map_start
|
if (caller >= (const void *) l->l_map_start
|
||||||
&& caller < (const void *) l->l_map_end)
|
&& caller < (const void *) l->l_map_end
|
||||||
/* There must be exactly one DSO for the range of the virtual
|
&& (l->l_contiguous
|
||||||
memory. Otherwise something is really broken. */
|
|| _dl_addr_inside_object (l, (ElfW(Addr)) caller)))
|
||||||
ns = cnt;
|
ns = cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* Map in a shared object's segments from the file.
|
/* Map in a shared object's segments from the file.
|
||||||
Copyright (C) 1995-2005, 2006 Free Software Foundation, Inc.
|
Copyright (C) 1995-2005, 2006, 2007 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it and/or
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
@ -1223,6 +1223,8 @@ cannot allocate TLS data structures for initial thread");
|
|||||||
loadcmds[nloadcmds - 1].mapstart - c->mapend,
|
loadcmds[nloadcmds - 1].mapstart - c->mapend,
|
||||||
PROT_NONE);
|
PROT_NONE);
|
||||||
|
|
||||||
|
l->l_contiguous = 1;
|
||||||
|
|
||||||
goto postmap;
|
goto postmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1242,6 +1244,7 @@ cannot allocate TLS data structures for initial thread");
|
|||||||
/* Remember which part of the address space this object uses. */
|
/* Remember which part of the address space this object uses. */
|
||||||
l->l_map_start = c->mapstart + l->l_addr;
|
l->l_map_start = c->mapstart + l->l_addr;
|
||||||
l->l_map_end = l->l_map_start + maplength;
|
l->l_map_end = l->l_map_start + maplength;
|
||||||
|
l->l_contiguous = !has_holes;
|
||||||
|
|
||||||
while (c < &loadcmds[nloadcmds])
|
while (c < &loadcmds[nloadcmds])
|
||||||
{
|
{
|
||||||
|
@ -201,10 +201,10 @@ dl_open_worker (void *a)
|
|||||||
for (Lmid_t ns = 0; ns < DL_NNS; ++ns)
|
for (Lmid_t ns = 0; ns < DL_NNS; ++ns)
|
||||||
for (l = GL(dl_ns)[ns]._ns_loaded; l != NULL; l = l->l_next)
|
for (l = GL(dl_ns)[ns]._ns_loaded; l != NULL; l = l->l_next)
|
||||||
if (caller_dlopen >= (const void *) l->l_map_start
|
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);
|
assert (ns == l->l_ns);
|
||||||
call_map = l;
|
call_map = l;
|
||||||
goto found_caller;
|
goto found_caller;
|
||||||
@ -662,3 +662,21 @@ show_scope (struct link_map *new)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
||||||
|
@ -98,10 +98,9 @@ do_sym (void *handle, const char *name, void *who,
|
|||||||
for (Lmid_t ns = 0; ns < DL_NNS; ++ns)
|
for (Lmid_t ns = 0; ns < DL_NNS; ++ns)
|
||||||
for (struct link_map *l = GL(dl_ns)[ns]._ns_loaded; l != NULL;
|
for (struct link_map *l = GL(dl_ns)[ns]._ns_loaded; l != NULL;
|
||||||
l = l->l_next)
|
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;
|
match = l;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -187,6 +187,9 @@ struct link_map
|
|||||||
is interested in the PLT interception.*/
|
is interested in the PLT interception.*/
|
||||||
unsigned int l_removed:1; /* Nozero if the object cannot be used anymore
|
unsigned int l_removed:1; /* Nozero if the object cannot be used anymore
|
||||||
since it is removed. */
|
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. */
|
/* Collected information about own RPATH directories. */
|
||||||
struct r_search_path_struct l_rpath_dirs;
|
struct r_search_path_struct l_rpath_dirs;
|
||||||
|
@ -439,18 +439,18 @@ struct rtld_global
|
|||||||
EXTERN void (*_dl_rtld_unlock_recursive) (void *);
|
EXTERN void (*_dl_rtld_unlock_recursive) (void *);
|
||||||
#endif
|
#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
|
/* If loading a shared object requires that we make the stack executable
|
||||||
when it was not, we do it by calling this function.
|
when it was not, we do it by calling this function.
|
||||||
It returns an errno code or zero on success. */
|
It returns an errno code or zero on success. */
|
||||||
EXTERN int (*_dl_make_stack_executable_hook) (void **) internal_function;
|
EXTERN int (*_dl_make_stack_executable_hook) (void **) internal_function;
|
||||||
|
|
||||||
/* Highest dtv index currently needed. */
|
/* Prevailing state of the stack, PF_X indicating it's executable. */
|
||||||
EXTERN size_t _dl_tls_max_dtv_idx;
|
EXTERN ElfW(Word) _dl_stack_flags;
|
||||||
|
|
||||||
/* Flag signalling whether there are gaps in the module ID allocation. */
|
/* Flag signalling whether there are gaps in the module ID allocation. */
|
||||||
EXTERN bool _dl_tls_dtv_gaps;
|
EXTERN bool _dl_tls_dtv_gaps;
|
||||||
|
/* Highest dtv index currently needed. */
|
||||||
|
EXTERN size_t _dl_tls_max_dtv_idx;
|
||||||
/* Information about the dtv slots. */
|
/* Information about the dtv slots. */
|
||||||
EXTERN struct dtv_slotinfo_list
|
EXTERN struct dtv_slotinfo_list
|
||||||
{
|
{
|
||||||
@ -534,15 +534,15 @@ struct rtld_global_ro
|
|||||||
#define DL_DEBUG_HELP (1 << 9)
|
#define DL_DEBUG_HELP (1 << 9)
|
||||||
#define DL_DEBUG_PRELINK (1 << 10)
|
#define DL_DEBUG_PRELINK (1 << 10)
|
||||||
|
|
||||||
/* Cached value of `getpagesize ()'. */
|
|
||||||
EXTERN size_t _dl_pagesize;
|
|
||||||
|
|
||||||
/* OS version. */
|
/* OS version. */
|
||||||
EXTERN unsigned int _dl_osversion;
|
EXTERN unsigned int _dl_osversion;
|
||||||
/* Platform name. */
|
/* Platform name. */
|
||||||
EXTERN const char *_dl_platform;
|
EXTERN const char *_dl_platform;
|
||||||
EXTERN size_t _dl_platformlen;
|
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. */
|
/* Copy of the content of `_dl_main_searchlist' at startup time. */
|
||||||
EXTERN struct r_scope_elem _dl_initial_searchlist;
|
EXTERN struct r_scope_elem _dl_initial_searchlist;
|
||||||
|
|
||||||
@ -571,9 +571,6 @@ struct rtld_global_ro
|
|||||||
/* Expected cache ID. */
|
/* Expected cache ID. */
|
||||||
EXTERN int _dl_correct_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. */
|
/* Mask for hardware capabilities that are available. */
|
||||||
EXTERN uint64_t _dl_hwcap;
|
EXTERN uint64_t _dl_hwcap;
|
||||||
|
|
||||||
@ -657,6 +654,9 @@ struct rtld_global_ro
|
|||||||
/* List of auditing interfaces. */
|
/* List of auditing interfaces. */
|
||||||
struct audit_ifaces *_dl_audit;
|
struct audit_ifaces *_dl_audit;
|
||||||
unsigned int _dl_naudit;
|
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__
|
# define __rtld_global_attribute__
|
||||||
# ifdef IS_IN_rtld
|
# ifdef IS_IN_rtld
|
||||||
@ -1061,6 +1061,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. */
|
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 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
|
__END_DECLS
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user