xref: /haiku/src/system/kernel/elf.cpp (revision 37c7d5d83a2372a6971e383411d5bacbeef0ebdc)
1 /*
2  * Copyright 2009-2010, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Copyright 2002-2009, Axel Dörfler, axeld@pinc-software.de.
4  * Distributed under the terms of the MIT License.
5  *
6  * Copyright 2001, Travis Geiselbrecht. All rights reserved.
7  * Distributed under the terms of the NewOS License.
8  */
9 
10 /*!	Contains the ELF loader */
11 
12 #include <elf.h>
13 
14 #include <OS.h>
15 
16 #include <unistd.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <stdio.h>
20 #include <ctype.h>
21 
22 #include <AutoDeleter.h>
23 #include <debug.h>
24 #include <image_defs.h>
25 #include <kernel.h>
26 #include <kimage.h>
27 #include <syscalls.h>
28 #include <team.h>
29 #include <thread.h>
30 #include <runtime_loader.h>
31 #include <util/AutoLock.h>
32 #include <util/khash.h>
33 #include <vfs.h>
34 #include <vm/vm.h>
35 #include <vm/vm_types.h>
36 #include <vm/VMAddressSpace.h>
37 #include <vm/VMArea.h>
38 
39 #include <arch/cpu.h>
40 #include <arch/elf.h>
41 #include <elf_priv.h>
42 #include <boot/elf.h>
43 
44 //#define TRACE_ELF
45 #ifdef TRACE_ELF
46 #	define TRACE(x) dprintf x
47 #else
48 #	define TRACE(x) ;
49 #endif
50 
51 
52 #define IMAGE_HASH_SIZE 16
53 
54 static hash_table *sImagesHash;
55 
56 static struct elf_image_info *sKernelImage = NULL;
57 static mutex sImageMutex = MUTEX_INITIALIZER("kimages_lock");
58 	// guards sImagesHash
59 static mutex sImageLoadMutex = MUTEX_INITIALIZER("kimages_load_lock");
60 	// serializes loading/unloading add-ons locking order
61 	// sImageLoadMutex -> sImageMutex
62 static bool sInitialized = false;
63 
64 
65 static struct Elf32_Sym *elf_find_symbol(struct elf_image_info *image,
66 	const char *name, const elf_version_info *version, bool lookupDefault);
67 
68 
69 /*! Calculates hash for an image using its ID */
70 static uint32
71 image_hash(void *_image, const void *_key, uint32 range)
72 {
73 	struct elf_image_info *image = (struct elf_image_info *)_image;
74 	image_id id = (image_id)_key;
75 
76 	if (image != NULL)
77 		return image->id % range;
78 
79 	return (uint32)id % range;
80 }
81 
82 
83 /*!	Compares an image to a given ID */
84 static int
85 image_compare(void *_image, const void *_key)
86 {
87 	struct elf_image_info *image = (struct elf_image_info *)_image;
88 	image_id id = (image_id)_key;
89 
90 	return id - image->id;
91 }
92 
93 
94 static void
95 unregister_elf_image(struct elf_image_info *image)
96 {
97 	unregister_image(team_get_kernel_team(), image->id);
98 	hash_remove(sImagesHash, image);
99 }
100 
101 
102 static void
103 register_elf_image(struct elf_image_info *image)
104 {
105 	image_info imageInfo;
106 
107 	memset(&imageInfo, 0, sizeof(image_info));
108 	imageInfo.id = image->id;
109 	imageInfo.type = B_SYSTEM_IMAGE;
110 	strlcpy(imageInfo.name, image->name, sizeof(imageInfo.name));
111 
112 	imageInfo.text = (void *)image->text_region.start;
113 	imageInfo.text_size = image->text_region.size;
114 	imageInfo.data = (void *)image->data_region.start;
115 	imageInfo.data_size = image->data_region.size;
116 
117 	if (image->text_region.id >= 0) {
118 		// evaluate the API/ABI version symbols
119 
120 		// Haiku API version
121 		imageInfo.api_version = 0;
122 		struct Elf32_Sym* symbol = elf_find_symbol(image,
123 			B_SHARED_OBJECT_HAIKU_VERSION_VARIABLE_NAME, NULL, true);
124 		if (symbol != NULL && symbol->st_shndx != SHN_UNDEF
125 			&& symbol->st_value > 0
126 			&& ELF32_ST_TYPE(symbol->st_info) == STT_OBJECT
127 			&& symbol->st_size >= sizeof(uint32)) {
128 			addr_t symbolAddress = symbol->st_value + image->text_region.delta;
129 			if (symbolAddress >= image->text_region.start
130 				&& symbolAddress - image->text_region.start + sizeof(uint32)
131 					<= image->text_region.size) {
132 				imageInfo.api_version = *(uint32*)symbolAddress;
133 			}
134 		}
135 
136 		// Haiku ABI
137 		imageInfo.abi = 0;
138 		symbol = elf_find_symbol(image,
139 			B_SHARED_OBJECT_HAIKU_ABI_VARIABLE_NAME, NULL, true);
140 		if (symbol != NULL && symbol->st_shndx != SHN_UNDEF
141 			&& symbol->st_value > 0
142 			&& ELF32_ST_TYPE(symbol->st_info) == STT_OBJECT
143 			&& symbol->st_size >= sizeof(uint32)) {
144 			addr_t symbolAddress = symbol->st_value + image->text_region.delta;
145 			if (symbolAddress >= image->text_region.start
146 				&& symbolAddress - image->text_region.start + sizeof(uint32)
147 					<= image->text_region.size) {
148 				imageInfo.api_version = *(uint32*)symbolAddress;
149 			}
150 		}
151 	} else {
152 		// in-memory image -- use the current values
153 		imageInfo.api_version = B_HAIKU_VERSION;
154 		imageInfo.abi = B_HAIKU_ABI;
155 	}
156 
157 	image->id = register_image(team_get_kernel_team(), &imageInfo,
158 		sizeof(image_info));
159 	hash_insert(sImagesHash, image);
160 }
161 
162 
163 /*!	Note, you must lock the image mutex when you call this function. */
164 static struct elf_image_info *
165 find_image_at_address(addr_t address)
166 {
167 	struct hash_iterator iterator;
168 	struct elf_image_info *image;
169 
170 #if KDEBUG
171 	if (!debug_debugger_running())
172 		ASSERT_LOCKED_MUTEX(&sImageMutex);
173 #endif
174 
175 	hash_open(sImagesHash, &iterator);
176 
177 	// get image that may contain the address
178 
179 	while ((image = (elf_image_info *)hash_next(sImagesHash, &iterator))
180 			!= NULL) {
181 		if ((address >= image->text_region.start && address
182 				<= (image->text_region.start + image->text_region.size))
183 			|| (address >= image->data_region.start
184 				&& address
185 					<= (image->data_region.start + image->data_region.size)))
186 			break;
187 	}
188 
189 	hash_close(sImagesHash, &iterator, false);
190 	return image;
191 }
192 
193 
194 static int
195 dump_address_info(int argc, char **argv)
196 {
197 	const char *symbol, *imageName;
198 	bool exactMatch;
199 	addr_t address, baseAddress;
200 
201 	if (argc < 2) {
202 		kprintf("usage: ls <address>\n");
203 		return 0;
204 	}
205 
206 	address = strtoul(argv[1], NULL, 16);
207 
208 	status_t error;
209 
210 	if (IS_KERNEL_ADDRESS(address)) {
211 		error = elf_debug_lookup_symbol_address(address, &baseAddress, &symbol,
212 			&imageName, &exactMatch);
213 	} else {
214 		error = elf_debug_lookup_user_symbol_address(
215 			debug_get_debugged_thread()->team, address, &baseAddress, &symbol,
216 			&imageName, &exactMatch);
217 	}
218 
219 	if (error == B_OK) {
220 		kprintf("%p = %s + 0x%lx (%s)%s\n", (void*)address, symbol,
221 			address - baseAddress, imageName, exactMatch ? "" : " (nearest)");
222 	} else
223 		kprintf("There is no image loaded at this address!\n");
224 
225 	return 0;
226 }
227 
228 
229 static struct elf_image_info *
230 find_image(image_id id)
231 {
232 	return (elf_image_info *)hash_lookup(sImagesHash, (void *)id);
233 }
234 
235 
236 static struct elf_image_info *
237 find_image_by_vnode(void *vnode)
238 {
239 	struct hash_iterator iterator;
240 	struct elf_image_info *image;
241 
242 	mutex_lock(&sImageMutex);
243 	hash_open(sImagesHash, &iterator);
244 
245 	while ((image = (elf_image_info *)hash_next(sImagesHash, &iterator))
246 			!= NULL) {
247 		if (image->vnode == vnode)
248 			break;
249 	}
250 
251 	hash_close(sImagesHash, &iterator, false);
252 	mutex_unlock(&sImageMutex);
253 
254 	return image;
255 }
256 
257 
258 static struct elf_image_info *
259 create_image_struct()
260 {
261 	struct elf_image_info *image
262 		= (struct elf_image_info *)malloc(sizeof(struct elf_image_info));
263 	if (image == NULL)
264 		return NULL;
265 
266 	memset(image, 0, sizeof(struct elf_image_info));
267 
268 	image->text_region.id = -1;
269 	image->data_region.id = -1;
270 	image->ref_count = 1;
271 
272 	return image;
273 }
274 
275 
276 static void
277 delete_elf_image(struct elf_image_info *image)
278 {
279 	if (image->text_region.id >= 0)
280 		delete_area(image->text_region.id);
281 
282 	if (image->data_region.id >= 0)
283 		delete_area(image->data_region.id);
284 
285 	if (image->vnode)
286 		vfs_put_vnode(image->vnode);
287 
288 	free(image->versions);
289 	free(image->debug_symbols);
290 	free((void*)image->debug_string_table);
291 	free(image->elf_header);
292 	free(image->name);
293 	free(image);
294 }
295 
296 
297 static uint32
298 elf_hash(const char *name)
299 {
300 	uint32 hash = 0;
301 	uint32 temp;
302 
303 	while (*name) {
304 		hash = (hash << 4) + (uint8)*name++;
305 		if ((temp = hash & 0xf0000000) != 0)
306 			hash ^= temp >> 24;
307 		hash &= ~temp;
308 	}
309 	return hash;
310 }
311 
312 
313 static const char *
314 get_symbol_type_string(struct Elf32_Sym *symbol)
315 {
316 	switch (ELF32_ST_TYPE(symbol->st_info)) {
317 		case STT_FUNC:
318 			return "func";
319 		case STT_OBJECT:
320 			return " obj";
321 		case STT_FILE:
322 			return "file";
323 		default:
324 			return "----";
325 	}
326 }
327 
328 
329 static const char *
330 get_symbol_bind_string(struct Elf32_Sym *symbol)
331 {
332 	switch (ELF32_ST_BIND(symbol->st_info)) {
333 		case STB_LOCAL:
334 			return "loc ";
335 		case STB_GLOBAL:
336 			return "glob";
337 		case STB_WEAK:
338 			return "weak";
339 		default:
340 			return "----";
341 	}
342 }
343 
344 
345 /*!	Searches a symbol (pattern) in all kernel images */
346 static int
347 dump_symbol(int argc, char **argv)
348 {
349 	if (argc != 2 || !strcmp(argv[1], "--help")) {
350 		kprintf("usage: %s <symbol-name>\n", argv[0]);
351 		return 0;
352 	}
353 
354 	struct elf_image_info *image = NULL;
355 	struct hash_iterator iterator;
356 	const char *pattern = argv[1];
357 
358 	void* symbolAddress = NULL;
359 
360 	hash_open(sImagesHash, &iterator);
361 	while ((image = (elf_image_info *)hash_next(sImagesHash, &iterator))
362 			!= NULL) {
363 		if (image->num_debug_symbols > 0) {
364 			// search extended debug symbol table (contains static symbols)
365 			for (uint32 i = 0; i < image->num_debug_symbols; i++) {
366 				struct Elf32_Sym *symbol = &image->debug_symbols[i];
367 				const char *name = image->debug_string_table + symbol->st_name;
368 
369 				if (symbol->st_value > 0 && strstr(name, pattern) != 0) {
370 					symbolAddress
371 						= (void*)(symbol->st_value + image->text_region.delta);
372 					kprintf("%p %5lu %s:%s\n", symbolAddress, symbol->st_size,
373 						image->name, name);
374 				}
375 			}
376 		} else {
377 			// search standard symbol lookup table
378 			for (uint32 i = 0; i < HASHTABSIZE(image); i++) {
379 				for (uint32 j = HASHBUCKETS(image)[i]; j != STN_UNDEF;
380 						j = HASHCHAINS(image)[j]) {
381 					struct Elf32_Sym *symbol = &image->syms[j];
382 					const char *name = SYMNAME(image, symbol);
383 
384 					if (symbol->st_value > 0 && strstr(name, pattern) != 0) {
385 						symbolAddress = (void*)(symbol->st_value
386 							+ image->text_region.delta);
387 						kprintf("%p %5lu %s:%s\n", symbolAddress,
388 							symbol->st_size, image->name, name);
389 					}
390 				}
391 			}
392 		}
393 	}
394 	hash_close(sImagesHash, &iterator, false);
395 
396 	if (symbolAddress != NULL)
397 		set_debug_variable("_", (addr_t)symbolAddress);
398 
399 	return 0;
400 }
401 
402 
403 static int
404 dump_symbols(int argc, char **argv)
405 {
406 	struct elf_image_info *image = NULL;
407 	struct hash_iterator iterator;
408 	uint32 i;
409 
410 	// if the argument looks like a hex number, treat it as such
411 	if (argc > 1) {
412 		if (isdigit(argv[1][0])) {
413 			uint32 num = strtoul(argv[1], NULL, 0);
414 
415 			if (IS_KERNEL_ADDRESS(num)) {
416 				// find image at address
417 
418 				hash_open(sImagesHash, &iterator);
419 				while ((image = (elf_image_info *)hash_next(sImagesHash,
420 						&iterator)) != NULL) {
421 					if (image->text_region.start <= num
422 						&& image->text_region.start + image->text_region.size
423 							>= num)
424 						break;
425 				}
426 				hash_close(sImagesHash, &iterator, false);
427 
428 				if (image == NULL)
429 					kprintf("No image covers 0x%lx in the kernel!\n", num);
430 			} else {
431 				image = (elf_image_info *)hash_lookup(sImagesHash, (void *)num);
432 				if (image == NULL)
433 					kprintf("image 0x%lx doesn't exist in the kernel!\n", num);
434 			}
435 		} else {
436 			// look for image by name
437 			hash_open(sImagesHash, &iterator);
438 			while ((image = (elf_image_info *)hash_next(sImagesHash,
439 					&iterator)) != NULL) {
440 				if (!strcmp(image->name, argv[1]))
441 					break;
442 			}
443 			hash_close(sImagesHash, &iterator, false);
444 
445 			if (image == NULL)
446 				kprintf("No image \"%s\" found in kernel!\n", argv[1]);
447 		}
448 	} else {
449 		kprintf("usage: %s image_name/image_id/address_in_image\n", argv[0]);
450 		return 0;
451 	}
452 
453 	if (image == NULL)
454 		return -1;
455 
456 	// dump symbols
457 
458 	kprintf("Symbols of image %ld \"%s\":\nAddress  Type       Size Name\n",
459 		image->id, image->name);
460 
461 	if (image->num_debug_symbols > 0) {
462 		// search extended debug symbol table (contains static symbols)
463 		for (i = 0; i < image->num_debug_symbols; i++) {
464 			struct Elf32_Sym *symbol = &image->debug_symbols[i];
465 
466 			if (symbol->st_value == 0 || symbol->st_size
467 					>= image->text_region.size + image->data_region.size)
468 				continue;
469 
470 			kprintf("%08lx %s/%s %5ld %s\n",
471 				symbol->st_value + image->text_region.delta,
472 				get_symbol_type_string(symbol), get_symbol_bind_string(symbol),
473 				symbol->st_size, image->debug_string_table + symbol->st_name);
474 		}
475 	} else {
476 		int32 j;
477 
478 		// search standard symbol lookup table
479 		for (i = 0; i < HASHTABSIZE(image); i++) {
480 			for (j = HASHBUCKETS(image)[i]; j != STN_UNDEF;
481 					j = HASHCHAINS(image)[j]) {
482 				struct Elf32_Sym *symbol = &image->syms[j];
483 
484 				if (symbol->st_value == 0 || symbol->st_size
485 						>= image->text_region.size + image->data_region.size)
486 					continue;
487 
488 				kprintf("%08lx %s/%s %5ld %s\n",
489 					symbol->st_value + image->text_region.delta,
490 					get_symbol_type_string(symbol),
491 					get_symbol_bind_string(symbol),
492 					symbol->st_size, SYMNAME(image, symbol));
493 			}
494 		}
495 	}
496 
497 	return 0;
498 }
499 
500 
501 static void
502 dump_elf_region(struct elf_region *region, const char *name)
503 {
504 	kprintf("   %s.id %ld\n", name, region->id);
505 	kprintf("   %s.start 0x%lx\n", name, region->start);
506 	kprintf("   %s.size 0x%lx\n", name, region->size);
507 	kprintf("   %s.delta %ld\n", name, region->delta);
508 }
509 
510 
511 static void
512 dump_image_info(struct elf_image_info *image)
513 {
514 	kprintf("elf_image_info at %p:\n", image);
515 	kprintf(" next %p\n", image->next);
516 	kprintf(" id %ld\n", image->id);
517 	dump_elf_region(&image->text_region, "text");
518 	dump_elf_region(&image->data_region, "data");
519 	kprintf(" dynamic_section 0x%lx\n", image->dynamic_section);
520 	kprintf(" needed %p\n", image->needed);
521 	kprintf(" symhash %p\n", image->symhash);
522 	kprintf(" syms %p\n", image->syms);
523 	kprintf(" strtab %p\n", image->strtab);
524 	kprintf(" rel %p\n", image->rel);
525 	kprintf(" rel_len 0x%x\n", image->rel_len);
526 	kprintf(" rela %p\n", image->rela);
527 	kprintf(" rela_len 0x%x\n", image->rela_len);
528 	kprintf(" pltrel %p\n", image->pltrel);
529 	kprintf(" pltrel_len 0x%x\n", image->pltrel_len);
530 
531 	kprintf(" debug_symbols %p (%ld)\n",
532 		image->debug_symbols, image->num_debug_symbols);
533 }
534 
535 
536 static int
537 dump_image(int argc, char **argv)
538 {
539 	struct hash_iterator iterator;
540 	struct elf_image_info *image;
541 
542 	// if the argument looks like a hex number, treat it as such
543 	if (argc > 1) {
544 		uint32 num = strtoul(argv[1], NULL, 0);
545 
546 		if (IS_KERNEL_ADDRESS(num)) {
547 			// semi-hack
548 			dump_image_info((struct elf_image_info *)num);
549 		} else {
550 			image = (elf_image_info *)hash_lookup(sImagesHash, (void *)num);
551 			if (image == NULL)
552 				kprintf("image 0x%lx doesn't exist in the kernel!\n", num);
553 			else
554 				dump_image_info(image);
555 		}
556 		return 0;
557 	}
558 
559 	kprintf("loaded kernel images:\n");
560 
561 	hash_open(sImagesHash, &iterator);
562 
563 	while ((image = (elf_image_info *)hash_next(sImagesHash, &iterator))
564 			!= NULL) {
565 		kprintf("%p (%ld) %s\n", image, image->id, image->name);
566 	}
567 
568 	hash_close(sImagesHash, &iterator, false);
569 	return 0;
570 }
571 
572 
573 // Currently unused
574 #if 0
575 static
576 void dump_symbol(struct elf_image_info *image, struct Elf32_Sym *sym)
577 {
578 
579 	kprintf("symbol at %p, in image %p\n", sym, image);
580 
581 	kprintf(" name index %d, '%s'\n", sym->st_name, SYMNAME(image, sym));
582 	kprintf(" st_value 0x%x\n", sym->st_value);
583 	kprintf(" st_size %d\n", sym->st_size);
584 	kprintf(" st_info 0x%x\n", sym->st_info);
585 	kprintf(" st_other 0x%x\n", sym->st_other);
586 	kprintf(" st_shndx %d\n", sym->st_shndx);
587 }
588 #endif
589 
590 
591 static struct Elf32_Sym *
592 elf_find_symbol(struct elf_image_info *image, const char *name,
593 	const elf_version_info *lookupVersion, bool lookupDefault)
594 {
595 	if (image->dynamic_section == 0 || HASHTABSIZE(image) == 0)
596 		return NULL;
597 
598 	Elf32_Sym* versionedSymbol = NULL;
599 	uint32 versionedSymbolCount = 0;
600 
601 	uint32 hash = elf_hash(name) % HASHTABSIZE(image);
602 	for (uint32 i = HASHBUCKETS(image)[hash]; i != STN_UNDEF;
603 			i = HASHCHAINS(image)[i]) {
604 		Elf32_Sym* symbol = &image->syms[i];
605 		if (strcmp(SYMNAME(image, symbol), name) != 0)
606 			continue;
607 
608 		// check the version
609 
610 		// Handle the simple cases -- the image doesn't have version
611 		// information -- first.
612 		if (image->symbol_versions == NULL) {
613 			if (lookupVersion == NULL) {
614 				// No specific symbol version was requested either, so the
615 				// symbol is just fine.
616 				return symbol;
617 			}
618 
619 			// A specific version is requested. Since the only possible
620 			// dependency is the kernel itself, the add-on was obviously linked
621 			// against a newer kernel.
622 			dprintf("Kernel add-on requires version support, but the kernel "
623 				"is too old.\n");
624 			return NULL;
625 		}
626 
627 		// The image has version information. Let's see what we've got.
628 		uint32 versionID = image->symbol_versions[i];
629 		uint32 versionIndex = VER_NDX(versionID);
630 		elf_version_info& version = image->versions[versionIndex];
631 
632 		// skip local versions
633 		if (versionIndex == VER_NDX_LOCAL)
634 			continue;
635 
636 		if (lookupVersion != NULL) {
637 			// a specific version is requested
638 
639 			// compare the versions
640 			if (version.hash == lookupVersion->hash
641 				&& strcmp(version.name, lookupVersion->name) == 0) {
642 				// versions match
643 				return symbol;
644 			}
645 
646 			// The versions don't match. We're still fine with the
647 			// base version, if it is public and we're not looking for
648 			// the default version.
649 			if ((versionID & VER_NDX_FLAG_HIDDEN) == 0
650 				&& versionIndex == VER_NDX_GLOBAL
651 				&& !lookupDefault) {
652 				// TODO: Revise the default version case! That's how
653 				// FreeBSD implements it, but glibc doesn't handle it
654 				// specially.
655 				return symbol;
656 			}
657 		} else {
658 			// No specific version requested, but the image has version
659 			// information. This can happen in either of these cases:
660 			//
661 			// * The dependent object was linked against an older version
662 			//   of the now versioned dependency.
663 			// * The symbol is looked up via find_image_symbol() or dlsym().
664 			//
665 			// In the first case we return the base version of the symbol
666 			// (VER_NDX_GLOBAL or VER_NDX_INITIAL), or, if that doesn't
667 			// exist, the unique, non-hidden versioned symbol.
668 			//
669 			// In the second case we want to return the public default
670 			// version of the symbol. The handling is pretty similar to the
671 			// first case, with the exception that we treat VER_NDX_INITIAL
672 			// as regular version.
673 
674 			// VER_NDX_GLOBAL is always good, VER_NDX_INITIAL is fine, if
675 			// we don't look for the default version.
676 			if (versionIndex == VER_NDX_GLOBAL
677 				|| (!lookupDefault && versionIndex == VER_NDX_INITIAL)) {
678 				return symbol;
679 			}
680 
681 			// If not hidden, remember the version -- we'll return it, if
682 			// it is the only one.
683 			if ((versionID & VER_NDX_FLAG_HIDDEN) == 0) {
684 				versionedSymbolCount++;
685 				versionedSymbol = symbol;
686 			}
687 		}
688 	}
689 
690 	return versionedSymbolCount == 1 ? versionedSymbol : NULL;
691 }
692 
693 
694 static status_t
695 elf_parse_dynamic_section(struct elf_image_info *image)
696 {
697 	struct Elf32_Dyn *d;
698 	int32 neededOffset = -1;
699 
700 	TRACE(("top of elf_parse_dynamic_section\n"));
701 
702 	image->symhash = 0;
703 	image->syms = 0;
704 	image->strtab = 0;
705 
706 	d = (struct Elf32_Dyn *)image->dynamic_section;
707 	if (!d)
708 		return B_ERROR;
709 
710 	for (int32 i = 0; d[i].d_tag != DT_NULL; i++) {
711 		switch (d[i].d_tag) {
712 			case DT_NEEDED:
713 				neededOffset = d[i].d_un.d_ptr + image->text_region.delta;
714 				break;
715 			case DT_HASH:
716 				image->symhash = (uint32 *)(d[i].d_un.d_ptr
717 					+ image->text_region.delta);
718 				break;
719 			case DT_STRTAB:
720 				image->strtab = (char *)(d[i].d_un.d_ptr
721 					+ image->text_region.delta);
722 				break;
723 			case DT_SYMTAB:
724 				image->syms = (struct Elf32_Sym *)(d[i].d_un.d_ptr
725 					+ image->text_region.delta);
726 				break;
727 			case DT_REL:
728 				image->rel = (struct Elf32_Rel *)(d[i].d_un.d_ptr
729 					+ image->text_region.delta);
730 				break;
731 			case DT_RELSZ:
732 				image->rel_len = d[i].d_un.d_val;
733 				break;
734 			case DT_RELA:
735 				image->rela = (struct Elf32_Rela *)(d[i].d_un.d_ptr
736 					+ image->text_region.delta);
737 				break;
738 			case DT_RELASZ:
739 				image->rela_len = d[i].d_un.d_val;
740 				break;
741 			case DT_JMPREL:
742 				image->pltrel = (struct Elf32_Rel *)(d[i].d_un.d_ptr
743 					+ image->text_region.delta);
744 				break;
745 			case DT_PLTRELSZ:
746 				image->pltrel_len = d[i].d_un.d_val;
747 				break;
748 			case DT_PLTREL:
749 				image->pltrel_type = d[i].d_un.d_val;
750 				break;
751 			case DT_VERSYM:
752 				image->symbol_versions = (Elf32_Versym*)
753 					(d[i].d_un.d_ptr + image->text_region.delta);
754 				break;
755 			case DT_VERDEF:
756 				image->version_definitions = (Elf32_Verdef*)
757 					(d[i].d_un.d_ptr + image->text_region.delta);
758 				break;
759 			case DT_VERDEFNUM:
760 				image->num_version_definitions = d[i].d_un.d_val;
761 				break;
762 			case DT_VERNEED:
763 				image->needed_versions = (Elf32_Verneed*)
764 					(d[i].d_un.d_ptr + image->text_region.delta);
765 				break;
766 			case DT_VERNEEDNUM:
767 				image->num_needed_versions = d[i].d_un.d_val;
768 				break;
769 
770 			default:
771 				continue;
772 		}
773 	}
774 
775 	// lets make sure we found all the required sections
776 	if (!image->symhash || !image->syms || !image->strtab)
777 		return B_ERROR;
778 
779 	TRACE(("needed_offset = %ld\n", neededOffset));
780 
781 	if (neededOffset >= 0)
782 		image->needed = STRING(image, neededOffset);
783 
784 	return B_OK;
785 }
786 
787 
788 static status_t
789 assert_defined_image_version(elf_image_info* dependentImage,
790 	elf_image_info* image, const elf_version_info& neededVersion, bool weak)
791 {
792 	// If the image doesn't have version definitions, we print a warning and
793 	// succeed. Weird, but that's how glibc does it. Not unlikely we'll fail
794 	// later when resolving versioned symbols.
795 	if (image->version_definitions == NULL) {
796 		dprintf("%s: No version information available (required by %s)\n",
797 			image->name, dependentImage->name);
798 		return B_OK;
799 	}
800 
801 	// iterate through the defined versions to find the given one
802 	Elf32_Verdef* definition = image->version_definitions;
803 	for (uint32 i = 0; i < image->num_version_definitions; i++) {
804 		uint32 versionIndex = VER_NDX(definition->vd_ndx);
805 		elf_version_info& info = image->versions[versionIndex];
806 
807 		if (neededVersion.hash == info.hash
808 			&& strcmp(neededVersion.name, info.name) == 0) {
809 			return B_OK;
810 		}
811 
812 		definition = (Elf32_Verdef*)
813 			((uint8*)definition + definition->vd_next);
814 	}
815 
816 	// version not found -- fail, if not weak
817 	if (!weak) {
818 		dprintf("%s: version \"%s\" not found (required by %s)\n", image->name,
819 			neededVersion.name, dependentImage->name);
820 		return B_MISSING_SYMBOL;
821 	}
822 
823 	return B_OK;
824 }
825 
826 
827 static status_t
828 init_image_version_infos(elf_image_info* image)
829 {
830 	// First find out how many version infos we need -- i.e. get the greatest
831 	// version index from the defined and needed versions (they use the same
832 	// index namespace).
833 	uint32 maxIndex = 0;
834 
835 	if (image->version_definitions != NULL) {
836 		Elf32_Verdef* definition = image->version_definitions;
837 		for (uint32 i = 0; i < image->num_version_definitions; i++) {
838 			if (definition->vd_version != 1) {
839 				dprintf("Unsupported version definition revision: %u\n",
840 					definition->vd_version);
841 				return B_BAD_VALUE;
842 			}
843 
844 			uint32 versionIndex = VER_NDX(definition->vd_ndx);
845 			if (versionIndex > maxIndex)
846 				maxIndex = versionIndex;
847 
848 			definition = (Elf32_Verdef*)
849 				((uint8*)definition	+ definition->vd_next);
850 		}
851 	}
852 
853 	if (image->needed_versions != NULL) {
854 		Elf32_Verneed* needed = image->needed_versions;
855 		for (uint32 i = 0; i < image->num_needed_versions; i++) {
856 			if (needed->vn_version != 1) {
857 				dprintf("Unsupported version needed revision: %u\n",
858 					needed->vn_version);
859 				return B_BAD_VALUE;
860 			}
861 
862 			Elf32_Vernaux* vernaux
863 				= (Elf32_Vernaux*)((uint8*)needed + needed->vn_aux);
864 			for (uint32 k = 0; k < needed->vn_cnt; k++) {
865 				uint32 versionIndex = VER_NDX(vernaux->vna_other);
866 				if (versionIndex > maxIndex)
867 					maxIndex = versionIndex;
868 
869 				vernaux = (Elf32_Vernaux*)((uint8*)vernaux + vernaux->vna_next);
870 			}
871 
872 			needed = (Elf32_Verneed*)((uint8*)needed + needed->vn_next);
873 		}
874 	}
875 
876 	if (maxIndex == 0)
877 		return B_OK;
878 
879 	// allocate the version infos
880 	image->versions
881 		= (elf_version_info*)malloc(sizeof(elf_version_info) * (maxIndex + 1));
882 	if (image->versions == NULL) {
883 		dprintf("Memory shortage in init_image_version_infos()\n");
884 		return B_NO_MEMORY;
885 	}
886 	image->num_versions = maxIndex + 1;
887 
888 	// init the version infos
889 
890 	// version definitions
891 	if (image->version_definitions != NULL) {
892 		Elf32_Verdef* definition = image->version_definitions;
893 		for (uint32 i = 0; i < image->num_version_definitions; i++) {
894 			if (definition->vd_cnt > 0
895 				&& (definition->vd_flags & VER_FLG_BASE) == 0) {
896 				Elf32_Verdaux* verdaux
897 					= (Elf32_Verdaux*)((uint8*)definition + definition->vd_aux);
898 
899 				uint32 versionIndex = VER_NDX(definition->vd_ndx);
900 				elf_version_info& info = image->versions[versionIndex];
901 				info.hash = definition->vd_hash;
902 				info.name = STRING(image, verdaux->vda_name);
903 			}
904 
905 			definition = (Elf32_Verdef*)
906 				((uint8*)definition + definition->vd_next);
907 		}
908 	}
909 
910 	// needed versions
911 	if (image->needed_versions != NULL) {
912 		Elf32_Verneed* needed = image->needed_versions;
913 		for (uint32 i = 0; i < image->num_needed_versions; i++) {
914 			const char* fileName = STRING(image, needed->vn_file);
915 
916 			Elf32_Vernaux* vernaux
917 				= (Elf32_Vernaux*)((uint8*)needed + needed->vn_aux);
918 			for (uint32 k = 0; k < needed->vn_cnt; k++) {
919 				uint32 versionIndex = VER_NDX(vernaux->vna_other);
920 				elf_version_info& info = image->versions[versionIndex];
921 				info.hash = vernaux->vna_hash;
922 				info.name = STRING(image, vernaux->vna_name);
923 				info.file_name = fileName;
924 
925 				vernaux = (Elf32_Vernaux*)((uint8*)vernaux + vernaux->vna_next);
926 			}
927 
928 			needed = (Elf32_Verneed*)((uint8*)needed + needed->vn_next);
929 		}
930 	}
931 
932 	return B_OK;
933 }
934 
935 
936 static status_t
937 check_needed_image_versions(elf_image_info* image)
938 {
939 	if (image->needed_versions == NULL)
940 		return B_OK;
941 
942 	Elf32_Verneed* needed = image->needed_versions;
943 	for (uint32 i = 0; i < image->num_needed_versions; i++) {
944 		elf_image_info* dependency = sKernelImage;
945 
946 		Elf32_Vernaux* vernaux
947 			= (Elf32_Vernaux*)((uint8*)needed + needed->vn_aux);
948 		for (uint32 k = 0; k < needed->vn_cnt; k++) {
949 			uint32 versionIndex = VER_NDX(vernaux->vna_other);
950 			elf_version_info& info = image->versions[versionIndex];
951 
952 			status_t error = assert_defined_image_version(image, dependency,
953 				info, (vernaux->vna_flags & VER_FLG_WEAK) != 0);
954 			if (error != B_OK)
955 				return error;
956 
957 			vernaux = (Elf32_Vernaux*)((uint8*)vernaux + vernaux->vna_next);
958 		}
959 
960 		needed = (Elf32_Verneed*)((uint8*)needed + needed->vn_next);
961 	}
962 
963 	return B_OK;
964 }
965 
966 
967 /*!	Resolves the \a symbol by linking against \a sharedImage if necessary.
968 	Returns the resolved symbol's address in \a _symbolAddress.
969 */
970 status_t
971 elf_resolve_symbol(struct elf_image_info *image, struct Elf32_Sym *symbol,
972 	struct elf_image_info *sharedImage, addr_t *_symbolAddress)
973 {
974 	switch (symbol->st_shndx) {
975 		case SHN_UNDEF:
976 		{
977 			struct Elf32_Sym *newSymbol;
978 			const char *symbolName = SYMNAME(image, symbol);
979 
980 			// get the version info
981 			const elf_version_info* versionInfo = NULL;
982 			if (image->symbol_versions != NULL) {
983 				uint32 index = symbol - image->syms;
984 				uint32 versionIndex = VER_NDX(image->symbol_versions[index]);
985 				if (versionIndex >= VER_NDX_INITIAL)
986 					versionInfo = image->versions + versionIndex;
987 			}
988 
989 			// it's undefined, must be outside this image, try the other image
990 			newSymbol = elf_find_symbol(sharedImage, symbolName, versionInfo,
991 				false);
992 			if (newSymbol == NULL) {
993 				dprintf("\"%s\": could not resolve symbol '%s'\n",
994 					image->name, symbolName);
995 				return B_MISSING_SYMBOL;
996 			}
997 
998 			// make sure they're the same type
999 			if (ELF32_ST_TYPE(symbol->st_info)
1000 					!= ELF32_ST_TYPE(newSymbol->st_info)) {
1001 				dprintf("elf_resolve_symbol: found symbol '%s' in shared image "
1002 					"but wrong type\n", symbolName);
1003 				return B_MISSING_SYMBOL;
1004 			}
1005 
1006 			if (ELF32_ST_BIND(newSymbol->st_info) != STB_GLOBAL
1007 				&& ELF32_ST_BIND(newSymbol->st_info) != STB_WEAK) {
1008 				TRACE(("elf_resolve_symbol: found symbol '%s' but not "
1009 					"exported\n", symbolName));
1010 				return B_MISSING_SYMBOL;
1011 			}
1012 
1013 			*_symbolAddress = newSymbol->st_value
1014 				+ sharedImage->text_region.delta;
1015 			return B_OK;
1016 		}
1017 		case SHN_ABS:
1018 			*_symbolAddress = symbol->st_value;
1019 			return B_OK;
1020 		case SHN_COMMON:
1021 			// ToDo: finish this
1022 			TRACE(("elf_resolve_symbol: COMMON symbol, finish me!\n"));
1023 			return B_ERROR;
1024 
1025 		default:
1026 			// standard symbol
1027 			*_symbolAddress = symbol->st_value + image->text_region.delta;
1028 			return B_OK;
1029 	}
1030 }
1031 
1032 
1033 /*! Until we have shared library support, just this links against the kernel */
1034 static int
1035 elf_relocate(struct elf_image_info *image)
1036 {
1037 	int status = B_NO_ERROR;
1038 
1039 	TRACE(("top of elf_relocate\n"));
1040 
1041 	// deal with the rels first
1042 	if (image->rel) {
1043 		TRACE(("total %i relocs\n",
1044 			image->rel_len / (int)sizeof(struct Elf32_Rel)));
1045 
1046 		status = arch_elf_relocate_rel(image, sKernelImage, image->rel,
1047 			image->rel_len);
1048 		if (status < B_OK)
1049 			return status;
1050 	}
1051 
1052 	if (image->pltrel) {
1053 		TRACE(("total %i plt-relocs\n",
1054 			image->pltrel_len / (int)sizeof(struct Elf32_Rel)));
1055 
1056 		if (image->pltrel_type == DT_REL) {
1057 			status = arch_elf_relocate_rel(image, sKernelImage, image->pltrel,
1058 				image->pltrel_len);
1059 		} else {
1060 			status = arch_elf_relocate_rela(image, sKernelImage,
1061 				(struct Elf32_Rela *)image->pltrel, image->pltrel_len);
1062 		}
1063 		if (status < B_OK)
1064 			return status;
1065 	}
1066 
1067 	if (image->rela) {
1068 		status = arch_elf_relocate_rela(image, sKernelImage, image->rela,
1069 			image->rela_len);
1070 		if (status < B_OK)
1071 			return status;
1072 	}
1073 
1074 	return status;
1075 }
1076 
1077 
1078 static int
1079 verify_eheader(struct Elf32_Ehdr *elfHeader)
1080 {
1081 	if (memcmp(elfHeader->e_ident, ELF_MAGIC, 4) != 0)
1082 		return B_NOT_AN_EXECUTABLE;
1083 
1084 	if (elfHeader->e_ident[4] != ELFCLASS32)
1085 		return B_NOT_AN_EXECUTABLE;
1086 
1087 	if (elfHeader->e_phoff == 0)
1088 		return B_NOT_AN_EXECUTABLE;
1089 
1090 	if (elfHeader->e_phentsize < sizeof(struct Elf32_Phdr))
1091 		return B_NOT_AN_EXECUTABLE;
1092 
1093 	return 0;
1094 }
1095 
1096 
1097 static void
1098 unload_elf_image(struct elf_image_info *image)
1099 {
1100 	if (atomic_add(&image->ref_count, -1) > 1)
1101 		return;
1102 
1103 	TRACE(("unload image %ld, %s\n", image->id, image->name));
1104 
1105 	unregister_elf_image(image);
1106 	delete_elf_image(image);
1107 }
1108 
1109 
1110 static status_t
1111 load_elf_symbol_table(int fd, struct elf_image_info *image)
1112 {
1113 	struct Elf32_Ehdr *elfHeader = image->elf_header;
1114 	struct Elf32_Sym *symbolTable = NULL;
1115 	struct Elf32_Shdr *stringHeader = NULL;
1116 	uint32 numSymbols = 0;
1117 	char *stringTable;
1118 	status_t status;
1119 	ssize_t length;
1120 	int32 i;
1121 
1122 	// get section headers
1123 
1124 	ssize_t size = elfHeader->e_shnum * elfHeader->e_shentsize;
1125 	struct Elf32_Shdr *sectionHeaders = (struct Elf32_Shdr *)malloc(size);
1126 	if (sectionHeaders == NULL) {
1127 		dprintf("error allocating space for section headers\n");
1128 		return B_NO_MEMORY;
1129 	}
1130 
1131 	length = read_pos(fd, elfHeader->e_shoff, sectionHeaders, size);
1132 	if (length < size) {
1133 		TRACE(("error reading in program headers\n"));
1134 		status = B_ERROR;
1135 		goto error1;
1136 	}
1137 
1138 	// find symbol table in section headers
1139 
1140 	for (i = 0; i < elfHeader->e_shnum; i++) {
1141 		if (sectionHeaders[i].sh_type == SHT_SYMTAB) {
1142 			stringHeader = &sectionHeaders[sectionHeaders[i].sh_link];
1143 
1144 			if (stringHeader->sh_type != SHT_STRTAB) {
1145 				TRACE(("doesn't link to string table\n"));
1146 				status = B_BAD_DATA;
1147 				goto error1;
1148 			}
1149 
1150 			// read in symbol table
1151 			symbolTable
1152 				= (struct Elf32_Sym *)malloc(size = sectionHeaders[i].sh_size);
1153 			if (symbolTable == NULL) {
1154 				status = B_NO_MEMORY;
1155 				goto error1;
1156 			}
1157 
1158 			length
1159 				= read_pos(fd, sectionHeaders[i].sh_offset, symbolTable, size);
1160 			if (length < size) {
1161 				TRACE(("error reading in symbol table\n"));
1162 				status = B_ERROR;
1163 				goto error1;
1164 			}
1165 
1166 			numSymbols = size / sizeof(struct Elf32_Sym);
1167 			break;
1168 		}
1169 	}
1170 
1171 	if (symbolTable == NULL) {
1172 		TRACE(("no symbol table\n"));
1173 		status = B_BAD_VALUE;
1174 		goto error1;
1175 	}
1176 
1177 	// read in string table
1178 
1179 	stringTable = (char *)malloc(size = stringHeader->sh_size);
1180 	if (stringTable == NULL) {
1181 		status = B_NO_MEMORY;
1182 		goto error2;
1183 	}
1184 
1185 	length = read_pos(fd, stringHeader->sh_offset, stringTable, size);
1186 	if (length < size) {
1187 		TRACE(("error reading in string table\n"));
1188 		status = B_ERROR;
1189 		goto error3;
1190 	}
1191 
1192 	TRACE(("loaded debug %ld symbols\n", numSymbols));
1193 
1194 	// insert tables into image
1195 	image->debug_symbols = symbolTable;
1196 	image->num_debug_symbols = numSymbols;
1197 	image->debug_string_table = stringTable;
1198 
1199 	free(sectionHeaders);
1200 	return B_OK;
1201 
1202 error3:
1203 	free(stringTable);
1204 error2:
1205 	free(symbolTable);
1206 error1:
1207 	free(sectionHeaders);
1208 
1209 	return status;
1210 }
1211 
1212 
1213 static status_t
1214 insert_preloaded_image(struct preloaded_image *preloadedImage, bool kernel)
1215 {
1216 	status_t status;
1217 
1218 	status = verify_eheader(&preloadedImage->elf_header);
1219 	if (status != B_OK)
1220 		return status;
1221 
1222 	elf_image_info *image = create_image_struct();
1223 	if (image == NULL)
1224 		return B_NO_MEMORY;
1225 
1226 	image->name = strdup(preloadedImage->name);
1227 	image->dynamic_section = preloadedImage->dynamic_section.start;
1228 
1229 	image->text_region = preloadedImage->text_region;
1230 	image->data_region = preloadedImage->data_region;
1231 
1232 	status = elf_parse_dynamic_section(image);
1233 	if (status != B_OK)
1234 		goto error1;
1235 
1236 	status = init_image_version_infos(image);
1237 	if (status != B_OK)
1238 		goto error1;
1239 
1240 	if (!kernel) {
1241 		status = check_needed_image_versions(image);
1242 		if (status != B_OK)
1243 			goto error1;
1244 
1245 		status = elf_relocate(image);
1246 		if (status != B_OK)
1247 			goto error1;
1248 	} else
1249 		sKernelImage = image;
1250 
1251 	// copy debug symbols to the kernel heap
1252 	if (preloadedImage->debug_symbols != NULL) {
1253 		int32 debugSymbolsSize = sizeof(Elf32_Sym)
1254 			* preloadedImage->num_debug_symbols;
1255 		image->debug_symbols = (Elf32_Sym*)malloc(debugSymbolsSize);
1256 		if (image->debug_symbols != NULL) {
1257 			memcpy(image->debug_symbols, preloadedImage->debug_symbols,
1258 				debugSymbolsSize);
1259 		}
1260 	}
1261 	image->num_debug_symbols = preloadedImage->num_debug_symbols;
1262 
1263 	// copy debug string table to the kernel heap
1264 	if (preloadedImage->debug_string_table != NULL) {
1265 		image->debug_string_table = (char*)malloc(
1266 			preloadedImage->debug_string_table_size);
1267 		if (image->debug_string_table != NULL) {
1268 			memcpy((void*)image->debug_string_table,
1269 				preloadedImage->debug_string_table,
1270 				preloadedImage->debug_string_table_size);
1271 		}
1272 	}
1273 
1274 	register_elf_image(image);
1275 	preloadedImage->id = image->id;
1276 		// modules_init() uses this information to get the preloaded images
1277 
1278 	// we now no longer need to write to the text area anymore
1279 	set_area_protection(image->text_region.id,
1280 		B_KERNEL_READ_AREA | B_KERNEL_EXECUTE_AREA);
1281 
1282 	return B_OK;
1283 
1284 error1:
1285 	delete_elf_image(image);
1286 
1287 	preloadedImage->id = -1;
1288 
1289 	return status;
1290 }
1291 
1292 
1293 //	#pragma mark - userland symbol lookup
1294 
1295 
1296 class UserSymbolLookup {
1297 public:
1298 	static UserSymbolLookup& Default()
1299 	{
1300 		return sLookup;
1301 	}
1302 
1303 	status_t Init(struct team* team)
1304 	{
1305 		// find the runtime loader debug area
1306 		VMArea* area;
1307 		for (VMAddressSpace::AreaIterator it
1308 					= team->address_space->GetAreaIterator();
1309 				(area = it.Next()) != NULL;) {
1310 			if (strcmp(area->name, RUNTIME_LOADER_DEBUG_AREA_NAME) == 0)
1311 				break;
1312 		}
1313 
1314 		if (area == NULL)
1315 			return B_ERROR;
1316 
1317 		// copy the runtime loader data structure
1318 		if (!_Read((runtime_loader_debug_area*)area->Base(), fDebugArea))
1319 			return B_BAD_ADDRESS;
1320 
1321 		return B_OK;
1322 	}
1323 
1324 	status_t LookupSymbolAddress(addr_t address, addr_t *_baseAddress,
1325 		const char **_symbolName, const char **_imageName, bool *_exactMatch)
1326 	{
1327 		// Note, that this function doesn't find all symbols that we would like
1328 		// to find. E.g. static functions do not appear in the symbol table
1329 		// as function symbols, but as sections without name and size. The
1330 		// .symtab section together with the .strtab section, which apparently
1331 		// differ from the tables referred to by the .dynamic section, also
1332 		// contain proper names and sizes for those symbols. Therefore, to get
1333 		// completely satisfying results, we would need to read those tables
1334 		// from the shared object.
1335 
1336 		// get the image for the address
1337 		image_t image;
1338 		status_t error = _FindImageAtAddress(address, image);
1339 		if (error != B_OK)
1340 			return error;
1341 
1342 		strlcpy(fImageName, image.name, sizeof(fImageName));
1343 
1344 		// symbol hash table size
1345 		uint32 hashTabSize;
1346 		if (!_Read(image.symhash, hashTabSize))
1347 			return B_BAD_ADDRESS;
1348 
1349 		// remote pointers to hash buckets and chains
1350 		const uint32* hashBuckets = image.symhash + 2;
1351 		const uint32* hashChains = image.symhash + 2 + hashTabSize;
1352 
1353 		const elf_region_t& textRegion = image.regions[0];
1354 
1355 		// search the image for the symbol
1356 		Elf32_Sym symbolFound;
1357 		addr_t deltaFound = INT_MAX;
1358 		bool exactMatch = false;
1359 
1360 		// to get rid of the erroneous "uninitialized" warnings
1361 		symbolFound.st_name = 0;
1362 		symbolFound.st_value = 0;
1363 
1364 		for (uint32 i = 0; i < hashTabSize; i++) {
1365 			uint32 bucket;
1366 			if (!_Read(&hashBuckets[i], bucket))
1367 				return B_BAD_ADDRESS;
1368 
1369 			for (uint32 j = bucket; j != STN_UNDEF;
1370 					_Read(&hashChains[j], j) ? 0 : j = STN_UNDEF) {
1371 
1372 				Elf32_Sym symbol;
1373 				if (!_Read(image.syms + j, symbol))
1374 					continue;
1375 
1376 				// The symbol table contains not only symbols referring to
1377 				// functions and data symbols within the shared object, but also
1378 				// referenced symbols of other shared objects, as well as
1379 				// section and file references. We ignore everything but
1380 				// function and data symbols that have an st_value != 0 (0
1381 				// seems to be an indication for a symbol defined elsewhere
1382 				// -- couldn't verify that in the specs though).
1383 				if ((ELF32_ST_TYPE(symbol.st_info) != STT_FUNC
1384 						&& ELF32_ST_TYPE(symbol.st_info) != STT_OBJECT)
1385 					|| symbol.st_value == 0
1386 					|| symbol.st_value + symbol.st_size + textRegion.delta
1387 						> textRegion.vmstart + textRegion.size) {
1388 					continue;
1389 				}
1390 
1391 				// skip symbols starting after the given address
1392 				addr_t symbolAddress = symbol.st_value + textRegion.delta;
1393 				if (symbolAddress > address)
1394 					continue;
1395 				addr_t symbolDelta = address - symbolAddress;
1396 
1397 				if (symbolDelta < deltaFound) {
1398 					deltaFound = symbolDelta;
1399 					symbolFound = symbol;
1400 
1401 					if (symbolDelta >= 0 && symbolDelta < symbol.st_size) {
1402 						// exact match
1403 						exactMatch = true;
1404 						break;
1405 					}
1406 				}
1407 			}
1408 		}
1409 
1410 		if (_imageName)
1411 			*_imageName = fImageName;
1412 
1413 		if (_symbolName) {
1414 			*_symbolName = NULL;
1415 
1416 			if (deltaFound < INT_MAX) {
1417 				if (_ReadString(image, symbolFound.st_name, fSymbolName,
1418 						sizeof(fSymbolName))) {
1419 					*_symbolName = fSymbolName;
1420 				} else {
1421 					// we can't get its name, so forget the symbol
1422 					deltaFound = INT_MAX;
1423 				}
1424 			}
1425 		}
1426 
1427 		if (_baseAddress) {
1428 			if (deltaFound < INT_MAX)
1429 				*_baseAddress = symbolFound.st_value + textRegion.delta;
1430 			else
1431 				*_baseAddress = textRegion.vmstart;
1432 		}
1433 
1434 		if (_exactMatch)
1435 			*_exactMatch = exactMatch;
1436 
1437 		return B_OK;
1438 	}
1439 
1440 	status_t _FindImageAtAddress(addr_t address, image_t& image)
1441 	{
1442 		image_queue_t imageQueue;
1443 		if (!_Read(fDebugArea.loaded_images, imageQueue))
1444 			return B_BAD_ADDRESS;
1445 
1446 		image_t* imageAddress = imageQueue.head;
1447 		while (imageAddress != NULL) {
1448 			if (!_Read(imageAddress, image))
1449 				return B_BAD_ADDRESS;
1450 
1451 			if (image.regions[0].vmstart <= address
1452 				&& address < image.regions[0].vmstart + image.regions[0].size) {
1453 				return B_OK;
1454 			}
1455 
1456 			imageAddress = image.next;
1457 		}
1458 
1459 		return B_ENTRY_NOT_FOUND;
1460 	}
1461 
1462 	bool _ReadString(const image_t& image, uint32 offset, char* buffer,
1463 		size_t bufferSize)
1464 	{
1465 		const char* address = image.strtab + offset;
1466 
1467 		if (!IS_USER_ADDRESS(address))
1468 			return false;
1469 
1470 		if (debug_debugger_running()) {
1471 			return debug_strlcpy(B_CURRENT_TEAM, buffer, address, bufferSize)
1472 				>= 0;
1473 		}
1474 		return user_strlcpy(buffer, address, bufferSize) >= 0;
1475 	}
1476 
1477 	template<typename T> bool _Read(const T* address, T& data);
1478 		// gcc 2.95.3 doesn't like it defined in-place
1479 
1480 private:
1481 	runtime_loader_debug_area	fDebugArea;
1482 	char						fImageName[B_OS_NAME_LENGTH];
1483 	char						fSymbolName[256];
1484 	static UserSymbolLookup		sLookup;
1485 };
1486 
1487 
1488 template<typename T>
1489 bool
1490 UserSymbolLookup::_Read(const T* address, T& data)
1491 {
1492 	if (!IS_USER_ADDRESS(address))
1493 		return false;
1494 
1495 	if (debug_debugger_running())
1496 		return debug_memcpy(B_CURRENT_TEAM, &data, address, sizeof(T)) == B_OK;
1497 	return user_memcpy(&data, address, sizeof(T)) == B_OK;
1498 }
1499 
1500 
1501 UserSymbolLookup UserSymbolLookup::sLookup;
1502 	// doesn't need construction, but has an Init() method
1503 
1504 
1505 //	#pragma mark - public kernel API
1506 
1507 
1508 status_t
1509 get_image_symbol(image_id id, const char *name, int32 symbolClass,
1510 	void **_symbol)
1511 {
1512 	struct elf_image_info *image;
1513 	struct Elf32_Sym *symbol;
1514 	status_t status = B_OK;
1515 
1516 	TRACE(("get_image_symbol(%s)\n", name));
1517 
1518 	mutex_lock(&sImageMutex);
1519 
1520 	image = find_image(id);
1521 	if (image == NULL) {
1522 		status = B_BAD_IMAGE_ID;
1523 		goto done;
1524 	}
1525 
1526 	symbol = elf_find_symbol(image, name, NULL, true);
1527 	if (symbol == NULL || symbol->st_shndx == SHN_UNDEF) {
1528 		status = B_ENTRY_NOT_FOUND;
1529 		goto done;
1530 	}
1531 
1532 	// TODO: support the "symbolClass" parameter!
1533 
1534 	TRACE(("found: %lx (%lx + %lx)\n",
1535 		symbol->st_value + image->text_region.delta,
1536 		symbol->st_value, image->text_region.delta));
1537 
1538 	*_symbol = (void *)(symbol->st_value + image->text_region.delta);
1539 
1540 done:
1541 	mutex_unlock(&sImageMutex);
1542 	return status;
1543 }
1544 
1545 
1546 //	#pragma mark - kernel private API
1547 
1548 
1549 /*!	Looks up a symbol by address in all images loaded in kernel space.
1550 	Note, if you need to call this function outside a debugger, make
1551 	sure you fix locking and the way it returns its information, first!
1552 */
1553 status_t
1554 elf_debug_lookup_symbol_address(addr_t address, addr_t *_baseAddress,
1555 	const char **_symbolName, const char **_imageName, bool *_exactMatch)
1556 {
1557 	struct elf_image_info *image;
1558 	struct Elf32_Sym *symbolFound = NULL;
1559 	const char *symbolName = NULL;
1560 	addr_t deltaFound = INT_MAX;
1561 	bool exactMatch = false;
1562 	status_t status;
1563 
1564 	TRACE(("looking up %p\n", (void *)address));
1565 
1566 	if (!sInitialized)
1567 		return B_ERROR;
1568 
1569 	//mutex_lock(&sImageMutex);
1570 
1571 	image = find_image_at_address(address);
1572 		// get image that may contain the address
1573 
1574 	if (image != NULL) {
1575 		addr_t symbolDelta;
1576 		uint32 i;
1577 		int32 j;
1578 
1579 		TRACE((" image %p, base = %p, size = %p\n", image,
1580 			(void *)image->text_region.start, (void *)image->text_region.size));
1581 
1582 		if (image->debug_symbols != NULL) {
1583 			// search extended debug symbol table (contains static symbols)
1584 
1585 			TRACE((" searching debug symbols...\n"));
1586 
1587 			for (i = 0; i < image->num_debug_symbols; i++) {
1588 				struct Elf32_Sym *symbol = &image->debug_symbols[i];
1589 
1590 				if (symbol->st_value == 0 || symbol->st_size
1591 						>= image->text_region.size + image->data_region.size)
1592 					continue;
1593 
1594 				symbolDelta
1595 					= address - (symbol->st_value + image->text_region.delta);
1596 				if (symbolDelta >= 0 && symbolDelta < symbol->st_size)
1597 					exactMatch = true;
1598 
1599 				if (exactMatch || symbolDelta < deltaFound) {
1600 					deltaFound = symbolDelta;
1601 					symbolFound = symbol;
1602 					symbolName = image->debug_string_table + symbol->st_name;
1603 
1604 					if (exactMatch)
1605 						break;
1606 				}
1607 			}
1608 		} else {
1609 			// search standard symbol lookup table
1610 
1611 			TRACE((" searching standard symbols...\n"));
1612 
1613 			for (i = 0; i < HASHTABSIZE(image); i++) {
1614 				for (j = HASHBUCKETS(image)[i]; j != STN_UNDEF;
1615 						j = HASHCHAINS(image)[j]) {
1616 					struct Elf32_Sym *symbol = &image->syms[j];
1617 
1618 					if (symbol->st_value == 0
1619 						|| symbol->st_size >= image->text_region.size
1620 							+ image->data_region.size)
1621 						continue;
1622 
1623 					symbolDelta = address - (long)(symbol->st_value
1624 						+ image->text_region.delta);
1625 					if (symbolDelta >= 0 && symbolDelta < symbol->st_size)
1626 						exactMatch = true;
1627 
1628 					if (exactMatch || symbolDelta < deltaFound) {
1629 						deltaFound = symbolDelta;
1630 						symbolFound = symbol;
1631 						symbolName = SYMNAME(image, symbol);
1632 
1633 						if (exactMatch)
1634 							goto symbol_found;
1635 					}
1636 				}
1637 			}
1638 		}
1639 	}
1640 symbol_found:
1641 
1642 	if (symbolFound != NULL) {
1643 		if (_symbolName)
1644 			*_symbolName = symbolName;
1645 		if (_imageName)
1646 			*_imageName = image->name;
1647 		if (_baseAddress)
1648 			*_baseAddress = symbolFound->st_value + image->text_region.delta;
1649 		if (_exactMatch)
1650 			*_exactMatch = exactMatch;
1651 
1652 		status = B_OK;
1653 	} else if (image != NULL) {
1654 		TRACE(("symbol not found!\n"));
1655 
1656 		if (_symbolName)
1657 			*_symbolName = NULL;
1658 		if (_imageName)
1659 			*_imageName = image->name;
1660 		if (_baseAddress)
1661 			*_baseAddress = image->text_region.start;
1662 		if (_exactMatch)
1663 			*_exactMatch = false;
1664 
1665 		status = B_OK;
1666 	} else {
1667 		TRACE(("image not found!\n"));
1668 		status = B_ENTRY_NOT_FOUND;
1669 	}
1670 
1671 	// Note, theoretically, all information we return back to our caller
1672 	// would have to be locked - but since this function is only called
1673 	// from the debugger, it's safe to do it this way
1674 
1675 	//mutex_unlock(&sImageMutex);
1676 
1677 	return status;
1678 }
1679 
1680 
1681 /*!	Tries to find a matching user symbol for the given address.
1682 	Note that the given team's address space must already be in effect.
1683 */
1684 status_t
1685 elf_debug_lookup_user_symbol_address(struct team* team, addr_t address,
1686 	addr_t *_baseAddress, const char **_symbolName, const char **_imageName,
1687 	bool *_exactMatch)
1688 {
1689 	if (team == NULL || team == team_get_kernel_team())
1690 		return B_BAD_VALUE;
1691 
1692 	UserSymbolLookup& lookup = UserSymbolLookup::Default();
1693 	status_t error = lookup.Init(team);
1694 	if (error != B_OK)
1695 		return error;
1696 
1697 	return lookup.LookupSymbolAddress(address, _baseAddress, _symbolName,
1698 		_imageName, _exactMatch);
1699 }
1700 
1701 
1702 /*!	Looks up a symbol in all kernel images. Note, this function is thought to
1703 	be used in the kernel debugger, and therefore doesn't perform any locking.
1704 */
1705 addr_t
1706 elf_debug_lookup_symbol(const char* searchName)
1707 {
1708 	struct elf_image_info *image = NULL;
1709 	struct hash_iterator iterator;
1710 
1711 	hash_open(sImagesHash, &iterator);
1712 	while ((image = (elf_image_info *)hash_next(sImagesHash, &iterator))
1713 			!= NULL) {
1714 		if (image->num_debug_symbols > 0) {
1715 			// search extended debug symbol table (contains static symbols)
1716 			for (uint32 i = 0; i < image->num_debug_symbols; i++) {
1717 				struct Elf32_Sym *symbol = &image->debug_symbols[i];
1718 				const char *name = image->debug_string_table + symbol->st_name;
1719 
1720 				if (symbol->st_value > 0 && !strcmp(name, searchName))
1721 					return symbol->st_value + image->text_region.delta;
1722 			}
1723 		} else {
1724 			// search standard symbol lookup table
1725 			for (uint32 i = 0; i < HASHTABSIZE(image); i++) {
1726 				for (uint32 j = HASHBUCKETS(image)[i]; j != STN_UNDEF;
1727 						j = HASHCHAINS(image)[j]) {
1728 					struct Elf32_Sym *symbol = &image->syms[j];
1729 					const char *name = SYMNAME(image, symbol);
1730 
1731 					if (symbol->st_value > 0 && !strcmp(name, searchName))
1732 						return symbol->st_value + image->text_region.delta;
1733 				}
1734 			}
1735 		}
1736 	}
1737 	hash_close(sImagesHash, &iterator, false);
1738 
1739 	return 0;
1740 }
1741 
1742 
1743 status_t
1744 elf_load_user_image(const char *path, struct team *team, int flags,
1745 	addr_t *entry)
1746 {
1747 	struct Elf32_Ehdr elfHeader;
1748 	struct Elf32_Phdr *programHeaders = NULL;
1749 	char baseName[B_OS_NAME_LENGTH];
1750 	status_t status;
1751 	ssize_t length;
1752 	int fd;
1753 	int i;
1754 
1755 	TRACE(("elf_load: entry path '%s', team %p\n", path, team));
1756 
1757 	fd = _kern_open(-1, path, O_RDONLY, 0);
1758 	if (fd < 0)
1759 		return fd;
1760 
1761 	struct stat st;
1762 	status = _kern_read_stat(fd, NULL, false, &st, sizeof(st));
1763 	if (status != B_OK)
1764 		return status;
1765 
1766 	// read and verify the ELF header
1767 
1768 	length = _kern_read(fd, 0, &elfHeader, sizeof(elfHeader));
1769 	if (length < B_OK) {
1770 		status = length;
1771 		goto error;
1772 	}
1773 
1774 	if (length != sizeof(elfHeader)) {
1775 		// short read
1776 		status = B_NOT_AN_EXECUTABLE;
1777 		goto error;
1778 	}
1779 	status = verify_eheader(&elfHeader);
1780 	if (status < B_OK)
1781 		goto error;
1782 
1783 	// read program header
1784 
1785 	programHeaders = (struct Elf32_Phdr *)malloc(
1786 		elfHeader.e_phnum * elfHeader.e_phentsize);
1787 	if (programHeaders == NULL) {
1788 		dprintf("error allocating space for program headers\n");
1789 		status = B_NO_MEMORY;
1790 		goto error;
1791 	}
1792 
1793 	TRACE(("reading in program headers at 0x%lx, length 0x%x\n",
1794 		elfHeader.e_phoff, elfHeader.e_phnum * elfHeader.e_phentsize));
1795 	length = _kern_read(fd, elfHeader.e_phoff, programHeaders,
1796 		elfHeader.e_phnum * elfHeader.e_phentsize);
1797 	if (length < B_OK) {
1798 		status = length;
1799 		dprintf("error reading in program headers\n");
1800 		goto error;
1801 	}
1802 	if (length != elfHeader.e_phnum * elfHeader.e_phentsize) {
1803 		dprintf("short read while reading in program headers\n");
1804 		status = -1;
1805 		goto error;
1806 	}
1807 
1808 	// construct a nice name for the region we have to create below
1809 	{
1810 		int32 length;
1811 
1812 		const char *leaf = strrchr(path, '/');
1813 		if (leaf == NULL)
1814 			leaf = path;
1815 		else
1816 			leaf++;
1817 
1818 		length = strlen(leaf);
1819 		if (length > B_OS_NAME_LENGTH - 8)
1820 			sprintf(baseName, "...%s", leaf + length + 8 - B_OS_NAME_LENGTH);
1821 		else
1822 			strcpy(baseName, leaf);
1823 	}
1824 
1825 	// map the program's segments into memory
1826 
1827 	image_info imageInfo;
1828 	memset(&imageInfo, 0, sizeof(image_info));
1829 
1830 	for (i = 0; i < elfHeader.e_phnum; i++) {
1831 		char regionName[B_OS_NAME_LENGTH];
1832 		char *regionAddress;
1833 		area_id id;
1834 
1835 		if (programHeaders[i].p_type != PT_LOAD)
1836 			continue;
1837 
1838 		regionAddress = (char *)ROUNDDOWN(programHeaders[i].p_vaddr,
1839 			B_PAGE_SIZE);
1840 		if (programHeaders[i].p_flags & PF_WRITE) {
1841 			// rw/data segment
1842 			uint32 memUpperBound = (programHeaders[i].p_vaddr % B_PAGE_SIZE)
1843 				+ programHeaders[i].p_memsz;
1844 			uint32 fileUpperBound = (programHeaders[i].p_vaddr % B_PAGE_SIZE)
1845 				+ programHeaders[i].p_filesz;
1846 
1847 			memUpperBound = ROUNDUP(memUpperBound, B_PAGE_SIZE);
1848 			fileUpperBound = ROUNDUP(fileUpperBound, B_PAGE_SIZE);
1849 
1850 			sprintf(regionName, "%s_seg%drw", baseName, i);
1851 
1852 			id = vm_map_file(team->id, regionName, (void **)&regionAddress,
1853 				B_EXACT_ADDRESS, fileUpperBound,
1854 				B_READ_AREA | B_WRITE_AREA, REGION_PRIVATE_MAP, false,
1855 				fd, ROUNDDOWN(programHeaders[i].p_offset, B_PAGE_SIZE));
1856 			if (id < B_OK) {
1857 				dprintf("error mapping file data: %s!\n", strerror(id));
1858 				status = B_NOT_AN_EXECUTABLE;
1859 				goto error;
1860 			}
1861 
1862 			imageInfo.data = regionAddress;
1863 			imageInfo.data_size = memUpperBound;
1864 
1865 			// clean garbage brought by mmap (the region behind the file,
1866 			// at least parts of it are the bss and have to be zeroed)
1867 			uint32 start = (uint32)regionAddress
1868 				+ (programHeaders[i].p_vaddr % B_PAGE_SIZE)
1869 				+ programHeaders[i].p_filesz;
1870 			uint32 amount = fileUpperBound
1871 				- (programHeaders[i].p_vaddr % B_PAGE_SIZE)
1872 				- (programHeaders[i].p_filesz);
1873 			memset((void *)start, 0, amount);
1874 
1875 			// Check if we need extra storage for the bss - we have to do this if
1876 			// the above region doesn't already comprise the memory size, too.
1877 
1878 			if (memUpperBound != fileUpperBound) {
1879 				size_t bssSize = memUpperBound - fileUpperBound;
1880 
1881 				snprintf(regionName, B_OS_NAME_LENGTH, "%s_bss%d", baseName, i);
1882 
1883 				regionAddress += fileUpperBound;
1884 				id = create_area_etc(team->id, regionName,
1885 					(void **)&regionAddress, B_EXACT_ADDRESS, bssSize,
1886 					B_NO_LOCK, B_READ_AREA | B_WRITE_AREA, 0, 0);
1887 				if (id < B_OK) {
1888 					dprintf("error allocating bss area: %s!\n", strerror(id));
1889 					status = B_NOT_AN_EXECUTABLE;
1890 					goto error;
1891 				}
1892 			}
1893 		} else {
1894 			// assume ro/text segment
1895 			snprintf(regionName, B_OS_NAME_LENGTH, "%s_seg%dro", baseName, i);
1896 
1897 			size_t segmentSize = ROUNDUP(programHeaders[i].p_memsz
1898 				+ (programHeaders[i].p_vaddr % B_PAGE_SIZE), B_PAGE_SIZE);
1899 
1900 			id = vm_map_file(team->id, regionName, (void **)&regionAddress,
1901 				B_EXACT_ADDRESS, segmentSize,
1902 				B_READ_AREA | B_EXECUTE_AREA, REGION_PRIVATE_MAP, false,
1903 				fd, ROUNDDOWN(programHeaders[i].p_offset, B_PAGE_SIZE));
1904 			if (id < B_OK) {
1905 				dprintf("error mapping file text: %s!\n", strerror(id));
1906 				status = B_NOT_AN_EXECUTABLE;
1907 				goto error;
1908 			}
1909 
1910 			imageInfo.text = regionAddress;
1911 			imageInfo.text_size = segmentSize;
1912 		}
1913 	}
1914 
1915 	// register the loaded image
1916 	imageInfo.type = B_LIBRARY_IMAGE;
1917     imageInfo.device = st.st_dev;
1918     imageInfo.node = st.st_ino;
1919 	strlcpy(imageInfo.name, path, sizeof(imageInfo.name));
1920 
1921 	imageInfo.api_version = B_HAIKU_VERSION;
1922 	imageInfo.abi = B_HAIKU_ABI;
1923 		// TODO: Get the actual values for the shared object. Currently only
1924 		// the runtime loader is loaded, so this is good enough for the time
1925 		// being.
1926 
1927 	imageInfo.id = register_image(team, &imageInfo, sizeof(image_info));
1928 	if (imageInfo.id >= 0 && team_get_current_team_id() == team->id)
1929 		user_debug_image_created(&imageInfo);
1930 		// Don't care, if registering fails. It's not crucial.
1931 
1932 	TRACE(("elf_load: done!\n"));
1933 
1934 	*entry = elfHeader.e_entry;
1935 	status = B_OK;
1936 
1937 error:
1938 	free(programHeaders);
1939 	_kern_close(fd);
1940 
1941 	return status;
1942 }
1943 
1944 
1945 image_id
1946 load_kernel_add_on(const char *path)
1947 {
1948 	struct Elf32_Phdr *programHeaders;
1949 	struct Elf32_Ehdr *elfHeader;
1950 	struct elf_image_info *image;
1951 	const char *fileName;
1952 	void *reservedAddress;
1953 	addr_t start;
1954 	size_t reservedSize;
1955 	status_t status;
1956 	ssize_t length;
1957 
1958 	TRACE(("elf_load_kspace: entry path '%s'\n", path));
1959 
1960 	int fd = _kern_open(-1, path, O_RDONLY, 0);
1961 	if (fd < 0)
1962 		return fd;
1963 
1964 	struct vnode *vnode;
1965 	status = vfs_get_vnode_from_fd(fd, true, &vnode);
1966 	if (status < B_OK)
1967 		goto error0;
1968 
1969 	// get the file name
1970 	fileName = strrchr(path, '/');
1971 	if (fileName == NULL)
1972 		fileName = path;
1973 	else
1974 		fileName++;
1975 
1976 	// Prevent someone else from trying to load this image
1977 	mutex_lock(&sImageLoadMutex);
1978 
1979 	// make sure it's not loaded already. Search by vnode
1980 	image = find_image_by_vnode(vnode);
1981 	if (image) {
1982 		atomic_add(&image->ref_count, 1);
1983 		goto done;
1984 	}
1985 
1986 	elfHeader = (struct Elf32_Ehdr *)malloc(sizeof(*elfHeader));
1987 	if (!elfHeader) {
1988 		status = B_NO_MEMORY;
1989 		goto error;
1990 	}
1991 
1992 	length = _kern_read(fd, 0, elfHeader, sizeof(*elfHeader));
1993 	if (length < B_OK) {
1994 		status = length;
1995 		goto error1;
1996 	}
1997 	if (length != sizeof(*elfHeader)) {
1998 		// short read
1999 		status = B_NOT_AN_EXECUTABLE;
2000 		goto error1;
2001 	}
2002 	status = verify_eheader(elfHeader);
2003 	if (status < B_OK)
2004 		goto error1;
2005 
2006 	image = create_image_struct();
2007 	if (!image) {
2008 		status = B_NO_MEMORY;
2009 		goto error1;
2010 	}
2011 	image->vnode = vnode;
2012 	image->elf_header = elfHeader;
2013 	image->name = strdup(path);
2014 	vnode = NULL;
2015 
2016 	programHeaders = (struct Elf32_Phdr *)malloc(elfHeader->e_phnum
2017 		* elfHeader->e_phentsize);
2018 	if (programHeaders == NULL) {
2019 		dprintf("%s: error allocating space for program headers\n", fileName);
2020 		status = B_NO_MEMORY;
2021 		goto error2;
2022 	}
2023 
2024 	TRACE(("reading in program headers at 0x%lx, length 0x%x\n",
2025 		elfHeader->e_phoff, elfHeader->e_phnum * elfHeader->e_phentsize));
2026 
2027 	length = _kern_read(fd, elfHeader->e_phoff, programHeaders,
2028 		elfHeader->e_phnum * elfHeader->e_phentsize);
2029 	if (length < B_OK) {
2030 		status = length;
2031 		TRACE(("%s: error reading in program headers\n", fileName));
2032 		goto error3;
2033 	}
2034 	if (length != elfHeader->e_phnum * elfHeader->e_phentsize) {
2035 		TRACE(("%s: short read while reading in program headers\n", fileName));
2036 		status = B_ERROR;
2037 		goto error3;
2038 	}
2039 
2040 	// determine how much space we need for all loaded segments
2041 
2042 	reservedSize = 0;
2043 	length = 0;
2044 
2045 	for (int32 i = 0; i < elfHeader->e_phnum; i++) {
2046 		size_t end;
2047 
2048 		if (programHeaders[i].p_type != PT_LOAD)
2049 			continue;
2050 
2051 		length += ROUNDUP(programHeaders[i].p_memsz
2052 			+ (programHeaders[i].p_vaddr % B_PAGE_SIZE), B_PAGE_SIZE);
2053 
2054 		end = ROUNDUP(programHeaders[i].p_memsz + programHeaders[i].p_vaddr,
2055 			B_PAGE_SIZE);
2056 		if (end > reservedSize)
2057 			reservedSize = end;
2058 	}
2059 
2060 	// Check whether the segments have an unreasonable amount of unused space
2061 	// inbetween.
2062 	if ((ssize_t)reservedSize > length + 8 * 1024) {
2063 		status = B_BAD_DATA;
2064 		goto error1;
2065 	}
2066 
2067 	// reserve that space and allocate the areas from that one
2068 	if (vm_reserve_address_range(VMAddressSpace::KernelID(), &reservedAddress,
2069 			B_ANY_KERNEL_ADDRESS, reservedSize, 0) < B_OK) {
2070 		status = B_NO_MEMORY;
2071 		goto error3;
2072 	}
2073 
2074 	start = (addr_t)reservedAddress;
2075 	image->data_region.size = 0;
2076 	image->text_region.size = 0;
2077 
2078 	for (int32 i = 0; i < elfHeader->e_phnum; i++) {
2079 		char regionName[B_OS_NAME_LENGTH];
2080 		elf_region *region;
2081 
2082 		TRACE(("looking at program header %ld\n", i));
2083 
2084 		switch (programHeaders[i].p_type) {
2085 			case PT_LOAD:
2086 				break;
2087 			case PT_DYNAMIC:
2088 				image->dynamic_section = programHeaders[i].p_vaddr;
2089 				continue;
2090 			default:
2091 				dprintf("%s: unhandled pheader type 0x%lx\n", fileName,
2092 					programHeaders[i].p_type);
2093 				continue;
2094 		}
2095 
2096 		// we're here, so it must be a PT_LOAD segment
2097 		if (programHeaders[i].IsReadWrite()) {
2098 			// this is the writable segment
2099 			if (image->data_region.size != 0) {
2100 				// we've already created this segment
2101 				continue;
2102 			}
2103 			region = &image->data_region;
2104 
2105 			snprintf(regionName, B_OS_NAME_LENGTH, "%s_data", fileName);
2106 		} else if (programHeaders[i].IsExecutable()) {
2107 			// this is the non-writable segment
2108 			if (image->text_region.size != 0) {
2109 				// we've already created this segment
2110 				continue;
2111 			}
2112 			region = &image->text_region;
2113 
2114 			snprintf(regionName, B_OS_NAME_LENGTH, "%s_text", fileName);
2115 		} else {
2116 			dprintf("%s: weird program header flags 0x%lx\n", fileName,
2117 				programHeaders[i].p_flags);
2118 			continue;
2119 		}
2120 
2121 		region->start = (addr_t)reservedAddress + ROUNDDOWN(
2122 			programHeaders[i].p_vaddr, B_PAGE_SIZE);
2123 		region->size = ROUNDUP(programHeaders[i].p_memsz
2124 			+ (programHeaders[i].p_vaddr % B_PAGE_SIZE), B_PAGE_SIZE);
2125 		region->id = create_area(regionName, (void **)&region->start,
2126 			B_EXACT_ADDRESS, region->size, B_FULL_LOCK,
2127 			B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
2128 		if (region->id < B_OK) {
2129 			dprintf("%s: error allocating area: %s\n", fileName,
2130 				strerror(region->id));
2131 			status = B_NOT_AN_EXECUTABLE;
2132 			goto error4;
2133 		}
2134 		region->delta = -ROUNDDOWN(programHeaders[i].p_vaddr, B_PAGE_SIZE);
2135 
2136 		TRACE(("elf_load_kspace: created area \"%s\" at %p\n",
2137 			regionName, (void *)region->start));
2138 
2139 		length = _kern_read(fd, programHeaders[i].p_offset,
2140 			(void *)(region->start + (programHeaders[i].p_vaddr % B_PAGE_SIZE)),
2141 			programHeaders[i].p_filesz);
2142 		if (length < B_OK) {
2143 			status = length;
2144 			dprintf("%s: error reading in segment %ld\n", fileName, i);
2145 			goto error5;
2146 		}
2147 	}
2148 
2149 	// get the segment order
2150 	elf_region *firstRegion;
2151 	elf_region *secondRegion;
2152 	if (image->text_region.start < image->data_region.start) {
2153 		firstRegion = &image->text_region;
2154 		secondRegion = &image->data_region;
2155 	} else {
2156 		firstRegion = &image->data_region;
2157 		secondRegion = &image->text_region;
2158 	}
2159 
2160 	image->data_region.delta += image->data_region.start;
2161 	image->text_region.delta += image->text_region.start;
2162 
2163 	// modify the dynamic ptr by the delta of the regions
2164 	image->dynamic_section += image->text_region.delta;
2165 
2166 	status = elf_parse_dynamic_section(image);
2167 	if (status < B_OK)
2168 		goto error5;
2169 
2170 	status = init_image_version_infos(image);
2171 	if (status != B_OK)
2172 		goto error5;
2173 
2174 	status = check_needed_image_versions(image);
2175 	if (status != B_OK)
2176 		goto error5;
2177 
2178 	status = elf_relocate(image);
2179 	if (status < B_OK)
2180 		goto error5;
2181 
2182 	// We needed to read in the contents of the "text" area, but
2183 	// now we can protect it read-only/execute
2184 	set_area_protection(image->text_region.id,
2185 		B_KERNEL_READ_AREA | B_KERNEL_EXECUTE_AREA);
2186 
2187 	// There might be a hole between the two segments, and we don't need to
2188 	// reserve this any longer
2189 	vm_unreserve_address_range(VMAddressSpace::KernelID(), reservedAddress,
2190 		reservedSize);
2191 
2192 	// ToDo: this should be enabled by kernel settings!
2193 	if (1)
2194 		load_elf_symbol_table(fd, image);
2195 
2196 	free(programHeaders);
2197 	mutex_lock(&sImageMutex);
2198 	register_elf_image(image);
2199 	mutex_unlock(&sImageMutex);
2200 
2201 done:
2202 	_kern_close(fd);
2203 	mutex_unlock(&sImageLoadMutex);
2204 
2205 	return image->id;
2206 
2207 error5:
2208 error4:
2209 	vm_unreserve_address_range(VMAddressSpace::KernelID(), reservedAddress,
2210 		reservedSize);
2211 error3:
2212 	free(programHeaders);
2213 error2:
2214 	delete_elf_image(image);
2215 	elfHeader = NULL;
2216 error1:
2217 	free(elfHeader);
2218 error:
2219 	mutex_unlock(&sImageLoadMutex);
2220 error0:
2221 	dprintf("Could not load kernel add-on \"%s\": %s\n", path,
2222 		strerror(status));
2223 
2224 	if (vnode)
2225 		vfs_put_vnode(vnode);
2226 	_kern_close(fd);
2227 
2228 	return status;
2229 }
2230 
2231 
2232 status_t
2233 unload_kernel_add_on(image_id id)
2234 {
2235 	MutexLocker _(sImageLoadMutex);
2236 	MutexLocker _2(sImageMutex);
2237 
2238 	elf_image_info *image = find_image(id);
2239 	if (image == NULL)
2240 		return B_BAD_IMAGE_ID;
2241 
2242 	unload_elf_image(image);
2243 	return B_OK;
2244 }
2245 
2246 
2247 struct elf_image_info*
2248 elf_get_kernel_image()
2249 {
2250 	return sKernelImage;
2251 }
2252 
2253 
2254 status_t
2255 elf_get_image_info_for_address(addr_t address, image_info* info)
2256 {
2257 	MutexLocker _(sImageMutex);
2258 	struct elf_image_info* elfInfo = find_image_at_address(address);
2259 	if (elfInfo == NULL)
2260 		return B_ENTRY_NOT_FOUND;
2261 
2262 	info->id = elfInfo->id;
2263     info->type = B_SYSTEM_IMAGE;
2264     info->sequence = 0;
2265     info->init_order = 0;
2266     info->init_routine = NULL;
2267     info->term_routine = NULL;
2268     info->device = -1;
2269     info->node = -1;
2270 		// TODO: We could actually fill device/node in.
2271 	strlcpy(info->name, elfInfo->name, sizeof(info->name));
2272     info->text = (void*)elfInfo->text_region.start;
2273     info->data = (void*)elfInfo->data_region.start;
2274     info->text_size = elfInfo->text_region.size;
2275     info->data_size = elfInfo->data_region.size;
2276 
2277 	return B_OK;
2278 }
2279 
2280 
2281 image_id
2282 elf_create_memory_image(const char* imageName, addr_t text, size_t textSize,
2283 	addr_t data, size_t dataSize)
2284 {
2285 	// allocate the image
2286 	elf_image_info* image = create_image_struct();
2287 	if (image == NULL)
2288 		return B_NO_MEMORY;
2289 	MemoryDeleter imageDeleter(image);
2290 
2291 	// allocate symbol and string tables -- we allocate an empty symbol table,
2292 	// so that elf_debug_lookup_symbol_address() won't try the dynamic symbol
2293 	// table, which we don't have.
2294 	Elf32_Sym* symbolTable = (Elf32_Sym*)malloc(0);
2295 	char* stringTable = (char*)malloc(1);
2296 	MemoryDeleter symbolTableDeleter(symbolTable);
2297 	MemoryDeleter stringTableDeleter(stringTable);
2298 	if (symbolTable == NULL || stringTable == NULL)
2299 		return B_NO_MEMORY;
2300 
2301 	// the string table always contains the empty string
2302 	stringTable[0] = '\0';
2303 
2304 	image->debug_symbols = symbolTable;
2305 	image->num_debug_symbols = 0;
2306 	image->debug_string_table = stringTable;
2307 
2308 	// dup image name
2309 	image->name = strdup(imageName);
2310 	if (image->name == NULL)
2311 		return B_NO_MEMORY;
2312 
2313 	// data and text region
2314 	image->text_region.id = -1;
2315 	image->text_region.start = text;
2316 	image->text_region.size = textSize;
2317 	image->text_region.delta = 0;
2318 
2319 	image->data_region.id = -1;
2320 	image->data_region.start = data;
2321 	image->data_region.size = dataSize;
2322 	image->data_region.delta = 0;
2323 
2324 	mutex_lock(&sImageMutex);
2325 	register_elf_image(image);
2326 	image_id imageID = image->id;
2327 	mutex_unlock(&sImageMutex);
2328 
2329 	// keep the allocated memory
2330 	imageDeleter.Detach();
2331 	symbolTableDeleter.Detach();
2332 	stringTableDeleter.Detach();
2333 
2334 	return imageID;
2335 }
2336 
2337 
2338 status_t
2339 elf_add_memory_image_symbol(image_id id, const char* name, addr_t address,
2340 	size_t size, int32 type)
2341 {
2342 	MutexLocker _(sImageMutex);
2343 
2344 	// get the image
2345 	struct elf_image_info* image = find_image(id);
2346 	if (image == NULL)
2347 		return B_ENTRY_NOT_FOUND;
2348 
2349 	// get the current string table size
2350 	size_t stringTableSize = 1;
2351 	if (image->num_debug_symbols > 0) {
2352 		for (uint32 i = image->num_debug_symbols - 1; i >= 0; i--) {
2353 			int32 nameIndex = image->debug_symbols[i].st_name;
2354 			if (nameIndex != 0) {
2355 				stringTableSize = nameIndex
2356 					+ strlen(image->debug_string_table + nameIndex) + 1;
2357 				break;
2358 			}
2359 		}
2360 	}
2361 
2362 	// enter the name in the string table
2363 	char* stringTable = (char*)image->debug_string_table;
2364 	size_t stringIndex = 0;
2365 	if (name != NULL) {
2366 		size_t nameSize = strlen(name) + 1;
2367 		stringIndex = stringTableSize;
2368 		stringTableSize += nameSize;
2369 		stringTable = (char*)realloc((char*)image->debug_string_table,
2370 			stringTableSize);
2371 		if (stringTable == NULL)
2372 			return B_NO_MEMORY;
2373 		image->debug_string_table = stringTable;
2374 		memcpy(stringTable + stringIndex, name, nameSize);
2375 	}
2376 
2377 	// resize the symbol table
2378 	int32 symbolCount = image->num_debug_symbols + 1;
2379 	Elf32_Sym* symbolTable = (Elf32_Sym*)realloc(
2380 		(Elf32_Sym*)image->debug_symbols, sizeof(Elf32_Sym) * symbolCount);
2381 	if (symbolTable == NULL)
2382 		return B_NO_MEMORY;
2383 	image->debug_symbols = symbolTable;
2384 
2385 	// enter the symbol
2386 	Elf32_Sym& symbol = symbolTable[symbolCount - 1];
2387 	uint32 symbolType = type == B_SYMBOL_TYPE_DATA ? STT_OBJECT : STT_FUNC;
2388 	symbol.st_name = stringIndex;
2389 	symbol.st_value = address;
2390 	symbol.st_size = size;
2391 	symbol.st_info = ELF32_ST_INFO(STB_GLOBAL, symbolType);
2392 	symbol.st_other = 0;
2393 	symbol.st_shndx = 0;
2394 	image->num_debug_symbols++;
2395 
2396 	return B_OK;
2397 }
2398 
2399 
2400 status_t
2401 elf_init(kernel_args *args)
2402 {
2403 	struct preloaded_image *image;
2404 
2405 	image_init();
2406 
2407 	sImagesHash = hash_init(IMAGE_HASH_SIZE, 0, image_compare, image_hash);
2408 	if (sImagesHash == NULL)
2409 		return B_NO_MEMORY;
2410 
2411 	// Build a image structure for the kernel, which has already been loaded.
2412 	// The preloaded_images were already prepared by the VM.
2413 	if (insert_preloaded_image(&args->kernel_image, true) < B_OK)
2414 		panic("could not create kernel image.\n");
2415 
2416 	// Build image structures for all preloaded images.
2417 	for (image = args->preloaded_images; image != NULL; image = image->next)
2418 		insert_preloaded_image(image, false);
2419 
2420 	add_debugger_command("ls", &dump_address_info,
2421 		"lookup symbol for a particular address");
2422 	add_debugger_command("symbols", &dump_symbols, "dump symbols for image");
2423 	add_debugger_command("symbol", &dump_symbol, "search symbol in images");
2424 	add_debugger_command_etc("image", &dump_image, "dump image info",
2425 		"Prints info about the specified image.\n"
2426 		"  <image>  - pointer to the semaphore structure, or ID\n"
2427 		"           of the image to print info for.\n", 0);
2428 
2429 	sInitialized = true;
2430 	return B_OK;
2431 }
2432 
2433 
2434 // #pragma mark -
2435 
2436 
2437 /*!	Reads the symbol and string table for the kernel image with the given ID.
2438 	\a _symbolCount and \a _stringTableSize are both in- and output parameters.
2439 	When called they call the size of the buffers given by \a symbolTable and
2440 	\a stringTable respectively. When the function returns successfully, they
2441 	will contain the actual sizes (which can be greater than the original ones).
2442 	The function will copy as much as possible into the buffers. For only
2443 	getting the required buffer sizes, it can be invoked with \c NULL buffers.
2444 	On success \a _imageDelta will contain the offset to be added to the symbol
2445 	values in the table to get the actual symbol addresses.
2446 */
2447 status_t
2448 _user_read_kernel_image_symbols(image_id id, struct Elf32_Sym* symbolTable,
2449 	int32* _symbolCount, char* stringTable, size_t* _stringTableSize,
2450 	addr_t* _imageDelta)
2451 {
2452 	// check params
2453 	if (_symbolCount == NULL || _stringTableSize == NULL)
2454 		return B_BAD_VALUE;
2455 	if (!IS_USER_ADDRESS(_symbolCount) || !IS_USER_ADDRESS(_stringTableSize)
2456 		|| (_imageDelta != NULL && !IS_USER_ADDRESS(_imageDelta))
2457 		|| (symbolTable != NULL && !IS_USER_ADDRESS(symbolTable))
2458 		|| (stringTable != NULL && !IS_USER_ADDRESS(stringTable))) {
2459 		return B_BAD_ADDRESS;
2460 	}
2461 
2462 	// get buffer sizes
2463 	int32 maxSymbolCount;
2464 	size_t maxStringTableSize;
2465 	if (user_memcpy(&maxSymbolCount, _symbolCount, sizeof(maxSymbolCount))
2466 			!= B_OK
2467 		|| user_memcpy(&maxStringTableSize, _stringTableSize,
2468 			sizeof(maxStringTableSize)) != B_OK) {
2469 		return B_BAD_ADDRESS;
2470 	}
2471 
2472 	// find the image
2473 	MutexLocker _(sImageMutex);
2474 	struct elf_image_info* image = find_image(id);
2475 	if (image == NULL)
2476 		return B_ENTRY_NOT_FOUND;
2477 
2478 	// get the tables and infos
2479 	addr_t imageDelta = image->text_region.delta;
2480 	const Elf32_Sym* symbols;
2481 	int32 symbolCount;
2482 	const char* strings;
2483 
2484 	if (image->debug_symbols != NULL) {
2485 		symbols = image->debug_symbols;
2486 		symbolCount = image->num_debug_symbols;
2487 		strings = image->debug_string_table;
2488 	} else {
2489 		symbols = image->syms;
2490 		symbolCount = image->symhash[1];
2491 		strings = image->strtab;
2492 	}
2493 
2494 	// The string table size isn't stored in the elf_image_info structure. Find
2495 	// out by iterating through all symbols.
2496 	size_t stringTableSize = 0;
2497 	for (int32 i = 0; i < symbolCount; i++) {
2498 		size_t index = symbols[i].st_name;
2499 		if (index > stringTableSize)
2500 			stringTableSize = index;
2501 	}
2502 	stringTableSize += strlen(strings + stringTableSize) + 1;
2503 		// add size of the last string
2504 
2505 	// copy symbol table
2506 	int32 symbolsToCopy = min_c(symbolCount, maxSymbolCount);
2507 	if (symbolTable != NULL && symbolsToCopy > 0) {
2508 		if (user_memcpy(symbolTable, symbols, sizeof(Elf32_Sym) * symbolsToCopy)
2509 				!= B_OK) {
2510 			return B_BAD_ADDRESS;
2511 		}
2512 	}
2513 
2514 	// copy string table
2515 	size_t stringsToCopy = min_c(stringTableSize, maxStringTableSize);
2516 	if (stringTable != NULL && stringsToCopy > 0) {
2517 		if (user_memcpy(stringTable, strings, stringsToCopy)
2518 				!= B_OK) {
2519 			return B_BAD_ADDRESS;
2520 		}
2521 	}
2522 
2523 	// copy sizes
2524 	if (user_memcpy(_symbolCount, &symbolCount, sizeof(symbolCount)) != B_OK
2525 		|| user_memcpy(_stringTableSize, &stringTableSize,
2526 				sizeof(stringTableSize)) != B_OK
2527 		|| (_imageDelta != NULL && user_memcpy(_imageDelta, &imageDelta,
2528 				sizeof(imageDelta)) != B_OK)) {
2529 		return B_BAD_ADDRESS;
2530 	}
2531 
2532 	return B_OK;
2533 }
2534