3535# include <sys/types.h>
3636# endif
3737#endif /* ZEND_WIN32 */
38- #if defined(__linux__ ) || defined(__FreeBSD__ ) || defined(__APPLE__ ) || defined(__OpenBSD__ )
38+ #if defined(__linux__ ) || defined(__FreeBSD__ ) || defined(__APPLE__ ) || defined(__OpenBSD__ ) || defined( __NetBSD__ )
3939# include <pthread.h>
4040#endif
4141#ifdef __FreeBSD__
@@ -51,6 +51,10 @@ typedef int boolean_t;
5151# include <sys/sysctl.h>
5252# include <sys/user.h>
5353#endif
54+ #ifdef __NetBSD__
55+ # include <sys/sysctl.h>
56+ # include <sys/syscall.h>
57+ #endif
5458#ifdef __linux__
5559#include <sys/syscall.h>
5660#endif
@@ -504,6 +508,119 @@ static bool zend_call_stack_get_openbsd(zend_call_stack *stack)
504508}
505509#endif /* defined(__OpenBSD__) */
506510
511+ #if defined(__NetBSD__ )
512+ # ifdef HAVE_PTHREAD_GETATTR_NP
513+ static bool zend_call_stack_get_netbsd_pthread (zend_call_stack * stack )
514+ {
515+ pthread_attr_t attr ;
516+ int error ;
517+ void * addr ;
518+ size_t max_size , guard_size ;
519+
520+ error = pthread_getattr_np (pthread_self (), & attr );
521+ if (error ) {
522+ return false;
523+ }
524+
525+ error = pthread_attr_getstack (& attr , & addr , & max_size );
526+ if (error ) {
527+ return false;
528+ }
529+
530+ error = pthread_attr_getguardsize (& attr , & guard_size );
531+ if (error ) {
532+ return false;
533+ }
534+
535+ addr = (char * )addr + guard_size ;
536+ max_size -= guard_size ;
537+
538+ stack -> base = (char * )addr + max_size ;
539+ stack -> max_size = max_size ;
540+
541+ return true;
542+ }
543+ # else
544+ static bool zend_call_stack_get_netbsd_pthread (zend_call_stack * stack )
545+ {
546+ return false;
547+ }
548+ # endif /* HAVE_PTHREAD_GETATTR_NP */
549+ static bool zend_call_stack_get_netbsd_vm (zend_call_stack * stack , void * * ptr )
550+ {
551+ /**
552+ * NetBSD supports procfs in a similar fashion as Linux
553+ * however NetBSD's mid/long term plan is to remove it completely.
554+ */
555+ char * start , * end ;
556+ struct kinfo_vmentry * entry ;
557+ size_t len , max_size ;
558+ char buffer [4096 ];
559+ uintptr_t addr_on_stack = (uintptr_t )& buffer ;
560+ int mib [5 ] = { CTL_VM , VM_PROC , VM_PROC_MAP , getpid (), sizeof (struct kinfo_vmentry ) };
561+ bool found = false;
562+ struct rlimit rlim ;
563+
564+ if (sysctl (mib , 5 , NULL , & len , NULL , 0 ) != 0 ) {
565+ return false;
566+ }
567+
568+ // kinfo_getvmmap uses the same formula, only we do not want to rely on libkvm
569+ len = len * 4 / 3 ;
570+ * ptr = malloc (len );
571+
572+ if (sysctl (mib , 5 , * ptr , & len , NULL , 0 ) != 0 ) {
573+ return false;
574+ }
575+
576+ start = (char * )* ptr ;
577+ end = start + len ;
578+
579+ while (start < end ) {
580+ entry = (struct kinfo_vmentry * )start ;
581+ if (entry -> kve_start <= addr_on_stack && entry -> kve_end >= addr_on_stack ) {
582+ found = true;
583+ break ;
584+ }
585+
586+ start += sizeof (struct kinfo_vmentry );
587+ }
588+
589+ if (!found ) {
590+ return false;
591+ }
592+
593+ if (getrlimit (RLIMIT_STACK , & rlim ) || rlim .rlim_cur == RLIM_INFINITY ) {
594+ return false;
595+ }
596+
597+ max_size = rlim .rlim_cur ;
598+
599+ stack -> base = (void * )entry -> kve_end ;
600+ stack -> max_size = max_size ;
601+
602+ return true;
603+ }
604+
605+
606+ static bool zend_call_stack_get_netbsd (zend_call_stack * stack )
607+ {
608+ if (syscall (SYS__lwp_self ) == 1 ) {
609+ void * ptr = NULL ;
610+ bool r = zend_call_stack_get_netbsd_vm (stack , & ptr );
611+ free (ptr );
612+ return r ;
613+ }
614+
615+ return zend_call_stack_get_netbsd_pthread (stack );
616+ }
617+ #else
618+ static bool zend_call_stack_get_netbsd (zend_call_stack * stack )
619+ {
620+ return false;
621+ }
622+ #endif /* defined(__NetBSD__) */
623+
507624/** Get the stack information for the calling thread */
508625ZEND_API bool zend_call_stack_get (zend_call_stack * stack )
509626{
@@ -527,6 +644,10 @@ ZEND_API bool zend_call_stack_get(zend_call_stack *stack)
527644 return true;
528645 }
529646
647+ if (zend_call_stack_get_netbsd (stack )) {
648+ return true;
649+ }
650+
530651 return false;
531652}
532653
0 commit comments