xref: /haiku/src/system/kernel/elf.cpp (revision f3eead13e4bdb056c4ab42d8e202b1e879c53e88)
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 				virtual_address_restrictions virtualRestrictions = {};
1885 				virtualRestrictions.address = regionAddress;
1886 				virtualRestrictions.address_specification = B_EXACT_ADDRESS;
1887 				physical_address_restrictions physicalRestrictions = {};
1888 				id = create_area_etc(team->id, regionName, bssSize, B_NO_LOCK,
1889 					B_READ_AREA | B_WRITE_AREA, 0, &virtualRestrictions,
1890 					&physicalRestrictions, (void**)&regionAddress);
1891 				if (id < B_OK) {
1892 					dprintf("error allocating bss area: %s!\n", strerror(id));
1893 					status = B_NOT_AN_EXECUTABLE;
1894 					goto error;
1895 				}
1896 			}
1897 		} else {
1898 			// assume ro/text segment
1899 			snprintf(regionName, B_OS_NAME_LENGTH, "%s_seg%dro", baseName, i);
1900 
1901 			size_t segmentSize = ROUNDUP(programHeaders[i].p_memsz
1902 				+ (programHeaders[i].p_vaddr % B_PAGE_SIZE), B_PAGE_SIZE);
1903 
1904 			id = vm_map_file(team->id, regionName, (void **)&regionAddress,
1905 				B_EXACT_ADDRESS, segmentSize,
1906 				B_READ_AREA | B_EXECUTE_AREA, REGION_PRIVATE_MAP, false,
1907 				fd, ROUNDDOWN(programHeaders[i].p_offset, B_PAGE_SIZE));
1908 			if (id < B_OK) {
1909 				dprintf("error mapping file text: %s!\n", strerror(id));
1910 				status = B_NOT_AN_EXECUTABLE;
1911 				goto error;
1912 			}
1913 
1914 			imageInfo.text = regionAddress;
1915 			imageInfo.text_size = segmentSize;
1916 		}
1917 	}
1918 
1919 	// register the loaded image
1920 	imageInfo.type = B_LIBRARY_IMAGE;
1921     imageInfo.device = st.st_dev;
1922     imageInfo.node = st.st_ino;
1923 	strlcpy(imageInfo.name, path, sizeof(imageInfo.name));
1924 
1925 	imageInfo.api_version = B_HAIKU_VERSION;
1926 	imageInfo.abi = B_HAIKU_ABI;
1927 		// TODO: Get the actual values for the shared object. Currently only
1928 		// the runtime loader is loaded, so this is good enough for the time
1929 		// being.
1930 
1931 	imageInfo.id = register_image(team, &imageInfo, sizeof(image_info));
1932 	if (imageInfo.id >= 0 && team_get_current_team_id() == team->id)
1933 		user_debug_image_created(&imageInfo);
1934 		// Don't care, if registering fails. It's not crucial.
1935 
1936 	TRACE(("elf_load: done!\n"));
1937 
1938 	*entry = elfHeader.e_entry;
1939 	status = B_OK;
1940 
1941 error:
1942 	free(programHeaders);
1943 	_kern_close(fd);
1944 
1945 	return status;
1946 }
1947 
1948 
1949 image_id
1950 load_kernel_add_on(const char *path)
1951 {
1952 	struct Elf32_Phdr *programHeaders;
1953 	struct Elf32_Ehdr *elfHeader;
1954 	struct elf_image_info *image;
1955 	const char *fileName;
1956 	void *reservedAddress;
1957 	addr_t start;
1958 	size_t reservedSize;
1959 	status_t status;
1960 	ssize_t length;
1961 
1962 	TRACE(("elf_load_kspace: entry path '%s'\n", path));
1963 
1964 	int fd = _kern_open(-1, path, O_RDONLY, 0);
1965 	if (fd < 0)
1966 		return fd;
1967 
1968 	struct vnode *vnode;
1969 	status = vfs_get_vnode_from_fd(fd, true, &vnode);
1970 	if (status < B_OK)
1971 		goto error0;
1972 
1973 	// get the file name
1974 	fileName = strrchr(path, '/');
1975 	if (fileName == NULL)
1976 		fileName = path;
1977 	else
1978 		fileName++;
1979 
1980 	// Prevent someone else from trying to load this image
1981 	mutex_lock(&sImageLoadMutex);
1982 
1983 	// make sure it's not loaded already. Search by vnode
1984 	image = find_image_by_vnode(vnode);
1985 	if (image) {
1986 		atomic_add(&image->ref_count, 1);
1987 		goto done;
1988 	}
1989 
1990 	elfHeader = (struct Elf32_Ehdr *)malloc(sizeof(*elfHeader));
1991 	if (!elfHeader) {
1992 		status = B_NO_MEMORY;
1993 		goto error;
1994 	}
1995 
1996 	length = _kern_read(fd, 0, elfHeader, sizeof(*elfHeader));
1997 	if (length < B_OK) {
1998 		status = length;
1999 		goto error1;
2000 	}
2001 	if (length != sizeof(*elfHeader)) {
2002 		// short read
2003 		status = B_NOT_AN_EXECUTABLE;
2004 		goto error1;
2005 	}
2006 	status = verify_eheader(elfHeader);
2007 	if (status < B_OK)
2008 		goto error1;
2009 
2010 	image = create_image_struct();
2011 	if (!image) {
2012 		status = B_NO_MEMORY;
2013 		goto error1;
2014 	}
2015 	image->vnode = vnode;
2016 	image->elf_header = elfHeader;
2017 	image->name = strdup(path);
2018 	vnode = NULL;
2019 
2020 	programHeaders = (struct Elf32_Phdr *)malloc(elfHeader->e_phnum
2021 		* elfHeader->e_phentsize);
2022 	if (programHeaders == NULL) {
2023 		dprintf("%s: error allocating space for program headers\n", fileName);
2024 		status = B_NO_MEMORY;
2025 		goto error2;
2026 	}
2027 
2028 	TRACE(("reading in program headers at 0x%lx, length 0x%x\n",
2029 		elfHeader->e_phoff, elfHeader->e_phnum * elfHeader->e_phentsize));
2030 
2031 	length = _kern_read(fd, elfHeader->e_phoff, programHeaders,
2032 		elfHeader->e_phnum * elfHeader->e_phentsize);
2033 	if (length < B_OK) {
2034 		status = length;
2035 		TRACE(("%s: error reading in program headers\n", fileName));
2036 		goto error3;
2037 	}
2038 	if (length != elfHeader->e_phnum * elfHeader->e_phentsize) {
2039 		TRACE(("%s: short read while reading in program headers\n", fileName));
2040 		status = B_ERROR;
2041 		goto error3;
2042 	}
2043 
2044 	// determine how much space we need for all loaded segments
2045 
2046 	reservedSize = 0;
2047 	length = 0;
2048 
2049 	for (int32 i = 0; i < elfHeader->e_phnum; i++) {
2050 		size_t end;
2051 
2052 		if (programHeaders[i].p_type != PT_LOAD)
2053 			continue;
2054 
2055 		length += ROUNDUP(programHeaders[i].p_memsz
2056 			+ (programHeaders[i].p_vaddr % B_PAGE_SIZE), B_PAGE_SIZE);
2057 
2058 		end = ROUNDUP(programHeaders[i].p_memsz + programHeaders[i].p_vaddr,
2059 			B_PAGE_SIZE);
2060 		if (end > reservedSize)
2061 			reservedSize = end;
2062 	}
2063 
2064 	// Check whether the segments have an unreasonable amount of unused space
2065 	// inbetween.
2066 	if ((ssize_t)reservedSize > length + 8 * 1024) {
2067 		status = B_BAD_DATA;
2068 		goto error1;
2069 	}
2070 
2071 	// reserve that space and allocate the areas from that one
2072 	if (vm_reserve_address_range(VMAddressSpace::KernelID(), &reservedAddress,
2073 			B_ANY_KERNEL_ADDRESS, reservedSize, 0) < B_OK) {
2074 		status = B_NO_MEMORY;
2075 		goto error3;
2076 	}
2077 
2078 	start = (addr_t)reservedAddress;
2079 	image->data_region.size = 0;
2080 	image->text_region.size = 0;
2081 
2082 	for (int32 i = 0; i < elfHeader->e_phnum; i++) {
2083 		char regionName[B_OS_NAME_LENGTH];
2084 		elf_region *region;
2085 
2086 		TRACE(("looking at program header %ld\n", i));
2087 
2088 		switch (programHeaders[i].p_type) {
2089 			case PT_LOAD:
2090 				break;
2091 			case PT_DYNAMIC:
2092 				image->dynamic_section = programHeaders[i].p_vaddr;
2093 				continue;
2094 			default:
2095 				dprintf("%s: unhandled pheader type 0x%lx\n", fileName,
2096 					programHeaders[i].p_type);
2097 				continue;
2098 		}
2099 
2100 		// we're here, so it must be a PT_LOAD segment
2101 		if (programHeaders[i].IsReadWrite()) {
2102 			// this is the writable segment
2103 			if (image->data_region.size != 0) {
2104 				// we've already created this segment
2105 				continue;
2106 			}
2107 			region = &image->data_region;
2108 
2109 			snprintf(regionName, B_OS_NAME_LENGTH, "%s_data", fileName);
2110 		} else if (programHeaders[i].IsExecutable()) {
2111 			// this is the non-writable segment
2112 			if (image->text_region.size != 0) {
2113 				// we've already created this segment
2114 				continue;
2115 			}
2116 			region = &image->text_region;
2117 
2118 			snprintf(regionName, B_OS_NAME_LENGTH, "%s_text", fileName);
2119 		} else {
2120 			dprintf("%s: weird program header flags 0x%lx\n", fileName,
2121 				programHeaders[i].p_flags);
2122 			continue;
2123 		}
2124 
2125 		region->start = (addr_t)reservedAddress + ROUNDDOWN(
2126 			programHeaders[i].p_vaddr, B_PAGE_SIZE);
2127 		region->size = ROUNDUP(programHeaders[i].p_memsz
2128 			+ (programHeaders[i].p_vaddr % B_PAGE_SIZE), B_PAGE_SIZE);
2129 		region->id = create_area(regionName, (void **)&region->start,
2130 			B_EXACT_ADDRESS, region->size, B_FULL_LOCK,
2131 			B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
2132 		if (region->id < B_OK) {
2133 			dprintf("%s: error allocating area: %s\n", fileName,
2134 				strerror(region->id));
2135 			status = B_NOT_AN_EXECUTABLE;
2136 			goto error4;
2137 		}
2138 		region->delta = -ROUNDDOWN(programHeaders[i].p_vaddr, B_PAGE_SIZE);
2139 
2140 		TRACE(("elf_load_kspace: created area \"%s\" at %p\n",
2141 			regionName, (void *)region->start));
2142 
2143 		length = _kern_read(fd, programHeaders[i].p_offset,
2144 			(void *)(region->start + (programHeaders[i].p_vaddr % B_PAGE_SIZE)),
2145 			programHeaders[i].p_filesz);
2146 		if (length < B_OK) {
2147 			status = length;
2148 			dprintf("%s: error reading in segment %ld\n", fileName, i);
2149 			goto error5;
2150 		}
2151 	}
2152 
2153 	// get the segment order
2154 	elf_region *firstRegion;
2155 	elf_region *secondRegion;
2156 	if (image->text_region.start < image->data_region.start) {
2157 		firstRegion = &image->text_region;
2158 		secondRegion = &image->data_region;
2159 	} else {
2160 		firstRegion = &image->data_region;
2161 		secondRegion = &image->text_region;
2162 	}
2163 
2164 	image->data_region.delta += image->data_region.start;
2165 	image->text_region.delta += image->text_region.start;
2166 
2167 	// modify the dynamic ptr by the delta of the regions
2168 	image->dynamic_section += image->text_region.delta;
2169 
2170 	status = elf_parse_dynamic_section(image);
2171 	if (status < B_OK)
2172 		goto error5;
2173 
2174 	status = init_image_version_infos(image);
2175 	if (status != B_OK)
2176 		goto error5;
2177 
2178 	status = check_needed_image_versions(image);
2179 	if (status != B_OK)
2180 		goto error5;
2181 
2182 	status = elf_relocate(image);
2183 	if (status < B_OK)
2184 		goto error5;
2185 
2186 	// We needed to read in the contents of the "text" area, but
2187 	// now we can protect it read-only/execute
2188 	set_area_protection(image->text_region.id,
2189 		B_KERNEL_READ_AREA | B_KERNEL_EXECUTE_AREA);
2190 
2191 	// There might be a hole between the two segments, and we don't need to
2192 	// reserve this any longer
2193 	vm_unreserve_address_range(VMAddressSpace::KernelID(), reservedAddress,
2194 		reservedSize);
2195 
2196 	// ToDo: this should be enabled by kernel settings!
2197 	if (1)
2198 		load_elf_symbol_table(fd, image);
2199 
2200 	free(programHeaders);
2201 	mutex_lock(&sImageMutex);
2202 	register_elf_image(image);
2203 	mutex_unlock(&sImageMutex);
2204 
2205 done:
2206 	_kern_close(fd);
2207 	mutex_unlock(&sImageLoadMutex);
2208 
2209 	return image->id;
2210 
2211 error5:
2212 error4:
2213 	vm_unreserve_address_range(VMAddressSpace::KernelID(), reservedAddress,
2214 		reservedSize);
2215 error3:
2216 	free(programHeaders);
2217 error2:
2218 	delete_elf_image(image);
2219 	elfHeader = NULL;
2220 error1:
2221 	free(elfHeader);
2222 error:
2223 	mutex_unlock(&sImageLoadMutex);
2224 error0:
2225 	dprintf("Could not load kernel add-on \"%s\": %s\n", path,
2226 		strerror(status));
2227 
2228 	if (vnode)
2229 		vfs_put_vnode(vnode);
2230 	_kern_close(fd);
2231 
2232 	return status;
2233 }
2234 
2235 
2236 status_t
2237 unload_kernel_add_on(image_id id)
2238 {
2239 	MutexLocker _(sImageLoadMutex);
2240 	MutexLocker _2(sImageMutex);
2241 
2242 	elf_image_info *image = find_image(id);
2243 	if (image == NULL)
2244 		return B_BAD_IMAGE_ID;
2245 
2246 	unload_elf_image(image);
2247 	return B_OK;
2248 }
2249 
2250 
2251 struct elf_image_info*
2252 elf_get_kernel_image()
2253 {
2254 	return sKernelImage;
2255 }
2256 
2257 
2258 status_t
2259 elf_get_image_info_for_address(addr_t address, image_info* info)
2260 {
2261 	MutexLocker _(sImageMutex);
2262 	struct elf_image_info* elfInfo = find_image_at_address(address);
2263 	if (elfInfo == NULL)
2264 		return B_ENTRY_NOT_FOUND;
2265 
2266 	info->id = elfInfo->id;
2267     info->type = B_SYSTEM_IMAGE;
2268     info->sequence = 0;
2269     info->init_order = 0;
2270     info->init_routine = NULL;
2271     info->term_routine = NULL;
2272     info->device = -1;
2273     info->node = -1;
2274 		// TODO: We could actually fill device/node in.
2275 	strlcpy(info->name, elfInfo->name, sizeof(info->name));
2276     info->text = (void*)elfInfo->text_region.start;
2277     info->data = (void*)elfInfo->data_region.start;
2278     info->text_size = elfInfo->text_region.size;
2279     info->data_size = elfInfo->data_region.size;
2280 
2281 	return B_OK;
2282 }
2283 
2284 
2285 image_id
2286 elf_create_memory_image(const char* imageName, addr_t text, size_t textSize,
2287 	addr_t data, size_t dataSize)
2288 {
2289 	// allocate the image
2290 	elf_image_info* image = create_image_struct();
2291 	if (image == NULL)
2292 		return B_NO_MEMORY;
2293 	MemoryDeleter imageDeleter(image);
2294 
2295 	// allocate symbol and string tables -- we allocate an empty symbol table,
2296 	// so that elf_debug_lookup_symbol_address() won't try the dynamic symbol
2297 	// table, which we don't have.
2298 	Elf32_Sym* symbolTable = (Elf32_Sym*)malloc(0);
2299 	char* stringTable = (char*)malloc(1);
2300 	MemoryDeleter symbolTableDeleter(symbolTable);
2301 	MemoryDeleter stringTableDeleter(stringTable);
2302 	if (symbolTable == NULL || stringTable == NULL)
2303 		return B_NO_MEMORY;
2304 
2305 	// the string table always contains the empty string
2306 	stringTable[0] = '\0';
2307 
2308 	image->debug_symbols = symbolTable;
2309 	image->num_debug_symbols = 0;
2310 	image->debug_string_table = stringTable;
2311 
2312 	// dup image name
2313 	image->name = strdup(imageName);
2314 	if (image->name == NULL)
2315 		return B_NO_MEMORY;
2316 
2317 	// data and text region
2318 	image->text_region.id = -1;
2319 	image->text_region.start = text;
2320 	image->text_region.size = textSize;
2321 	image->text_region.delta = 0;
2322 
2323 	image->data_region.id = -1;
2324 	image->data_region.start = data;
2325 	image->data_region.size = dataSize;
2326 	image->data_region.delta = 0;
2327 
2328 	mutex_lock(&sImageMutex);
2329 	register_elf_image(image);
2330 	image_id imageID = image->id;
2331 	mutex_unlock(&sImageMutex);
2332 
2333 	// keep the allocated memory
2334 	imageDeleter.Detach();
2335 	symbolTableDeleter.Detach();
2336 	stringTableDeleter.Detach();
2337 
2338 	return imageID;
2339 }
2340 
2341 
2342 status_t
2343 elf_add_memory_image_symbol(image_id id, const char* name, addr_t address,
2344 	size_t size, int32 type)
2345 {
2346 	MutexLocker _(sImageMutex);
2347 
2348 	// get the image
2349 	struct elf_image_info* image = find_image(id);
2350 	if (image == NULL)
2351 		return B_ENTRY_NOT_FOUND;
2352 
2353 	// get the current string table size
2354 	size_t stringTableSize = 1;
2355 	if (image->num_debug_symbols > 0) {
2356 		for (uint32 i = image->num_debug_symbols - 1; i >= 0; i--) {
2357 			int32 nameIndex = image->debug_symbols[i].st_name;
2358 			if (nameIndex != 0) {
2359 				stringTableSize = nameIndex
2360 					+ strlen(image->debug_string_table + nameIndex) + 1;
2361 				break;
2362 			}
2363 		}
2364 	}
2365 
2366 	// enter the name in the string table
2367 	char* stringTable = (char*)image->debug_string_table;
2368 	size_t stringIndex = 0;
2369 	if (name != NULL) {
2370 		size_t nameSize = strlen(name) + 1;
2371 		stringIndex = stringTableSize;
2372 		stringTableSize += nameSize;
2373 		stringTable = (char*)realloc((char*)image->debug_string_table,
2374 			stringTableSize);
2375 		if (stringTable == NULL)
2376 			return B_NO_MEMORY;
2377 		image->debug_string_table = stringTable;
2378 		memcpy(stringTable + stringIndex, name, nameSize);
2379 	}
2380 
2381 	// resize the symbol table
2382 	int32 symbolCount = image->num_debug_symbols + 1;
2383 	Elf32_Sym* symbolTable = (Elf32_Sym*)realloc(
2384 		(Elf32_Sym*)image->debug_symbols, sizeof(Elf32_Sym) * symbolCount);
2385 	if (symbolTable == NULL)
2386 		return B_NO_MEMORY;
2387 	image->debug_symbols = symbolTable;
2388 
2389 	// enter the symbol
2390 	Elf32_Sym& symbol = symbolTable[symbolCount - 1];
2391 	uint32 symbolType = type == B_SYMBOL_TYPE_DATA ? STT_OBJECT : STT_FUNC;
2392 	symbol.st_name = stringIndex;
2393 	symbol.st_value = address;
2394 	symbol.st_size = size;
2395 	symbol.st_info = ELF32_ST_INFO(STB_GLOBAL, symbolType);
2396 	symbol.st_other = 0;
2397 	symbol.st_shndx = 0;
2398 	image->num_debug_symbols++;
2399 
2400 	return B_OK;
2401 }
2402 
2403 
2404 status_t
2405 elf_init(kernel_args *args)
2406 {
2407 	struct preloaded_image *image;
2408 
2409 	image_init();
2410 
2411 	sImagesHash = hash_init(IMAGE_HASH_SIZE, 0, image_compare, image_hash);
2412 	if (sImagesHash == NULL)
2413 		return B_NO_MEMORY;
2414 
2415 	// Build a image structure for the kernel, which has already been loaded.
2416 	// The preloaded_images were already prepared by the VM.
2417 	if (insert_preloaded_image(&args->kernel_image, true) < B_OK)
2418 		panic("could not create kernel image.\n");
2419 
2420 	// Build image structures for all preloaded images.
2421 	for (image = args->preloaded_images; image != NULL; image = image->next)
2422 		insert_preloaded_image(image, false);
2423 
2424 	add_debugger_command("ls", &dump_address_info,
2425 		"lookup symbol for a particular address");
2426 	add_debugger_command("symbols", &dump_symbols, "dump symbols for image");
2427 	add_debugger_command("symbol", &dump_symbol, "search symbol in images");
2428 	add_debugger_command_etc("image", &dump_image, "dump image info",
2429 		"Prints info about the specified image.\n"
2430 		"  <image>  - pointer to the semaphore structure, or ID\n"
2431 		"           of the image to print info for.\n", 0);
2432 
2433 	sInitialized = true;
2434 	return B_OK;
2435 }
2436 
2437 
2438 // #pragma mark -
2439 
2440 
2441 /*!	Reads the symbol and string table for the kernel image with the given ID.
2442 	\a _symbolCount and \a _stringTableSize are both in- and output parameters.
2443 	When called they call the size of the buffers given by \a symbolTable and
2444 	\a stringTable respectively. When the function returns successfully, they
2445 	will contain the actual sizes (which can be greater than the original ones).
2446 	The function will copy as much as possible into the buffers. For only
2447 	getting the required buffer sizes, it can be invoked with \c NULL buffers.
2448 	On success \a _imageDelta will contain the offset to be added to the symbol
2449 	values in the table to get the actual symbol addresses.
2450 */
2451 status_t
2452 _user_read_kernel_image_symbols(image_id id, struct Elf32_Sym* symbolTable,
2453 	int32* _symbolCount, char* stringTable, size_t* _stringTableSize,
2454 	addr_t* _imageDelta)
2455 {
2456 	// check params
2457 	if (_symbolCount == NULL || _stringTableSize == NULL)
2458 		return B_BAD_VALUE;
2459 	if (!IS_USER_ADDRESS(_symbolCount) || !IS_USER_ADDRESS(_stringTableSize)
2460 		|| (_imageDelta != NULL && !IS_USER_ADDRESS(_imageDelta))
2461 		|| (symbolTable != NULL && !IS_USER_ADDRESS(symbolTable))
2462 		|| (stringTable != NULL && !IS_USER_ADDRESS(stringTable))) {
2463 		return B_BAD_ADDRESS;
2464 	}
2465 
2466 	// get buffer sizes
2467 	int32 maxSymbolCount;
2468 	size_t maxStringTableSize;
2469 	if (user_memcpy(&maxSymbolCount, _symbolCount, sizeof(maxSymbolCount))
2470 			!= B_OK
2471 		|| user_memcpy(&maxStringTableSize, _stringTableSize,
2472 			sizeof(maxStringTableSize)) != B_OK) {
2473 		return B_BAD_ADDRESS;
2474 	}
2475 
2476 	// find the image
2477 	MutexLocker _(sImageMutex);
2478 	struct elf_image_info* image = find_image(id);
2479 	if (image == NULL)
2480 		return B_ENTRY_NOT_FOUND;
2481 
2482 	// get the tables and infos
2483 	addr_t imageDelta = image->text_region.delta;
2484 	const Elf32_Sym* symbols;
2485 	int32 symbolCount;
2486 	const char* strings;
2487 
2488 	if (image->debug_symbols != NULL) {
2489 		symbols = image->debug_symbols;
2490 		symbolCount = image->num_debug_symbols;
2491 		strings = image->debug_string_table;
2492 	} else {
2493 		symbols = image->syms;
2494 		symbolCount = image->symhash[1];
2495 		strings = image->strtab;
2496 	}
2497 
2498 	// The string table size isn't stored in the elf_image_info structure. Find
2499 	// out by iterating through all symbols.
2500 	size_t stringTableSize = 0;
2501 	for (int32 i = 0; i < symbolCount; i++) {
2502 		size_t index = symbols[i].st_name;
2503 		if (index > stringTableSize)
2504 			stringTableSize = index;
2505 	}
2506 	stringTableSize += strlen(strings + stringTableSize) + 1;
2507 		// add size of the last string
2508 
2509 	// copy symbol table
2510 	int32 symbolsToCopy = min_c(symbolCount, maxSymbolCount);
2511 	if (symbolTable != NULL && symbolsToCopy > 0) {
2512 		if (user_memcpy(symbolTable, symbols, sizeof(Elf32_Sym) * symbolsToCopy)
2513 				!= B_OK) {
2514 			return B_BAD_ADDRESS;
2515 		}
2516 	}
2517 
2518 	// copy string table
2519 	size_t stringsToCopy = min_c(stringTableSize, maxStringTableSize);
2520 	if (stringTable != NULL && stringsToCopy > 0) {
2521 		if (user_memcpy(stringTable, strings, stringsToCopy)
2522 				!= B_OK) {
2523 			return B_BAD_ADDRESS;
2524 		}
2525 	}
2526 
2527 	// copy sizes
2528 	if (user_memcpy(_symbolCount, &symbolCount, sizeof(symbolCount)) != B_OK
2529 		|| user_memcpy(_stringTableSize, &stringTableSize,
2530 				sizeof(stringTableSize)) != B_OK
2531 		|| (_imageDelta != NULL && user_memcpy(_imageDelta, &imageDelta,
2532 				sizeof(imageDelta)) != B_OK)) {
2533 		return B_BAD_ADDRESS;
2534 	}
2535 
2536 	return B_OK;
2537 }
2538