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