Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated to determine PAGE_SIZE dynamically. #330

Merged
merged 1 commit into from
Mar 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 9 additions & 0 deletions include/libunwind_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
#include <errno.h>
#include <stdio.h>

#if defined(HAVE_ELF_H)
# include <elf.h>
Expand Down Expand Up @@ -288,6 +290,13 @@ print_error (const char *string)
return write (2, string, strlen (string));
}

HIDDEN extern long unw_page_size;

static inline unw_word_t uwn_page_start(unw_word_t addr)
{
return addr & ~(unw_page_size - 1);
}

#define mi_init UNWI_ARCH_OBJ(mi_init)

extern void mi_init (void); /* machine-independent initializations */
Expand Down
19 changes: 8 additions & 11 deletions src/aarch64/Ginit.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,6 @@ get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
return 0;
}

#define PAGE_SIZE 4096
#define PAGE_START(a) ((a) & ~(PAGE_SIZE-1))

static int mem_validate_pipe[2] = {-1, -1};

Expand Down Expand Up @@ -197,11 +195,14 @@ tdep_init_mem_validate (void)

#ifdef HAVE_MINCORE
unsigned char present = 1;
unw_word_t addr = PAGE_START((unw_word_t)&present);
size_t len = unw_page_size;
unw_word_t addr = uwn_page_start((unw_word_t)&present);
unsigned char mvec[1];
int ret;
while ((ret = mincore ((void*)addr, PAGE_SIZE, (unsigned char *)mvec)) == -1 &&
errno == EAGAIN) {}
while ((ret = mincore((void *)addr, len, (unsigned char *)mvec)) == -1 &&
errno == EAGAIN)
{
}
if (ret == 0)
{
Debug(1, "using mincore to validate memory\n");
Expand Down Expand Up @@ -295,12 +296,8 @@ validate_mem (unw_word_t addr)
{
size_t len;

if (PAGE_START(addr + sizeof (unw_word_t) - 1) == PAGE_START(addr))
len = PAGE_SIZE;
else
len = PAGE_SIZE * 2;

addr = PAGE_START(addr);
len = unw_page_size;
addr = uwn_page_start(addr);

if (addr == 0)
return -1;
Expand Down
13 changes: 2 additions & 11 deletions src/arm/Ginit.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,6 @@ get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
return 0;
}

#define PAGE_SIZE 4096
#define PAGE_START(a) ((a) & ~(PAGE_SIZE-1))

/* Cache of already validated addresses */
#define NLGA 4
static unw_word_t last_good_addr[NLGA];
Expand All @@ -83,14 +80,8 @@ static int
validate_mem (unw_word_t addr)
{
int i, victim;
size_t len;

if (PAGE_START(addr + sizeof (unw_word_t) - 1) == PAGE_START(addr))
len = PAGE_SIZE;
else
len = PAGE_SIZE * 2;

addr = PAGE_START(addr);
size_t len = unw_page_size;
addr = uwn_page_start(addr);

if (addr == 0)
return -1;
Expand Down
28 changes: 26 additions & 2 deletions src/mi/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,30 @@ static const char rcsid[] UNUSED =
long unwi_debug_level;

#endif /* UNW_DEBUG */
long unw_page_size;
static void
unw_init_page_size ()
{
errno = 0;
long result = sysconf (_SC_PAGESIZE);
if (result == -1)
{
if (errno != 0)
{
print_error ("Failed to get _SC_PAGESIZE: ");
print_error (strerror(errno));
print_error ("\n");
}
else
print_error ("Failed to get _SC_PAGESIZE, errno was not set.\n");

unw_page_size = 4096;
}
else
{
unw_page_size = result;
}
}

HIDDEN void
mi_init (void)
Expand All @@ -55,6 +79,6 @@ mi_init (void)
setbuf (stderr, NULL);
}
#endif

assert (sizeof (struct cursor) <= sizeof (unw_cursor_t));
unw_init_page_size();
assert(sizeof(struct cursor) <= sizeof(unw_cursor_t));
}
22 changes: 8 additions & 14 deletions src/riscv/Ginit.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,6 @@ get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,

// Memory validation routines are from aarch64

#define PAGE_SIZE 4096
#define PAGE_START(a) ((a) & ~(PAGE_SIZE-1))

static int mem_validate_pipe[2] = {-1, -1};

#ifdef HAVE_PIPE2
Expand Down Expand Up @@ -210,11 +207,14 @@ tdep_init_mem_validate (void)

#ifdef HAVE_MINCORE
unsigned char present = 1;
unw_word_t addr = PAGE_START((unw_word_t)&present);
size_t len = unw_page_size;
unw_word_t addr = uwn_page_start((unw_word_t)&present);
unsigned char mvec[1];
int ret;
while ((ret = mincore ((void*)addr, PAGE_SIZE, (unsigned char *)mvec)) == -1 &&
errno == EAGAIN) {}
while ((ret = mincore((void *)addr, len, (unsigned char *)mvec)) == -1 &&
errno == EAGAIN)
{
}
if (ret == 0)
{
Debug(1, "using mincore to validate memory\n");
Expand Down Expand Up @@ -306,14 +306,8 @@ cache_valid_mem(unw_word_t addr)
static int
validate_mem (unw_word_t addr)
{
size_t len;

if (PAGE_START(addr + sizeof (unw_word_t) - 1) == PAGE_START(addr))
len = PAGE_SIZE;
else
len = PAGE_SIZE * 2;

addr = PAGE_START(addr);
size_t len = unw_page_size;
addr = uwn_page_start(addr);

if (addr == 0)
return -1;
Expand Down
25 changes: 10 additions & 15 deletions src/s390x/Ginit.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */

#include "libunwind_i.h"
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
Expand Down Expand Up @@ -93,9 +94,6 @@ get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
return 0;
}

#define PAGE_SIZE 4096
#define PAGE_START(a) ((a) & ~(PAGE_SIZE-1))

static int mem_validate_pipe[2] = {-1, -1};

static inline void
Expand Down Expand Up @@ -163,7 +161,7 @@ static int mincore_validate (void *addr, size_t len)
return -1;
}

for (i = 0; i < (len + PAGE_SIZE - 1) / PAGE_SIZE; i++)
for (i = 0; i < (len + unw_page_size - 1) / unw_page_size; i++)
{
if (!(mvec[i] & 1)) return -1;
}
Expand All @@ -183,11 +181,14 @@ tdep_init_mem_validate (void)

#ifdef HAVE_MINCORE
unsigned char present = 1;
unw_word_t addr = PAGE_START((unw_word_t)&present);
size_t len = unw_page_size;
unw_word_t addr = uwn_page_start((unw_word_t)&present);
unsigned char mvec[1];
int ret;
while ((ret = mincore ((void*)addr, PAGE_SIZE, mvec)) == -1 &&
errno == EAGAIN) {}
while ((ret = mincore((void *)addr, len, mvec)) == -1 &&
errno == EAGAIN)
{
}
if (ret == 0 && (mvec[0] & 1))
{
Debug(1, "using mincore to validate memory\n");
Expand All @@ -210,14 +211,8 @@ static int
validate_mem (unw_word_t addr)
{
int i, victim;
size_t len;

if (PAGE_START(addr + sizeof (unw_word_t) - 1) == PAGE_START(addr))
len = PAGE_SIZE;
else
len = PAGE_SIZE * 2;

addr = PAGE_START(addr);
size_t len = unw_page_size;
addr = uwn_page_start(addr);

if (addr == 0)
return -1;
Expand Down
13 changes: 2 additions & 11 deletions src/x86/Ginit.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,6 @@ get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
return 0;
}

#define PAGE_SIZE 4096
#define PAGE_START(a) ((a) & ~(PAGE_SIZE-1))

/* Cache of already validated addresses */
#define NLGA 4
static unw_word_t last_good_addr[NLGA];
Expand All @@ -89,14 +86,8 @@ validate_mem (unw_word_t addr)
#ifdef HAVE_MINCORE
unsigned char mvec[2]; /* Unaligned access may cross page boundary */
#endif
size_t len;

if (PAGE_START(addr + sizeof (unw_word_t) - 1) == PAGE_START(addr))
len = PAGE_SIZE;
else
len = PAGE_SIZE * 2;

addr = PAGE_START(addr);
size_t len = unw_page_size;
addr = uwn_page_start(addr);

if (addr == 0)
return -1;
Expand Down
18 changes: 5 additions & 13 deletions src/x86_64/Ginit.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,6 @@ get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
return 0;
}

#define PAGE_SIZE 4096
#define PAGE_START(a) ((a) & ~(PAGE_SIZE-1))

static int mem_validate_pipe[2] = {-1, -1};

#ifdef HAVE_PIPE2
Expand Down Expand Up @@ -191,10 +188,11 @@ tdep_init_mem_validate (void)

#ifdef HAVE_MINCORE
unsigned char present = 1;
unw_word_t addr = PAGE_START((unw_word_t)&present);
size_t len = unw_page_size;
unw_word_t addr = uwn_page_start((unw_word_t)&present);
unsigned char mvec[1];
int ret;
while ((ret = mincore ((void*)addr, PAGE_SIZE, (unsigned char *)mvec)) == -1 &&
while ((ret = mincore ((void*)addr, len, (unsigned char *)mvec)) == -1 &&
errno == EAGAIN) {}
if (ret == 0)
{
Expand Down Expand Up @@ -287,14 +285,8 @@ cache_valid_mem(unw_word_t addr)
static int
validate_mem (unw_word_t addr)
{
size_t len;

if (PAGE_START(addr + sizeof (unw_word_t) - 1) == PAGE_START(addr))
len = PAGE_SIZE;
else
len = PAGE_SIZE * 2;

addr = PAGE_START(addr);
size_t len = unw_page_size;
addr = uwn_page_start(addr);

if (addr == 0)
return -1;
Expand Down