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