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