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