this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat(proc_info): Implement additional flavors

Additional flavors are implemented: PIDTASKINFO, PIDTASKALLINFO, PIDLISTTHREADS.
Furthermore, PIDTBSDINFO gets a valid pbi_start_tvsec and pbi_start_tvusec

+247 -3
+7
src/kernel/emulation/linux/elfcalls_wrapper.c
··· 26 26 _elfcalls->exit(ec); 27 27 } 28 28 29 + long native_sysconf(int name) 30 + { 31 + if (_elfcalls) 32 + return _elfcalls->sysconf(name); 33 + return -1; 34 + } 35 + 29 36 void* __darling_thread_create(unsigned long stack_size, unsigned long pthobj_size, 30 37 void* entry_point, uintptr_t arg3, 31 38 uintptr_t arg4, uintptr_t arg5, uintptr_t arg6,
+2
src/kernel/emulation/linux/elfcalls_wrapper.h
··· 15 15 16 16 void native_exit(int ec); 17 17 18 + long native_sysconf(int name); 19 + 18 20 // Native thread wrapping 19 21 void* __darling_thread_create(unsigned long stack_size, unsigned long pthobj_size, 20 22 void* entry_point, uintptr_t arg3,
+231 -3
src/kernel/emulation/linux/misc/proc_info.c
··· 6 6 #include <sys/errno.h> 7 7 #include <sys/proc_info.h> 8 8 #include <mach/vm_prot.h> 9 + #include "../dirent/getdirentries.h" 9 10 #include "../ext/syslog.h" 10 11 #include "../fcntl/open.h" 11 12 #include "../unistd/close.h" ··· 22 23 #include <lkm/api.h> 23 24 #include "../mach/lkm.h" 24 25 #include "sysctl_proc.h" 26 + #include <stddef.h> 27 + #include "../elfcalls_wrapper.h" 25 28 26 29 #define LINUX_PR_SET_NAME 15 27 30 ··· 32 35 extern void *memcpy(void *dest, const void *src, __SIZE_TYPE__ n); 33 36 extern char *strcpy(char *dest, const char *src); 34 37 extern char *strncpy(char *dest, const char *src, __SIZE_TYPE__ n); 38 + extern int strncmp (const char * str1, const char * str2, __SIZE_TYPE__ num); 39 + extern char *strchr(char *str, int character); 35 40 36 41 long sys_proc_info(uint32_t callnum, int32_t pid, uint32_t flavor, 37 42 uint64_t arg, void* buffer, int32_t bufsize) ··· 98 103 static long _proc_pidinfo_pidthreadinfo(int32_t pid, uint64_t thread_handle, void* buffer, int32_t bufsize); 99 104 static long _proc_pidinfo_pathinfo(int32_t pid, void* buffer, int32_t bufsize); 100 105 static long _proc_pidinfo_regionpath(int32_t pid, uint64_t arg, void* buffer, int32_t buffer_size); 106 + static long _proc_pidinfo_taskinfo(int32_t pid, void* buffer, int32_t bufsize); 107 + static long _proc_pidinfo_taskallinfo(int32_t pid, void* buffer, int32_t bufsize); 108 + static long _proc_pidinfo_listthreads(int32_t pid, void* buffer, int32_t bufsize); 101 109 102 110 long _proc_pidinfo(int32_t pid, uint32_t flavor, uint64_t arg, void* buffer, int32_t bufsize) 103 111 { ··· 135 143 { 136 144 return _proc_pidinfo_regionpath(pid, arg, buffer, bufsize); 137 145 } 146 + case PROC_PIDTASKINFO: 147 + { 148 + return _proc_pidinfo_taskinfo(pid, buffer, bufsize); 149 + } 150 + case PROC_PIDTASKALLINFO: 151 + { 152 + return _proc_pidinfo_taskallinfo(pid, buffer, bufsize); 153 + } 154 + case PROC_PIDLISTTHREADS: 155 + { 156 + return _proc_pidinfo_listthreads(pid, buffer, bufsize); 157 + } 138 158 default: 139 159 { 140 160 __simple_printf("sys_proc_info(): Unsupported pidinfo flavor: %d\n", ··· 215 235 return 1; 216 236 } 217 237 238 + // glibc bits/confname.h 239 + #define _SC_CLK_TCK 2 240 + 218 241 static long _proc_pidinfo_tbsdinfo(int32_t pid, void* buffer, int32_t bufsize) 219 242 { 220 243 struct proc_bsdinfo* info = (struct proc_bsdinfo*) buffer; ··· 241 264 info->pbi_svuid = shortinfo.pbsi_svuid; 242 265 info->pbi_svgid = shortinfo.pbsi_svgid; 243 266 info->pbi_pgid = shortinfo.pbsi_pgid; 244 - // info->pbi_nice 245 - // info->pbi_start 267 + 268 + char path[64], stat[4096]; 269 + char *statptr; 270 + const char* elem; 271 + 272 + __simple_sprintf(path, "/proc/%d/stat", pid); 273 + if (!read_string(path, stat, sizeof(stat))) 274 + return -ESRCH; 275 + 276 + #define READELEM() elem = next_stat_elem(&statptr); if (!elem) goto reterr 277 + 278 + statptr = stat; 279 + skip_stat_elems(&statptr, 18); // skip until ppid 280 + 281 + READELEM(); 282 + info->pbi_nice = elem[0] == '-' ? -__simple_atoi(elem + 1, NULL) : __simple_atoi(elem, NULL); 283 + 284 + skip_stat_elems(&statptr, 2); // skip until starttime 285 + READELEM(); 286 + 287 + uint64_t starttime = __simple_atoi(elem, NULL); 288 + 289 + if (!read_string("/proc/stat", stat, sizeof(stat))) 290 + return -ESRCH; 291 + 292 + statptr = stat; 293 + 294 + uint64_t btime; 295 + 296 + while (statptr < stat + sizeof(stat)) 297 + { 298 + if (strncmp(statptr, "btime ", 6) == 0) 299 + { 300 + statptr += 6; 301 + btime = __simple_atoi(statptr, NULL); 302 + break; 303 + } 304 + 305 + char* next = strchr(statptr, '\n'); 306 + if (!next) 307 + return -ESRCH; 308 + 309 + statptr = next + 1; 310 + } 311 + 312 + long ticks_per_sec = native_sysconf(_SC_CLK_TCK); 313 + uint64_t starttime_secs = starttime / ticks_per_sec; 314 + uint64_t starttime_usecs = (starttime % ticks_per_sec) * 1000000 / ticks_per_sec; 315 + 316 + info->pbi_start_tvsec = btime + starttime_secs; 317 + info->pbi_start_tvusec = starttime_usecs; 246 318 247 319 memcpy(info->pbi_comm, shortinfo.pbsi_comm, sizeof(info->pbi_comm)); 248 320 249 - return err; 321 + return sizeof(struct proc_bsdinfo); 322 + reterr: 323 + return -EINVAL; 250 324 } 251 325 252 326 static long _proc_pidinfo_pidthreadinfo(int32_t pid, uint64_t thread_handle, void* buffer, int32_t bufsize) ··· 583 657 strncpy(buffer, args.path, bufsize); 584 658 return strlen(args.path); 585 659 } 660 + 661 + static long _proc_pidinfo_taskinfo(int32_t pid, void* buffer, int32_t bufsize) 662 + { 663 + if (!buffer) 664 + return -EFAULT; 665 + if (bufsize < sizeof(struct proc_taskinfo)) 666 + return -ENOSPC; 667 + 668 + char path[64], stat[1024]; 669 + char *statptr; 670 + const char* elem; 671 + 672 + memset(buffer, 0, bufsize); 673 + struct proc_taskinfo* ti = (struct proc_taskinfo*) buffer; 674 + 675 + __simple_sprintf(path, "/proc/%d/stat", pid); 676 + if (!read_string(path, stat, sizeof(stat))) 677 + return -ESRCH; 678 + 679 + #define READELEM() elem = next_stat_elem(&statptr); if (!elem) goto reterr 680 + 681 + statptr = stat; 682 + skip_stat_elems(&statptr, 9); // skip until minflt 683 + READELEM(); 684 + int32_t minflt = __simple_atoi(elem, NULL); 685 + 686 + skip_stat_elems(&statptr, 1); // skip until majflt 687 + READELEM(); 688 + int32_t majflt = __simple_atoi(elem, NULL); 689 + 690 + skip_stat_elems(&statptr, 1); // skip until utime 691 + READELEM(); 692 + uint64_t utime = __simple_atoi(elem, NULL); 693 + 694 + READELEM(); 695 + uint64_t stime = __simple_atoi(elem, NULL); 696 + 697 + skip_stat_elems(&statptr, 2); // skip until priority 698 + READELEM(); 699 + // Can be negative, according to docs. 700 + int32_t priority = (elem[0] == '-') ? -__simple_atoi(elem + 1, NULL) : __simple_atoi(elem, NULL); 701 + 702 + skip_stat_elems(&statptr, 1); // skip until num_threads 703 + READELEM(); 704 + int32_t num_threads = __simple_atoi(elem, NULL); 705 + 706 + skip_stat_elems(&statptr, 2); // skip until vsize 707 + READELEM(); 708 + uint64_t vsize = __simple_atoi(elem, NULL); 709 + 710 + READELEM(); 711 + uint64_t rss = __simple_atoi(elem, NULL); 712 + 713 + ti->pti_virtual_size = vsize; 714 + ti->pti_resident_size = rss; 715 + ti->pti_total_user = utime; 716 + ti->pti_total_system = stime; 717 + // ti->pti_threads_user 718 + // ti->pti_threads_system 719 + // ti->pti_policy 720 + ti->pti_faults = minflt + majflt; 721 + // ti->pti_pageins 722 + // ti->pti_cow_faults 723 + // ti->pti_messages_sent 724 + // ti->pti_messages_received 725 + // ti->pti_syscalls_mach 726 + // ti->pti_syscalls_unix 727 + // ti->pti_csw 728 + ti->pti_threadnum = num_threads; 729 + // ti->pti_numrunning 730 + ti->pti_priority = priority; 731 + 732 + return sizeof(struct proc_taskinfo); 733 + reterr: 734 + return -EINVAL; 735 + } 736 + 737 + static long _proc_pidinfo_taskallinfo(int32_t pid, void* buffer, int32_t bufsize) 738 + { 739 + if (!buffer) 740 + return -EFAULT; 741 + if (bufsize < sizeof(struct proc_taskallinfo)) 742 + return -ENOSPC; 743 + 744 + long err = _proc_pidinfo_tbsdinfo(pid, buffer + offsetof(struct proc_taskallinfo, pbsd), sizeof(struct proc_bsdinfo)); 745 + 746 + if (err < 0) 747 + return err; 748 + 749 + err = _proc_pidinfo_taskinfo(pid, buffer + offsetof(struct proc_taskallinfo, ptinfo), sizeof(struct proc_taskinfo)); 750 + 751 + if (err < 0) 752 + return err; 753 + 754 + return sizeof(struct proc_taskallinfo); 755 + } 756 + 757 + #ifndef isdigit 758 + # define isdigit(c) (c >= '0' && c <= '9') 759 + #endif 760 + #ifndef DT_DIR 761 + # define DT_DIR 4 762 + #endif 763 + 764 + static long _proc_pidinfo_listthreads(int32_t pid, void* buffer, int32_t bufsize) 765 + { 766 + if (!buffer) 767 + return -EFAULT; 768 + 769 + uint64_t* threads = (uint64_t*)buffer; 770 + int32_t maxCount = bufsize / sizeof(uint64_t); 771 + int32_t count = 0; 772 + int fd, ret; 773 + long basep = 0; 774 + char dents[256]; 775 + char path[64]; 776 + 777 + __simple_sprintf(path, "/proc/%d/task", pid); 778 + 779 + fd = sys_open_nocancel(path, BSD_O_RDONLY | BSD_O_DIRECTORY, 0); 780 + if (fd < 0) 781 + return -ESRCH; 782 + 783 + while ((ret = sys_getdirentries(fd, (char*) dents, sizeof(dents), &basep)) > 0) 784 + { 785 + int pos = 0; 786 + 787 + while (pos < ret) 788 + { 789 + struct bsd_dirent* dent = (struct bsd_dirent*) &dents[pos]; 790 + 791 + if (dent->d_type != DT_DIR || !isdigit(dent->d_name[0])) 792 + { 793 + pos += dent->d_reclen; 794 + continue; 795 + } 796 + 797 + threads[count] = __simple_atoi(dent->d_name, NULL); 798 + ++count; 799 + 800 + if (count >= maxCount) 801 + { 802 + goto bail; 803 + return -ENOSPC; 804 + } 805 + 806 + pos += dent->d_reclen; 807 + } 808 + } 809 + 810 + bail: 811 + close_internal(fd); 812 + return count * sizeof(uint64_t); 813 + }
+4
src/libelfloader/native/elfcalls.c
··· 5 5 #include <sys/mman.h> 6 6 #include <semaphore.h> 7 7 #include <locale.h> 8 + #include <unistd.h> 8 9 #include "elfcalls.h" 9 10 #include "threads.h" 10 11 ··· 67 68 68 69 calls->get_errno = get_errno; 69 70 calls->exit = exit; 71 + 72 + calls->sysconf = sysconf; 73 + 70 74 *((void**)&calls->sem_open) = sem_open; 71 75 *((void**)&calls->sem_wait) = sem_wait; 72 76 *((void**)&calls->sem_trywait) = sem_trywait;
+3
src/libelfloader/native/elfcalls.h
··· 46 46 int (*shm_unlink)(const char* name); 47 47 48 48 void (*exit)(int ec); 49 + 50 + // POSIX sysconf 51 + long (*sysconf)(int name); 49 52 }; 50 53 51 54 #endif