diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 2eac6d5..195cf28 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -5136,6 +5136,30 @@ static int open_self_auxv(void *cpu_env, int fd) return 0; } +static int open_self_exe(void *cpu_env, int fd) +{ + CPUState *cpu = ENV_GET_CPU((CPUArchState *)cpu_env); + TaskState *ts = cpu->opaque; + FILE *fp; + + fp = fopen(ts->bprm->argv[0], "rb"); + if (fp == NULL) { + return -EACCES; + } + while (!feof(fp)) { + char buffer[512]; + ssize_t read; + read = fread(buffer, 1, sizeof(buffer), fp); + if (write(fd, buffer, read) != read) { + fclose(fp); + return -1; + } + } + + fclose(fp); + return 0; +} + static int is_proc_myself(const char *filename, const char *entry) { if (!strncmp(filename, "/proc/", strlen("/proc/"))) { @@ -5216,6 +5240,7 @@ static int do_open(void *cpu_env, const char *pathname, int flags, mode_t mode) { "maps", open_self_maps, is_proc_myself }, { "stat", open_self_stat, is_proc_myself }, { "auxv", open_self_auxv, is_proc_myself }, + { "exe", open_self_exe, is_proc_myself }, #if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN) { "/proc/net/route", open_net_route, is_proc }, #endif