Flush (work in progress)
[mono.git] / mono / io-layer / processes.c
index df8f660b129daf4032829244a59781452aaf773d..57f6bab425211888e849077b8dd7d62869ae54e7 100644 (file)
 #endif
 #endif
 
+#ifdef __HAIKU__
+#include <KernelKit.h>
+#endif
+
 #include <mono/io-layer/wapi.h>
 #include <mono/io-layer/wapi-private.h>
 #include <mono/io-layer/handles-private.h>
@@ -1533,17 +1537,17 @@ gboolean EnumProcesses (guint32 *pids, guint32 len, guint32 *needed)
        name[2] = KERN_PROC_ALL;
        name[3] = 0;
        name[4] = sizeof(struct kinfo_proc2);
-       name[5] = 400; /* XXX */
+       name[5] = 0;
 #else
        struct kinfo_proc *result;
        static const int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0 };
 #endif
-       
+
        mono_once (&process_current_once, process_set_current);
-       
+
        result = NULL;
        done = FALSE;
-       
+
        do {
                proclength = 0;
 #if defined(__OpenBSD__)
@@ -1558,7 +1562,11 @@ gboolean EnumProcesses (guint32 *pids, guint32 len, guint32 *needed)
 
                        if (result == NULL)
                                return FALSE;
-                       
+
+#if defined(__OpenBSD__)
+                       name[5] = (int)(proclength / sizeof(struct kinfo_proc2));
+#endif
+
                        err = sysctl ((int *) name, size, result, &proclength, NULL, 0);
 
                        if (err == 0) 
@@ -1595,6 +1603,24 @@ gboolean EnumProcesses (guint32 *pids, guint32 len, guint32 *needed)
        
        return(TRUE);
 }
+#elif defined(__HAIKU__)
+
+gboolean EnumProcesses (guint32 *pids, guint32 len, guint32 *needed)
+{
+       guint32 fit, i = 0;
+       int32 cookie = 0;
+       team_info teamInfo;
+
+       mono_once (&process_current_once, process_set_current);
+
+       fit = len / sizeof (guint32);
+       while (get_next_team_info (&cookie, &teamInfo) == B_OK && i < fit) {
+               pids [i++] = teamInfo.team;
+       }
+       *needed = i * sizeof (guint32);
+
+       return TRUE;
+}
 #else
 gboolean EnumProcesses (guint32 *pids, guint32 len, guint32 *needed)
 {
@@ -1681,6 +1707,9 @@ gpointer OpenProcess (guint32 req_access G_GNUC_UNUSED, gboolean inherit G_GNUC_
        if (handle == 0) {
 #if defined(__OpenBSD__)
                if ((kill(pid, 0) == 0) || (errno == EPERM)) {
+#elif defined(__HAIKU__)
+               team_info teamInfo;
+               if (get_team_info ((team_id)pid, &teamInfo) == B_OK) {
 #else
                gchar *dir = g_strdup_printf ("/proc/%d", pid);
                if (!access (dir, F_OK)) {
@@ -1862,15 +1891,24 @@ static GSList *load_modules (void)
        int i = 0;
 
        for (i = 0; i < count; i++) {
+#if SIZEOF_VOID_P == 8
+               const struct mach_header_64 *hdr;
+               const struct section_64 *sec;
+#else
                const struct mach_header *hdr;
                const struct section *sec;
+#endif
                const char *name;
                intptr_t slide;
 
                slide = _dyld_get_image_vmaddr_slide (i);
                name = _dyld_get_image_name (i);
                hdr = _dyld_get_image_header (i);
+#if SIZEOF_VOID_P == 8
+               sec = getsectbynamefromheader_64 (hdr, SEG_DATA, SECT_DATA);
+#else
                sec = getsectbynamefromheader (hdr, SEG_DATA, SECT_DATA);
+#endif
 
                /* Some dynlibs do not have data sections on osx (#533893) */
                if (sec == 0) {
@@ -1901,7 +1939,6 @@ static GSList *load_modules (void)
 #include <link.h>
 static int load_modules_callback (struct dl_phdr_info *info, size_t size, void *ptr)
 {
-
        if (size < offsetof (struct dl_phdr_info, dlpi_phnum)
            + sizeof (info->dlpi_phnum))
                return (-1);
@@ -1928,21 +1965,22 @@ static GSList *load_modules (void)
                return (ret);
 
        for (i = 0; i < dlarray->len; i++) {
-               int j;
-               char *end = NULL;
-
                struct dl_phdr_info *info = g_ptr_array_index (dlarray, i);
-               for (j = 0; j < info->dlpi_phnum; j++)
-                       end = (char *)(info->dlpi_addr + info->dlpi_phdr[j].p_vaddr);
 
                mod = g_new0 (WapiProcModule, 1);
-               mod->address_start = GINT_TO_POINTER(info->dlpi_addr);
-               mod->address_end = end;
+               mod->address_start = (gpointer)(info->dlpi_addr + info->dlpi_phdr[0].p_vaddr);
+               mod->address_end = (gpointer)(info->dlpi_addr +
+                                       info->dlpi_phdr[info->dlpi_phnum - 1].p_vaddr);
                mod->perms = g_strdup ("r--p");
                mod->address_offset = 0;
                mod->inode = (ino_t) i;
                mod->filename = g_strdup (info->dlpi_name); 
 
+#ifdef DEBUG
+               g_message ("%s: inode=%d, filename=%s, address_start=%p, address_end=%p", __func__,
+                                  mod->inode, mod->filename, mod->address_start, mod->address_end);
+#endif
+
                free(info);
 
                if (g_slist_find_custom (ret, mod, find_procmodule) == NULL) {
@@ -1958,6 +1996,37 @@ static GSList *load_modules (void)
 
        return(ret);
 }
+#elif defined(__HAIKU__)
+
+static GSList *load_modules (void)
+{
+       GSList *ret = NULL;
+       WapiProcModule *mod;
+       int32 cookie = 0;
+       image_info imageInfo;
+
+       while (get_next_image_info (B_CURRENT_TEAM, &cookie, &imageInfo) == B_OK) {
+               mod = g_new0 (WapiProcModule, 1);
+               mod->device = imageInfo.device;
+               mod->inode = imageInfo.node;
+               mod->filename = g_strdup (imageInfo.name);
+               mod->address_start = MIN (imageInfo.text, imageInfo.data);
+               mod->address_end = MAX ((uint8_t*)imageInfo.text + imageInfo.text_size,
+                       (uint8_t*)imageInfo.data + imageInfo.data_size);
+               mod->perms = g_strdup ("r--p");
+               mod->address_offset = 0;
+
+               if (g_slist_find_custom (ret, mod, find_procmodule) == NULL) {
+                       ret = g_slist_prepend (ret, mod);
+               } else {
+                       free_procmodule (mod);
+               }
+       }
+
+       ret = g_slist_reverse (ret);
+
+       return ret;
+}
 #else
 static GSList *load_modules (FILE *fp)
 {
@@ -2176,7 +2245,7 @@ gboolean EnumProcessModules (gpointer process, gpointer *modules,
                proc_name = process_handle->proc_name;
        }
        
-#if defined(PLATFORM_MACOSX) || defined(__OpenBSD__)
+#if defined(PLATFORM_MACOSX) || defined(__OpenBSD__) || defined(__HAIKU__)
        {
                mods = load_modules ();
 #else
@@ -2224,10 +2293,12 @@ gboolean EnumProcessModules (gpointer process, gpointer *modules,
 
 static gchar *get_process_name_from_proc (pid_t pid)
 {
+#if !defined(__OpenBSD__)
+       FILE *fp;
        gchar *filename = NULL;
-       gchar *ret = NULL;
        gchar buf[256];
-       FILE *fp;
+#endif
+       gchar *ret = NULL;
 
 #if defined(PLATFORM_SOLARIS)
        filename = g_strdup_printf ("/proc/%d/psinfo", pid);
@@ -2248,6 +2319,47 @@ static gchar *get_process_name_from_proc (pid_t pid)
        proc_name (pid, buf, sizeof(buf));
        if (strlen (buf) > 0)
                ret = g_strdup (buf);
+#elif defined(__OpenBSD__)
+       int mib [6];
+       size_t size;
+       struct kinfo_proc2 *pi;
+
+       mib [0] = CTL_KERN;
+       mib [1] = KERN_PROC2;
+       mib [2] = KERN_PROC_PID;
+       mib [3] = pid;
+       mib [4] = sizeof(struct kinfo_proc2);
+       mib [5] = 0;
+
+retry:
+       if (sysctl(mib, 6, NULL, &size, NULL, 0) < 0)
+               return(ret);
+
+       if ((pi = malloc(size)) == NULL)
+               return(ret);
+
+       mib[5] = (int)(size / sizeof(struct kinfo_proc2));
+
+       if ((sysctl (mib, 6, pi, &size, NULL, 0) < 0) ||
+               (size != sizeof (struct kinfo_proc2))) {
+               if (errno == ENOMEM) {
+                       free(pi);
+                       goto retry;
+               }
+               return(ret);
+       }
+
+       if (strlen (pi->p_comm) > 0)
+               ret = g_strdup (pi->p_comm);
+
+       free(pi);
+#elif defined(__HAIKU__)
+       image_info imageInfo;
+       int32 cookie = 0;
+
+       if (get_next_image_info ((team_id)pid, &cookie, &imageInfo) == B_OK) {
+               ret = g_strdup (imageInfo.name);
+       }
 #else
        memset (buf, '\0', sizeof(buf));
        filename = g_strdup_printf ("/proc/%d/exe", pid);
@@ -2355,7 +2467,7 @@ static guint32 get_module_name (gpointer process, gpointer module,
        }
 
        /* Look up the address in /proc/<pid>/maps */
-#if defined(PLATFORM_MACOSX) || defined(__OpenBSD__)
+#if defined(PLATFORM_MACOSX) || defined(__OpenBSD__) || defined(__HAIKU__)
        {
                mods = load_modules ();
 #else
@@ -2507,7 +2619,7 @@ gboolean GetModuleInformation (gpointer process, gpointer module,
                proc_name = g_strdup (process_handle->proc_name);
        }
 
-#if defined(PLATFORM_MACOSX) || defined(__OpenBSD__)
+#if defined(PLATFORM_MACOSX) || defined(__OpenBSD__) || defined(__HAIKU__)
        {
                mods = load_modules ();
 #else