From be1f4fe8000a0e6d3e3f9c30920eef3a79f2234f Mon Sep 17 00:00:00 2001 From: Oliver Tappe Date: Wed, 8 Jul 2009 21:22:12 +0000 Subject: [PATCH] * find_symbol_breadth_first() didn't ever set _foundInImage, although it's signature indicates that it should - the callers just never use the value currently, so it caused no harm * squashed a TODO in the runtime_loader about the resolving strategy for undefined symbols in add-ons: I've implemented the breadth-first strategy (leaving out the add-on itself), as that one made most sense to me. This avoids loader problems with older optional packages of Pe on gcc4, as some add-ons (e.g. "Expand Tabs") could not be loaded due to them containing undefined symbols that are found in second level dependencies (libstdc++.so in this case). Ingo: please review. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31465 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../runtime_loader/elf_symbol_lookup.cpp | 50 +++++++++++++++---- 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/src/system/runtime_loader/elf_symbol_lookup.cpp b/src/system/runtime_loader/elf_symbol_lookup.cpp index 3ec8cd1839..bd4a70d726 100644 --- a/src/system/runtime_loader/elf_symbol_lookup.cpp +++ b/src/system/runtime_loader/elf_symbol_lookup.cpp @@ -237,6 +237,8 @@ find_symbol_breadth_first(image_t* image, const SymbolLookupInfo& lookupInfo, image = queue[index++]; if (find_symbol(image, lookupInfo, _location) == B_OK) { + if (_foundInImage != NULL) + *_foundInImage = image; found = true; break; } @@ -311,15 +313,45 @@ Elf32_Sym* find_undefined_symbol_add_on(image_t* rootImage, image_t* image, const SymbolLookupInfo& lookupInfo, image_t** foundInImage) { -// TODO: How do we want to implement this one? Using global scope resolution -// might be undesired as it is now, since libraries could refer to symbols in -// the add-on, which would result in add-on symbols implicitely becoming used -// outside of the add-on. So the options would be to use the global scope but -// skip the add-on, or to do breadth-first resolution in the add-on dependency -// scope, also skipping the add-on itself. BeOS style resolution is safe, too, -// but we miss out features like undefined symbols and preloading. - return find_undefined_symbol_beos(rootImage, image, lookupInfo, - foundInImage); + // Do a breadth-first resolution in the add-on dependency scope, + // skipping the add-on itself. + Elf32_Sym* foundSymbol = NULL; + + image_t* queue[count_loaded_images()]; + uint32 count = 0; + uint32 index = 0; + queue[count++] = image; + image->flags |= RFLAG_VISITED; + + image_t* currentImage; + while (index < count) { + // pop next image + currentImage = queue[index++]; + + if (currentImage != image) { + foundSymbol = find_symbol(currentImage, lookupInfo); + if (foundSymbol != NULL) { + if (foundInImage != NULL) + *foundInImage = currentImage; + break; + } + } + + // push needed images + for (uint32 i = 0; i < currentImage->num_needed; i++) { + image_t* needed = currentImage->needed[i]; + if ((needed->flags & RFLAG_VISITED) == 0) { + queue[count++] = needed; + needed->flags |= RFLAG_VISITED; + } + } + } + + // clear visited flags + for (uint32 i = 0; i < count; i++) + queue[i]->flags &= ~RFLAG_VISITED; + + return foundSymbol; }