Index: libexec/rtld-elf/rtld.c =================================================================== --- libexec/rtld-elf/rtld.c +++ libexec/rtld-elf/rtld.c @@ -134,7 +134,8 @@ static void objlist_push_tail(Objlist *, Obj_Entry *); static void objlist_put_after(Objlist *, Obj_Entry *, Obj_Entry *); static void objlist_remove(Objlist *, Obj_Entry *); -static int open_binary_fd(const char *argv0, bool search_in_path); +static int open_binary_fd(const char *argv0, bool search_in_path, + const char **binpath_res); static int parse_args(char* argv[], int argc, bool *use_pathp, int *fdp); static int parse_integer(const char *); static void *path_enumerate(const char *, path_enum_proc, const char *, void *); @@ -378,7 +379,7 @@ struct stat st; Elf_Addr *argcp; char **argv, **env, **envp, *kexecpath, *library_path_rpath; - const char *argv0; + const char *argv0, *binpath; caddr_t imgentry; char buf[MAXPATHLEN]; int argc, fd, i, phnum, rtld_argc; @@ -441,7 +442,7 @@ argv0 = argv[rtld_argc]; explicit_fd = (fd != -1); if (!explicit_fd) - fd = open_binary_fd(argv0, search_in_path); + fd = open_binary_fd(argv0, search_in_path, &binpath); if (fstat(fd, &st) == -1) { _rtld_error("Failed to fstat FD %d (%s): %s", fd, explicit_fd ? "user-provided descriptor" : argv0, @@ -506,6 +507,7 @@ if (auxp->a_type < AT_COUNT) aux_info[auxp->a_type] = auxp; } + aux_info[AT_EXECPATH]->a_un.a_ptr = __DECONST(void *, binpath); } else { _rtld_error("No binary"); rtld_die(); @@ -5470,12 +5472,14 @@ } static int -open_binary_fd(const char *argv0, bool search_in_path) +open_binary_fd(const char *argv0, bool search_in_path, + const char **binpath_res) { - char *pathenv, *pe, binpath[PATH_MAX]; + char *pathenv, *pe, *binpath; int fd; if (search_in_path && strchr(argv0, '/') == NULL) { + binpath = xmalloc(PATH_MAX); pathenv = getenv("PATH"); if (pathenv == NULL) { _rtld_error("-p and no PATH environment variable"); @@ -5500,12 +5504,15 @@ sizeof(binpath)) continue; fd = open(binpath, O_RDONLY | O_CLOEXEC | O_VERIFY); - if (fd != -1 || errno != ENOENT) + if (fd != -1 || errno != ENOENT) { + *binpath_res = binpath; break; + } } free(pathenv); } else { fd = open(argv0, O_RDONLY | O_CLOEXEC | O_VERIFY); + *binpath_res = argv0; } if (fd == -1) {