Skip to content

Commit

Permalink
linux-user: Emulate /proc/self/smaps
Browse files Browse the repository at this point in the history
/proc/self/smaps is an extension of /proc/self/maps: it provides the
same lines, plus additional information about each range.

GDB uses /proc/self/smaps when available, which means that
generate-core-file tries it first before falling back to
/proc/self/maps. This, in turn, causes it to dump the host mappings,
since /proc/self/smaps is not emulated and is just passed through.

Fix by emulating /proc/self/smaps. Provide true values only for
Size, KernelPageSize, MMUPageSize and VmFlags. Leave all other values
at 0, which is a valid conservative estimate.

Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20230621203627.1808446-4-iii@linux.ibm.com>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20230630180423.558337-34-alex.bennee@linaro.org>
  • Loading branch information
iii-i authored and stsquad committed Jul 3, 2023
1 parent 35be898 commit 77ae576
Showing 1 changed file with 57 additions and 1 deletion.
58 changes: 57 additions & 1 deletion linux-user/syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -8042,7 +8042,36 @@ static int open_self_cmdline(CPUArchState *cpu_env, int fd)
return 0;
}

static int open_self_maps(CPUArchState *cpu_env, int fd)
static void show_smaps(int fd, unsigned long size)
{
unsigned long page_size_kb = TARGET_PAGE_SIZE >> 10;
unsigned long size_kb = size >> 10;

dprintf(fd, "Size: %lu kB\n"
"KernelPageSize: %lu kB\n"
"MMUPageSize: %lu kB\n"
"Rss: 0 kB\n"
"Pss: 0 kB\n"
"Pss_Dirty: 0 kB\n"
"Shared_Clean: 0 kB\n"
"Shared_Dirty: 0 kB\n"
"Private_Clean: 0 kB\n"
"Private_Dirty: 0 kB\n"
"Referenced: 0 kB\n"
"Anonymous: 0 kB\n"
"LazyFree: 0 kB\n"
"AnonHugePages: 0 kB\n"
"ShmemPmdMapped: 0 kB\n"
"FilePmdMapped: 0 kB\n"
"Shared_Hugetlb: 0 kB\n"
"Private_Hugetlb: 0 kB\n"
"Swap: 0 kB\n"
"SwapPss: 0 kB\n"
"Locked: 0 kB\n"
"THPeligible: 0\n", size_kb, page_size_kb, page_size_kb);
}

static int open_self_maps_1(CPUArchState *cpu_env, int fd, bool smaps)
{
CPUState *cpu = env_cpu(cpu_env);
TaskState *ts = cpu->opaque;
Expand Down Expand Up @@ -8089,6 +8118,18 @@ static int open_self_maps(CPUArchState *cpu_env, int fd)
} else {
dprintf(fd, "\n");
}
if (smaps) {
show_smaps(fd, max - min);
dprintf(fd, "VmFlags:%s%s%s%s%s%s%s%s\n",
(flags & PAGE_READ) ? " rd" : "",
(flags & PAGE_WRITE_ORG) ? " wr" : "",
(flags & PAGE_EXEC) ? " ex" : "",
e->is_priv ? "" : " sh",
(flags & PAGE_READ) ? " mr" : "",
(flags & PAGE_WRITE_ORG) ? " mw" : "",
(flags & PAGE_EXEC) ? " me" : "",
e->is_priv ? "" : " ms");
}
}
}

Expand All @@ -8103,11 +8144,25 @@ static int open_self_maps(CPUArchState *cpu_env, int fd)
" --xp 00000000 00:00 0",
TARGET_VSYSCALL_PAGE, TARGET_VSYSCALL_PAGE + TARGET_PAGE_SIZE);
dprintf(fd, "%*s%s\n", 73 - count, "", "[vsyscall]");
if (smaps) {
show_smaps(fd, TARGET_PAGE_SIZE);
dprintf(fd, "VmFlags: ex\n");
}
#endif

return 0;
}

static int open_self_maps(CPUArchState *cpu_env, int fd)
{
return open_self_maps_1(cpu_env, fd, false);
}

static int open_self_smaps(CPUArchState *cpu_env, int fd)
{
return open_self_maps_1(cpu_env, fd, true);
}

static int open_self_stat(CPUArchState *cpu_env, int fd)
{
CPUState *cpu = env_cpu(cpu_env);
Expand Down Expand Up @@ -8459,6 +8514,7 @@ int do_guest_openat(CPUArchState *cpu_env, int dirfd, const char *pathname,
const struct fake_open *fake_open;
static const struct fake_open fakes[] = {
{ "maps", open_self_maps, is_proc_myself },
{ "smaps", open_self_smaps, is_proc_myself },
{ "stat", open_self_stat, is_proc_myself },
{ "auxv", open_self_auxv, is_proc_myself },
{ "cmdline", open_self_cmdline, is_proc_myself },
Expand Down

0 comments on commit 77ae576

Please sign in to comment.