Hi Jason, For the purpose of supporting GCC stack unwinding, the __sigtramp_check_np function would work as a solution. Backporting to NetBSD-9 branch would definitely be nice as well. Thanks, John
On Wed, Oct 27, 2021 at 9:51 AM Jason Thorpe <thor...@me.com> wrote: > > > On Oct 18, 2021, at 9:41 AM, John Marino (NetBSD) <net...@marino.st> > wrote: > > > > yes, it sounds like a __in_signal_trampoline function would work for > > the GCC unwind, and I would think it would work for GDB as well. > > Ok, I have implemented a new function with this signature: > > /* > * __sigtramp_check_np -- > * > * Non-portable function that checks if the specified program > * counter value is within the signal return trampoline. Returns > * the trampoline version numnber corresponding to what style of > * trampoline it matches, or -1 if the program value is not within > * the signal return trampoline. > */ > int __sigtramp_check_np(void *pc); > > Usage would be like: > > /* > * If you need access to “struct sigcontext” to perform the unwind, you > must > * define _LIBC before including <signal.h>. > */ > #define _LIBC > #include <signal.h> > > . > . > . > > int rv = __sigtramp_check_np((void *)context->return_address); > > if (rv == -1) { > /* address was not within a signal return trampoline. */ > } > > if (rv == __SIGTRAMP_SIGCODE_VERSION) { > /* > * ultra-legacy — this will never be returned for modern > binaries. > * in fact, the current implementation of > __sigtramp_check_np() > * will never return it and there is no reason to add > support for it. > */ > } > > if (rv >= __SIGTRAMP_SIGCONTEXT_VERSION_MIN && > rv <= __SIGTRAMP_SIGCONTEXT_VERSION_MAX) { > #ifdef __HAVE_STRUCT_SIGCONTEXT > /* do sigcontext stuff, distinguishing between versions, > as needed */ > #else > /* > * no sigcontext structure is available here, so none of > these values > * should have been returned. > */ > #endif > } > > if (rv >= __SIGTRAMP_SIGINFO_VERSION_MIN && > rv <= __SIGTRAMP_SIGINFO_VERSION_MAX) { > /* do siginfo stuff, distinguishing between versions, as > needed */ > } > > /* > * Address was within a signal return trampoline, but it’s not a > version > * that this program knows how to decode so *shrug*. > */ > > For the most part, the MIN and MAX values will be the same (currently only > the VAX has multiple versions of either kind of signal trampoline, and it’s > for the “sigcontext” type). > > Again, to be clear, this can query the current process ONLY. > > Is this suitable for your needs? Looking at your GCC unwinder for FreeBSD > (link in your original email), it seems it would work fine (that unwinder > uses getpid() to pass to the sysctl). > > You would be able to test for the availability of __sigtramp_check_np() by > testing for __SIGTRAMP_SIGCODE_VERSION being defined: > > #ifdef __SIGTRAMP_SIGCODE_VERSION > /* > * Code to check if we’re in a NetBSD signal trampoline. > */ > ... > #endif /* __SIGTRAMP_SIGCODE_VERSION */ > > It’s not the prettiest API in the world, but you’re by definition diving > into implementation details here, and the API does provide all the info > needed to do the work. > > Any other comments? Christos? > > …and while there was a flurry of activity lately around this area, the > minimal changes to support __sigtramp_check_np() are easily isolated and > could be back ported to the netbsd-9 branch without much trouble. > > -- thorpej > >