Update libunwind to latest (#68899)
authorJan Vorlicek <jan.vorlicek@volny.cz>
Fri, 6 May 2022 20:29:59 +0000 (22:29 +0200)
committerGitHub <noreply@github.com>
Fri, 6 May 2022 20:29:59 +0000 (13:29 -0700)
* Update libunwind

This change updates libunwind copy by a fix for non-4kB page sizes
that is needed e.g. for Linux arm64 with kernel set to use 64kB page
sizes (RHEL8 is one such case).

It also applies a fix for incorrect register storage in ARM64
getcontext.

* Add dummy `write` method implementation

* Update src/native/external/libunwind-version.txt

Co-authored-by: Adeel Mujahid <3840695+am11@users.noreply.github.com>
12 files changed:
src/native/external/libunwind-version.txt
src/native/external/libunwind/include/libunwind-aarch64.h
src/native/external/libunwind/include/libunwind_i.h
src/native/external/libunwind/include/win/unistd.h
src/native/external/libunwind/src/aarch64/Ginit.c
src/native/external/libunwind/src/arm/Ginit.c
src/native/external/libunwind/src/mi/init.c
src/native/external/libunwind/src/riscv/Ginit.c
src/native/external/libunwind/src/s390x/Ginit.c
src/native/external/libunwind/src/win/pal-single-threaded.c
src/native/external/libunwind/src/x86/Ginit.c
src/native/external/libunwind/src/x86_64/Ginit.c

index 4b47acf..94f198a 100644 (file)
@@ -3,8 +3,11 @@ https://github.com/libunwind/libunwind/commit/b3ca1b59a795a617877c01fe5d299ab7a0
 
 Reapply changes from https://github.com/dotnet/runtime/commit/1b5719c2e3dde393531eaeb5b5cde05dabeef5b8
 Apply https://github.com/libunwind/libunwind/pull/317
+Apply https://github.com/libunwind/libunwind/pull/330
 Apply https://github.com/libunwind/libunwind/pull/333
 Apply https://github.com/libunwind/libunwind/pull/342
+Apply https://github.com/libunwind/libunwind/pull/353
+Apply https://github.com/libunwind/libunwind/pull/358
 
 For LoongArch64:
 Apply https://github.com/libunwind/libunwind/pull/316 and https://github.com/libunwind/libunwind/pull/322
index a5265c4..a7c71ed 100644 (file)
@@ -243,7 +243,7 @@ typedef ucontext_t unw_tdep_context_t;
      "stp x8, x9, [%[base], #64]\n" \
      "stp x10, x11, [%[base], #80]\n" \
      "stp x12, x13, [%[base], #96]\n" \
-     "stp x14, x13, [%[base], #112]\n" \
+     "stp x14, x15, [%[base], #112]\n" \
      "stp x16, x17, [%[base], #128]\n" \
      "stp x18, x19, [%[base], #144]\n" \
      "stp x20, x21, [%[base], #160]\n" \
index fea5c26..dadf824 100644 (file)
@@ -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 */
index 1a3aee5..d4ff227 100644 (file)
@@ -24,5 +24,8 @@ int          getpagesize(void);
 int          open(const char *, int, ...);
 ssize_t      read(int fd, void *buf, size_t count);
 ssize_t      write(int, const void *, size_t);
+long         sysconf(int name);
+
+#define _SC_PAGESIZE 11
 
 #endif // _MSC_VER
index 2b08feb..fe6e511 100644 (file)
@@ -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;
index 1932160..680b2d4 100644 (file)
@@ -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))
-
 /* Cache of already validated addresses */
 #define NLGA 4
 static unw_word_t last_good_addr[NLGA];
@@ -85,14 +82,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;
index 60a48c5..aa93199 100644 (file)
@@ -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));
 }
index 907f729..4faeecb 100644 (file)
@@ -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;
index db01743..2bce2f4 100644 (file)
@@ -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;
index b46ff2d..d291fd6 100644 (file)
@@ -15,6 +15,7 @@
 #include <sys/mman.h>
 #include <sys/stat.h>
 #include <unistd.h>
+#include <errno.h>
 #include "libunwind_i.h"
 #include "compiler.h"
 
@@ -25,6 +26,17 @@ int getpagesize(void)
     return 4096;
 }
 
+long sysconf(int name)
+{
+    if (name == _SC_PAGESIZE)
+    {
+        return getpagesize();
+    }
+
+    errno = EINVAL;
+    return -1;
+}
+
 void* mmap(void *addr, size_t length, int prot, int flags, int fd, size_t offset)
 {
     // We shouldn't be doing anything other than anonymous mappings
@@ -100,6 +112,13 @@ ssize_t read(int fd, void *buf, size_t count)
     return -1;
 }
 
+ssize_t write(int fd, const void *buf, size_t nbyte)
+{
+    // For dump debugging we shouldn't need to open files
+    // Especially since we didn't implement open()
+    return -1;
+}
+
 int close(int fd)
 {
     // For dump debugging we shouldn't need to open files
index 3cec74a..4261fb5 100644 (file)
@@ -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;
index 0b121bc..e75f92a 100644 (file)
@@ -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;