From 5fd6637b4d3f8e4e47227db92daa5dc39226aa12 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Sun, 23 Mar 2008 19:43:41 +0000 Subject: [PATCH] * Decide whether to use BeOS style symbol resolution at run time depending on the gcc version of the executable. * Adjusted non-BeOS-style symbol resolution so that add-ons and dynamically loaded libraries find symbols in the executable. This change re-enables support for undefined symbols. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24537 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../private/runtime_loader/runtime_loader.h | 5 ++ src/system/runtime_loader/Jamfile | 3 +- src/system/runtime_loader/elf.cpp | 46 ++++++++++++++----- 3 files changed, 41 insertions(+), 13 deletions(-) diff --git a/headers/private/runtime_loader/runtime_loader.h b/headers/private/runtime_loader/runtime_loader.h index 55259c1382..15266e3390 100644 --- a/headers/private/runtime_loader/runtime_loader.h +++ b/headers/private/runtime_loader/runtime_loader.h @@ -74,6 +74,11 @@ typedef struct image_queue_t { image_t *tail; } image_queue_t; +// image_t::flags +#define IMAGE_FLAG_RTLD_MASK 0x03 + // RTLD_{LAZY,NOW} | RTLD_{LOCAL,GLOBAL} +#define IMAGE_FLAG_R5_SYMBOL_RESOLUTION 0x04 + #define STRING(image, offset) ((char *)(&(image)->strtab[(offset)])) #define SYMNAME(image, sym) STRING(image, (sym)->st_name) #define SYMBOL(image, num) ((struct Elf32_Sym *)&(image)->syms[num]) diff --git a/src/system/runtime_loader/Jamfile b/src/system/runtime_loader/Jamfile index deee55e771..31a704e805 100644 --- a/src/system/runtime_loader/Jamfile +++ b/src/system/runtime_loader/Jamfile @@ -8,8 +8,7 @@ UseHeaders $(TARGET_PRIVATE_KERNEL_HEADERS) : true ; SubDirCcFlags -fno-builtin ; SubDirC++Flags -fno-builtin -fno-exceptions ; -# default to BeOS style symbol resolution -DEFINES += BEOS_STYLE_SYMBOLS_RESOLUTION +DEFINES += KMESSAGE_CONTAINER_ONLY _LOADER_MODE ; diff --git a/src/system/runtime_loader/elf.cpp b/src/system/runtime_loader/elf.cpp index 8e689946aa..eaa3b6ed94 100644 --- a/src/system/runtime_loader/elf.cpp +++ b/src/system/runtime_loader/elf.cpp @@ -82,12 +82,6 @@ static uint32 sLoadedImageCount = 0; static image_t *sProgramImage; static KMessage sErrorMessage; -#ifdef BEOS_STYLE_SYMBOLS_RESOLUTION -static bool sResolveSymbolsBeOSStyle = true; -#else -static bool sResolveSymbolsBeOSStyle = false; -#endif - // a recursive lock static sem_id rld_sem; static thread_id rld_sem_owner; @@ -280,18 +274,28 @@ find_loaded_image_by_id(image_id id) } -static const char * -get_program_path() +static image_t* +get_program_image() { for (image_t *image = sLoadedImages.head; image; image = image->next) { if (image->type == B_APP_IMAGE) - return image->path; + return image; } return NULL; } +static const char * +get_program_path() +{ + if (image_t* image = get_program_image()) + return image->path; + + return NULL; +} + + static status_t parse_elf_header(struct Elf32_Ehdr *eheader, int32 *_pheaderSize, int32 *_sheaderSize) @@ -1020,8 +1024,20 @@ find_undefined_symbol(image_t* rootImage, image_t* image, const char* name, // If not simulating BeOS style symbol resolution, undefined symbols are // search recursively starting from the root image. (Note, breadth first // might be better than the depth first use here.) - if (!sResolveSymbolsBeOSStyle) - return find_symbol_recursively(rootImage, name, foundInImage); + if ((rootImage->flags & IMAGE_FLAG_R5_SYMBOL_RESOLUTION) == 0) { + Elf32_Sym* symbol = find_symbol_recursively(rootImage, name, + foundInImage); + if (symbol != NULL) + return symbol; + + // If the root image is not the program image (i.e. it is a dynamically + // loaded add-on or library), we try the program image hierarchy too. + image_t* programImage = get_program_image(); + if (rootImage != programImage) + return find_symbol_recursively(programImage, name, foundInImage); + + return NULL; + } // BeOS style symbol resolution: It is sufficient to check the direct // dependencies. The linker would have complained, if the symbol wasn't @@ -1256,6 +1272,14 @@ load_container(char const *name, image_type type, const char *rpath, image_t **_ // not really fatal, actually } + // init gcc version dependent image flags + // symbol resolution strategy (fallback is R5-style, if version is + // unavailable) + if (image->gcc_version.major == 0 + || image->gcc_version.major == 2 && image->gcc_version.middle < 95) { + image->flags |= IMAGE_FLAG_R5_SYMBOL_RESOLUTION; + } + status = map_image(fd, path, image, type == B_APP_IMAGE); if (status < B_OK) { FATAL("Could not map image: %s\n", strerror(status));