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