kernel: Fix ELF hashtable iterator handling.

As a result of the refactoring for OpenHashTable, the iterator semantics
have changed a bit, such that the end of the table is no longer signalled
by the iterator returning NULL. This wasn't taken into account during
refactoring, which would lead to various places returning the last item
in the list in the case where no matching item was found, causing e.g.
drivers not to be loaded properly. This fixes the boot hang regressions
introduced in hrev48640.
This commit is contained in:
Rene Gollent
2015-01-09 14:42:13 -05:00
parent 9550c5ec8e
commit d05a5a70e0
+17 -19
View File
@@ -165,8 +165,6 @@ register_elf_image(struct elf_image_info *image)
static struct elf_image_info * static struct elf_image_info *
find_image_at_address(addr_t address) find_image_at_address(addr_t address)
{ {
struct elf_image_info *image = NULL;
#if KDEBUG #if KDEBUG
if (!debug_debugger_running()) if (!debug_debugger_running())
ASSERT_LOCKED_MUTEX(&sImageMutex); ASSERT_LOCKED_MUTEX(&sImageMutex);
@@ -177,16 +175,16 @@ find_image_at_address(addr_t address)
// get image that may contain the address // get image that may contain the address
while (iterator.HasNext()) { while (iterator.HasNext()) {
image = iterator.Next(); struct elf_image_info* image = iterator.Next();
if ((address >= image->text_region.start && address if ((address >= image->text_region.start && address
<= (image->text_region.start + image->text_region.size)) <= (image->text_region.start + image->text_region.size))
|| (address >= image->data_region.start || (address >= image->data_region.start
&& address && address
<= (image->data_region.start + image->data_region.size))) <= (image->data_region.start + image->data_region.size)))
break; return image;
} }
return image; return NULL;
} }
@@ -235,20 +233,16 @@ find_image(image_id id)
static struct elf_image_info * static struct elf_image_info *
find_image_by_vnode(void *vnode) find_image_by_vnode(void *vnode)
{ {
struct elf_image_info *image = NULL; MutexLocker locker(sImageMutex);
mutex_lock(&sImageMutex);
ImageHash::Iterator iterator(sImagesHash); ImageHash::Iterator iterator(sImagesHash);
while (iterator.HasNext()) { while (iterator.HasNext()) {
image = iterator.Next(); struct elf_image_info* image = iterator.Next();
if (image->vnode == vnode) if (image->vnode == vnode)
break; return image;
} }
mutex_unlock(&sImageMutex); return NULL;
return image;
} }
@@ -411,12 +405,14 @@ dump_symbols(int argc, char **argv)
ImageHash::Iterator iterator(sImagesHash); ImageHash::Iterator iterator(sImagesHash);
while (iterator.HasNext()) { while (iterator.HasNext()) {
image = iterator.Next(); elf_image_info* current = iterator.Next();
if (image->text_region.start <= num if (current->text_region.start <= num
&& image->text_region.start + image->text_region.size && current->text_region.start + current->text_region.size
>= num) >= num) {
image = current;
break; break;
} }
}
if (image == NULL) { if (image == NULL) {
kprintf("No image covers %#" B_PRIxADDR " in the kernel!\n", kprintf("No image covers %#" B_PRIxADDR " in the kernel!\n",
@@ -433,10 +429,12 @@ dump_symbols(int argc, char **argv)
// look for image by name // look for image by name
ImageHash::Iterator iterator(sImagesHash); ImageHash::Iterator iterator(sImagesHash);
while (iterator.HasNext()) { while (iterator.HasNext()) {
image = iterator.Next(); elf_image_info* current = iterator.Next();
if (!strcmp(image->name, argv[1])) if (!strcmp(current->name, argv[1])) {
image = current;
break; break;
} }
}
if (image == NULL) if (image == NULL)
kprintf("No image \"%s\" found in kernel!\n", argv[1]); kprintf("No image \"%s\" found in kernel!\n", argv[1]);