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