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

Add VDSO support to libunwind , port the patch from https://sourcewar… #728

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

araychaudhury
Copy link

…e.org/pipermail/frysk-cvs/2008q1/007245.html

This commit attempts to add support of VDSO in libunwind . VDSO is mapped in the process address space by the kernel. It is not a physical file ,hence libunwind fails to open it and mmap it.
Instead this patch copies the VDSO in the calling process address space and then mmaps it for finding symbols or stack walking.
NOTE: it is ported from original work as documented in https://sourceware.org/pipermail/frysk-cvs/2008q1/007245.html

This is further to the discussion I had in #696. I am submitting a PR for running CI/CD.
I have verified it in 64bit x86_64 kernel and x86 32 bit apps.

Copy link
Member

@bregma bregma left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I get a failure building for QNX. Haven't tried FreeBSD yet but I expect similar.

  CC       nto/unw_nto_get_proc_name.lo
In file included from ../../src/elf64.h:7,
                 from ../../include/tdep-aarch64/libunwind_i.h:37,
                 from ../include/tdep/libunwind_i.h:7,
                 from ../../include/libunwind_i.h:422,
                 from ../../src/nto/unw_nto_elf.c:31:
../../src/elfxx.h:42:25: warning: '_Uelf64_add_hex_byte' defined but not used [-Wunused-function]
   42 | # define elf_w(x)       _Uelf64_##x
      |                         ^~~~~~~~
../../src/nto/../elfxx.c:776:1: note: in expansion of macro 'elf_w'
  776 | elf_w (add_hex_byte) (char *str, uint8_t byte)
      | ^~~~~
  CC       nto/unw_nto_get_elf_filename.lo
  CC       nto/unw_nto_put_unwind_info.lo
../../src/nto/unw_nto_find_proc_info.c: In function 'unw_nto_find_proc_info':
../../src/nto/unw_nto_find_proc_info.c:72:29: warning: passing argument 1 of '_Uaarch64_get_elf_image' from incompatible pointer type [-Wincompatible-pointer-types]
   72 |   ret = tdep_get_elf_image (&uni->edi.ei,
      |                             ^~~~~~~~~~~~
      |                             |
      |                             struct elf_image *
In file included from ../include/tdep/libunwind_i.h:7,
                 from ../../include/libunwind_i.h:422,
                 from ../../src/nto/unw_nto_internal.h:29,
                 from ../../src/nto/unw_nto_find_proc_info.c:25:
../../include/tdep-aarch64/libunwind_i.h:323:49: note: expected 'unw_addr_space_t' {aka 'struct unw_addr_space *'} but argument is of type 'struct elf_image *'
  323 | extern int tdep_get_elf_image (unw_addr_space_t as, struct elf_image *ei, pid_t pid, unw_word_t ip,
      |                                ~~~~~~~~~~~~~~~~~^~
../../src/nto/unw_nto_find_proc_info.c:73:32: warning: passing argument 2 of '_Uaarch64_get_elf_image' makes pointer from integer without a cast [-Wint-conversion]
   73 |                             uni->pid,
      |                             ~~~^~~~~
      |                                |
      |                                pid_t {aka int}
../../include/tdep-aarch64/libunwind_i.h:323:71: note: expected 'struct elf_image *' but argument is of type 'pid_t' {aka 'int'}
  323 | extern int tdep_get_elf_image (unw_addr_space_t as, struct elf_image *ei, pid_t pid, unw_word_t ip,
      |                                                     ~~~~~~~~~~~~~~~~~~^~
../../src/nto/unw_nto_find_proc_info.c:75:29: warning: passing argument 4 of '_Uaarch64_get_elf_image' makes integer from pointer without a cast [-Wint-conversion]
   75 |                             &segbase,
      |                             ^~~~~~~~
      |                             |
      |                             long unsigned int *
../../include/tdep-aarch64/libunwind_i.h:323:97: note: expected 'unw_word_t' {aka 'long unsigned int'} but argument is of type 'long unsigned int *'
  323 | extern int tdep_get_elf_image (unw_addr_space_t as, struct elf_image *ei, pid_t pid, unw_word_t ip,
      |                                                                                      ~~~~~~~~~~~^~
../../src/nto/unw_nto_find_proc_info.c:77:29: warning: passing argument 6 of '_Uaarch64_get_elf_image' from incompatible pointer type [-Wincompatible-pointer-types]
   77 |                             path,
      |                             ^~~~
      |                             |
      |                             char *
../../include/tdep-aarch64/libunwind_i.h:324:71: note: expected 'long unsigned int *' but argument is of type 'char *'
  324 |                                unsigned long *segbase, unsigned long *mapoff,
      |                                                        ~~~~~~~~~~~~~~~^~~~~~
../../src/nto/unw_nto_find_proc_info.c:78:29: warning: passing argument 7 of '_Uaarch64_get_elf_image' makes pointer from integer without a cast [-Wint-conversion]
   78 |                             sizeof (path),arg);
      |                             ^~~~~~~~~~~~~
      |                             |
      |                             long unsigned int
../../include/tdep-aarch64/libunwind_i.h:325:38: note: expected 'char *' but argument is of type 'long unsigned int'
  325 |                                char *path, size_t pathlen, void *arg);
      |                                ~~~~~~^~~~
../../src/nto/unw_nto_find_proc_info.c:78:43: warning: passing argument 8 of '_Uaarch64_get_elf_image' makes integer from pointer without a cast [-Wint-conversion]
   78 |                             sizeof (path),arg);
      |                                           ^~~
      |                                           |
      |                                           void *
../../include/tdep-aarch64/libunwind_i.h:325:51: note: expected 'size_t' {aka 'long unsigned int'} but argument is of type 'void *'
  325 |                                char *path, size_t pathlen, void *arg);
      |                                            ~~~~~~~^~~~~~~
In file included from ../../include/libunwind-aarch64.h:238,
                 from ../include/libunwind.h:7,
                 from ../../include/libunwind-nto.h:34,
                 from ../../src/nto/unw_nto_internal.h:28:
../include/libunwind-common.h:49:56: error: too few arguments to function '_Uaarch64_get_elf_image'
   49 | #define UNW_ARCH_OBJ(fn) UNW_PASTE(UNW_PASTE(UNW_PASTE(_U,UNW_TARGET),_), fn)
      |                                                        ^~
../include/libunwind-common.h:46:25: note: in definition of macro 'UNW_PASTE2'
   46 | #define UNW_PASTE2(x,y) x##y
      |                         ^
../include/libunwind-common.h:49:26: note: in expansion of macro 'UNW_PASTE'
   49 | #define UNW_ARCH_OBJ(fn) UNW_PASTE(UNW_PASTE(UNW_PASTE(_U,UNW_TARGET),_), fn)
      |                          ^~~~~~~~~
../include/libunwind-common.h:47:25: note: in expansion of macro 'UNW_PASTE2'
   47 | #define UNW_PASTE(x,y)  UNW_PASTE2(x,y)
      |                         ^~~~~~~~~~
../include/libunwind-common.h:49:36: note: in expansion of macro 'UNW_PASTE'
   49 | #define UNW_ARCH_OBJ(fn) UNW_PASTE(UNW_PASTE(UNW_PASTE(_U,UNW_TARGET),_), fn)
      |                                    ^~~~~~~~~
../include/libunwind-common.h:47:25: note: in expansion of macro 'UNW_PASTE2'
   47 | #define UNW_PASTE(x,y)  UNW_PASTE2(x,y)
      |                         ^~~~~~~~~~
../include/libunwind-common.h:49:46: note: in expansion of macro 'UNW_PASTE'
   49 | #define UNW_ARCH_OBJ(fn) UNW_PASTE(UNW_PASTE(UNW_PASTE(_U,UNW_TARGET),_), fn)
      |                                              ^~~~~~~~~
../../include/tdep-aarch64/libunwind_i.h:287:41: note: in expansion of macro 'UNW_ARCH_OBJ'
  287 | #define tdep_get_elf_image              UNW_ARCH_OBJ(get_elf_image)
      |                                         ^~~~~~~~~~~~
../../src/nto/unw_nto_find_proc_info.c:72:9: note: in expansion of macro 'tdep_get_elf_image'
   72 |   ret = tdep_get_elf_image (&uni->edi.ei,
      |         ^~~~~~~~~~~~~~~~~~
../include/libunwind-common.h:49:56: note: declared here
   49 | #define UNW_ARCH_OBJ(fn) UNW_PASTE(UNW_PASTE(UNW_PASTE(_U,UNW_TARGET),_), fn)
      |                                                        ^~
../include/libunwind-common.h:46:25: note: in definition of macro 'UNW_PASTE2'
   46 | #define UNW_PASTE2(x,y) x##y
      |                         ^
../include/libunwind-common.h:49:26: note: in expansion of macro 'UNW_PASTE'
   49 | #define UNW_ARCH_OBJ(fn) UNW_PASTE(UNW_PASTE(UNW_PASTE(_U,UNW_TARGET),_), fn)
      |                          ^~~~~~~~~
../include/libunwind-common.h:47:25: note: in expansion of macro 'UNW_PASTE2'
   47 | #define UNW_PASTE(x,y)  UNW_PASTE2(x,y)
      |                         ^~~~~~~~~~
../include/libunwind-common.h:49:36: note: in expansion of macro 'UNW_PASTE'
   49 | #define UNW_ARCH_OBJ(fn) UNW_PASTE(UNW_PASTE(UNW_PASTE(_U,UNW_TARGET),_), fn)
      |                                    ^~~~~~~~~
../include/libunwind-common.h:47:25: note: in expansion of macro 'UNW_PASTE2'
   47 | #define UNW_PASTE(x,y)  UNW_PASTE2(x,y)
      |                         ^~~~~~~~~~
../include/libunwind-common.h:49:46: note: in expansion of macro 'UNW_PASTE'
   49 | #define UNW_ARCH_OBJ(fn) UNW_PASTE(UNW_PASTE(UNW_PASTE(_U,UNW_TARGET),_), fn)
      |                                              ^~~~~~~~~
../../include/tdep-aarch64/libunwind_i.h:287:41: note: in expansion of macro 'UNW_ARCH_OBJ'
  287 | #define tdep_get_elf_image              UNW_ARCH_OBJ(get_elf_image)
      |                                         ^~~~~~~~~~~~
../../include/tdep-aarch64/libunwind_i.h:323:12: note: in expansion of macro 'tdep_get_elf_image'
  323 | extern int tdep_get_elf_image (unw_addr_space_t as, struct elf_image *ei, pid_t pid, unw_word_t ip,
      |            ^~~~~~~~~~~~~~~~~~
make[2]: *** [Makefile:4795: nto/unw_nto_find_proc_info.lo] Error 1
make[2]: *** Waiting for unfinished jobs....
../../src/nto/unw_nto_get_proc_name.c: In function 'unw_nto_get_proc_name':
../../src/nto/unw_nto_get_proc_name.c:49:9: error: too few arguments to function '_Uelf64_get_proc_name'
   49 |   ret = _Uelf64_get_proc_name (as, uni->pid, ip, symbol, symbol_len, offp);
      |         ^~~~~~~~~~~~~~~~~~~~~
In file included from ../../src/elf64.h:7,
                 from ../../include/tdep-aarch64/libunwind_i.h:37,
                 from ../include/tdep/libunwind_i.h:7,
                 from ../../include/libunwind_i.h:422,
                 from ../../src/nto/unw_nto_internal.h:29,
                 from ../../src/nto/unw_nto_get_proc_name.c:25:
../../src/elfxx.h:42:25: note: declared here
   42 | # define elf_w(x)       _Uelf64_##x
      |                         ^~~~~~~~
../../src/elfxx.h:45:12: note: in expansion of macro 'elf_w'
   45 | extern int elf_w (get_proc_name) (unw_addr_space_t as,
      |            ^~~~~
../../src/nto/unw_nto_get_proc_name.c:46:10: warning: unused variable 'path_len' [-Wunused-variable]
   46 |   size_t path_len = sizeof (path);
      |          ^~~~~~~~
../../src/nto/unw_nto_get_proc_name.c: In function 'unw_nto_get_proc_ip_range':
../../src/nto/unw_nto_get_proc_name.c:80:9: error: too few arguments to function '_Uelf64_get_proc_ip_range'
   80 |   ret = _Uelf64_get_proc_ip_range (as, uni->pid, ip, start, end);
      |         ^~~~~~~~~~~~~~~~~~~~~~~~~
../../src/elfxx.h:42:25: note: declared here
   42 | # define elf_w(x)       _Uelf64_##x
      |                         ^~~~~~~~
../../src/elfxx.h:56:12: note: in expansion of macro 'elf_w'
   56 | extern int elf_w (get_proc_ip_range) (unw_addr_space_t as,
      |            ^~~~~
make[2]: *** [Makefile:4795: nto/unw_nto_get_proc_name.lo] Error 1
../../src/nto/unw_nto_get_elf_filename.c: In function 'unw_nto_get_elf_filename':
../../src/nto/unw_nto_get_elf_filename.c:40:9: error: too few arguments to function '_Uelf64_get_elf_filename'
   40 |   ret = _Uelf64_get_elf_filename (as, uni->pid, ip, path, path_len, offp);
      |         ^~~~~~~~~~~~~~~~~~~~~~~~
In file included from ../../src/elf64.h:7,
                 from ../../include/tdep-aarch64/libunwind_i.h:37,
                 from ../include/tdep/libunwind_i.h:7,
                 from ../../include/libunwind_i.h:422,
                 from ../../src/nto/unw_nto_internal.h:29,
                 from ../../src/nto/unw_nto_get_elf_filename.c:23:
../../src/elfxx.h:42:25: note: declared here
   42 | # define elf_w(x)       _Uelf64_##x
      |                         ^~~~~~~~
../../src/elfxx.h:64:12: note: in expansion of macro 'elf_w'
   64 | extern int elf_w (get_elf_filename) (unw_addr_space_t as, pid_t pid, unw_word_t ip,
      |            ^~~~~
make[2]: *** [Makefile:4795: nto/unw_nto_get_elf_filename.lo] Error 1
make[2]: Leaving directory '/home/swebb/projects/libunwind/gh-728/aarch64-nto-qnx8.0.0/src'
make[1]: *** [Makefile:2913: all] Error 2
make[1]: Leaving directory '/home/swebb/projects/libunwind/gh-728/aarch64-nto-qnx8.0.0/src'
make: *** [Makefile:617: all-recursive] Error 1

include/tdep-aarch64/libunwind_i.h Outdated Show resolved Hide resolved
doc/unw_get_proc_name_by_ip.man Outdated Show resolved Hide resolved
include/tdep-sh/libunwind_i.h Outdated Show resolved Hide resolved
src/aarch64/Ginit.c Outdated Show resolved Hide resolved
@araychaudhury
Copy link
Author

How do I build for QnX and PSOS ? Any docker support you have ?

@bregma
Copy link
Member

bregma commented Feb 29, 2024

Building for QNX is a challenge. There are no pulblicly available builders for CI purposes. Other OS targets (eg. HP-UX) aren't really supported any more because we have no way to run CI.

The following changes make QNX build cleanly and given no new regressions in the testsuite, You should be able to apply it with patch -p1.

diff --git a/src/nto/unw_nto_find_proc_info.c b/src/nto/unw_nto_find_proc_info.c
index 870ba646..78ea3648 100644
--- a/src/nto/unw_nto_find_proc_info.c
+++ b/src/nto/unw_nto_find_proc_info.c
@@ -69,7 +69,8 @@ int unw_nto_find_proc_info (unw_addr_space_t as,
   unsigned long mapoff = 0;
   char path[PATH_MAX];
   invalidate_edi (&uni->edi);
-  ret = tdep_get_elf_image (&uni->edi.ei,
+  ret = tdep_get_elf_image (as,
+                            &uni->edi.ei,
                             uni->pid,
                             ip,
                             &segbase,
diff --git a/src/nto/unw_nto_get_elf_filename.c b/src/nto/unw_nto_get_elf_filename.c
index 1654099f..41cee75c 100644
--- a/src/nto/unw_nto_get_elf_filename.c
+++ b/src/nto/unw_nto_get_elf_filename.c
@@ -37,9 +37,9 @@ int unw_nto_get_elf_filename (unw_addr_space_t  as,
   size_t path_len = sizeof (path);
   int ret = -UNW_ENOINFO;
 #if UNW_ELF_CLASS == UNW_ELFCLASS64
-  ret = _Uelf64_get_elf_filename (as, uni->pid, ip, path, path_len, offp);
+  ret = _Uelf64_get_elf_filename (as, uni->pid, ip, path, path_len, offp, NULL);
 #elif UNW_ELF_CLASS == UNW_ELFCLASS32
-  ret = _Uelf32_get_elf_filename (as, uni->pid, ip, path, path_len, offp);
+  ret = _Uelf32_get_elf_filename (as, uni->pid, ip, path, path_len, offp, NULL);
 #else
 # error no valid ELF class defined
 #endif
diff --git a/src/nto/unw_nto_get_proc_name.c b/src/nto/unw_nto_get_proc_name.c
index 87a2af07..acf32ed8 100644
--- a/src/nto/unw_nto_get_proc_name.c
+++ b/src/nto/unw_nto_get_proc_name.c
@@ -46,9 +46,9 @@ int unw_nto_get_proc_name (unw_addr_space_t  as,
   size_t path_len = sizeof (path);
   int ret = -UNW_ENOINFO;
 #if UNW_ELF_CLASS == UNW_ELFCLASS64
-  ret = _Uelf64_get_proc_name (as, uni->pid, ip, symbol, symbol_len, offp);
+  ret = _Uelf64_get_proc_name (as, uni->pid, ip, symbol, symbol_len, offp, NULL);
 #elif UNW_ELF_CLASS == UNW_ELFCLASS32
-  ret = _Uelf32_get_proc_name (as, uni->pid, ip, symbol, symbol_len, offp);
+  ret = _Uelf32_get_proc_name (as, uni->pid, ip, symbol, symbol_len, offp, NULL);
 #else
 # error no valid ELF class defined
 #endif
@@ -77,9 +77,9 @@ int unw_nto_get_proc_ip_range (unw_addr_space_t  as,
   int ret = -UNW_ENOINFO;
 
 #if UNW_ELF_CLASS == UNW_ELFCLASS64
-  ret = _Uelf64_get_proc_ip_range (as, uni->pid, ip, start, end);
+  ret = _Uelf64_get_proc_ip_range (as, uni->pid, ip, start, end, NULL);
 #elif UNW_ELF_CLASS == UNW_ELFCLASS32
-  ret = _Uelf32_get_proc_ip_range (as, uni->pid, ip, start, end);
+  ret = _Uelf32_get_proc_ip_range (as, uni->pid, ip, start, end, NULL);
 #else
 # error no valid ELF class defined
 #endif

@bregma bregma added this to the 1.9.0 milestone Apr 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants