From 52d0d5e53e69a54f4138b0301d574591307a5292 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Tue, 23 Sep 2008 21:13:38 +0000 Subject: [PATCH] elf_load_user_image() does now register the loaded image. That is every team does have a runtime loader image. The "profile" tool can thus translate addresses in the runtime loader correctly. Note that this change will break code that assumes that the application image is the first image returned by get_next_image_info(). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27715 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/system/kernel/elf.cpp | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/system/kernel/elf.cpp b/src/system/kernel/elf.cpp index e100d2317e..e0e7ba6229 100644 --- a/src/system/kernel/elf.cpp +++ b/src/system/kernel/elf.cpp @@ -1367,6 +1367,11 @@ elf_load_user_image(const char *path, struct team *team, int flags, if (fd < 0) return fd; + struct stat st; + status = _kern_read_stat(fd, NULL, false, &st, sizeof(st)); + if (status != B_OK) + return status; + // read and verify the ELF header length = _kern_read(fd, 0, &elfHeader, sizeof(elfHeader)); @@ -1428,6 +1433,9 @@ elf_load_user_image(const char *path, struct team *team, int flags, // map the program's segments into memory + image_info imageInfo; + memset(&imageInfo, 0, sizeof(image_info)); + for (i = 0; i < elfHeader.e_phnum; i++) { char regionName[B_OS_NAME_LENGTH]; char *regionAddress; @@ -1460,6 +1468,9 @@ elf_load_user_image(const char *path, struct team *team, int flags, goto error; } + imageInfo.data = regionAddress; + imageInfo.data_size = memUpperBound; + // clean garbage brought by mmap (the region behind the file, // at least parts of it are the bss and have to be zeroed) uint32 start = (uint32)regionAddress @@ -1492,9 +1503,11 @@ elf_load_user_image(const char *path, struct team *team, int flags, // assume ro/text segment snprintf(regionName, B_OS_NAME_LENGTH, "%s_seg%dro", baseName, i); + size_t segmentSize = ROUNDUP(programHeaders[i].p_memsz + + (programHeaders[i].p_vaddr % B_PAGE_SIZE), B_PAGE_SIZE); + id = vm_map_file(team->id, regionName, (void **)®ionAddress, - B_EXACT_ADDRESS, ROUNDUP(programHeaders[i].p_memsz - + (programHeaders[i].p_vaddr % B_PAGE_SIZE), B_PAGE_SIZE), + B_EXACT_ADDRESS, segmentSize, B_READ_AREA | B_EXECUTE_AREA, REGION_PRIVATE_MAP, fd, ROUNDOWN(programHeaders[i].p_offset, B_PAGE_SIZE)); if (id < B_OK) { @@ -1502,9 +1515,21 @@ elf_load_user_image(const char *path, struct team *team, int flags, status = B_NOT_AN_EXECUTABLE; goto error; } + + imageInfo.text = regionAddress; + imageInfo.text_size = segmentSize; } } + // register the loaded image + imageInfo.type = B_LIBRARY_IMAGE; + imageInfo.device = st.st_dev; + imageInfo.node = st.st_ino; + strlcpy(imageInfo.name, path, sizeof(imageInfo.name)); + + register_image(team, &imageInfo, sizeof(image_info)); + // Don't care, if registering fails. It's not crucial. + TRACE(("elf_load: done!\n")); *entry = elfHeader.e_entry;