xref: /haiku/src/system/kernel/elf.cpp (revision 35ead8815b679605a9b4db8130613ea100f4b14c)
1 /*
2  * Copyright 2009, 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(buffer, address, bufferSize) >= 0;
1472 		return user_strlcpy(buffer, address, bufferSize) >= 0;
1473 	}
1474 
1475 	template<typename T> bool _Read(const T* address, T& data);
1476 		// gcc 2.95.3 doesn't like it defined in-place
1477 
1478 private:
1479 	runtime_loader_debug_area	fDebugArea;
1480 	char						fImageName[B_OS_NAME_LENGTH];
1481 	char						fSymbolName[256];
1482 	static UserSymbolLookup		sLookup;
1483 };
1484 
1485 
1486 template<typename T>
1487 bool
1488 UserSymbolLookup::_Read(const T* address, T& data)
1489 {
1490 	if (!IS_USER_ADDRESS(address))
1491 		return false;
1492 
1493 	if (debug_debugger_running())
1494 		return debug_memcpy(&data, address, sizeof(T)) == B_OK;
1495 	return user_memcpy(&data, address, sizeof(T)) == B_OK;
1496 }
1497 
1498 
1499 UserSymbolLookup UserSymbolLookup::sLookup;
1500 	// doesn't need construction, but has an Init() method
1501 
1502 
1503 //	#pragma mark - public kernel API
1504 
1505 
1506 status_t
1507 get_image_symbol(image_id id, const char *name, int32 symbolClass,
1508 	void **_symbol)
1509 {
1510 	struct elf_image_info *image;
1511 	struct Elf32_Sym *symbol;
1512 	status_t status = B_OK;
1513 
1514 	TRACE(("get_image_symbol(%s)\n", name));
1515 
1516 	mutex_lock(&sImageMutex);
1517 
1518 	image = find_image(id);
1519 	if (image == NULL) {
1520 		status = B_BAD_IMAGE_ID;
1521 		goto done;
1522 	}
1523 
1524 	symbol = elf_find_symbol(image, name, NULL, true);
1525 	if (symbol == NULL || symbol->st_shndx == SHN_UNDEF) {
1526 		status = B_ENTRY_NOT_FOUND;
1527 		goto done;
1528 	}
1529 
1530 	// TODO: support the "symbolClass" parameter!
1531 
1532 	TRACE(("found: %lx (%lx + %lx)\n",
1533 		symbol->st_value + image->text_region.delta,
1534 		symbol->st_value, image->text_region.delta));
1535 
1536 	*_symbol = (void *)(symbol->st_value + image->text_region.delta);
1537 
1538 done:
1539 	mutex_unlock(&sImageMutex);
1540 	return status;
1541 }
1542 
1543 
1544 //	#pragma mark - kernel private API
1545 
1546 
1547 /*!	Looks up a symbol by address in all images loaded in kernel space.
1548 	Note, if you need to call this function outside a debugger, make
1549 	sure you fix locking and the way it returns its information, first!
1550 */
1551 status_t
1552 elf_debug_lookup_symbol_address(addr_t address, addr_t *_baseAddress,
1553 	const char **_symbolName, const char **_imageName, bool *_exactMatch)
1554 {
1555 	struct elf_image_info *image;
1556 	struct Elf32_Sym *symbolFound = NULL;
1557 	const char *symbolName = NULL;
1558 	addr_t deltaFound = INT_MAX;
1559 	bool exactMatch = false;
1560 	status_t status;
1561 
1562 	TRACE(("looking up %p\n", (void *)address));
1563 
1564 	if (!sInitialized)
1565 		return B_ERROR;
1566 
1567 	//mutex_lock(&sImageMutex);
1568 
1569 	image = find_image_at_address(address);
1570 		// get image that may contain the address
1571 
1572 	if (image != NULL) {
1573 		addr_t symbolDelta;
1574 		uint32 i;
1575 		int32 j;
1576 
1577 		TRACE((" image %p, base = %p, size = %p\n", image,
1578 			(void *)image->text_region.start, (void *)image->text_region.size));
1579 
1580 		if (image->debug_symbols != NULL) {
1581 			// search extended debug symbol table (contains static symbols)
1582 
1583 			TRACE((" searching debug symbols...\n"));
1584 
1585 			for (i = 0; i < image->num_debug_symbols; i++) {
1586 				struct Elf32_Sym *symbol = &image->debug_symbols[i];
1587 
1588 				if (symbol->st_value == 0 || symbol->st_size
1589 						>= image->text_region.size + image->data_region.size)
1590 					continue;
1591 
1592 				symbolDelta
1593 					= address - (symbol->st_value + image->text_region.delta);
1594 				if (symbolDelta >= 0 && symbolDelta < symbol->st_size)
1595 					exactMatch = true;
1596 
1597 				if (exactMatch || symbolDelta < deltaFound) {
1598 					deltaFound = symbolDelta;
1599 					symbolFound = symbol;
1600 					symbolName = image->debug_string_table + symbol->st_name;
1601 
1602 					if (exactMatch)
1603 						break;
1604 				}
1605 			}
1606 		} else {
1607 			// search standard symbol lookup table
1608 
1609 			TRACE((" searching standard symbols...\n"));
1610 
1611 			for (i = 0; i < HASHTABSIZE(image); i++) {
1612 				for (j = HASHBUCKETS(image)[i]; j != STN_UNDEF;
1613 						j = HASHCHAINS(image)[j]) {
1614 					struct Elf32_Sym *symbol = &image->syms[j];
1615 
1616 					if (symbol->st_value == 0
1617 						|| symbol->st_size >= image->text_region.size
1618 							+ image->data_region.size)
1619 						continue;
1620 
1621 					symbolDelta = address - (long)(symbol->st_value
1622 						+ image->text_region.delta);
1623 					if (symbolDelta >= 0 && symbolDelta < symbol->st_size)
1624 						exactMatch = true;
1625 
1626 					if (exactMatch || symbolDelta < deltaFound) {
1627 						deltaFound = symbolDelta;
1628 						symbolFound = symbol;
1629 						symbolName = SYMNAME(image, symbol);
1630 
1631 						if (exactMatch)
1632 							goto symbol_found;
1633 					}
1634 				}
1635 			}
1636 		}
1637 	}
1638 symbol_found:
1639 
1640 	if (symbolFound != NULL) {
1641 		if (_symbolName)
1642 			*_symbolName = symbolName;
1643 		if (_imageName)
1644 			*_imageName = image->name;
1645 		if (_baseAddress)
1646 			*_baseAddress = symbolFound->st_value + image->text_region.delta;
1647 		if (_exactMatch)
1648 			*_exactMatch = exactMatch;
1649 
1650 		status = B_OK;
1651 	} else if (image != NULL) {
1652 		TRACE(("symbol not found!\n"));
1653 
1654 		if (_symbolName)
1655 			*_symbolName = NULL;
1656 		if (_imageName)
1657 			*_imageName = image->name;
1658 		if (_baseAddress)
1659 			*_baseAddress = image->text_region.start;
1660 		if (_exactMatch)
1661 			*_exactMatch = false;
1662 
1663 		status = B_OK;
1664 	} else {
1665 		TRACE(("image not found!\n"));
1666 		status = B_ENTRY_NOT_FOUND;
1667 	}
1668 
1669 	// Note, theoretically, all information we return back to our caller
1670 	// would have to be locked - but since this function is only called
1671 	// from the debugger, it's safe to do it this way
1672 
1673 	//mutex_unlock(&sImageMutex);
1674 
1675 	return status;
1676 }
1677 
1678 
1679 /*!	Tries to find a matching user symbol for the given address.
1680 	Note that the given team's address space must already be in effect.
1681 */
1682 status_t
1683 elf_debug_lookup_user_symbol_address(struct team* team, addr_t address,
1684 	addr_t *_baseAddress, const char **_symbolName, const char **_imageName,
1685 	bool *_exactMatch)
1686 {
1687 	if (team == NULL || team == team_get_kernel_team())
1688 		return B_BAD_VALUE;
1689 
1690 	UserSymbolLookup& lookup = UserSymbolLookup::Default();
1691 	status_t error = lookup.Init(team);
1692 	if (error != B_OK)
1693 		return error;
1694 
1695 	return lookup.LookupSymbolAddress(address, _baseAddress, _symbolName,
1696 		_imageName, _exactMatch);
1697 }
1698 
1699 
1700 /*!	Looks up a symbol in all kernel images. Note, this function is thought to
1701 	be used in the kernel debugger, and therefore doesn't perform any locking.
1702 */
1703 addr_t
1704 elf_debug_lookup_symbol(const char* searchName)
1705 {
1706 	struct elf_image_info *image = NULL;
1707 	struct hash_iterator iterator;
1708 
1709 	hash_open(sImagesHash, &iterator);
1710 	while ((image = (elf_image_info *)hash_next(sImagesHash, &iterator))
1711 			!= NULL) {
1712 		if (image->num_debug_symbols > 0) {
1713 			// search extended debug symbol table (contains static symbols)
1714 			for (uint32 i = 0; i < image->num_debug_symbols; i++) {
1715 				struct Elf32_Sym *symbol = &image->debug_symbols[i];
1716 				const char *name = image->debug_string_table + symbol->st_name;
1717 
1718 				if (symbol->st_value > 0 && !strcmp(name, searchName))
1719 					return symbol->st_value + image->text_region.delta;
1720 			}
1721 		} else {
1722 			// search standard symbol lookup table
1723 			for (uint32 i = 0; i < HASHTABSIZE(image); i++) {
1724 				for (uint32 j = HASHBUCKETS(image)[i]; j != STN_UNDEF;
1725 						j = HASHCHAINS(image)[j]) {
1726 					struct Elf32_Sym *symbol = &image->syms[j];
1727 					const char *name = SYMNAME(image, symbol);
1728 
1729 					if (symbol->st_value > 0 && !strcmp(name, searchName))
1730 						return symbol->st_value + image->text_region.delta;
1731 				}
1732 			}
1733 		}
1734 	}
1735 	hash_close(sImagesHash, &iterator, false);
1736 
1737 	return 0;
1738 }
1739 
1740 
1741 status_t
1742 elf_load_user_image(const char *path, struct team *team, int flags,
1743 	addr_t *entry)
1744 {
1745 	struct Elf32_Ehdr elfHeader;
1746 	struct Elf32_Phdr *programHeaders = NULL;
1747 	char baseName[B_OS_NAME_LENGTH];
1748 	status_t status;
1749 	ssize_t length;
1750 	int fd;
1751 	int i;
1752 
1753 	TRACE(("elf_load: entry path '%s', team %p\n", path, team));
1754 
1755 	fd = _kern_open(-1, path, O_RDONLY, 0);
1756 	if (fd < 0)
1757 		return fd;
1758 
1759 	struct stat st;
1760 	status = _kern_read_stat(fd, NULL, false, &st, sizeof(st));
1761 	if (status != B_OK)
1762 		return status;
1763 
1764 	// read and verify the ELF header
1765 
1766 	length = _kern_read(fd, 0, &elfHeader, sizeof(elfHeader));
1767 	if (length < B_OK) {
1768 		status = length;
1769 		goto error;
1770 	}
1771 
1772 	if (length != sizeof(elfHeader)) {
1773 		// short read
1774 		status = B_NOT_AN_EXECUTABLE;
1775 		goto error;
1776 	}
1777 	status = verify_eheader(&elfHeader);
1778 	if (status < B_OK)
1779 		goto error;
1780 
1781 	// read program header
1782 
1783 	programHeaders = (struct Elf32_Phdr *)malloc(
1784 		elfHeader.e_phnum * elfHeader.e_phentsize);
1785 	if (programHeaders == NULL) {
1786 		dprintf("error allocating space for program headers\n");
1787 		status = B_NO_MEMORY;
1788 		goto error;
1789 	}
1790 
1791 	TRACE(("reading in program headers at 0x%lx, length 0x%x\n",
1792 		elfHeader.e_phoff, elfHeader.e_phnum * elfHeader.e_phentsize));
1793 	length = _kern_read(fd, elfHeader.e_phoff, programHeaders,
1794 		elfHeader.e_phnum * elfHeader.e_phentsize);
1795 	if (length < B_OK) {
1796 		status = length;
1797 		dprintf("error reading in program headers\n");
1798 		goto error;
1799 	}
1800 	if (length != elfHeader.e_phnum * elfHeader.e_phentsize) {
1801 		dprintf("short read while reading in program headers\n");
1802 		status = -1;
1803 		goto error;
1804 	}
1805 
1806 	// construct a nice name for the region we have to create below
1807 	{
1808 		int32 length;
1809 
1810 		const char *leaf = strrchr(path, '/');
1811 		if (leaf == NULL)
1812 			leaf = path;
1813 		else
1814 			leaf++;
1815 
1816 		length = strlen(leaf);
1817 		if (length > B_OS_NAME_LENGTH - 8)
1818 			sprintf(baseName, "...%s", leaf + length + 8 - B_OS_NAME_LENGTH);
1819 		else
1820 			strcpy(baseName, leaf);
1821 	}
1822 
1823 	// map the program's segments into memory
1824 
1825 	image_info imageInfo;
1826 	memset(&imageInfo, 0, sizeof(image_info));
1827 
1828 	for (i = 0; i < elfHeader.e_phnum; i++) {
1829 		char regionName[B_OS_NAME_LENGTH];
1830 		char *regionAddress;
1831 		area_id id;
1832 
1833 		if (programHeaders[i].p_type != PT_LOAD)
1834 			continue;
1835 
1836 		regionAddress = (char *)ROUNDDOWN(programHeaders[i].p_vaddr,
1837 			B_PAGE_SIZE);
1838 		if (programHeaders[i].p_flags & PF_WRITE) {
1839 			// rw/data segment
1840 			uint32 memUpperBound = (programHeaders[i].p_vaddr % B_PAGE_SIZE)
1841 				+ programHeaders[i].p_memsz;
1842 			uint32 fileUpperBound = (programHeaders[i].p_vaddr % B_PAGE_SIZE)
1843 				+ programHeaders[i].p_filesz;
1844 
1845 			memUpperBound = ROUNDUP(memUpperBound, B_PAGE_SIZE);
1846 			fileUpperBound = ROUNDUP(fileUpperBound, B_PAGE_SIZE);
1847 
1848 			sprintf(regionName, "%s_seg%drw", baseName, i);
1849 
1850 			id = vm_map_file(team->id, regionName, (void **)&regionAddress,
1851 				B_EXACT_ADDRESS, fileUpperBound,
1852 				B_READ_AREA | B_WRITE_AREA, REGION_PRIVATE_MAP, false,
1853 				fd, ROUNDDOWN(programHeaders[i].p_offset, B_PAGE_SIZE));
1854 			if (id < B_OK) {
1855 				dprintf("error mapping file data: %s!\n", strerror(id));
1856 				status = B_NOT_AN_EXECUTABLE;
1857 				goto error;
1858 			}
1859 
1860 			imageInfo.data = regionAddress;
1861 			imageInfo.data_size = memUpperBound;
1862 
1863 			// clean garbage brought by mmap (the region behind the file,
1864 			// at least parts of it are the bss and have to be zeroed)
1865 			uint32 start = (uint32)regionAddress
1866 				+ (programHeaders[i].p_vaddr % B_PAGE_SIZE)
1867 				+ programHeaders[i].p_filesz;
1868 			uint32 amount = fileUpperBound
1869 				- (programHeaders[i].p_vaddr % B_PAGE_SIZE)
1870 				- (programHeaders[i].p_filesz);
1871 			memset((void *)start, 0, amount);
1872 
1873 			// Check if we need extra storage for the bss - we have to do this if
1874 			// the above region doesn't already comprise the memory size, too.
1875 
1876 			if (memUpperBound != fileUpperBound) {
1877 				size_t bssSize = memUpperBound - fileUpperBound;
1878 
1879 				snprintf(regionName, B_OS_NAME_LENGTH, "%s_bss%d", baseName, i);
1880 
1881 				regionAddress += fileUpperBound;
1882 				id = create_area_etc(team->id, regionName,
1883 					(void **)&regionAddress, B_EXACT_ADDRESS, bssSize,
1884 					B_NO_LOCK, B_READ_AREA | B_WRITE_AREA, 0, 0);
1885 				if (id < B_OK) {
1886 					dprintf("error allocating bss area: %s!\n", strerror(id));
1887 					status = B_NOT_AN_EXECUTABLE;
1888 					goto error;
1889 				}
1890 			}
1891 		} else {
1892 			// assume ro/text segment
1893 			snprintf(regionName, B_OS_NAME_LENGTH, "%s_seg%dro", baseName, i);
1894 
1895 			size_t segmentSize = ROUNDUP(programHeaders[i].p_memsz
1896 				+ (programHeaders[i].p_vaddr % B_PAGE_SIZE), B_PAGE_SIZE);
1897 
1898 			id = vm_map_file(team->id, regionName, (void **)&regionAddress,
1899 				B_EXACT_ADDRESS, segmentSize,
1900 				B_READ_AREA | B_EXECUTE_AREA, REGION_PRIVATE_MAP, false,
1901 				fd, ROUNDDOWN(programHeaders[i].p_offset, B_PAGE_SIZE));
1902 			if (id < B_OK) {
1903 				dprintf("error mapping file text: %s!\n", strerror(id));
1904 				status = B_NOT_AN_EXECUTABLE;
1905 				goto error;
1906 			}
1907 
1908 			imageInfo.text = regionAddress;
1909 			imageInfo.text_size = segmentSize;
1910 		}
1911 	}
1912 
1913 	// register the loaded image
1914 	imageInfo.type = B_LIBRARY_IMAGE;
1915     imageInfo.device = st.st_dev;
1916     imageInfo.node = st.st_ino;
1917 	strlcpy(imageInfo.name, path, sizeof(imageInfo.name));
1918 
1919 	imageInfo.api_version = B_HAIKU_VERSION;
1920 	imageInfo.abi = B_HAIKU_ABI;
1921 		// TODO: Get the actual values for the shared object. Currently only
1922 		// the runtime loader is loaded, so this is good enough for the time
1923 		// being.
1924 
1925 	imageInfo.id = register_image(team, &imageInfo, sizeof(image_info));
1926 	if (imageInfo.id >= 0 && team_get_current_team_id() == team->id)
1927 		user_debug_image_created(&imageInfo);
1928 		// Don't care, if registering fails. It's not crucial.
1929 
1930 	TRACE(("elf_load: done!\n"));
1931 
1932 	*entry = elfHeader.e_entry;
1933 	status = B_OK;
1934 
1935 error:
1936 	free(programHeaders);
1937 	_kern_close(fd);
1938 
1939 	return status;
1940 }
1941 
1942 
1943 image_id
1944 load_kernel_add_on(const char *path)
1945 {
1946 	struct Elf32_Phdr *programHeaders;
1947 	struct Elf32_Ehdr *elfHeader;
1948 	struct elf_image_info *image;
1949 	const char *fileName;
1950 	void *reservedAddress;
1951 	addr_t start;
1952 	size_t reservedSize;
1953 	status_t status;
1954 	ssize_t length;
1955 
1956 	TRACE(("elf_load_kspace: entry path '%s'\n", path));
1957 
1958 	int fd = _kern_open(-1, path, O_RDONLY, 0);
1959 	if (fd < 0)
1960 		return fd;
1961 
1962 	struct vnode *vnode;
1963 	status = vfs_get_vnode_from_fd(fd, true, &vnode);
1964 	if (status < B_OK)
1965 		goto error0;
1966 
1967 	// get the file name
1968 	fileName = strrchr(path, '/');
1969 	if (fileName == NULL)
1970 		fileName = path;
1971 	else
1972 		fileName++;
1973 
1974 	// Prevent someone else from trying to load this image
1975 	mutex_lock(&sImageLoadMutex);
1976 
1977 	// make sure it's not loaded already. Search by vnode
1978 	image = find_image_by_vnode(vnode);
1979 	if (image) {
1980 		atomic_add(&image->ref_count, 1);
1981 		goto done;
1982 	}
1983 
1984 	elfHeader = (struct Elf32_Ehdr *)malloc(sizeof(*elfHeader));
1985 	if (!elfHeader) {
1986 		status = B_NO_MEMORY;
1987 		goto error;
1988 	}
1989 
1990 	length = _kern_read(fd, 0, elfHeader, sizeof(*elfHeader));
1991 	if (length < B_OK) {
1992 		status = length;
1993 		goto error1;
1994 	}
1995 	if (length != sizeof(*elfHeader)) {
1996 		// short read
1997 		status = B_NOT_AN_EXECUTABLE;
1998 		goto error1;
1999 	}
2000 	status = verify_eheader(elfHeader);
2001 	if (status < B_OK)
2002 		goto error1;
2003 
2004 	image = create_image_struct();
2005 	if (!image) {
2006 		status = B_NO_MEMORY;
2007 		goto error1;
2008 	}
2009 	image->vnode = vnode;
2010 	image->elf_header = elfHeader;
2011 	image->name = strdup(path);
2012 	vnode = NULL;
2013 
2014 	programHeaders = (struct Elf32_Phdr *)malloc(elfHeader->e_phnum
2015 		* elfHeader->e_phentsize);
2016 	if (programHeaders == NULL) {
2017 		dprintf("%s: error allocating space for program headers\n", fileName);
2018 		status = B_NO_MEMORY;
2019 		goto error2;
2020 	}
2021 
2022 	TRACE(("reading in program headers at 0x%lx, length 0x%x\n",
2023 		elfHeader->e_phoff, elfHeader->e_phnum * elfHeader->e_phentsize));
2024 
2025 	length = _kern_read(fd, elfHeader->e_phoff, programHeaders,
2026 		elfHeader->e_phnum * elfHeader->e_phentsize);
2027 	if (length < B_OK) {
2028 		status = length;
2029 		TRACE(("%s: error reading in program headers\n", fileName));
2030 		goto error3;
2031 	}
2032 	if (length != elfHeader->e_phnum * elfHeader->e_phentsize) {
2033 		TRACE(("%s: short read while reading in program headers\n", fileName));
2034 		status = B_ERROR;
2035 		goto error3;
2036 	}
2037 
2038 	// determine how much space we need for all loaded segments
2039 
2040 	reservedSize = 0;
2041 	length = 0;
2042 
2043 	for (int32 i = 0; i < elfHeader->e_phnum; i++) {
2044 		size_t end;
2045 
2046 		if (programHeaders[i].p_type != PT_LOAD)
2047 			continue;
2048 
2049 		length += ROUNDUP(programHeaders[i].p_memsz
2050 			+ (programHeaders[i].p_vaddr % B_PAGE_SIZE), B_PAGE_SIZE);
2051 
2052 		end = ROUNDUP(programHeaders[i].p_memsz + programHeaders[i].p_vaddr,
2053 			B_PAGE_SIZE);
2054 		if (end > reservedSize)
2055 			reservedSize = end;
2056 	}
2057 
2058 	// Check whether the segments have an unreasonable amount of unused space
2059 	// inbetween.
2060 	if ((ssize_t)reservedSize > length + 8 * 1024) {
2061 		status = B_BAD_DATA;
2062 		goto error1;
2063 	}
2064 
2065 	// reserve that space and allocate the areas from that one
2066 	if (vm_reserve_address_range(VMAddressSpace::KernelID(), &reservedAddress,
2067 			B_ANY_KERNEL_ADDRESS, reservedSize, 0) < B_OK) {
2068 		status = B_NO_MEMORY;
2069 		goto error3;
2070 	}
2071 
2072 	start = (addr_t)reservedAddress;
2073 	image->data_region.size = 0;
2074 	image->text_region.size = 0;
2075 
2076 	for (int32 i = 0; i < elfHeader->e_phnum; i++) {
2077 		char regionName[B_OS_NAME_LENGTH];
2078 		elf_region *region;
2079 
2080 		TRACE(("looking at program header %ld\n", i));
2081 
2082 		switch (programHeaders[i].p_type) {
2083 			case PT_LOAD:
2084 				break;
2085 			case PT_DYNAMIC:
2086 				image->dynamic_section = programHeaders[i].p_vaddr;
2087 				continue;
2088 			default:
2089 				dprintf("%s: unhandled pheader type 0x%lx\n", fileName,
2090 					programHeaders[i].p_type);
2091 				continue;
2092 		}
2093 
2094 		// we're here, so it must be a PT_LOAD segment
2095 		if (programHeaders[i].IsReadWrite()) {
2096 			// this is the writable segment
2097 			if (image->data_region.size != 0) {
2098 				// we've already created this segment
2099 				continue;
2100 			}
2101 			region = &image->data_region;
2102 
2103 			snprintf(regionName, B_OS_NAME_LENGTH, "%s_data", fileName);
2104 		} else if (programHeaders[i].IsExecutable()) {
2105 			// this is the non-writable segment
2106 			if (image->text_region.size != 0) {
2107 				// we've already created this segment
2108 				continue;
2109 			}
2110 			region = &image->text_region;
2111 
2112 			snprintf(regionName, B_OS_NAME_LENGTH, "%s_text", fileName);
2113 		} else {
2114 			dprintf("%s: weird program header flags 0x%lx\n", fileName,
2115 				programHeaders[i].p_flags);
2116 			continue;
2117 		}
2118 
2119 		region->start = (addr_t)reservedAddress + ROUNDDOWN(
2120 			programHeaders[i].p_vaddr, B_PAGE_SIZE);
2121 		region->size = ROUNDUP(programHeaders[i].p_memsz
2122 			+ (programHeaders[i].p_vaddr % B_PAGE_SIZE), B_PAGE_SIZE);
2123 		region->id = create_area(regionName, (void **)&region->start,
2124 			B_EXACT_ADDRESS, region->size, B_FULL_LOCK,
2125 			B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
2126 		if (region->id < B_OK) {
2127 			dprintf("%s: error allocating area: %s\n", fileName,
2128 				strerror(region->id));
2129 			status = B_NOT_AN_EXECUTABLE;
2130 			goto error4;
2131 		}
2132 		region->delta = -ROUNDDOWN(programHeaders[i].p_vaddr, B_PAGE_SIZE);
2133 
2134 		TRACE(("elf_load_kspace: created area \"%s\" at %p\n",
2135 			regionName, (void *)region->start));
2136 
2137 		length = _kern_read(fd, programHeaders[i].p_offset,
2138 			(void *)(region->start + (programHeaders[i].p_vaddr % B_PAGE_SIZE)),
2139 			programHeaders[i].p_filesz);
2140 		if (length < B_OK) {
2141 			status = length;
2142 			dprintf("%s: error reading in segment %ld\n", fileName, i);
2143 			goto error5;
2144 		}
2145 	}
2146 
2147 	// get the segment order
2148 	elf_region *firstRegion;
2149 	elf_region *secondRegion;
2150 	if (image->text_region.start < image->data_region.start) {
2151 		firstRegion = &image->text_region;
2152 		secondRegion = &image->data_region;
2153 	} else {
2154 		firstRegion = &image->data_region;
2155 		secondRegion = &image->text_region;
2156 	}
2157 
2158 	image->data_region.delta += image->data_region.start;
2159 	image->text_region.delta += image->text_region.start;
2160 
2161 	// modify the dynamic ptr by the delta of the regions
2162 	image->dynamic_section += image->text_region.delta;
2163 
2164 	status = elf_parse_dynamic_section(image);
2165 	if (status < B_OK)
2166 		goto error5;
2167 
2168 	status = init_image_version_infos(image);
2169 	if (status != B_OK)
2170 		goto error5;
2171 
2172 	status = check_needed_image_versions(image);
2173 	if (status != B_OK)
2174 		goto error5;
2175 
2176 	status = elf_relocate(image);
2177 	if (status < B_OK)
2178 		goto error5;
2179 
2180 	// We needed to read in the contents of the "text" area, but
2181 	// now we can protect it read-only/execute
2182 	set_area_protection(image->text_region.id,
2183 		B_KERNEL_READ_AREA | B_KERNEL_EXECUTE_AREA);
2184 
2185 	// There might be a hole between the two segments, and we don't need to
2186 	// reserve this any longer
2187 	vm_unreserve_address_range(VMAddressSpace::KernelID(), reservedAddress,
2188 		reservedSize);
2189 
2190 	// ToDo: this should be enabled by kernel settings!
2191 	if (1)
2192 		load_elf_symbol_table(fd, image);
2193 
2194 	free(programHeaders);
2195 	mutex_lock(&sImageMutex);
2196 	register_elf_image(image);
2197 	mutex_unlock(&sImageMutex);
2198 
2199 done:
2200 	_kern_close(fd);
2201 	mutex_unlock(&sImageLoadMutex);
2202 
2203 	return image->id;
2204 
2205 error5:
2206 error4:
2207 	vm_unreserve_address_range(VMAddressSpace::KernelID(), reservedAddress,
2208 		reservedSize);
2209 error3:
2210 	free(programHeaders);
2211 error2:
2212 	delete_elf_image(image);
2213 	elfHeader = NULL;
2214 error1:
2215 	free(elfHeader);
2216 error:
2217 	mutex_unlock(&sImageLoadMutex);
2218 error0:
2219 	dprintf("Could not load kernel add-on \"%s\": %s\n", path,
2220 		strerror(status));
2221 
2222 	if (vnode)
2223 		vfs_put_vnode(vnode);
2224 	_kern_close(fd);
2225 
2226 	return status;
2227 }
2228 
2229 
2230 status_t
2231 unload_kernel_add_on(image_id id)
2232 {
2233 	MutexLocker _(sImageLoadMutex);
2234 	MutexLocker _2(sImageMutex);
2235 
2236 	elf_image_info *image = find_image(id);
2237 	if (image == NULL)
2238 		return B_BAD_IMAGE_ID;
2239 
2240 	unload_elf_image(image);
2241 	return B_OK;
2242 }
2243 
2244 
2245 struct elf_image_info*
2246 elf_get_kernel_image()
2247 {
2248 	return sKernelImage;
2249 }
2250 
2251 
2252 status_t
2253 elf_get_image_info_for_address(addr_t address, image_info* info)
2254 {
2255 	MutexLocker _(sImageMutex);
2256 	struct elf_image_info* elfInfo = find_image_at_address(address);
2257 	if (elfInfo == NULL)
2258 		return B_ENTRY_NOT_FOUND;
2259 
2260 	info->id = elfInfo->id;
2261     info->type = B_SYSTEM_IMAGE;
2262     info->sequence = 0;
2263     info->init_order = 0;
2264     info->init_routine = NULL;
2265     info->term_routine = NULL;
2266     info->device = -1;
2267     info->node = -1;
2268 		// TODO: We could actually fill device/node in.
2269 	strlcpy(info->name, elfInfo->name, sizeof(info->name));
2270     info->text = (void*)elfInfo->text_region.start;
2271     info->data = (void*)elfInfo->data_region.start;
2272     info->text_size = elfInfo->text_region.size;
2273     info->data_size = elfInfo->data_region.size;
2274 
2275 	return B_OK;
2276 }
2277 
2278 
2279 image_id
2280 elf_create_memory_image(const char* imageName, addr_t text, size_t textSize,
2281 	addr_t data, size_t dataSize)
2282 {
2283 	// allocate the image
2284 	elf_image_info* image = create_image_struct();
2285 	if (image == NULL)
2286 		return B_NO_MEMORY;
2287 	MemoryDeleter imageDeleter(image);
2288 
2289 	// allocate symbol and string tables -- we allocate an empty symbol table,
2290 	// so that elf_debug_lookup_symbol_address() won't try the dynamic symbol
2291 	// table, which we don't have.
2292 	Elf32_Sym* symbolTable = (Elf32_Sym*)malloc(0);
2293 	char* stringTable = (char*)malloc(1);
2294 	MemoryDeleter symbolTableDeleter(symbolTable);
2295 	MemoryDeleter stringTableDeleter(stringTable);
2296 	if (symbolTable == NULL || stringTable == NULL)
2297 		return B_NO_MEMORY;
2298 
2299 	// the string table always contains the empty string
2300 	stringTable[0] = '\0';
2301 
2302 	image->debug_symbols = symbolTable;
2303 	image->num_debug_symbols = 0;
2304 	image->debug_string_table = stringTable;
2305 
2306 	// dup image name
2307 	image->name = strdup(imageName);
2308 	if (image->name == NULL)
2309 		return B_NO_MEMORY;
2310 
2311 	// data and text region
2312 	image->text_region.id = -1;
2313 	image->text_region.start = text;
2314 	image->text_region.size = textSize;
2315 	image->text_region.delta = 0;
2316 
2317 	image->data_region.id = -1;
2318 	image->data_region.start = data;
2319 	image->data_region.size = dataSize;
2320 	image->data_region.delta = 0;
2321 
2322 	mutex_lock(&sImageMutex);
2323 	register_elf_image(image);
2324 	image_id imageID = image->id;
2325 	mutex_unlock(&sImageMutex);
2326 
2327 	// keep the allocated memory
2328 	imageDeleter.Detach();
2329 	symbolTableDeleter.Detach();
2330 	stringTableDeleter.Detach();
2331 
2332 	return imageID;
2333 }
2334 
2335 
2336 status_t
2337 elf_add_memory_image_symbol(image_id id, const char* name, addr_t address,
2338 	size_t size, int32 type)
2339 {
2340 	MutexLocker _(sImageMutex);
2341 
2342 	// get the image
2343 	struct elf_image_info* image = find_image(id);
2344 	if (image == NULL)
2345 		return B_ENTRY_NOT_FOUND;
2346 
2347 	// get the current string table size
2348 	size_t stringTableSize = 1;
2349 	if (image->num_debug_symbols > 0) {
2350 		for (uint32 i = image->num_debug_symbols - 1; i >= 0; i--) {
2351 			int32 nameIndex = image->debug_symbols[i].st_name;
2352 			if (nameIndex != 0) {
2353 				stringTableSize = nameIndex
2354 					+ strlen(image->debug_string_table + nameIndex) + 1;
2355 				break;
2356 			}
2357 		}
2358 	}
2359 
2360 	// enter the name in the string table
2361 	char* stringTable = (char*)image->debug_string_table;
2362 	size_t stringIndex = 0;
2363 	if (name != NULL) {
2364 		size_t nameSize = strlen(name) + 1;
2365 		stringIndex = stringTableSize;
2366 		stringTableSize += nameSize;
2367 		stringTable = (char*)realloc((char*)image->debug_string_table,
2368 			stringTableSize);
2369 		if (stringTable == NULL)
2370 			return B_NO_MEMORY;
2371 		image->debug_string_table = stringTable;
2372 		memcpy(stringTable + stringIndex, name, nameSize);
2373 	}
2374 
2375 	// resize the symbol table
2376 	int32 symbolCount = image->num_debug_symbols + 1;
2377 	Elf32_Sym* symbolTable = (Elf32_Sym*)realloc(
2378 		(Elf32_Sym*)image->debug_symbols, sizeof(Elf32_Sym) * symbolCount);
2379 	if (symbolTable == NULL)
2380 		return B_NO_MEMORY;
2381 	image->debug_symbols = symbolTable;
2382 
2383 	// enter the symbol
2384 	Elf32_Sym& symbol = symbolTable[symbolCount - 1];
2385 	uint32 symbolType = type == B_SYMBOL_TYPE_DATA ? STT_OBJECT : STT_FUNC;
2386 	symbol.st_name = stringIndex;
2387 	symbol.st_value = address;
2388 	symbol.st_size = size;
2389 	symbol.st_info = ELF32_ST_INFO(STB_GLOBAL, symbolType);
2390 	symbol.st_other = 0;
2391 	symbol.st_shndx = 0;
2392 	image->num_debug_symbols++;
2393 
2394 	return B_OK;
2395 }
2396 
2397 
2398 status_t
2399 elf_init(kernel_args *args)
2400 {
2401 	struct preloaded_image *image;
2402 
2403 	image_init();
2404 
2405 	sImagesHash = hash_init(IMAGE_HASH_SIZE, 0, image_compare, image_hash);
2406 	if (sImagesHash == NULL)
2407 		return B_NO_MEMORY;
2408 
2409 	// Build a image structure for the kernel, which has already been loaded.
2410 	// The preloaded_images were already prepared by the VM.
2411 	if (insert_preloaded_image(&args->kernel_image, true) < B_OK)
2412 		panic("could not create kernel image.\n");
2413 
2414 	// Build image structures for all preloaded images.
2415 	for (image = args->preloaded_images; image != NULL; image = image->next)
2416 		insert_preloaded_image(image, false);
2417 
2418 	add_debugger_command("ls", &dump_address_info,
2419 		"lookup symbol for a particular address");
2420 	add_debugger_command("symbols", &dump_symbols, "dump symbols for image");
2421 	add_debugger_command("symbol", &dump_symbol, "search symbol in images");
2422 	add_debugger_command_etc("image", &dump_image, "dump image info",
2423 		"Prints info about the specified image.\n"
2424 		"  <image>  - pointer to the semaphore structure, or ID\n"
2425 		"           of the image to print info for.\n", 0);
2426 
2427 	sInitialized = true;
2428 	return B_OK;
2429 }
2430 
2431 
2432 // #pragma mark -
2433 
2434 
2435 /*!	Reads the symbol and string table for the kernel image with the given ID.
2436 	\a _symbolCount and \a _stringTableSize are both in- and output parameters.
2437 	When called they call the size of the buffers given by \a symbolTable and
2438 	\a stringTable respectively. When the function returns successfully, they
2439 	will contain the actual sizes (which can be greater than the original ones).
2440 	The function will copy as much as possible into the buffers. For only
2441 	getting the required buffer sizes, it can be invoked with \c NULL buffers.
2442 	On success \a _imageDelta will contain the offset to be added to the symbol
2443 	values in the table to get the actual symbol addresses.
2444 */
2445 status_t
2446 _user_read_kernel_image_symbols(image_id id, struct Elf32_Sym* symbolTable,
2447 	int32* _symbolCount, char* stringTable, size_t* _stringTableSize,
2448 	addr_t* _imageDelta)
2449 {
2450 	// check params
2451 	if (_symbolCount == NULL || _stringTableSize == NULL)
2452 		return B_BAD_VALUE;
2453 	if (!IS_USER_ADDRESS(_symbolCount) || !IS_USER_ADDRESS(_stringTableSize)
2454 		|| (_imageDelta != NULL && !IS_USER_ADDRESS(_imageDelta))
2455 		|| (symbolTable != NULL && !IS_USER_ADDRESS(symbolTable))
2456 		|| (stringTable != NULL && !IS_USER_ADDRESS(stringTable))) {
2457 		return B_BAD_ADDRESS;
2458 	}
2459 
2460 	// get buffer sizes
2461 	int32 maxSymbolCount;
2462 	size_t maxStringTableSize;
2463 	if (user_memcpy(&maxSymbolCount, _symbolCount, sizeof(maxSymbolCount))
2464 			!= B_OK
2465 		|| user_memcpy(&maxStringTableSize, _stringTableSize,
2466 			sizeof(maxStringTableSize)) != B_OK) {
2467 		return B_BAD_ADDRESS;
2468 	}
2469 
2470 	// find the image
2471 	MutexLocker _(sImageMutex);
2472 	struct elf_image_info* image = find_image(id);
2473 	if (image == NULL)
2474 		return B_ENTRY_NOT_FOUND;
2475 
2476 	// get the tables and infos
2477 	addr_t imageDelta = image->text_region.delta;
2478 	const Elf32_Sym* symbols;
2479 	int32 symbolCount;
2480 	const char* strings;
2481 
2482 	if (image->debug_symbols != NULL) {
2483 		symbols = image->debug_symbols;
2484 		symbolCount = image->num_debug_symbols;
2485 		strings = image->debug_string_table;
2486 	} else {
2487 		symbols = image->syms;
2488 		symbolCount = image->symhash[1];
2489 		strings = image->strtab;
2490 	}
2491 
2492 	// The string table size isn't stored in the elf_image_info structure. Find
2493 	// out by iterating through all symbols.
2494 	size_t stringTableSize = 0;
2495 	for (int32 i = 0; i < symbolCount; i++) {
2496 		size_t index = symbols[i].st_name;
2497 		if (index > stringTableSize)
2498 			stringTableSize = index;
2499 	}
2500 	stringTableSize += strlen(strings + stringTableSize) + 1;
2501 		// add size of the last string
2502 
2503 	// copy symbol table
2504 	int32 symbolsToCopy = min_c(symbolCount, maxSymbolCount);
2505 	if (symbolTable != NULL && symbolsToCopy > 0) {
2506 		if (user_memcpy(symbolTable, symbols, sizeof(Elf32_Sym) * symbolsToCopy)
2507 				!= B_OK) {
2508 			return B_BAD_ADDRESS;
2509 		}
2510 	}
2511 
2512 	// copy string table
2513 	size_t stringsToCopy = min_c(stringTableSize, maxStringTableSize);
2514 	if (stringTable != NULL && stringsToCopy > 0) {
2515 		if (user_memcpy(stringTable, strings, stringsToCopy)
2516 				!= B_OK) {
2517 			return B_BAD_ADDRESS;
2518 		}
2519 	}
2520 
2521 	// copy sizes
2522 	if (user_memcpy(_symbolCount, &symbolCount, sizeof(symbolCount)) != B_OK
2523 		|| user_memcpy(_stringTableSize, &stringTableSize,
2524 				sizeof(stringTableSize)) != B_OK
2525 		|| (_imageDelta != NULL && user_memcpy(_imageDelta, &imageDelta,
2526 				sizeof(imageDelta)) != B_OK)) {
2527 		return B_BAD_ADDRESS;
2528 	}
2529 
2530 	return B_OK;
2531 }
2532