diff --git a/libunwind-1.6.2-dynamic-page-size.patch b/libunwind-1.6.2-dynamic-page-size.patch new file mode 100644 index 0000000..c1fff91 --- /dev/null +++ b/libunwind-1.6.2-dynamic-page-size.patch @@ -0,0 +1,355 @@ +From cf6b9aadd60a85107afe5196251ca2ed198a96d0 Mon Sep 17 00:00:00 2001 +From: Daniel Moody +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 + #include + #include ++#include ++#include + + #if defined(HAVE_ELF_H) + # include +@@ -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 + #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; diff --git a/libunwind.spec b/libunwind.spec index a5ffafe..e4f1747 100644 --- a/libunwind.spec +++ b/libunwind.spec @@ -13,6 +13,7 @@ Source: http://download-mirror.savannah.gnu.org/releases/libunwind/libunwind-%{v Patch1: libunwind-arm-default-to-exidx.patch # Make libunwind.h multilib friendly Patch2: libunwind-1.3.1-multilib-fix.patch +Patch3: libunwind-1.6.2-dynamic-page-size.patch ExclusiveArch: %{arm} aarch64 hppa ia64 mips ppc %{power64} s390x %{ix86} x86_64 @@ -89,6 +90,9 @@ echo ====================TESTSUITE DISABLED========================= %{_includedir}/libunwind*.h %changelog +* Sun Aug 28 2022 Leif Liddy - 1.6.2-4 +- enable dynamic page size support (bz2118019) + * Thu Jul 21 2022 Fedora Release Engineering - 1.6.2-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild