| |
@@ -0,0 +1,355 @@
|
| |
+ From cf6b9aadd60a85107afe5196251ca2ed198a96d0 Mon Sep 17 00:00:00 2001
|
| |
+ From: Daniel Moody <daniel.moody@mongodb.com>
|
| |
+ Date: Fri, 18 Feb 2022 14:24:37 -0600
|
| |
+ Subject: [PATCH] Updated to determine PAGE_SIZE dynamically.
|
| |
+
|
| |
+ ---
|
| |
+ include/libunwind_i.h | 9 +++++++++
|
| |
+ src/aarch64/Ginit.c | 19 ++++++++-----------
|
| |
+ src/arm/Ginit.c | 13 ++-----------
|
| |
+ src/mi/init.c | 28 ++++++++++++++++++++++++++--
|
| |
+ src/riscv/Ginit.c | 22 ++++++++--------------
|
| |
+ src/s390x/Ginit.c | 25 ++++++++++---------------
|
| |
+ src/x86/Ginit.c | 13 ++-----------
|
| |
+ src/x86_64/Ginit.c | 18 +++++-------------
|
| |
+ 8 files changed, 70 insertions(+), 77 deletions(-)
|
| |
+
|
| |
+ diff --git a/include/libunwind_i.h b/include/libunwind_i.h
|
| |
+ index 6c7dda9a8..bcf229566 100644
|
| |
+ --- a/include/libunwind_i.h
|
| |
+ +++ b/include/libunwind_i.h
|
| |
+ @@ -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>
|
| |
+ @@ -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 */
|
| |
+ diff --git a/src/aarch64/Ginit.c b/src/aarch64/Ginit.c
|
| |
+ index 2b08feb36..fe6e511df 100644
|
| |
+ --- a/src/aarch64/Ginit.c
|
| |
+ +++ b/src/aarch64/Ginit.c
|
| |
+ @@ -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};
|
| |
+
|
| |
+ @@ -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");
|
| |
+ @@ -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;
|
| |
+ diff --git a/src/arm/Ginit.c b/src/arm/Ginit.c
|
| |
+ index 0bac0d72d..bce52dc34 100644
|
| |
+ --- a/src/arm/Ginit.c
|
| |
+ +++ b/src/arm/Ginit.c
|
| |
+ @@ -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];
|
| |
+ @@ -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;
|
| |
+ diff --git a/src/mi/init.c b/src/mi/init.c
|
| |
+ index 60a48c589..aa9319981 100644
|
| |
+ --- a/src/mi/init.c
|
| |
+ +++ b/src/mi/init.c
|
| |
+ @@ -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)
|
| |
+ @@ -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));
|
| |
+ }
|
| |
+ diff --git a/src/riscv/Ginit.c b/src/riscv/Ginit.c
|
| |
+ index 907f72962..4faeecbfd 100644
|
| |
+ --- a/src/riscv/Ginit.c
|
| |
+ +++ b/src/riscv/Ginit.c
|
| |
+ @@ -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
|
| |
+ @@ -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");
|
| |
+ @@ -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;
|
| |
+ diff --git a/src/s390x/Ginit.c b/src/s390x/Ginit.c
|
| |
+ index db01743c0..2bce2f4b6 100644
|
| |
+ --- a/src/s390x/Ginit.c
|
| |
+ +++ b/src/s390x/Ginit.c
|
| |
+ @@ -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
|
| |
+ @@ -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
|
| |
+ @@ -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;
|
| |
+ }
|
| |
+ @@ -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");
|
| |
+ @@ -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;
|
| |
+ diff --git a/src/x86/Ginit.c b/src/x86/Ginit.c
|
| |
+ index 3cec74a21..4261fb523 100644
|
| |
+ --- a/src/x86/Ginit.c
|
| |
+ +++ b/src/x86/Ginit.c
|
| |
+ @@ -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];
|
| |
+ @@ -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;
|
| |
+ diff --git a/src/x86_64/Ginit.c b/src/x86_64/Ginit.c
|
| |
+ index 0b121bc91..e75f92a5f 100644
|
| |
+ --- a/src/x86_64/Ginit.c
|
| |
+ +++ b/src/x86_64/Ginit.c
|
| |
+ @@ -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
|
| |
+ @@ -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)
|
| |
+ {
|
| |
+ @@ -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;
|
| |
enable dynamic page size support by applying this patch here:
https://github.com/libunwind/libunwind/commit/e85b65cec757ef589f28957d0c6c21c498a03bdf
Resolves issue with processors that don't support 4K page sizes
https://bugzilla.redhat.com/show_bug.cgi?id=2118019