mirror of
https://github.com/tobast/libunwind-eh_elf.git
synced 2025-01-10 19:23:41 +01:00
Auto-detect whether to use msync() or mincore() for address validation.
This commit is contained in:
parent
f643684978
commit
28f33c8ce0
4 changed files with 43 additions and 9 deletions
|
@ -223,7 +223,8 @@ AC_ARG_ENABLE(conservative_checks,
|
||||||
[ --enable-conservative-checks Validate all memory addresses before use],
|
[ --enable-conservative-checks Validate all memory addresses before use],
|
||||||
[enable_conservative_checks=$enableval], [enable_conservative_checks=yes])
|
[enable_conservative_checks=$enableval], [enable_conservative_checks=yes])
|
||||||
if test x$enable_conservative_checks = xyes; then
|
if test x$enable_conservative_checks = xyes; then
|
||||||
CPPFLAGS="${CPPFLAGS} -DCONSERVATIVE_CHECKS"
|
AC_DEFINE(CONSERVATIVE_CHECKS, 1,
|
||||||
|
[Define to 1 if you want every memory access validated])
|
||||||
fi
|
fi
|
||||||
AC_MSG_RESULT([$enable_conservative_checks])
|
AC_MSG_RESULT([$enable_conservative_checks])
|
||||||
|
|
||||||
|
|
|
@ -155,6 +155,7 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define tdep_needs_initialization UNW_OBJ(needs_initialization)
|
#define tdep_needs_initialization UNW_OBJ(needs_initialization)
|
||||||
|
#define tdep_init_mem_validate UNW_OBJ(init_mem_validate)
|
||||||
#define tdep_init UNW_OBJ(init)
|
#define tdep_init UNW_OBJ(init)
|
||||||
/* Platforms that support UNW_INFO_FORMAT_TABLE need to define
|
/* Platforms that support UNW_INFO_FORMAT_TABLE need to define
|
||||||
tdep_search_unwind_table. */
|
tdep_search_unwind_table. */
|
||||||
|
@ -195,6 +196,7 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val)
|
||||||
extern int tdep_needs_initialization;
|
extern int tdep_needs_initialization;
|
||||||
|
|
||||||
extern void tdep_init (void);
|
extern void tdep_init (void);
|
||||||
|
extern void tdep_init_mem_validate (void);
|
||||||
extern int tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip,
|
extern int tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip,
|
||||||
unw_dyn_info_t *di, unw_proc_info_t *pi,
|
unw_dyn_info_t *di, unw_proc_info_t *pi,
|
||||||
int need_unwind_info, void *arg);
|
int need_unwind_info, void *arg);
|
||||||
|
|
|
@ -71,6 +71,8 @@ tdep_init (void)
|
||||||
|
|
||||||
dwarf_init ();
|
dwarf_init ();
|
||||||
|
|
||||||
|
tdep_init_mem_validate ();
|
||||||
|
|
||||||
#ifndef UNW_REMOTE_ONLY
|
#ifndef UNW_REMOTE_ONLY
|
||||||
x86_64_local_addr_space_init ();
|
x86_64_local_addr_space_init ();
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -81,6 +81,42 @@ get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
|
||||||
#define PAGE_SIZE 4096
|
#define PAGE_SIZE 4096
|
||||||
#define PAGE_START(a) ((a) & ~(PAGE_SIZE-1))
|
#define PAGE_START(a) ((a) & ~(PAGE_SIZE-1))
|
||||||
|
|
||||||
|
static int (*mem_validate_func) (void *addr, size_t len);
|
||||||
|
static int msync_validate (void *addr, size_t len)
|
||||||
|
{
|
||||||
|
return msync (addr, len, MS_ASYNC);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_MINCORE
|
||||||
|
static int mincore_validate (void *addr, size_t len)
|
||||||
|
{
|
||||||
|
unsigned char mvec[2]; /* Unaligned access may cross page boundary */
|
||||||
|
return mincore (addr, len, mvec);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Initialise memory validation method. On linux kernels <2.6.21,
|
||||||
|
mincore() returns incorrect value for MAP_PRIVATE mappings,
|
||||||
|
such as stacks. If mincore() was available at compile time,
|
||||||
|
check if we can actually use it. If not, use msync() instead. */
|
||||||
|
HIDDEN void
|
||||||
|
tdep_init_mem_validate (void)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_MINCORE
|
||||||
|
unsigned char present = 1;
|
||||||
|
if (mincore (&present, 1, &present) == 0)
|
||||||
|
{
|
||||||
|
Debug(1, "using mincore to validate memory\n");
|
||||||
|
mem_validate_func = mincore_validate;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
Debug(1, "using msync to validate memory\n");
|
||||||
|
mem_validate_func = msync_validate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Cache of already validated addresses */
|
/* Cache of already validated addresses */
|
||||||
#define NLGA 4
|
#define NLGA 4
|
||||||
static unw_word_t last_good_addr[NLGA];
|
static unw_word_t last_good_addr[NLGA];
|
||||||
|
@ -90,9 +126,6 @@ static int
|
||||||
validate_mem (unw_word_t addr)
|
validate_mem (unw_word_t addr)
|
||||||
{
|
{
|
||||||
int i, victim;
|
int i, victim;
|
||||||
#ifdef HAVE_MINCORE
|
|
||||||
unsigned char mvec[2]; /* Unaligned access may cross page boundary */
|
|
||||||
#endif
|
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
if (PAGE_START(addr + sizeof (unw_word_t) - 1) == PAGE_START(addr))
|
if (PAGE_START(addr + sizeof (unw_word_t) - 1) == PAGE_START(addr))
|
||||||
|
@ -111,11 +144,7 @@ validate_mem (unw_word_t addr)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_MINCORE
|
if (mem_validate_func ((void *) addr, len) == -1)
|
||||||
if (mincore ((void *) addr, len, mvec) == -1)
|
|
||||||
#else
|
|
||||||
if (msync ((void *) addr, len, MS_ASYNC) == -1)
|
|
||||||
#endif
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
victim = lga_victim;
|
victim = lga_victim;
|
||||||
|
|
Loading…
Reference in a new issue