Beispiel #1
0
GSList*
mono_w32process_get_modules (pid_t pid)
{
	GSList *ret = NULL;
	MonoW32ProcessModule *mod;
	guint32 count;
	int i = 0;

	if (pid != getpid ())
		return NULL;

	count = _dyld_image_count ();
	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;

		name = _dyld_get_image_name (i);
#if SIZEOF_VOID_P == 8
		hdr = (const struct mach_header_64*)_dyld_get_image_header (i);
		sec = getsectbynamefromheader_64 (hdr, SEG_DATA, SECT_DATA);
#else
		hdr = _dyld_get_image_header (i);
		sec = getsectbynamefromheader (hdr, SEG_DATA, SECT_DATA);
#endif

		/* Some dynlibs do not have data sections on osx (#533893) */
		if (sec == 0)
			continue;

		mod = g_new0 (MonoW32ProcessModule, 1);
		mod->address_start = GINT_TO_POINTER (sec->addr);
		mod->address_end = GINT_TO_POINTER (sec->addr+sec->size);
		mod->perms = g_strdup ("r--p");
		mod->address_offset = 0;
		mod->device = makedev (0, 0);
		mod->inode = i;
		mod->filename = g_strdup (name);

		if (g_slist_find_custom (ret, mod, mono_w32process_module_equals) == NULL) {
			ret = g_slist_prepend (ret, mod);
		} else {
			mono_w32process_module_free (mod);
		}
	}

	return g_slist_reverse (ret);
}
Beispiel #2
0
GSList*
mono_w32process_get_modules (pid_t pid)
{
	GSList *ret = NULL;
	MonoW32ProcessModule *mod;
	GPtrArray *dlarray = g_ptr_array_new();
	gint i;

	if (dl_iterate_phdr (mono_w32process_get_modules_callback, dlarray) < 0)
		return NULL;

	for (i = 0; i < dlarray->len; i++) {
		struct dl_phdr_info *info = g_ptr_array_index (dlarray, i);

		mod = g_new0 (MonoW32ProcessModule, 1);
		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 = i;
		mod->filename = g_strdup (info->dlpi_name);

		mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_PROCESS, "%s: inode=%d, filename=%s, address_start=%p, address_end=%p",
			__func__, mod->inode, mod->filename, mod->address_start, mod->address_end);

		g_free (info);

		if (g_slist_find_custom (ret, mod, mono_w32process_module_equals) == NULL) {
			ret = g_slist_prepend (ret, mod);
		} else {
			mono_w32process_module_free (mod);
		}
	}

	g_ptr_array_free (dlarray, TRUE);

	return g_slist_reverse (ret);
}
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);
}