* 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
This commit is contained in:
Oliver Tappe 2009-07-08 21:22:12 +00:00
parent 3a111f3310
commit be1f4fe800

View File

@ -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;
}