aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Graf <agraf@suse.de>2012-03-12 14:01:36 +0000
committerPeter Maydell <peter.maydell@linaro.org>2012-03-12 14:51:11 +0000
commitdb7e95865ad1d3c1f67d8d91ec7a1e4f415546ab (patch)
tree88192edebeb851005edf65e535812b6000d82515
parent7ca6aaa648d10d7334827619af48a60b6c31c17d (diff)
linux-user: improve emulation of /proc/self/maps2012.03.rebasing
Improve the emulation of /proc/self/maps by reading the underlying host maps file and passing lines through with addresses adjusted to be guest addresses. PMM: This is a combination of commits 1e34dbb1, 8132af00 and 9a860d42 from Alex's suse-1.0 branch; these should eventually be submitted upstream.
-rw-r--r--linux-user/syscall.c42
1 files changed, 41 insertions, 1 deletions
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index f6a46833b..8363fee64 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4640,13 +4640,53 @@ int get_osversion(void)
static int open_self_maps(void *cpu_env, int fd)
{
+#if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
TaskState *ts = ((CPUState *)cpu_env)->opaque;
+#endif
+ FILE *fp;
+ char *line = NULL;
+ size_t len = 0;
+ ssize_t read;
+
+ fp = fopen("/proc/self/maps", "r");
+ if (fp == NULL) {
+ return -EACCES;
+ }
+ while ((read = getline(&line, &len, fp)) != -1) {
+ int fields, dev_maj, dev_min, inode;
+ uint64_t min, max, offset;
+ char flag_r, flag_w, flag_x, flag_p;
+ char path[512] = "";
+ fields = sscanf(line, "%"PRIx64"-%"PRIx64" %c%c%c%c %"PRIx64" %x:%x %d"
+ " %512s", &min, &max, &flag_r, &flag_w, &flag_x,
+ &flag_p, &offset, &dev_maj, &dev_min, &inode, path);
+
+ if ((fields < 10) || (fields > 11)) {
+ continue;
+ }
+ if (!strncmp(path, "[stack]", 7)) {
+ continue;
+ }
+ if (h2g_valid(min) && h2g_valid(max)) {
+ dprintf(fd, TARGET_ABI_FMT_lx "-" TARGET_ABI_FMT_lx
+ " %c%c%c%c %08" PRIx64 " %02x:%02x %d%s%s\n",
+ h2g(min), h2g(max), flag_r, flag_w,
+ flag_x, flag_p, offset, dev_maj, dev_min, inode,
+ path[0] ? " " : "", path);
+ }
+ }
+
+ free(line);
+ fclose(fp);
+
+#if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
dprintf(fd, "%08llx-%08llx rw-p %08llx 00:00 0 [stack]\n",
(unsigned long long)ts->info->stack_limit,
(unsigned long long)(ts->stack_base + (TARGET_PAGE_SIZE - 1))
& TARGET_PAGE_MASK,
- (unsigned long long)ts->stack_base);
+ (unsigned long long)0);
+#endif
return 0;
}