35
35
# include <sys/types.h>
36
36
# endif
37
37
#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__ )
39
39
# include <pthread.h>
40
40
#endif
41
41
#ifdef __FreeBSD__
@@ -51,6 +51,10 @@ typedef int boolean_t;
51
51
# include <sys/sysctl.h>
52
52
# include <sys/user.h>
53
53
#endif
54
+ #ifdef __NetBSD__
55
+ # include <sys/sysctl.h>
56
+ # include <sys/syscall.h>
57
+ #endif
54
58
#ifdef __linux__
55
59
#include <sys/syscall.h>
56
60
#endif
@@ -504,6 +508,119 @@ static bool zend_call_stack_get_openbsd(zend_call_stack *stack)
504
508
}
505
509
#endif /* defined(__OpenBSD__) */
506
510
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
+
507
624
/** Get the stack information for the calling thread */
508
625
ZEND_API bool zend_call_stack_get (zend_call_stack * stack )
509
626
{
@@ -527,6 +644,10 @@ ZEND_API bool zend_call_stack_get(zend_call_stack *stack)
527
644
return true;
528
645
}
529
646
647
+ if (zend_call_stack_get_netbsd (stack )) {
648
+ return true;
649
+ }
650
+
530
651
return false;
531
652
}
532
653
0 commit comments