GSList* mono_w32process_get_modules (pid_t pid) { #if defined(_AIX) /* due to procfs, this won't work on i */ GSList *ret = NULL; FILE *fp; MonoW32ProcessModule *mod; struct prmap module; int i; fpos64_t curpos; char pidpath[32]; /* "/proc/<uint64_t max>/map" plus null, rounded */ char libpath[MAXPATHLEN + 1]; char membername[MAXPATHLEN + 1]; char combinedname[(MAXPATHLEN * 2) + 3]; /* lib, member, (), and nul */ sprintf (pidpath, "/proc/%d/map", pid); if ((fp = fopen(pidpath, "r"))) { while (fread (&module, sizeof (module), 1, fp) == 1 /* proc(4) declares such a struct to be the array terminator */ && (module.pr_size != 0 && module.pr_mflags != 0) && (module.pr_mflags & MA_READ)) { fgetpos64 (fp, &curpos); /* save our position */ fseeko (fp, module.pr_pathoff, SEEK_SET); while ((libpath[i++] = fgetc (fp))); i = 0; while ((membername[i++] = fgetc (fp))); i = 0; fsetpos64 (fp, &curpos); /* back to normal */ mod = g_new0 (MonoW32ProcessModule, 1); mod->address_start = module.pr_vaddr; mod->address_end = module.pr_vaddr + module.pr_size; mod->address_offset = module.pr_off; mod->perms = g_strdup ("r--p"); /* XXX? */ /* AIX has what appears to be device, channel and inode information, * but it's in a string. Try parsing it. * * XXX: I believe it's fstype.devno.chano.inode, but I'm uncertain * as to how that maps out, so I only fill in the inode (like BSD) */ sscanf (module.pr_mapname, "%*[^.].%*lu.%*u.%lu", &(mod->inode)); if (membername[0]) { snprintf(combinedname, MAXPATHLEN, "%s(%s)", libpath, membername); mod->filename = g_strdup (combinedname); } else { mod->filename = g_strdup (libpath); } if (g_slist_find_custom (ret, mod, mono_w32process_module_equals) == NULL) { ret = g_slist_prepend (ret, mod); } else { mono_w32process_module_free (mod); } } } else { mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_PROCESS, "%s: Can't open process map file for pid %d", __func__, pid); return NULL; } if (ret) ret = g_slist_reverse (ret); fclose (fp); return(ret); #else GSList *ret = NULL; FILE *fp; MonoW32ProcessModule *mod; gchar buf[MAXPATHLEN + 1], *p, *endp; gchar *start_start, *end_start, *prot_start, *offset_start; gchar *maj_dev_start, *min_dev_start, *inode_start, prot_buf[5]; gpointer address_start, address_end, address_offset; guint32 maj_dev, min_dev; guint64 inode; guint64 device; fp = open_process_map (pid, "r"); if (!fp) { mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_PROCESS, "%s: Can't open process map file for pid %d", __func__, pid); return NULL; } while (fgets (buf, sizeof(buf), fp)) { p = buf; while (g_ascii_isspace (*p)) ++p; start_start = p; if (!g_ascii_isxdigit (*start_start)) { continue; } address_start = (gpointer)strtoul (start_start, &endp, 16); p = endp; if (*p != '-') { continue; } ++p; end_start = p; if (!g_ascii_isxdigit (*end_start)) { continue; } address_end = (gpointer)strtoul (end_start, &endp, 16); p = endp; if (!g_ascii_isspace (*p)) { continue; } while (g_ascii_isspace (*p)) ++p; prot_start = p; if (*prot_start != 'r' && *prot_start != '-') { continue; } memcpy (prot_buf, prot_start, 4); prot_buf[4] = '\0'; while (!g_ascii_isspace (*p)) ++p; while (g_ascii_isspace (*p)) ++p; offset_start = p; if (!g_ascii_isxdigit (*offset_start)) { continue; } address_offset = (gpointer)strtoul (offset_start, &endp, 16); p = endp; if (!g_ascii_isspace (*p)) { continue; } while(g_ascii_isspace (*p)) ++p; maj_dev_start = p; if (!g_ascii_isxdigit (*maj_dev_start)) { continue; } maj_dev = strtoul (maj_dev_start, &endp, 16); p = endp; if (*p != ':') { continue; } ++p; min_dev_start = p; if (!g_ascii_isxdigit (*min_dev_start)) { continue; } min_dev = strtoul (min_dev_start, &endp, 16); p = endp; if (!g_ascii_isspace (*p)) { continue; } while (g_ascii_isspace (*p)) ++p; inode_start = p; if (!g_ascii_isxdigit (*inode_start)) { continue; } inode = (guint64)strtol (inode_start, &endp, 10); p = endp; if (!g_ascii_isspace (*p)) { continue; } #if defined(MAJOR_IN_MKDEV) || defined(MAJOR_IN_SYSMACROS) device = makedev ((int)maj_dev, (int)min_dev); #else device = 0; #endif if ((device == 0) && (inode == 0)) { continue; } while(g_ascii_isspace (*p)) ++p; /* p now points to the filename */ mod = g_new0 (MonoW32ProcessModule, 1); mod->address_start = address_start; mod->address_end = address_end; mod->perms = g_strdup (prot_buf); mod->address_offset = address_offset; mod->device = device; mod->inode = inode; mod->filename = g_strdup (g_strstrip (p)); if (g_slist_find_custom (ret, mod, mono_w32process_module_equals) == NULL) { ret = g_slist_prepend (ret, mod); } else { mono_w32process_module_free (mod); } } ret = g_slist_reverse (ret); fclose (fp); return(ret); #endif }
GSList* mono_w32process_get_modules (pid_t pid) { GSList *ret = NULL; FILE *fp; MonoW32ProcessModule *mod; gchar buf[MAXPATHLEN + 1], *p, *endp; gchar *start_start, *end_start, *prot_start, *offset_start; gchar *maj_dev_start, *min_dev_start, *inode_start, prot_buf[5]; gpointer address_start, address_end, address_offset; guint32 maj_dev, min_dev; guint64 inode; guint64 device; fp = open_process_map (pid, "r"); if (!fp) return NULL; while (fgets (buf, sizeof(buf), fp)) { p = buf; while (g_ascii_isspace (*p)) ++p; start_start = p; if (!g_ascii_isxdigit (*start_start)) { continue; } address_start = (gpointer)strtoul (start_start, &endp, 16); p = endp; if (*p != '-') { continue; } ++p; end_start = p; if (!g_ascii_isxdigit (*end_start)) { continue; } address_end = (gpointer)strtoul (end_start, &endp, 16); p = endp; if (!g_ascii_isspace (*p)) { continue; } while (g_ascii_isspace (*p)) ++p; prot_start = p; if (*prot_start != 'r' && *prot_start != '-') { continue; } memcpy (prot_buf, prot_start, 4); prot_buf[4] = '\0'; while (!g_ascii_isspace (*p)) ++p; while (g_ascii_isspace (*p)) ++p; offset_start = p; if (!g_ascii_isxdigit (*offset_start)) { continue; } address_offset = (gpointer)strtoul (offset_start, &endp, 16); p = endp; if (!g_ascii_isspace (*p)) { continue; } while(g_ascii_isspace (*p)) ++p; maj_dev_start = p; if (!g_ascii_isxdigit (*maj_dev_start)) { continue; } maj_dev = strtoul (maj_dev_start, &endp, 16); p = endp; if (*p != ':') { continue; } ++p; min_dev_start = p; if (!g_ascii_isxdigit (*min_dev_start)) { continue; } min_dev = strtoul (min_dev_start, &endp, 16); p = endp; if (!g_ascii_isspace (*p)) { continue; } while (g_ascii_isspace (*p)) ++p; inode_start = p; if (!g_ascii_isxdigit (*inode_start)) { continue; } inode = (guint64)strtol (inode_start, &endp, 10); p = endp; if (!g_ascii_isspace (*p)) { continue; } device = makedev ((int)maj_dev, (int)min_dev); if ((device == 0) && (inode == 0)) { continue; } while(g_ascii_isspace (*p)) ++p; /* p now points to the filename */ mod = g_new0 (MonoW32ProcessModule, 1); mod->address_start = address_start; mod->address_end = address_end; mod->perms = g_strdup (prot_buf); mod->address_offset = address_offset; mod->device = device; mod->inode = inode; mod->filename = g_strdup (g_strstrip (p)); if (g_slist_find_custom (ret, mod, mono_w32process_module_equals) == NULL) { ret = g_slist_prepend (ret, mod); } else { mono_w32process_module_free (mod); } } ret = g_slist_reverse (ret); fclose (fp); return(ret); }