xref: /haiku/src/system/runtime_loader/elf.cpp (revision 4f2fd49bdc6078128b1391191e4edac647044c3d)
1 /*
2  * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Copyright 2003-2008, Axel Dörfler, axeld@pinc-software.de.
4  * Distributed under the terms of the MIT License.
5  *
6  * Copyright 2002, Manuel J. Petit. All rights reserved.
7  * Copyright 2001, Travis Geiselbrecht. All rights reserved.
8  * Distributed under the terms of the NewOS License.
9  */
10 
11 #include "runtime_loader_private.h"
12 
13 #include <ctype.h>
14 #include <dlfcn.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 
19 #include <OS.h>
20 
21 #include <elf32.h>
22 #include <runtime_loader.h>
23 #include <syscalls.h>
24 #include <user_runtime.h>
25 #include <util/DoublyLinkedList.h>
26 #include <util/kernel_cpp.h>
27 #include <util/KMessage.h>
28 #include <vm_defs.h>
29 
30 #include "tracing_config.h"
31 
32 
33 //#define TRACE_RLD
34 #ifdef TRACE_RLD
35 #	define TRACE(x) dprintf x
36 #else
37 #	define TRACE(x) ;
38 #endif
39 
40 
41 // TODO: implement better locking strategy
42 // TODO: implement lazy binding
43 
44 #define	PAGE_MASK (B_PAGE_SIZE - 1)
45 
46 #define	PAGE_OFFSET(x) ((x) & (PAGE_MASK))
47 #define	PAGE_BASE(x) ((x) & ~(PAGE_MASK))
48 #define TO_PAGE_SIZE(x) ((x + (PAGE_MASK)) & ~(PAGE_MASK))
49 
50 #define RLD_PROGRAM_BASE 0x00200000
51 	/* keep in sync with app ldscript */
52 
53 // a handle returned by load_library() (dlopen())
54 #define RLD_GLOBAL_SCOPE	((void*)-2l)
55 
56 enum {
57 	// the lower two bits are reserved for RTLD_NOW and RTLD_GLOBAL
58 
59 	RFLAG_RW					= 0x0010,
60 	RFLAG_ANON					= 0x0020,
61 
62 	RFLAG_TERMINATED			= 0x0200,
63 	RFLAG_INITIALIZED			= 0x0400,
64 	RFLAG_SYMBOLIC				= 0x0800,
65 	RFLAG_RELOCATED				= 0x1000,
66 	RFLAG_PROTECTED				= 0x2000,
67 	RFLAG_DEPENDENCIES_LOADED	= 0x4000,
68 	RFLAG_REMAPPED				= 0x8000,
69 
70 	RFLAG_VISITED				= 0x10000,
71 	RFLAG_USE_FOR_RESOLVING		= 0x20000
72 		// temporarily set in the symbol resolution code
73 };
74 
75 
76 #define IMAGE_TYPE_TO_MASK(type)	(1 << ((type) - 1))
77 #define ALL_IMAGE_TYPES				(IMAGE_TYPE_TO_MASK(B_APP_IMAGE) \
78 									| IMAGE_TYPE_TO_MASK(B_LIBRARY_IMAGE) \
79 									| IMAGE_TYPE_TO_MASK(B_ADD_ON_IMAGE) \
80 									| IMAGE_TYPE_TO_MASK(B_SYSTEM_IMAGE))
81 #define APP_OR_LIBRARY_TYPE			(IMAGE_TYPE_TO_MASK(B_APP_IMAGE) \
82 									| IMAGE_TYPE_TO_MASK(B_LIBRARY_IMAGE))
83 
84 typedef void (*init_term_function)(image_id);
85 
86 
87 // image events
88 enum {
89 	IMAGE_EVENT_LOADED,
90 	IMAGE_EVENT_RELOCATED,
91 	IMAGE_EVENT_INITIALIZED,
92 	IMAGE_EVENT_UNINITIALIZING,
93 	IMAGE_EVENT_UNLOADING
94 };
95 
96 
97 struct RuntimeLoaderAddOn
98 		: public DoublyLinkedListLinkImpl<RuntimeLoaderAddOn> {
99 	image_t*				image;
100 	runtime_loader_add_on*	addOn;
101 
102 	RuntimeLoaderAddOn(image_t* image, runtime_loader_add_on* addOn)
103 		:
104 		image(image),
105 		addOn(addOn)
106 	{
107 	}
108 };
109 
110 typedef DoublyLinkedList<RuntimeLoaderAddOn> AddOnList;
111 
112 struct RuntimeLoaderSymbolPatcher {
113 	RuntimeLoaderSymbolPatcher*		next;
114 	runtime_loader_symbol_patcher*	patcher;
115 	void*							cookie;
116 
117 	RuntimeLoaderSymbolPatcher(runtime_loader_symbol_patcher* patcher,
118 			void* cookie)
119 		:
120 		patcher(patcher),
121 		cookie(cookie)
122 	{
123 	}
124 };
125 
126 
127 static image_queue_t sLoadedImages = {0, 0};
128 static image_queue_t sDisposableImages = {0, 0};
129 static uint32 sLoadedImageCount = 0;
130 static image_t *sProgramImage;
131 static KMessage sErrorMessage;
132 static bool sProgramLoaded = false;
133 static const char *sSearchPathSubDir = NULL;
134 static bool sInvalidImageIDs;
135 static image_t **sPreloadedImages = NULL;
136 static uint32 sPreloadedImageCount = 0;
137 static AddOnList sAddOns;
138 
139 // a recursive lock
140 static sem_id sSem;
141 static thread_id sSemOwner;
142 static int32 sSemCount;
143 
144 extern runtime_loader_add_on_export gRuntimeLoaderAddOnExport;
145 
146 
147 void
148 dprintf(const char *format, ...)
149 {
150 	char buffer[1024];
151 
152 	va_list list;
153 	va_start(list, format);
154 
155 	vsnprintf(buffer, sizeof(buffer), format, list);
156 	_kern_debug_output(buffer);
157 
158 	va_end(list);
159 }
160 
161 #define FATAL(x...)							\
162 	do {									\
163 		dprintf("runtime_loader: " x);		\
164 		if (!sProgramLoaded)				\
165 			printf("runtime_loader: " x);	\
166 	} while (false)
167 
168 
169 /*!	Mini atoi(), so we don't have to include the libroot dependencies.
170  */
171 int
172 atoi(const char* num)
173 {
174 	int result = 0;
175 	while (*num >= '0' && *num <= '9') {
176 		result = (result * 10) + (*num - '0');
177 		num++;
178 	}
179 
180 	return result;
181 }
182 
183 
184 #if RUNTIME_LOADER_TRACING
185 
186 void
187 ktrace_printf(const char *format, ...)
188 {
189 	va_list list;
190 	va_start(list, format);
191 
192 	char buffer[1024];
193 	vsnprintf(buffer, sizeof(buffer), format, list);
194 	_kern_ktrace_output(buffer);
195 
196 	va_end(list);
197 }
198 
199 #define KTRACE(x...)	ktrace_printf(x)
200 
201 #else
202 #	define KTRACE(x...)
203 #endif	// RUNTIME_LOADER_TRACING
204 
205 
206 static void
207 rld_unlock()
208 {
209 	if (sSemCount-- == 1) {
210 		sSemOwner = -1;
211 		release_sem(sSem);
212 	}
213 }
214 
215 
216 static void
217 rld_lock()
218 {
219 	thread_id self = find_thread(NULL);
220 	if (self != sSemOwner) {
221 		acquire_sem(sSem);
222 		sSemOwner = self;
223 	}
224 	sSemCount++;
225 }
226 
227 
228 static void
229 enqueue_image(image_queue_t *queue, image_t *image)
230 {
231 	image->next = 0;
232 
233 	image->prev = queue->tail;
234 	if (queue->tail)
235 		queue->tail->next = image;
236 
237 	queue->tail = image;
238 	if (!queue->head)
239 		queue->head = image;
240 }
241 
242 
243 static void
244 dequeue_image(image_queue_t *queue, image_t *image)
245 {
246 	if (image->next)
247 		image->next->prev = image->prev;
248 	else
249 		queue->tail = image->prev;
250 
251 	if (image->prev)
252 		image->prev->next = image->next;
253 	else
254 		queue->head = image->next;
255 
256 	image->prev = 0;
257 	image->next = 0;
258 }
259 
260 
261 static uint32
262 elf_hash(const uint8 *name)
263 {
264 	uint32 hash = 0;
265 	uint32 temp;
266 
267 	while (*name) {
268 		hash = (hash << 4) + *name++;
269 		if ((temp = hash & 0xf0000000)) {
270 			hash ^= temp >> 24;
271 		}
272 		hash &= ~temp;
273 	}
274 	return hash;
275 }
276 
277 
278 static inline bool
279 report_errors()
280 {
281 	return gProgramArgs->error_port >= 0;
282 }
283 
284 
285 //! Remaps the image ID of \a image after fork.
286 static status_t
287 update_image_id(image_t *image)
288 {
289 	int32 cookie = 0;
290 	image_info info;
291 	while (_kern_get_next_image_info(B_CURRENT_TEAM, &cookie, &info,
292 			sizeof(image_info)) == B_OK) {
293 		for (uint32 i = 0; i < image->num_regions; i++) {
294 			if (image->regions[i].vmstart == (addr_t)info.text) {
295 				image->id = info.id;
296 				return B_OK;
297 			}
298 		}
299 	}
300 
301 	FATAL("Could not update image ID %ld after fork()!\n", image->id);
302 	return B_ENTRY_NOT_FOUND;
303 }
304 
305 
306 //! After fork, we lazily rebuild the image IDs of all loaded images.
307 static status_t
308 update_image_ids(void)
309 {
310 	for (image_t *image = sLoadedImages.head; image; image = image->next) {
311 		status_t status = update_image_id(image);
312 		if (status != B_OK)
313 			return status;
314 	}
315 	for (image_t *image = sDisposableImages.head; image; image = image->next) {
316 		status_t status = update_image_id(image);
317 		if (status != B_OK)
318 			return status;
319 	}
320 
321 	sInvalidImageIDs = false;
322 	return B_OK;
323 }
324 
325 
326 static image_t *
327 find_image_in_queue(image_queue_t *queue, const char *name, bool isPath,
328 	uint32 typeMask)
329 {
330 	for (image_t *image = queue->head; image; image = image->next) {
331 		const char *imageName = isPath ? image->path : image->name;
332 		int length = isPath ? sizeof(image->path) : sizeof(image->name);
333 
334 		if (!strncmp(imageName, name, length)
335 			&& (typeMask & IMAGE_TYPE_TO_MASK(image->type)) != 0) {
336 			return image;
337 		}
338 	}
339 
340 	return NULL;
341 }
342 
343 
344 static image_t *
345 find_image(char const *name, uint32 typeMask)
346 {
347 	bool isPath = strchr(name, '/') != NULL;
348 	return find_image_in_queue(&sLoadedImages, name, isPath, typeMask);
349 }
350 
351 
352 static image_t *
353 find_loaded_image_by_id(image_id id)
354 {
355 	if (sInvalidImageIDs) {
356 		// After fork, we lazily rebuild the image IDs of all loaded images
357 		update_image_ids();
358 	}
359 
360 	for (image_t *image = sLoadedImages.head; image; image = image->next) {
361 		if (image->id == id)
362 			return image;
363 	}
364 
365 	// For the termination routine, we need to look into the list of
366 	// disposable images as well
367 	for (image_t *image = sDisposableImages.head; image; image = image->next) {
368 		if (image->id == id)
369 			return image;
370 	}
371 
372 	return NULL;
373 }
374 
375 
376 static image_t*
377 get_program_image()
378 {
379 	for (image_t *image = sLoadedImages.head; image; image = image->next) {
380 		if (image->type == B_APP_IMAGE)
381 			return image;
382 	}
383 
384 	return NULL;
385 }
386 
387 
388 static const char *
389 get_program_path()
390 {
391 	if (image_t* image = get_program_image())
392 		return image->path;
393 
394 	return NULL;
395 }
396 
397 
398 static status_t
399 parse_elf_header(struct Elf32_Ehdr *eheader, int32 *_pheaderSize,
400 	int32 *_sheaderSize)
401 {
402 	if (memcmp(eheader->e_ident, ELF_MAGIC, 4) != 0)
403 		return B_NOT_AN_EXECUTABLE;
404 
405 	if (eheader->e_ident[4] != ELFCLASS32)
406 		return B_NOT_AN_EXECUTABLE;
407 
408 	if (eheader->e_phoff == 0)
409 		return B_NOT_AN_EXECUTABLE;
410 
411 	if (eheader->e_phentsize < sizeof(struct Elf32_Phdr))
412 		return B_NOT_AN_EXECUTABLE;
413 
414 	*_pheaderSize = eheader->e_phentsize * eheader->e_phnum;
415 	*_sheaderSize = eheader->e_shentsize * eheader->e_shnum;
416 
417 	if (*_pheaderSize <= 0 || *_sheaderSize <= 0)
418 		return B_NOT_AN_EXECUTABLE;
419 
420 	return B_OK;
421 }
422 
423 
424 static int32
425 count_regions(char const *buff, int phnum, int phentsize)
426 {
427 	struct Elf32_Phdr *pheaders;
428 	int32 count = 0;
429 	int i;
430 
431 	for (i = 0; i < phnum; i++) {
432 		pheaders = (struct Elf32_Phdr *)(buff + i * phentsize);
433 
434 		switch (pheaders->p_type) {
435 			case PT_NULL:
436 				/* NOP header */
437 				break;
438 			case PT_LOAD:
439 				count += 1;
440 				if (pheaders->p_memsz != pheaders->p_filesz) {
441 					addr_t A = TO_PAGE_SIZE(pheaders->p_vaddr + pheaders->p_memsz);
442 					addr_t B = TO_PAGE_SIZE(pheaders->p_vaddr + pheaders->p_filesz);
443 
444 					if (A != B)
445 						count += 1;
446 				}
447 				break;
448 			case PT_DYNAMIC:
449 				/* will be handled at some other place */
450 				break;
451 			case PT_INTERP:
452 				/* should check here for appropiate interpreter */
453 				break;
454 			case PT_NOTE:
455 				/* unsupported */
456 				break;
457 			case PT_SHLIB:
458 				/* undefined semantics */
459 				break;
460 			case PT_PHDR:
461 				/* we don't use it */
462 				break;
463 			default:
464 				FATAL("unhandled pheader type 0x%lx\n", pheaders[i].p_type);
465 				return B_BAD_DATA;
466 		}
467 	}
468 
469 	return count;
470 }
471 
472 
473 static image_t *
474 create_image(const char *name, const char *path, int num_regions)
475 {
476 	size_t allocSize = sizeof(image_t) + (num_regions - 1) * sizeof(elf_region_t);
477 	const char *lastSlash;
478 
479 	image_t *image = (image_t*)malloc(allocSize);
480 	if (image == NULL) {
481 		FATAL("no memory for image %s\n", path);
482 		return NULL;
483 	}
484 
485 	memset(image, 0, allocSize);
486 
487 	strlcpy(image->path, path, sizeof(image->path));
488 
489 	// Make the last component of the supplied name the image name.
490 	// If present, DT_SONAME will replace this name.
491 	if ((lastSlash = strrchr(name, '/')))
492 		strlcpy(image->name, lastSlash + 1, sizeof(image->name));
493 	else
494 		strlcpy(image->name, name, sizeof(image->name));
495 
496 	image->ref_count = 1;
497 	image->num_regions = num_regions;
498 
499 	return image;
500 }
501 
502 
503 static void
504 delete_image_struct(image_t *image)
505 {
506 #ifdef DEBUG
507 	size_t size = sizeof(image_t) + (image->num_regions - 1) * sizeof(elf_region_t);
508 	memset(image->needed, 0xa5, sizeof(image->needed[0]) * image->num_needed);
509 #endif
510 	free(image->needed);
511 
512 	while (RuntimeLoaderSymbolPatcher* patcher
513 			= image->defined_symbol_patchers) {
514 		image->defined_symbol_patchers = patcher->next;
515 		delete patcher;
516 	}
517 	while (RuntimeLoaderSymbolPatcher* patcher
518 			= image->undefined_symbol_patchers) {
519 		image->undefined_symbol_patchers = patcher->next;
520 		delete patcher;
521 	}
522 
523 #ifdef DEBUG
524 	// overwrite images to make sure they aren't accidently reused anywhere
525 	memset(image, 0xa5, size);
526 #endif
527 	free(image);
528 }
529 
530 
531 static void
532 delete_image(image_t *image)
533 {
534 	if (image == NULL)
535 		return;
536 
537 	_kern_unregister_image(image->id);
538 		// registered in load_container()
539 
540 	delete_image_struct(image);
541 }
542 
543 
544 static void
545 update_image_flags_recursively(image_t* image, uint32 flagsToSet,
546 	uint32 flagsToClear)
547 {
548 	image_t* queue[sLoadedImageCount];
549 	uint32 count = 0;
550 	uint32 index = 0;
551 	queue[count++] = image;
552 	image->flags |= RFLAG_VISITED;
553 
554 	while (index < count) {
555 		// pop next image
556 		image = queue[index++];
557 
558 		// push dependencies
559 		for (uint32 i = 0; i < image->num_needed; i++) {
560 			image_t* needed = image->needed[i];
561 			if ((needed->flags & RFLAG_VISITED) == 0) {
562 				queue[count++] = needed;
563 				needed->flags |= RFLAG_VISITED;
564 			}
565 		}
566 	}
567 
568 	// update flags
569 	for (uint32 i = 0; i < count; i++) {
570 		queue[i]->flags = (queue[i]->flags | flagsToSet)
571 			& ~(flagsToClear | RFLAG_VISITED);
572 	}
573 }
574 
575 
576 static void
577 set_image_flags_recursively(image_t* image, uint32 flags)
578 {
579 	update_image_flags_recursively(image, flags, 0);
580 }
581 
582 
583 static void
584 clear_image_flags_recursively(image_t* image, uint32 flags)
585 {
586 	update_image_flags_recursively(image, 0, flags);
587 }
588 
589 
590 static status_t
591 parse_program_headers(image_t *image, char *buff, int phnum, int phentsize)
592 {
593 	struct Elf32_Phdr *pheader;
594 	int regcount;
595 	int i;
596 
597 	regcount = 0;
598 	for (i = 0; i < phnum; i++) {
599 		pheader = (struct Elf32_Phdr *)(buff + i * phentsize);
600 
601 		switch (pheader->p_type) {
602 			case PT_NULL:
603 				/* NOP header */
604 				break;
605 			case PT_LOAD:
606 				if (pheader->p_memsz == pheader->p_filesz) {
607 					/*
608 					 * everything in one area
609 					 */
610 					image->regions[regcount].start = pheader->p_vaddr;
611 					image->regions[regcount].size = pheader->p_memsz;
612 					image->regions[regcount].vmstart = PAGE_BASE(pheader->p_vaddr);
613 					image->regions[regcount].vmsize = TO_PAGE_SIZE(pheader->p_memsz
614 						+ PAGE_OFFSET(pheader->p_vaddr));
615 					image->regions[regcount].fdstart = pheader->p_offset;
616 					image->regions[regcount].fdsize = pheader->p_filesz;
617 					image->regions[regcount].delta = 0;
618 					image->regions[regcount].flags = 0;
619 					if (pheader->p_flags & PF_WRITE) {
620 						// this is a writable segment
621 						image->regions[regcount].flags |= RFLAG_RW;
622 					}
623 				} else {
624 					/*
625 					 * may require splitting
626 					 */
627 					addr_t A = TO_PAGE_SIZE(pheader->p_vaddr + pheader->p_memsz);
628 					addr_t B = TO_PAGE_SIZE(pheader->p_vaddr + pheader->p_filesz);
629 
630 					image->regions[regcount].start = pheader->p_vaddr;
631 					image->regions[regcount].size = pheader->p_filesz;
632 					image->regions[regcount].vmstart = PAGE_BASE(pheader->p_vaddr);
633 					image->regions[regcount].vmsize = TO_PAGE_SIZE(pheader->p_filesz
634 						+ PAGE_OFFSET(pheader->p_vaddr));
635 					image->regions[regcount].fdstart = pheader->p_offset;
636 					image->regions[regcount].fdsize = pheader->p_filesz;
637 					image->regions[regcount].delta = 0;
638 					image->regions[regcount].flags = 0;
639 					if (pheader->p_flags & PF_WRITE) {
640 						// this is a writable segment
641 						image->regions[regcount].flags |= RFLAG_RW;
642 					}
643 
644 					if (A != B) {
645 						/*
646 						 * yeah, it requires splitting
647 						 */
648 						regcount += 1;
649 						image->regions[regcount].start = pheader->p_vaddr;
650 						image->regions[regcount].size = pheader->p_memsz - pheader->p_filesz;
651 						image->regions[regcount].vmstart = image->regions[regcount-1].vmstart + image->regions[regcount-1].vmsize;
652 						image->regions[regcount].vmsize = TO_PAGE_SIZE(pheader->p_memsz + PAGE_OFFSET(pheader->p_vaddr))
653 							- image->regions[regcount-1].vmsize;
654 						image->regions[regcount].fdstart = 0;
655 						image->regions[regcount].fdsize = 0;
656 						image->regions[regcount].delta = 0;
657 						image->regions[regcount].flags = RFLAG_ANON;
658 						if (pheader->p_flags & PF_WRITE) {
659 							// this is a writable segment
660 							image->regions[regcount].flags |= RFLAG_RW;
661 						}
662 					}
663 				}
664 				regcount += 1;
665 				break;
666 			case PT_DYNAMIC:
667 				image->dynamic_ptr = pheader->p_vaddr;
668 				break;
669 			case PT_INTERP:
670 				/* should check here for appropiate interpreter */
671 				break;
672 			case PT_NOTE:
673 				/* unsupported */
674 				break;
675 			case PT_SHLIB:
676 				/* undefined semantics */
677 				break;
678 			case PT_PHDR:
679 				/* we don't use it */
680 				break;
681 			default:
682 				FATAL("unhandled pheader type 0x%lx\n", pheader[i].p_type);
683 				return B_BAD_DATA;
684 		}
685 	}
686 
687 	return B_OK;
688 }
689 
690 
691 static bool
692 analyze_object_gcc_version(int fd, image_t* image, Elf32_Ehdr& eheader,
693 	int32 sheaderSize, char* buffer, size_t bufferSize)
694 {
695 	image->gcc_version.major = 0;
696 	image->gcc_version.middle = 0;
697 	image->gcc_version.minor = 0;
698 
699 	if (sheaderSize > (int)bufferSize) {
700 		FATAL("Cannot handle section headers bigger than %lu\n", bufferSize);
701 		return false;
702 	}
703 
704 	// read section headers
705 	ssize_t length = _kern_read(fd, eheader.e_shoff, buffer, sheaderSize);
706 	if (length != sheaderSize) {
707 		FATAL("Could not read section headers: %s\n", strerror(length));
708 		return false;
709 	}
710 
711 	// load the string section
712 	Elf32_Shdr* sectionHeader
713 		= (Elf32_Shdr*)(buffer + eheader.e_shstrndx * eheader.e_shentsize);
714 
715 	if (sheaderSize + sectionHeader->sh_size > bufferSize) {
716 		FATAL("Buffer not big enough for section string section\n");
717 		return false;
718 	}
719 
720 	char* sectionStrings = buffer + bufferSize - sectionHeader->sh_size;
721 	length = _kern_read(fd, sectionHeader->sh_offset, sectionStrings,
722 		sectionHeader->sh_size);
723 	if (length != (int)sectionHeader->sh_size) {
724 		FATAL("Could not read section string section: %s\n", strerror(length));
725 		return false;
726 	}
727 
728 	// find the .comment section
729 	off_t commentOffset = 0;
730 	size_t commentSize = 0;
731 	for (uint32 i = 0; i < eheader.e_shnum; i++) {
732 		sectionHeader = (Elf32_Shdr*)(buffer + i * eheader.e_shentsize);
733 		const char* sectionName = sectionStrings + sectionHeader->sh_name;
734 		if (sectionHeader->sh_name != 0
735 			&& strcmp(sectionName, ".comment") == 0) {
736 			commentOffset = sectionHeader->sh_offset;
737 			commentSize = sectionHeader->sh_size;
738 			break;
739 		}
740 	}
741 
742 	if (commentSize == 0) {
743 		FATAL("Could not find .comment section\n");
744 		return false;
745 	}
746 
747 	// read a part of the comment section
748 	if (commentSize > 512)
749 		commentSize = 512;
750 
751 	length = _kern_read(fd, commentOffset, buffer, commentSize);
752 	if (length != (int)commentSize) {
753 		FATAL("Could not read .comment section: %s\n", strerror(length));
754 		return false;
755 	}
756 
757 	// the common prefix of the strings in the .comment section
758 	static const char* kGCCVersionPrefix = "GCC: (GNU) ";
759 	size_t gccVersionPrefixLen = strlen(kGCCVersionPrefix);
760 
761 	size_t index = 0;
762 	int gccMajor = 0;
763 	int gccMiddle = 0;
764 	int gccMinor = 0;
765 	bool isHaiku = true;
766 
767 	// Read up to 10 comments. The first three or four are usually from the
768 	// glue code.
769 	for (int i = 0; i < 10; i++) {
770 		// skip '\0'
771 		while (index < commentSize && buffer[index] == '\0')
772 			index++;
773 		char* stringStart = buffer + index;
774 
775 		// find string end
776 		while (index < commentSize && buffer[index] != '\0')
777 			index++;
778 
779 		// ignore the entry at the end of the buffer
780 		if (index == commentSize)
781 			break;
782 
783 		// We have to analyze string like these:
784 		// GCC: (GNU) 2.9-beos-991026
785 		// GCC: (GNU) 2.95.3-haiku-080322
786 		// GCC: (GNU) 4.1.2
787 
788 		// skip the common prefix
789 		if (strncmp(stringStart, kGCCVersionPrefix, gccVersionPrefixLen) != 0)
790 			continue;
791 
792 		// the rest is the GCC version
793 		char* gccVersion = stringStart + gccVersionPrefixLen;
794 		char* gccPlatform = strchr(gccVersion, '-');
795 		char* patchLevel = NULL;
796 		if (gccPlatform != NULL) {
797 			*gccPlatform = '\0';
798 			gccPlatform++;
799 			patchLevel = strchr(gccPlatform, '-');
800 			if (patchLevel != NULL) {
801 				*patchLevel = '\0';
802 				patchLevel++;
803 			}
804 		}
805 
806 		// split the gcc version into major, middle, and minor
807 		int version[3] = { 0, 0, 0 };
808 
809 		for (int k = 0; gccVersion != NULL && k < 3; k++) {
810 			char* dot = strchr(gccVersion, '.');
811 			if (dot) {
812 				*dot = '\0';
813 				dot++;
814 			}
815 			version[k] = atoi(gccVersion);
816 			gccVersion = dot;
817 		}
818 
819 		// got any version?
820 		if (version[0] == 0)
821 			continue;
822 
823 		// Select the gcc version with the smallest major, but the greatest
824 		// middle/minor. This should usually ignore the glue code version as
825 		// well as cases where e.g. in a gcc 2 program a single C file has
826 		// been compiled with gcc 4.
827 		if (gccMajor == 0 || gccMajor > version[0]
828 		 	|| gccMajor == version[0]
829 				&& (gccMiddle < version[1]
830 					|| gccMiddle == version[1] && gccMinor < version[2])) {
831 			gccMajor = version[0];
832 			gccMiddle = version[1];
833 			gccMinor = version[2];
834 		}
835 
836 		if (gccMajor == 2 && gccPlatform != NULL && strcmp(gccPlatform, "haiku"))
837 			isHaiku = false;
838 	}
839 
840 	image->gcc_version.major = gccMajor;
841 	image->gcc_version.middle = gccMiddle;
842 	image->gcc_version.minor = gccMinor;
843 	image->gcc_version.haiku = isHaiku;
844 
845 	return gccMajor != 0;
846 }
847 
848 
849 static bool
850 assert_dynamic_loadable(image_t *image)
851 {
852 	uint32 i;
853 
854 	if (!image->dynamic_ptr)
855 		return true;
856 
857 	for (i = 0; i < image->num_regions; i++) {
858 		if (image->dynamic_ptr >= image->regions[i].start
859 			&& image->dynamic_ptr < image->regions[i].start + image->regions[i].size)
860 			return true;
861 	}
862 
863 	return false;
864 }
865 
866 
867 /**	This function will change the protection of all read-only segments
868  *	to really be read-only.
869  *	The areas have to be read/write first, so that they can be relocated.
870  */
871 
872 static void
873 remap_images(void)
874 {
875 	image_t *image;
876 	uint32 i;
877 
878 	for (image = sLoadedImages.head; image != NULL; image = image->next) {
879 		for (i = 0; i < image->num_regions; i++) {
880 			if ((image->regions[i].flags & RFLAG_RW) == 0
881 				&& (image->regions[i].flags & RFLAG_REMAPPED) == 0) {
882 				// we only need to do this once, so we remember those we've already mapped
883 				if (_kern_set_area_protection(image->regions[i].id,
884 						B_READ_AREA | B_EXECUTE_AREA) == B_OK)
885 					image->regions[i].flags |= RFLAG_REMAPPED;
886 			}
887 		}
888 	}
889 }
890 
891 
892 static status_t
893 map_image(int fd, char const *path, image_t *image, bool fixed)
894 {
895 	status_t status = B_OK;
896 	const char *baseName;
897 	uint32 i;
898 
899 	(void)(fd);
900 
901 	// cut the file name from the path as base name for the created areas
902 	baseName = strrchr(path, '/');
903 	if (baseName != NULL)
904 		baseName++;
905 	else
906 		baseName = path;
907 
908 	for (i = 0; i < image->num_regions; i++) {
909 		char regionName[B_OS_NAME_LENGTH];
910 		addr_t loadAddress;
911 		uint32 addressSpecifier;
912 
913 		// for BeOS compatibility: if we load an old BeOS executable, we
914 		// have to relocate it, if possible - we recognize it because the
915 		// vmstart is set to 0 (hopefully always)
916 		if (fixed && image->regions[i].vmstart == 0)
917 			fixed = false;
918 
919 		snprintf(regionName, sizeof(regionName), "%s_seg%lu%s",
920 			baseName, i, (image->regions[i].flags & RFLAG_RW) ? "rw" : "ro");
921 
922 		if (image->dynamic_ptr && !fixed) {
923 			// relocatable image... we can afford to place wherever
924 			if (i == 0) {
925 				// but only the first segment gets a free ride
926 				loadAddress = RLD_PROGRAM_BASE;
927 				addressSpecifier = B_BASE_ADDRESS;
928 			} else {
929 				loadAddress = image->regions[i].vmstart + image->regions[i-1].delta;
930 				addressSpecifier = B_EXACT_ADDRESS;
931 			}
932 		} else {
933 			// not relocatable, put it where it asks or die trying
934 			loadAddress = image->regions[i].vmstart;
935 			addressSpecifier = B_EXACT_ADDRESS;
936 		}
937 
938 		if (image->regions[i].flags & RFLAG_ANON) {
939 			image->regions[i].id = _kern_create_area(regionName, (void **)&loadAddress,
940 				addressSpecifier, image->regions[i].vmsize, B_NO_LOCK,
941 				B_READ_AREA | B_WRITE_AREA);
942 
943 			if (image->regions[i].id < 0) {
944 				status = image->regions[i].id;
945 				goto error;
946 			}
947 
948 			image->regions[i].delta = loadAddress - image->regions[i].vmstart;
949 			image->regions[i].vmstart = loadAddress;
950 		} else {
951 			image->regions[i].id = _kern_map_file(regionName,
952 				(void **)&loadAddress, addressSpecifier,
953 				image->regions[i].vmsize, B_READ_AREA | B_WRITE_AREA,
954 				REGION_PRIVATE_MAP, fd, PAGE_BASE(image->regions[i].fdstart));
955 
956 			if (image->regions[i].id < 0) {
957 				status = image->regions[i].id;
958 				goto error;
959 			}
960 
961 			TRACE(("\"%s\" at %p, 0x%lx bytes (%s)\n", path,
962 				(void *)loadAddress, image->regions[i].vmsize,
963 				image->regions[i].flags & RFLAG_RW ? "rw" : "read-only"));
964 
965 			image->regions[i].delta = loadAddress - image->regions[i].vmstart;
966 			image->regions[i].vmstart = loadAddress;
967 
968 			// handle trailer bits in data segment
969 			if (image->regions[i].flags & RFLAG_RW) {
970 				addr_t startClearing;
971 				addr_t toClear;
972 
973 				startClearing = image->regions[i].vmstart
974 					+ PAGE_OFFSET(image->regions[i].start)
975 					+ image->regions[i].size;
976 				toClear = image->regions[i].vmsize
977 					- PAGE_OFFSET(image->regions[i].start)
978 					- image->regions[i].size;
979 
980 				TRACE(("cleared 0x%lx and the following 0x%lx bytes\n", startClearing, toClear));
981 				memset((void *)startClearing, 0, toClear);
982 			}
983 		}
984 	}
985 
986 	if (image->dynamic_ptr)
987 		image->dynamic_ptr += image->regions[0].delta;
988 
989 	return B_OK;
990 
991 error:
992 	return status;
993 }
994 
995 
996 static void
997 unmap_image(image_t *image)
998 {
999 	uint32 i;
1000 
1001 	for (i = 0; i < image->num_regions; i++) {
1002 		_kern_delete_area(image->regions[i].id);
1003 
1004 		image->regions[i].id = -1;
1005 	}
1006 }
1007 
1008 
1009 static bool
1010 parse_dynamic_segment(image_t *image)
1011 {
1012 	struct Elf32_Dyn *d;
1013 	int i;
1014 	int sonameOffset = -1;
1015 
1016 	image->symhash = 0;
1017 	image->syms = 0;
1018 	image->strtab = 0;
1019 
1020 	d = (struct Elf32_Dyn *)image->dynamic_ptr;
1021 	if (!d)
1022 		return true;
1023 
1024 	for (i = 0; d[i].d_tag != DT_NULL; i++) {
1025 		switch (d[i].d_tag) {
1026 			case DT_NEEDED:
1027 				image->num_needed += 1;
1028 				break;
1029 			case DT_HASH:
1030 				image->symhash = (uint32 *)(d[i].d_un.d_ptr + image->regions[0].delta);
1031 				break;
1032 			case DT_STRTAB:
1033 				image->strtab = (char *)(d[i].d_un.d_ptr + image->regions[0].delta);
1034 				break;
1035 			case DT_SYMTAB:
1036 				image->syms = (struct Elf32_Sym *)(d[i].d_un.d_ptr + image->regions[0].delta);
1037 				break;
1038 			case DT_REL:
1039 				image->rel = (struct Elf32_Rel *)(d[i].d_un.d_ptr + image->regions[0].delta);
1040 				break;
1041 			case DT_RELSZ:
1042 				image->rel_len = d[i].d_un.d_val;
1043 				break;
1044 			case DT_RELA:
1045 				image->rela = (struct Elf32_Rela *)(d[i].d_un.d_ptr + image->regions[0].delta);
1046 				break;
1047 			case DT_RELASZ:
1048 				image->rela_len = d[i].d_un.d_val;
1049 				break;
1050 			// TK: procedure linkage table
1051 			case DT_JMPREL:
1052 				image->pltrel = (struct Elf32_Rel *)(d[i].d_un.d_ptr + image->regions[0].delta);
1053 				break;
1054 			case DT_PLTRELSZ:
1055 				image->pltrel_len = d[i].d_un.d_val;
1056 				break;
1057 			case DT_INIT:
1058 				image->init_routine = (d[i].d_un.d_ptr + image->regions[0].delta);
1059 				break;
1060 			case DT_FINI:
1061 				image->term_routine = (d[i].d_un.d_ptr + image->regions[0].delta);
1062 				break;
1063 			case DT_SONAME:
1064 				sonameOffset = d[i].d_un.d_val;
1065 				break;
1066 			default:
1067 				continue;
1068 		}
1069 	}
1070 
1071 	// lets make sure we found all the required sections
1072 	if (!image->symhash || !image->syms || !image->strtab)
1073 		return false;
1074 
1075 	if (sonameOffset >= 0)
1076 		strlcpy(image->name, STRING(image, sonameOffset), sizeof(image->name));
1077 
1078 	return true;
1079 }
1080 
1081 
1082 static void
1083 patch_defined_symbol(image_t* image, const char* name, void** symbol,
1084 	int32* type)
1085 {
1086 	RuntimeLoaderSymbolPatcher* patcher = image->defined_symbol_patchers;
1087 	while (patcher != NULL && *symbol != 0) {
1088 		image_t* inImage = image;
1089 		patcher->patcher(patcher->cookie, NULL, image, name, &inImage,
1090 			symbol, type);
1091 		patcher = patcher->next;
1092 	}
1093 }
1094 
1095 
1096 static void
1097 patch_undefined_symbol(image_t* rootImage, image_t* image, const char* name,
1098 	image_t** foundInImage, void** symbol, int32* type)
1099 {
1100 	if (*foundInImage != NULL)
1101 		patch_defined_symbol(*foundInImage, name, symbol, type);
1102 
1103 	RuntimeLoaderSymbolPatcher* patcher = image->undefined_symbol_patchers;
1104 	while (patcher != NULL) {
1105 		patcher->patcher(patcher->cookie, rootImage, image, name, foundInImage,
1106 			symbol, type);
1107 		patcher = patcher->next;
1108 	}
1109 }
1110 
1111 
1112 status_t
1113 register_defined_symbol_patcher(struct image_t* image,
1114 	runtime_loader_symbol_patcher* _patcher, void* cookie)
1115 {
1116 	RuntimeLoaderSymbolPatcher* patcher
1117 		= new(mynothrow) RuntimeLoaderSymbolPatcher(_patcher, cookie);
1118 	if (patcher == NULL)
1119 		return B_NO_MEMORY;
1120 
1121 	patcher->next = image->defined_symbol_patchers;
1122 	image->defined_symbol_patchers = patcher;
1123 
1124 	return B_OK;
1125 }
1126 
1127 
1128 void
1129 unregister_defined_symbol_patcher(struct image_t* image,
1130 	runtime_loader_symbol_patcher* _patcher, void* cookie)
1131 {
1132 	RuntimeLoaderSymbolPatcher** patcher = &image->defined_symbol_patchers;
1133 	while (*patcher != NULL) {
1134 		if ((*patcher)->patcher == _patcher && (*patcher)->cookie == cookie) {
1135 			RuntimeLoaderSymbolPatcher* toDelete = *patcher;
1136 			*patcher = (*patcher)->next;
1137 			delete toDelete;
1138 			return;
1139 		}
1140 		patcher = &(*patcher)->next;
1141 	}
1142 }
1143 
1144 
1145 status_t
1146 register_undefined_symbol_patcher(struct image_t* image,
1147 	runtime_loader_symbol_patcher* _patcher, void* cookie)
1148 {
1149 	RuntimeLoaderSymbolPatcher* patcher
1150 		= new(mynothrow) RuntimeLoaderSymbolPatcher(_patcher, cookie);
1151 	if (patcher == NULL)
1152 		return B_NO_MEMORY;
1153 
1154 	patcher->next = image->undefined_symbol_patchers;
1155 	image->undefined_symbol_patchers = patcher;
1156 
1157 	return B_OK;
1158 }
1159 
1160 
1161 void
1162 unregister_undefined_symbol_patcher(struct image_t* image,
1163 	runtime_loader_symbol_patcher* _patcher, void* cookie)
1164 {
1165 	RuntimeLoaderSymbolPatcher** patcher = &image->undefined_symbol_patchers;
1166 	while (*patcher != NULL) {
1167 		if ((*patcher)->patcher == _patcher && (*patcher)->cookie == cookie) {
1168 			RuntimeLoaderSymbolPatcher* toDelete = *patcher;
1169 			*patcher = (*patcher)->next;
1170 			delete toDelete;
1171 			return;
1172 		}
1173 		patcher = &(*patcher)->next;
1174 	}
1175 }
1176 
1177 
1178 runtime_loader_add_on_export gRuntimeLoaderAddOnExport = {
1179 	register_defined_symbol_patcher,
1180 	unregister_defined_symbol_patcher,
1181 	register_undefined_symbol_patcher,
1182 	unregister_undefined_symbol_patcher
1183 };
1184 
1185 
1186 static struct Elf32_Sym *
1187 find_symbol(image_t *image, const char *name, int32 type)
1188 {
1189 	uint32 hash, i;
1190 
1191 	// ToDo: "type" is currently ignored!
1192 	(void)type;
1193 
1194 	if (image->dynamic_ptr == 0)
1195 		return NULL;
1196 
1197 	hash = elf_hash((uint8 *)name) % HASHTABSIZE(image);
1198 
1199 	for (i = HASHBUCKETS(image)[hash]; i != STN_UNDEF; i = HASHCHAINS(image)[i]) {
1200 		struct Elf32_Sym *symbol = &image->syms[i];
1201 
1202 		if (symbol->st_shndx != SHN_UNDEF
1203 			&& ((ELF32_ST_BIND(symbol->st_info)== STB_GLOBAL)
1204 				|| (ELF32_ST_BIND(symbol->st_info) == STB_WEAK))
1205 			&& !strcmp(SYMNAME(image, symbol), name)) {
1206 			// check if the type matches
1207 			if ((type == B_SYMBOL_TYPE_TEXT && ELF32_ST_TYPE(symbol->st_info) != STT_FUNC)
1208 				|| (type == B_SYMBOL_TYPE_DATA && ELF32_ST_TYPE(symbol->st_info) != STT_OBJECT))
1209 				continue;
1210 
1211 			return symbol;
1212 		}
1213 	}
1214 
1215 	return NULL;
1216 }
1217 
1218 
1219 static status_t
1220 find_symbol(image_t* image, char const* symbolName, int32 symbolType,
1221 	void **_location)
1222 {
1223 	// get the symbol in the image
1224 	struct Elf32_Sym* symbol = find_symbol(image, symbolName, symbolType);
1225 	if (symbol == NULL)
1226 		return B_ENTRY_NOT_FOUND;
1227 
1228 	void* location = (void*)(symbol->st_value + image->regions[0].delta);
1229 	patch_defined_symbol(image, symbolName, &location, &symbolType);
1230 
1231 	if (_location != NULL)
1232 		*_location = location;
1233 
1234 	return B_OK;
1235 }
1236 
1237 
1238 static status_t
1239 find_symbol_breadth_first(image_t* image, const char* name, int32 type,
1240 	image_t** _foundInImage, void** _location)
1241 {
1242 	image_t* queue[sLoadedImageCount];
1243 	uint32 count = 0;
1244 	uint32 index = 0;
1245 	queue[count++] = image;
1246 	image->flags |= RFLAG_VISITED;
1247 
1248 	bool found = false;
1249 	while (index < count) {
1250 		// pop next image
1251 		image = queue[index++];
1252 
1253 		if (find_symbol(image, name, type, _location) == B_OK) {
1254 			found = true;
1255 			break;
1256 		}
1257 
1258 		// push needed images
1259 		for (uint32 i = 0; i < image->num_needed; i++) {
1260 			image_t* needed = image->needed[i];
1261 			if ((needed->flags & RFLAG_VISITED) == 0) {
1262 				queue[count++] = needed;
1263 				needed->flags |= RFLAG_VISITED;
1264 			}
1265 		}
1266 	}
1267 
1268 	// clear visited flags
1269 	for (uint32 i = 0; i < count; i++)
1270 		queue[i]->flags &= ~RFLAG_VISITED;
1271 
1272 	return found ? B_OK : B_ENTRY_NOT_FOUND;
1273 }
1274 
1275 
1276 static struct Elf32_Sym*
1277 find_undefined_symbol_beos(image_t* rootImage, image_t* image, const char* name,
1278 	image_t** foundInImage)
1279 {
1280 	// BeOS style symbol resolution: It is sufficient to check the direct
1281 	// dependencies. The linker would have complained, if the symbol wasn't
1282 	// there.
1283 	for (uint32 i = 0; i < image->num_needed; i++) {
1284 		if (image->needed[i]->dynamic_ptr) {
1285 			struct Elf32_Sym *symbol = find_symbol(image->needed[i], name,
1286 				B_SYMBOL_TYPE_ANY);
1287 			if (symbol) {
1288 				*foundInImage = image->needed[i];
1289 				return symbol;
1290 			}
1291 		}
1292 	}
1293 
1294 	return NULL;
1295 }
1296 
1297 
1298 static struct Elf32_Sym*
1299 find_undefined_symbol_global(image_t* rootImage, image_t* image,
1300 	const char* name, image_t** foundInImage)
1301 {
1302 	// Global load order symbol resolution: All loaded images are searched for
1303 	// the symbol in the order they have been loaded. We skip add-on images and
1304 	// RTLD_LOCAL images though.
1305 	image_t* otherImage = sLoadedImages.head;
1306 	while (otherImage != NULL) {
1307 		if (otherImage == rootImage
1308 			|| otherImage->type != B_ADD_ON_IMAGE
1309 				&& (otherImage->flags
1310 					& (RTLD_GLOBAL | RFLAG_USE_FOR_RESOLVING)) != 0) {
1311 			struct Elf32_Sym *symbol = find_symbol(otherImage, name,
1312 				B_SYMBOL_TYPE_ANY);
1313 			if (symbol) {
1314 				*foundInImage = otherImage;
1315 				return symbol;
1316 			}
1317 		}
1318 		otherImage = otherImage->next;
1319 	}
1320 
1321 	return NULL;
1322 }
1323 
1324 
1325 static struct Elf32_Sym*
1326 find_undefined_symbol_add_on(image_t* rootImage, image_t* image,
1327 	const char* name, image_t** foundInImage)
1328 {
1329 // TODO: How do we want to implement this one? Using global scope resolution
1330 // might be undesired as it is now, since libraries could refer to symbols in
1331 // the add-on, which would result in add-on symbols implicitely becoming used
1332 // outside of the add-on. So the options would be to use the global scope but
1333 // skip the add-on, or to do breadth-first resolution in the add-on dependency
1334 // scope, also skipping the add-on itself. BeOS style resolution is safe, too,
1335 // but we miss out features like undefined symbols and preloading.
1336 	return find_undefined_symbol_beos(rootImage, image, name, foundInImage);
1337 }
1338 
1339 
1340 /*!	This function is called when we run BeOS images on Haiku.
1341 	It allows us to redirect functions to ensure compatibility.
1342 */
1343 static const char*
1344 beos_compatibility_map_symbol(const char* symbolName)
1345 {
1346 	struct symbol_mapping {
1347 		const char* from;
1348 		const char* to;
1349 	};
1350 	static const struct symbol_mapping kMappings[] = {
1351 		// TODO: Improve this, and also use it for libnet.so compatibility!
1352 		// Allow an image to provide a function that will be invoked for every
1353 		// (transitively) depending image. The function can return a table to
1354 		// remap symbols (probably better address to address). All the tables
1355 		// for a single image would be combined into a hash table and an
1356 		// undefined symbol patcher using this hash table would be added.
1357 		{"fstat", "__be_fstat"},
1358 		{"lstat", "__be_lstat"},
1359 		{"stat", "__be_stat"},
1360 	};
1361 	const uint32 kMappingCount = sizeof(kMappings) / sizeof(kMappings[0]);
1362 
1363 	for (uint32 i = 0; i < kMappingCount; i++) {
1364 		if (!strcmp(symbolName, kMappings[i].from))
1365 			return kMappings[i].to;
1366 	}
1367 
1368 	return symbolName;
1369 }
1370 
1371 
1372 int
1373 resolve_symbol(image_t *rootImage, image_t *image, struct Elf32_Sym *sym,
1374 	addr_t *symAddress)
1375 {
1376 	switch (sym->st_shndx) {
1377 		case SHN_UNDEF:
1378 		{
1379 			struct Elf32_Sym *sharedSym;
1380 			image_t *sharedImage;
1381 			const char *symName;
1382 
1383 			// patch the symbol name
1384 			symName = SYMNAME(image, sym);
1385 			if (!image->gcc_version.haiku) {
1386 				// The image has been compiled with a BeOS compiler. This means
1387 				// we'll have to redirect some functions for compatibility.
1388 				symName = beos_compatibility_map_symbol(symName);
1389 			}
1390 
1391 			int32 type = B_SYMBOL_TYPE_ANY;
1392 			if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC)
1393 				type = B_SYMBOL_TYPE_TEXT;
1394 			else if (ELF32_ST_TYPE(sym->st_info) == STT_OBJECT)
1395 				type = B_SYMBOL_TYPE_DATA;
1396 
1397 			// it's undefined, must be outside this image, try the other images
1398 			sharedSym = rootImage->find_undefined_symbol(rootImage, image,
1399 				symName, &sharedImage);
1400 			void* location = NULL;
1401 
1402 			enum {
1403 				ERROR_NO_SYMBOL,
1404 				ERROR_WRONG_TYPE,
1405 				ERROR_NOT_EXPORTED,
1406 				ERROR_UNPATCHED
1407 			};
1408 			uint32 lookupError = ERROR_UNPATCHED;
1409 
1410 			if (sharedSym == NULL) {
1411 				// symbol not found at all
1412 				lookupError = ERROR_NO_SYMBOL;
1413 				sharedImage = NULL;
1414 			} else if (ELF32_ST_TYPE(sym->st_info) != STT_NOTYPE
1415 				&& ELF32_ST_TYPE(sym->st_info)
1416 					!= ELF32_ST_TYPE(sharedSym->st_info)) {
1417 				// symbol not of the requested type
1418 				lookupError = ERROR_WRONG_TYPE;
1419 				sharedImage = NULL;
1420 			} else if (ELF32_ST_BIND(sharedSym->st_info) != STB_GLOBAL
1421 				&& ELF32_ST_BIND(sharedSym->st_info) != STB_WEAK) {
1422 				// symbol not exported
1423 				lookupError = ERROR_NOT_EXPORTED;
1424 				sharedImage = NULL;
1425 			} else {
1426 				// symbol is fine, get its location
1427 				location = (void*)(sharedSym->st_value
1428 					+ sharedImage->regions[0].delta);
1429 			}
1430 
1431 			patch_undefined_symbol(rootImage, image, symName, &sharedImage,
1432 				&location, &type);
1433 
1434 			if (location == NULL) {
1435 				switch (lookupError) {
1436 					case ERROR_NO_SYMBOL:
1437 						FATAL("elf_resolve_symbol: could not resolve symbol "
1438 							"'%s'\n", symName);
1439 						break;
1440 					case ERROR_WRONG_TYPE:
1441 						FATAL("elf_resolve_symbol: found symbol '%s' in shared "
1442 							"image but wrong type\n", symName);
1443 						break;
1444 					case ERROR_NOT_EXPORTED:
1445 						FATAL("elf_resolve_symbol: found symbol '%s', but not "
1446 							"exported\n", symName);
1447 						break;
1448 					case ERROR_UNPATCHED:
1449 						FATAL("elf_resolve_symbol: found symbol '%s', but was "
1450 							"hidden by symbol patchers\n", symName);
1451 						break;
1452 				}
1453 				return B_MISSING_SYMBOL;
1454 			}
1455 
1456 			*symAddress = (addr_t)location;
1457 			return B_OK;
1458 		}
1459 
1460 		case SHN_ABS:
1461 			*symAddress = sym->st_value + image->regions[0].delta;
1462 			return B_NO_ERROR;
1463 
1464 		case SHN_COMMON:
1465 			// ToDo: finish this
1466 			FATAL("elf_resolve_symbol: COMMON symbol, finish me!\n");
1467 			return B_ERROR; //ERR_NOT_IMPLEMENTED_YET;
1468 
1469 		default:
1470 			// standard symbol
1471 			*symAddress = sym->st_value + image->regions[0].delta;
1472 			return B_NO_ERROR;
1473 	}
1474 }
1475 
1476 
1477 static void
1478 image_event(image_t* image, uint32 event)
1479 {
1480 	AddOnList::Iterator it = sAddOns.GetIterator();
1481 	while (RuntimeLoaderAddOn* addOn = it.Next()) {
1482 		void (*function)(image_t* image) = NULL;
1483 
1484 		switch (event) {
1485 			case IMAGE_EVENT_LOADED:
1486 				function = addOn->addOn->image_loaded;
1487 				break;
1488 			case IMAGE_EVENT_RELOCATED:
1489 				function = addOn->addOn->image_relocated;
1490 				break;
1491 			case IMAGE_EVENT_INITIALIZED:
1492 				function = addOn->addOn->image_initialized;
1493 				break;
1494 			case IMAGE_EVENT_UNINITIALIZING:
1495 				function = addOn->addOn->image_uninitializing;
1496 				break;
1497 			case IMAGE_EVENT_UNLOADING:
1498 				function = addOn->addOn->image_unloading;
1499 				break;
1500 		}
1501 
1502 		if (function != NULL)
1503 			function(image);
1504 	}
1505 }
1506 
1507 
1508 static void
1509 register_image(image_t *image, int fd, const char *path)
1510 {
1511 	struct stat stat;
1512 	image_info info;
1513 
1514 	// ToDo: set these correctly
1515 	info.id = 0;
1516 	info.type = image->type;
1517 	info.sequence = 0;
1518 	info.init_order = 0;
1519 	info.init_routine = (void (*)())image->init_routine;
1520 	info.term_routine = (void (*)())image->term_routine;
1521 
1522 	if (_kern_read_stat(fd, NULL, false, &stat, sizeof(struct stat)) == B_OK) {
1523 		info.device = stat.st_dev;
1524 		info.node = stat.st_ino;
1525 	} else {
1526 		info.device = -1;
1527 		info.node = -1;
1528 	}
1529 
1530 	strlcpy(info.name, path, sizeof(info.name));
1531 	info.text = (void *)image->regions[0].vmstart;
1532 	info.text_size = image->regions[0].vmsize;
1533 	info.data = (void *)image->regions[1].vmstart;
1534 	info.data_size = image->regions[1].vmsize;
1535 	image->id = _kern_register_image(&info, sizeof(image_info));
1536 }
1537 
1538 
1539 static status_t
1540 relocate_image(image_t *rootImage, image_t *image)
1541 {
1542 	status_t status = arch_relocate_image(rootImage, image);
1543 	if (status < B_OK) {
1544 		FATAL("troubles relocating: 0x%lx (image: %s, %s)\n", status,
1545 			image->path, image->name);
1546 		return status;
1547 	}
1548 
1549 	_kern_image_relocated(image->id);
1550 	image_event(image, IMAGE_EVENT_RELOCATED);
1551 	return B_OK;
1552 }
1553 
1554 
1555 static status_t
1556 load_container(char const *name, image_type type, const char *rpath,
1557 	image_t **_image)
1558 {
1559 	int32 pheaderSize, sheaderSize;
1560 	char path[PATH_MAX];
1561 	ssize_t length;
1562 	char ph_buff[4096];
1563 	int32 numRegions;
1564 	image_t *found;
1565 	image_t *image;
1566 	status_t status;
1567 	int fd;
1568 
1569 	struct Elf32_Ehdr eheader;
1570 
1571 	// Have we already loaded that image? Don't check for add-ons -- we always
1572 	// reload them.
1573 	if (type != B_ADD_ON_IMAGE) {
1574 		found = find_image(name, APP_OR_LIBRARY_TYPE);
1575 
1576 		if (found == NULL && type != B_APP_IMAGE) {
1577 			// Special case for add-ons that link against the application
1578 			// executable, with the executable not having a soname set.
1579 			if (const char* lastSlash = strrchr(name, '/')) {
1580 				image_t* programImage = get_program_image();
1581 				if (strcmp(programImage->name, lastSlash + 1) == 0)
1582 					found = programImage;
1583 			}
1584 		}
1585 
1586 		if (found) {
1587 			atomic_add(&found->ref_count, 1);
1588 			*_image = found;
1589 			KTRACE("rld: load_container(\"%s\", type: %d, rpath: \"%s\") "
1590 				"already loaded", name, type, rpath);
1591 			return B_OK;
1592 		}
1593 	}
1594 
1595 	KTRACE("rld: load_container(\"%s\", type: %d, rpath: \"%s\")", name, type,
1596 		rpath);
1597 
1598 	strlcpy(path, name, sizeof(path));
1599 
1600 	// find and open the file
1601 	fd = open_executable(path, type, rpath, get_program_path(),
1602 		sSearchPathSubDir);
1603 	if (fd < 0) {
1604 		FATAL("cannot open file %s\n", name);
1605 		KTRACE("rld: load_container(\"%s\"): failed to open file", name);
1606 		return fd;
1607 	}
1608 
1609 	// normalize the image path
1610 	status = _kern_normalize_path(path, true, path);
1611 	if (status != B_OK)
1612 		goto err1;
1613 
1614 	// Test again if this image has been registered already - this time,
1615 	// we can check the full path, not just its name as noted.
1616 	// You could end up loading an image twice with symbolic links, else.
1617 	if (type != B_ADD_ON_IMAGE) {
1618 		found = find_image(path, APP_OR_LIBRARY_TYPE);
1619 		if (found) {
1620 			atomic_add(&found->ref_count, 1);
1621 			*_image = found;
1622 			_kern_close(fd);
1623 			KTRACE("rld: load_container(\"%s\"): already loaded after all",
1624 				name);
1625 			return B_OK;
1626 		}
1627 	}
1628 
1629 	length = _kern_read(fd, 0, &eheader, sizeof(eheader));
1630 	if (length != sizeof(eheader)) {
1631 		status = B_NOT_AN_EXECUTABLE;
1632 		FATAL("troubles reading ELF header\n");
1633 		goto err1;
1634 	}
1635 
1636 	status = parse_elf_header(&eheader, &pheaderSize, &sheaderSize);
1637 	if (status < B_OK) {
1638 		FATAL("incorrect ELF header\n");
1639 		goto err1;
1640 	}
1641 
1642 	// ToDo: what to do about this restriction??
1643 	if (pheaderSize > (int)sizeof(ph_buff)) {
1644 		FATAL("Cannot handle program headers bigger than %lu\n", sizeof(ph_buff));
1645 		status = B_UNSUPPORTED;
1646 		goto err1;
1647 	}
1648 
1649 	length = _kern_read(fd, eheader.e_phoff, ph_buff, pheaderSize);
1650 	if (length != pheaderSize) {
1651 		FATAL("Could not read program headers: %s\n", strerror(length));
1652 		status = B_BAD_DATA;
1653 		goto err1;
1654 	}
1655 
1656 	numRegions = count_regions(ph_buff, eheader.e_phnum, eheader.e_phentsize);
1657 	if (numRegions <= 0) {
1658 		FATAL("Troubles parsing Program headers, numRegions = %ld\n", numRegions);
1659 		status = B_BAD_DATA;
1660 		goto err1;
1661 	}
1662 
1663 	image = create_image(name, path, numRegions);
1664 	if (image == NULL) {
1665 		FATAL("Failed to allocate image_t object\n");
1666 		status = B_NO_MEMORY;
1667 		goto err1;
1668 	}
1669 
1670 	status = parse_program_headers(image, ph_buff, eheader.e_phnum, eheader.e_phentsize);
1671 	if (status < B_OK)
1672 		goto err2;
1673 
1674 	if (!assert_dynamic_loadable(image)) {
1675 		FATAL("Dynamic segment must be loadable (implementation restriction)\n");
1676 		status = B_UNSUPPORTED;
1677 		goto err2;
1678 	}
1679 
1680 	if (analyze_object_gcc_version(fd, image, eheader, sheaderSize, ph_buff,
1681 			sizeof(ph_buff))) {
1682 		// If this is the executable image, we init the search path
1683 		// subdir, if the compiler version doesn't match ours.
1684 		if (type == B_APP_IMAGE) {
1685 			#if __GNUC__ == 2
1686 				if (image->gcc_version.major > 2)
1687 					sSearchPathSubDir = "gcc4";
1688 			#elif __GNUC__ == 4
1689 				if (image->gcc_version.major == 2)
1690 					sSearchPathSubDir = "gcc2";
1691 			#endif
1692 		}
1693 	} else {
1694 		FATAL("Failed to get gcc version for %s\n", path);
1695 		// not really fatal, actually
1696 	}
1697 
1698 	// init gcc version dependent image flags
1699 	// symbol resolution strategy (fallback is R5-style, if version is
1700 	// unavailable)
1701 	if (image->gcc_version.major == 0
1702 		|| image->gcc_version.major == 2 && image->gcc_version.middle < 95) {
1703 		image->find_undefined_symbol = find_undefined_symbol_beos;
1704 	}
1705 
1706 	status = map_image(fd, path, image, type == B_APP_IMAGE);
1707 	if (status < B_OK) {
1708 		FATAL("Could not map image: %s\n", strerror(status));
1709 		status = B_ERROR;
1710 		goto err2;
1711 	}
1712 
1713 	if (!parse_dynamic_segment(image)) {
1714 		FATAL("Troubles handling dynamic section\n");
1715 		status = B_BAD_DATA;
1716 		goto err3;
1717 	}
1718 
1719 	if (eheader.e_entry != 0)
1720 		image->entry_point = eheader.e_entry + image->regions[0].delta;
1721 
1722 	image->type = type;
1723 	register_image(image, fd, path);
1724 	image_event(image, IMAGE_EVENT_LOADED);
1725 
1726 	_kern_close(fd);
1727 
1728 	enqueue_image(&sLoadedImages, image);
1729 	sLoadedImageCount++;
1730 
1731 	*_image = image;
1732 
1733 	KTRACE("rld: load_container(\"%s\"): done: id: %ld (gcc: %d.%d.%d)", name,
1734 		image->id, image->gcc_version.major, image->gcc_version.middle,
1735 		image->gcc_version.minor);
1736 
1737 	return B_OK;
1738 
1739 err3:
1740 	unmap_image(image);
1741 err2:
1742 	delete_image_struct(image);
1743 err1:
1744 	_kern_close(fd);
1745 
1746 	KTRACE("rld: load_container(\"%s\"): failed: %s", name,
1747 		strerror(status));
1748 
1749 	return status;
1750 }
1751 
1752 
1753 static const char *
1754 find_dt_rpath(image_t *image)
1755 {
1756 	int i;
1757 	struct Elf32_Dyn *d = (struct Elf32_Dyn *)image->dynamic_ptr;
1758 
1759 	for (i = 0; d[i].d_tag != DT_NULL; i++) {
1760 		if (d[i].d_tag == DT_RPATH)
1761 			return STRING(image, d[i].d_un.d_val);
1762 	}
1763 
1764 	return NULL;
1765 }
1766 
1767 
1768 static status_t
1769 load_immediate_dependencies(image_t *image)
1770 {
1771 	struct Elf32_Dyn *d = (struct Elf32_Dyn *)image->dynamic_ptr;
1772 	bool reportErrors = report_errors();
1773 	status_t status = B_OK;
1774 	uint32 i, j;
1775 	const char *rpath;
1776 
1777 	if (!d || (image->flags & RFLAG_DEPENDENCIES_LOADED))
1778 		return B_OK;
1779 
1780 	image->flags |= RFLAG_DEPENDENCIES_LOADED;
1781 
1782 	if (image->num_needed == 0)
1783 		return B_OK;
1784 
1785 	KTRACE("rld: load_dependencies(\"%s\", id: %ld)", image->name,
1786 		image->id);
1787 
1788 	image->needed = (image_t**)malloc(image->num_needed * sizeof(image_t *));
1789 	if (image->needed == NULL) {
1790 		FATAL("failed to allocate needed struct\n");
1791 		KTRACE("rld: load_dependencies(\"%s\", id: %ld) failed: no memory",
1792 			image->name, image->id);
1793 		return B_NO_MEMORY;
1794 	}
1795 
1796 	memset(image->needed, 0, image->num_needed * sizeof(image_t *));
1797 	rpath = find_dt_rpath(image);
1798 
1799 	for (i = 0, j = 0; d[i].d_tag != DT_NULL; i++) {
1800 		switch (d[i].d_tag) {
1801 			case DT_NEEDED:
1802 			{
1803 				int32 neededOffset = d[i].d_un.d_val;
1804 				const char *name = STRING(image, neededOffset);
1805 
1806 				status_t loadStatus = load_container(name, B_LIBRARY_IMAGE,
1807 					rpath, &image->needed[j]);
1808 				if (loadStatus < B_OK) {
1809 					status = loadStatus;
1810 					// correct error code in case the file could not been found
1811 					if (status == B_ENTRY_NOT_FOUND) {
1812 						status = B_MISSING_LIBRARY;
1813 
1814 						if (reportErrors)
1815 							sErrorMessage.AddString("missing library", name);
1816 					}
1817 
1818 					// Collect all missing libraries in case we report back
1819 					if (!reportErrors) {
1820 						KTRACE("rld: load_dependencies(\"%s\", id: %ld) "
1821 							"failed: %s", image->name, image->id,
1822 							strerror(status));
1823 						return status;
1824 					}
1825 				}
1826 
1827 				j += 1;
1828 				break;
1829 			}
1830 
1831 			default:
1832 				// ignore any other tag
1833 				continue;
1834 		}
1835 	}
1836 
1837 	if (status < B_OK) {
1838 		KTRACE("rld: load_dependencies(\"%s\", id: %ld) "
1839 			"failed: %s", image->name, image->id,
1840 			strerror(status));
1841 		return status;
1842 	}
1843 
1844 	if (j != image->num_needed) {
1845 		FATAL("Internal error at load_dependencies()");
1846 		KTRACE("rld: load_dependencies(\"%s\", id: %ld) "
1847 			"failed: internal error", image->name, image->id);
1848 		return B_ERROR;
1849 	}
1850 
1851 	KTRACE("rld: load_dependencies(\"%s\", id: %ld) done", image->name,
1852 		image->id);
1853 
1854 	return B_OK;
1855 }
1856 
1857 
1858 static status_t
1859 load_dependencies(image_t* image)
1860 {
1861 	for (image_t* otherImage = image; otherImage != NULL;
1862 			otherImage = otherImage->next) {
1863 		status_t status = load_immediate_dependencies(otherImage);
1864 		if (status != B_OK)
1865 			return status;
1866 	}
1867 
1868 	return B_OK;
1869 }
1870 
1871 
1872 static uint32
1873 topological_sort(image_t *image, uint32 slot, image_t **initList,
1874 	uint32 sortFlag)
1875 {
1876 	uint32 i;
1877 
1878 	if (image->flags & sortFlag)
1879 		return slot;
1880 
1881 	image->flags |= sortFlag; /* make sure we don't visit this one */
1882 	for (i = 0; i < image->num_needed; i++)
1883 		slot = topological_sort(image->needed[i], slot, initList, sortFlag);
1884 
1885 	initList[slot] = image;
1886 	return slot + 1;
1887 }
1888 
1889 
1890 static ssize_t
1891 get_sorted_image_list(image_t *image, image_t ***_list, uint32 sortFlag)
1892 {
1893 	image_t **list;
1894 
1895 	list = (image_t**)malloc(sLoadedImageCount * sizeof(image_t *));
1896 	if (list == NULL) {
1897 		FATAL("memory shortage in get_sorted_image_list()");
1898 		*_list = NULL;
1899 		return B_NO_MEMORY;
1900 	}
1901 
1902 	memset(list, 0, sLoadedImageCount * sizeof(image_t *));
1903 
1904 	*_list = list;
1905 	return topological_sort(image, 0, list, sortFlag);
1906 }
1907 
1908 
1909 static status_t
1910 relocate_dependencies(image_t *image)
1911 {
1912 	// get the images that still have to be relocated
1913 	image_t **list;
1914 	ssize_t count = get_sorted_image_list(image, &list, RFLAG_RELOCATED);
1915 	if (count < B_OK)
1916 		return count;
1917 
1918 	// relocate
1919 	for (ssize_t i = 0; i < count; i++) {
1920 		status_t status = relocate_image(image, list[i]);
1921 		if (status < B_OK) {
1922 			free(list);
1923 			return status;
1924 		}
1925 	}
1926 
1927 	free(list);
1928 	return B_OK;
1929 }
1930 
1931 
1932 static void
1933 init_dependencies(image_t *image, bool initHead)
1934 {
1935 	image_t **initList;
1936 	ssize_t count, i;
1937 
1938 	count = get_sorted_image_list(image, &initList, RFLAG_INITIALIZED);
1939 	if (count <= 0)
1940 		return;
1941 
1942 	if (!initHead) {
1943 		// this removes the "calling" image
1944 		image->flags &= ~RFLAG_INITIALIZED;
1945 		initList[--count] = NULL;
1946 	}
1947 
1948 	TRACE(("%ld: init dependencies\n", find_thread(NULL)));
1949 	for (i = 0; i < count; i++) {
1950 		image = initList[i];
1951 
1952 		TRACE(("%ld:  init: %s\n", find_thread(NULL), image->name));
1953 
1954 		if (image->init_routine != 0)
1955 			((init_term_function)image->init_routine)(image->id);
1956 
1957 		image_event(image, IMAGE_EVENT_INITIALIZED);
1958 	}
1959 	TRACE(("%ld:  init done.\n", find_thread(NULL)));
1960 
1961 	free(initList);
1962 }
1963 
1964 
1965 static void
1966 put_image(image_t *image)
1967 {
1968 	// If all references to the image are gone, add it to the disposable list
1969 	// and remove all dependencies
1970 
1971 	if (atomic_add(&image->ref_count, -1) == 1) {
1972 		size_t i;
1973 
1974 		dequeue_image(&sLoadedImages, image);
1975 		enqueue_image(&sDisposableImages, image);
1976 		sLoadedImageCount--;
1977 
1978 		for (i = 0; i < image->num_needed; i++) {
1979 			put_image(image->needed[i]);
1980 		}
1981 	}
1982 }
1983 
1984 
1985 void
1986 inject_runtime_loader_api(image_t* rootImage)
1987 {
1988 	// We patch any exported __gRuntimeLoader symbols to point to our private
1989 	// API.
1990 	image_t* image;
1991 	void* _export;
1992 	if (find_symbol_breadth_first(rootImage, "__gRuntimeLoader",
1993 			B_SYMBOL_TYPE_DATA, &image, &_export) == B_OK) {
1994 		*(void**)_export = &gRuntimeLoader;
1995 	}
1996 }
1997 
1998 
1999 static status_t
2000 add_preloaded_image(image_t* image)
2001 {
2002 	// We realloc() everytime -- not particularly efficient, but good enough for
2003 	// small number of preloaded images.
2004 	image_t** newArray = (image_t**)realloc(sPreloadedImages,
2005 		sizeof(image_t*) * (sPreloadedImageCount + 1));
2006 	if (newArray == NULL)
2007 		return B_NO_MEMORY;
2008 
2009 	sPreloadedImages = newArray;
2010 	newArray[sPreloadedImageCount++] = image;
2011 
2012 	return B_OK;
2013 }
2014 
2015 
2016 image_id
2017 preload_image(char const* path)
2018 {
2019 	if (path == NULL)
2020 		return B_BAD_VALUE;
2021 
2022 	KTRACE("rld: preload_image(\"%s\")", path);
2023 
2024 	image_t *image = NULL;
2025 	status_t status = load_container(path, B_ADD_ON_IMAGE, NULL, &image);
2026 	if (status < B_OK) {
2027 		rld_unlock();
2028 		KTRACE("rld: preload_image(\"%s\") failed to load container: %s", path,
2029 			strerror(status));
2030 		return status;
2031 	}
2032 
2033 	if (image->find_undefined_symbol == NULL)
2034 		image->find_undefined_symbol = find_undefined_symbol_global;
2035 
2036 	status = load_dependencies(image);
2037 	if (status < B_OK)
2038 		goto err;
2039 
2040 	set_image_flags_recursively(image, RTLD_GLOBAL);
2041 
2042 	status = relocate_dependencies(image);
2043 	if (status < B_OK)
2044 		goto err;
2045 
2046 	status = add_preloaded_image(image);
2047 	if (status < B_OK)
2048 		goto err;
2049 
2050 	inject_runtime_loader_api(image);
2051 
2052 	remap_images();
2053 	init_dependencies(image, true);
2054 
2055 	// if the image contains an add-on, register it
2056 	runtime_loader_add_on* addOnStruct;
2057 	if (find_symbol(image, "__gRuntimeLoaderAddOn", B_SYMBOL_TYPE_DATA,
2058 			(void**)&addOnStruct) == B_OK) {
2059 		RuntimeLoaderAddOn* addOn = new(mynothrow) RuntimeLoaderAddOn(image,
2060 			addOnStruct);
2061 		if (addOn != NULL) {
2062 			sAddOns.Add(addOn);
2063 			addOnStruct->init(&gRuntimeLoader, &gRuntimeLoaderAddOnExport);
2064 		}
2065 	}
2066 
2067 	KTRACE("rld: preload_image(\"%s\") done: id: %ld", path, image->id);
2068 
2069 	return image->id;
2070 
2071 err:
2072 	KTRACE("rld: preload_image(\"%s\") failed: %s", path, strerror(status));
2073 
2074 	dequeue_image(&sLoadedImages, image);
2075 	sLoadedImageCount--;
2076 	delete_image(image);
2077 	return status;
2078 }
2079 
2080 
2081 static void
2082 preload_images()
2083 {
2084 	const char* imagePaths = getenv("LD_PRELOAD");
2085 	if (imagePaths == NULL)
2086 		return;
2087 
2088 	while (*imagePaths != '\0') {
2089 		// find begin of image path
2090 		while (*imagePaths != '\0' && isspace(*imagePaths))
2091 			imagePaths++;
2092 
2093 		if (*imagePaths == '\0')
2094 			break;
2095 
2096 		// find end of image path
2097 		const char* imagePath = imagePaths;
2098 		while (*imagePaths != '\0' && !isspace(*imagePaths))
2099 			imagePaths++;
2100 
2101 		// extract the path
2102 		char path[B_PATH_NAME_LENGTH];
2103 		size_t pathLen = imagePaths - imagePath;
2104 		if (pathLen > sizeof(path) - 1)
2105 			continue;
2106 		memcpy(path, imagePath, pathLen);
2107 		path[pathLen] = '\0';
2108 
2109 		// load the image
2110 		preload_image(path);
2111 	}
2112 }
2113 
2114 
2115 //	#pragma mark - libroot.so exported functions
2116 
2117 
2118 image_id
2119 load_program(char const *path, void **_entry)
2120 {
2121 	status_t status;
2122 	image_t *image;
2123 
2124 	KTRACE("rld: load_program(\"%s\")", path);
2125 
2126 	rld_lock();
2127 		// for now, just do stupid simple global locking
2128 
2129 	preload_images();
2130 
2131 	TRACE(("rld: load %s\n", path));
2132 
2133 	status = load_container(path, B_APP_IMAGE, NULL, &sProgramImage);
2134 	if (status < B_OK)
2135 		goto err;
2136 
2137 	if (sProgramImage->find_undefined_symbol == NULL)
2138 		sProgramImage->find_undefined_symbol = find_undefined_symbol_global;
2139 
2140 	status = load_dependencies(sProgramImage);
2141 	if (status < B_OK)
2142 		goto err;
2143 
2144 	// Set RTLD_GLOBAL on all libraries, but clear it on the program image.
2145 	// This results in the desired symbol resolution for dlopen()ed libraries.
2146 	set_image_flags_recursively(sProgramImage, RTLD_GLOBAL);
2147 	sProgramImage->flags &= ~RTLD_GLOBAL;
2148 
2149 	status = relocate_dependencies(sProgramImage);
2150 	if (status < B_OK)
2151 		goto err;
2152 
2153 	inject_runtime_loader_api(sProgramImage);
2154 
2155 	remap_images();
2156 	init_dependencies(sProgramImage, true);
2157 
2158 	// Since the images are initialized now, we no longer should use our
2159 	// getenv(), but use the one from libroot.so
2160 	find_symbol_breadth_first(sProgramImage, "getenv", B_SYMBOL_TYPE_TEXT,
2161 		&image, (void**)&gGetEnv);
2162 
2163 	if (sProgramImage->entry_point == 0) {
2164 		status = B_NOT_AN_EXECUTABLE;
2165 		goto err;
2166 	}
2167 
2168 	*_entry = (void *)(sProgramImage->entry_point);
2169 
2170 	rld_unlock();
2171 
2172 	sProgramLoaded = true;
2173 
2174 	KTRACE("rld: load_program(\"%s\") done: entry: %p, id: %ld", path,
2175 		*_entry, sProgramImage->id);
2176 
2177 	return sProgramImage->id;
2178 
2179 err:
2180 	KTRACE("rld: load_program(\"%s\") failed: %s", path, strerror(status));
2181 
2182 	delete_image(sProgramImage);
2183 
2184 	if (report_errors()) {
2185 		// send error message
2186 		sErrorMessage.AddInt32("error", status);
2187 		sErrorMessage.SetDeliveryInfo(gProgramArgs->error_token,
2188 			-1, 0, find_thread(NULL));
2189 
2190 		_kern_write_port_etc(gProgramArgs->error_port, 'KMSG',
2191 			sErrorMessage.Buffer(), sErrorMessage.ContentSize(), 0, 0);
2192 	}
2193 	_kern_loading_app_failed(status);
2194 	rld_unlock();
2195 
2196 	return status;
2197 }
2198 
2199 
2200 image_id
2201 load_library(char const *path, uint32 flags, bool addOn, void** _handle)
2202 {
2203 	image_t *image = NULL;
2204 	image_type type = (addOn ? B_ADD_ON_IMAGE : B_LIBRARY_IMAGE);
2205 	status_t status;
2206 
2207 	if (path == NULL && addOn)
2208 		return B_BAD_VALUE;
2209 
2210 	KTRACE("rld: load_library(\"%s\", 0x%lx, %d)", path, flags, addOn);
2211 
2212 	rld_lock();
2213 		// for now, just do stupid simple global locking
2214 
2215 	// have we already loaded this library?
2216 	// Checking it at this stage saves loading its dependencies again
2217 	if (!addOn) {
2218 		// a NULL path is fine -- it means the global scope shall be opened
2219 		if (path == NULL) {
2220 			*_handle = RLD_GLOBAL_SCOPE;
2221 			rld_unlock();
2222 			return 0;
2223 		}
2224 
2225 		image = find_image(path, APP_OR_LIBRARY_TYPE);
2226 		if (image != NULL && (flags & RTLD_GLOBAL) != 0)
2227 			set_image_flags_recursively(image, RTLD_GLOBAL);
2228 
2229 		if (image) {
2230 			atomic_add(&image->ref_count, 1);
2231 			rld_unlock();
2232 			KTRACE("rld: load_library(\"%s\"): already loaded: %ld", path,
2233 				image->id);
2234 			*_handle = image;
2235 			return image->id;
2236 		}
2237 	}
2238 
2239 	status = load_container(path, type, NULL, &image);
2240 	if (status < B_OK) {
2241 		rld_unlock();
2242 		KTRACE("rld: load_library(\"%s\") failed to load container: %s", path,
2243 			strerror(status));
2244 		return status;
2245 	}
2246 
2247 	if (image->find_undefined_symbol == NULL) {
2248 		if (addOn)
2249 			image->find_undefined_symbol = find_undefined_symbol_add_on;
2250 		else
2251 			image->find_undefined_symbol = find_undefined_symbol_global;
2252 	}
2253 
2254 	status = load_dependencies(image);
2255 	if (status < B_OK)
2256 		goto err;
2257 
2258 	// If specified, set the RTLD_GLOBAL flag recursively on this image and all
2259 	// dependencies. If not specified, we temporarily set
2260 	// RFLAG_USE_FOR_RESOLVING so that the dependencies will correctly be used
2261 	// for undefined symbol resolution.
2262 	if ((flags & RTLD_GLOBAL) != 0)
2263 		set_image_flags_recursively(image, RTLD_GLOBAL);
2264 	else
2265 		set_image_flags_recursively(image, RFLAG_USE_FOR_RESOLVING);
2266 
2267 	status = relocate_dependencies(image);
2268 	if (status < B_OK)
2269 		goto err;
2270 
2271 	if ((flags & RTLD_GLOBAL) == 0)
2272 		clear_image_flags_recursively(image, RFLAG_USE_FOR_RESOLVING);
2273 
2274 	remap_images();
2275 	init_dependencies(image, true);
2276 
2277 	rld_unlock();
2278 
2279 	KTRACE("rld: load_library(\"%s\") done: id: %ld", path, image->id);
2280 
2281 	*_handle = image;
2282 	return image->id;
2283 
2284 err:
2285 	KTRACE("rld: load_library(\"%s\") failed: %s", path, strerror(status));
2286 
2287 	dequeue_image(&sLoadedImages, image);
2288 	sLoadedImageCount--;
2289 	delete_image(image);
2290 	rld_unlock();
2291 	return status;
2292 }
2293 
2294 
2295 status_t
2296 unload_library(void* handle, image_id imageID, bool addOn)
2297 {
2298 	image_t *image;
2299 	image_type type = addOn ? B_ADD_ON_IMAGE : B_LIBRARY_IMAGE;
2300 
2301 	if (handle == NULL && imageID < 0)
2302 		return B_BAD_IMAGE_ID;
2303 
2304 	if (handle == RLD_GLOBAL_SCOPE)
2305 		return B_OK;
2306 
2307 	rld_lock();
2308 		// for now, just do stupid simple global locking
2309 
2310 	if (sInvalidImageIDs) {
2311 		// After fork, we lazily rebuild the image IDs of all loaded images
2312 		update_image_ids();
2313 	}
2314 
2315 	// we only check images that have been already initialized
2316 
2317 	status_t status = B_BAD_IMAGE_ID;
2318 
2319 	if (handle != NULL) {
2320 		image = (image_t*)handle;
2321 		put_image(image);
2322 		status = B_OK;
2323 	} else {
2324 		for (image = sLoadedImages.head; image; image = image->next) {
2325 			if (image->id == imageID) {
2326 				// unload image
2327 				if (type == image->type) {
2328 					put_image(image);
2329 					status = B_OK;
2330 				} else
2331 					status = B_BAD_VALUE;
2332 				break;
2333 			}
2334 		}
2335 	}
2336 
2337 	if (status == B_OK) {
2338 		while ((image = sDisposableImages.head) != NULL) {
2339 			// call image fini here...
2340 			if (gRuntimeLoader.call_atexit_hooks_for_range) {
2341 				gRuntimeLoader.call_atexit_hooks_for_range(
2342 					image->regions[0].vmstart, image->regions[0].vmsize);
2343 			}
2344 
2345 			image_event(image, IMAGE_EVENT_UNINITIALIZING);
2346 
2347 			if (image->term_routine)
2348 				((init_term_function)image->term_routine)(image->id);
2349 
2350 			dequeue_image(&sDisposableImages, image);
2351 			unmap_image(image);
2352 
2353 			image_event(image, IMAGE_EVENT_UNLOADING);
2354 
2355 			delete_image(image);
2356 		}
2357 	}
2358 
2359 	rld_unlock();
2360 	return status;
2361 }
2362 
2363 
2364 status_t
2365 get_nth_symbol(image_id imageID, int32 num, char *nameBuffer,
2366 	int32 *_nameLength, int32 *_type, void **_location)
2367 {
2368 	int32 count = 0, j;
2369 	uint32 i;
2370 	image_t *image;
2371 
2372 	rld_lock();
2373 
2374 	// get the image from those who have been already initialized
2375 	image = find_loaded_image_by_id(imageID);
2376 	if (image == NULL) {
2377 		rld_unlock();
2378 		return B_BAD_IMAGE_ID;
2379 	}
2380 
2381 	// iterate through all the hash buckets until we've found the one
2382 	for (i = 0; i < HASHTABSIZE(image); i++) {
2383 		for (j = HASHBUCKETS(image)[i]; j != STN_UNDEF; j = HASHCHAINS(image)[j]) {
2384 			struct Elf32_Sym *symbol = &image->syms[j];
2385 
2386 			if (count == num) {
2387 				const char* symbolName = SYMNAME(image, symbol);
2388 				strlcpy(nameBuffer, symbolName, *_nameLength);
2389 				*_nameLength = strlen(symbolName);
2390 
2391 				void* location = (void*)(symbol->st_value
2392 					+ image->regions[0].delta);
2393 				int32 type;
2394 				if (ELF32_ST_TYPE(symbol->st_info) == STT_FUNC)
2395 					type = B_SYMBOL_TYPE_TEXT;
2396 				else if (ELF32_ST_TYPE(symbol->st_info) == STT_OBJECT)
2397 					type = B_SYMBOL_TYPE_DATA;
2398 				else
2399 					type = B_SYMBOL_TYPE_ANY;
2400 					// TODO: check with the return types of that BeOS function
2401 
2402 				patch_defined_symbol(image, symbolName, &location, &type);
2403 
2404 				if (_type != NULL)
2405 					*_type = type;
2406 				if (_location != NULL)
2407 					*_location = location;
2408 				goto out;
2409 			}
2410 			count++;
2411 		}
2412 	}
2413 out:
2414 	rld_unlock();
2415 
2416 	if (num != count)
2417 		return B_BAD_INDEX;
2418 
2419 	return B_OK;
2420 }
2421 
2422 
2423 status_t
2424 get_symbol(image_id imageID, char const *symbolName, int32 symbolType,
2425 	void **_location)
2426 {
2427 	status_t status = B_OK;
2428 	image_t *image;
2429 
2430 	if (imageID < B_OK)
2431 		return B_BAD_IMAGE_ID;
2432 	if (symbolName == NULL)
2433 		return B_BAD_VALUE;
2434 
2435 	rld_lock();
2436 		// for now, just do stupid simple global locking
2437 
2438 	// get the image from those who have been already initialized
2439 	image = find_loaded_image_by_id(imageID);
2440 	if (image != NULL)
2441 		status = find_symbol(image, symbolName, symbolType, _location);
2442 	else
2443 		status = B_BAD_IMAGE_ID;
2444 
2445 	rld_unlock();
2446 	return status;
2447 }
2448 
2449 
2450 status_t
2451 get_library_symbol(void* handle, void* caller, const char* symbolName,
2452 	void **_location)
2453 {
2454 	status_t status = B_ENTRY_NOT_FOUND;
2455 
2456 	if (symbolName == NULL)
2457 		return B_BAD_VALUE;
2458 
2459 	rld_lock();
2460 		// for now, just do stupid simple global locking
2461 
2462 	if (handle == RTLD_DEFAULT || handle == RLD_GLOBAL_SCOPE) {
2463 		// look in the default scope
2464 		image_t* image;
2465 		Elf32_Sym* symbol = find_undefined_symbol_global(sProgramImage,
2466 			sProgramImage, symbolName, &image);
2467 		if (symbol != NULL) {
2468 			*_location = (void*)(symbol->st_value + image->regions[0].delta);
2469 			int32 symbolType = ELF32_ST_TYPE(symbol->st_info) == STT_FUNC
2470 				? B_SYMBOL_TYPE_TEXT : B_SYMBOL_TYPE_DATA;
2471 			patch_defined_symbol(image, symbolName, _location, &symbolType);
2472 			status = B_OK;
2473 		}
2474 	} else if (handle == RTLD_NEXT) {
2475 		// Look in the default scope, but also in the dependencies of the
2476 		// calling image. Return the next after the caller symbol.
2477 
2478 		// First of all, find the caller symbol and its image.
2479 		Elf32_Sym* callerSymbol = NULL;
2480 		image_t* callerImage = sLoadedImages.head;
2481 		for (; callerImage != NULL; callerImage = callerImage->next) {
2482 			elf_region_t& text = callerImage->regions[0];
2483 			if ((addr_t)caller < text.vmstart
2484 				|| (addr_t)caller >= text.vmstart + text.vmsize) {
2485 				continue;
2486 			}
2487 
2488 			// found the image -- now find the symbol
2489 			for (uint32 i = 0; i < callerImage->symhash[1]; i++) {
2490 				Elf32_Sym& symbol = callerImage->syms[i];
2491 				if ((ELF32_ST_TYPE(symbol.st_info) != STT_FUNC)
2492 					|| symbol.st_value == 0) {
2493 					continue;
2494 				}
2495 
2496 				addr_t address = symbol.st_value
2497 					+ callerImage->regions[0].delta;
2498 				if ((addr_t)caller >= address
2499 					&& (addr_t)caller < address + symbol.st_size) {
2500 					callerSymbol = &symbol;
2501 					break;
2502 				}
2503 			}
2504 
2505 			break;
2506 		}
2507 
2508 		if (callerSymbol != NULL) {
2509 			// found the caller -- now search the global scope until we find
2510 			// the next symbol
2511 			set_image_flags_recursively(callerImage, RFLAG_USE_FOR_RESOLVING);
2512 
2513 			image_t* image = sLoadedImages.head;
2514 			for (; image != NULL; image = image->next) {
2515 				if (image != callerImage
2516 					&& (image->type == B_ADD_ON_IMAGE
2517 						|| (image->flags
2518 							& (RTLD_GLOBAL | RFLAG_USE_FOR_RESOLVING)) == 0)) {
2519 					continue;
2520 				}
2521 
2522 				struct Elf32_Sym *symbol = find_symbol(image, symbolName,
2523 					B_SYMBOL_TYPE_TEXT);
2524 				if (symbol == NULL)
2525 					continue;
2526 
2527 				if (callerSymbol == NULL) {
2528 					// already skipped the caller symbol -- so this is
2529 					// the one we're looking for
2530 					*_location = (void*)(symbol->st_value
2531 						+ image->regions[0].delta);
2532 					int32 symbolType = B_SYMBOL_TYPE_TEXT;
2533 					patch_defined_symbol(image, symbolName, _location,
2534 						&symbolType);
2535 					status = B_OK;
2536 					break;
2537 				}
2538 				if (symbol == callerSymbol) {
2539 					// found the caller symbol
2540 					callerSymbol = NULL;
2541 				}
2542 			}
2543 
2544 			clear_image_flags_recursively(callerImage, RFLAG_USE_FOR_RESOLVING);
2545 		}
2546 
2547 	} else {
2548 		// breadth-first search in the given image and its dependencies
2549 		image_t* inImage;
2550 		status = find_symbol_breadth_first((image_t*)handle, symbolName,
2551 			B_SYMBOL_TYPE_ANY, &inImage, _location);
2552 	}
2553 
2554 	rld_unlock();
2555 	return status;
2556 }
2557 
2558 
2559 status_t
2560 get_next_image_dependency(image_id id, uint32 *cookie, const char **_name)
2561 {
2562 	uint32 i, j, searchIndex = *cookie;
2563 	struct Elf32_Dyn *dynamicSection;
2564 	image_t *image;
2565 
2566 	if (_name == NULL)
2567 		return B_BAD_VALUE;
2568 
2569 	rld_lock();
2570 
2571 	image = find_loaded_image_by_id(id);
2572 	if (image == NULL) {
2573 		rld_unlock();
2574 		return B_BAD_IMAGE_ID;
2575 	}
2576 
2577 	dynamicSection = (struct Elf32_Dyn *)image->dynamic_ptr;
2578 	if (dynamicSection == NULL || image->num_needed <= searchIndex) {
2579 		rld_unlock();
2580 		return B_ENTRY_NOT_FOUND;
2581 	}
2582 
2583 	for (i = 0, j = 0; dynamicSection[i].d_tag != DT_NULL; i++) {
2584 		if (dynamicSection[i].d_tag != DT_NEEDED)
2585 			continue;
2586 
2587 		if (j++ == searchIndex) {
2588 			int32 neededOffset = dynamicSection[i].d_un.d_val;
2589 
2590 			*_name = STRING(image, neededOffset);
2591 			*cookie = searchIndex + 1;
2592 			rld_unlock();
2593 			return B_OK;
2594 		}
2595 	}
2596 
2597 	rld_unlock();
2598 	return B_ENTRY_NOT_FOUND;
2599 }
2600 
2601 
2602 //	#pragma mark - runtime_loader private exports
2603 
2604 
2605 /*! Read and verify the ELF header */
2606 status_t
2607 elf_verify_header(void *header, int32 length)
2608 {
2609 	int32 programSize, sectionSize;
2610 
2611 	if (length < (int32)sizeof(struct Elf32_Ehdr))
2612 		return B_NOT_AN_EXECUTABLE;
2613 
2614 	return parse_elf_header((struct Elf32_Ehdr *)header, &programSize,
2615 		&sectionSize);
2616 }
2617 
2618 
2619 void
2620 terminate_program(void)
2621 {
2622 	image_t **termList;
2623 	ssize_t count, i;
2624 
2625 	count = get_sorted_image_list(sProgramImage, &termList, RFLAG_TERMINATED);
2626 	if (count < B_OK)
2627 		return;
2628 
2629 	if (sInvalidImageIDs) {
2630 		// After fork, we lazily rebuild the image IDs of all loaded images
2631 		update_image_ids();
2632 	}
2633 
2634 	TRACE(("%ld: terminate dependencies\n", find_thread(NULL)));
2635 	for (i = count; i-- > 0;) {
2636 		image_t *image = termList[i];
2637 
2638 		TRACE(("%ld:  term: %s\n", find_thread(NULL), image->name));
2639 
2640 		image_event(image, IMAGE_EVENT_UNINITIALIZING);
2641 
2642 		if (image->term_routine)
2643 			((init_term_function)image->term_routine)(image->id);
2644 
2645 		image_event(image, IMAGE_EVENT_UNLOADING);
2646 	}
2647 	TRACE(("%ld:  term done.\n", find_thread(NULL)));
2648 
2649 	free(termList);
2650 }
2651 
2652 
2653 void
2654 rldelf_init(void)
2655 {
2656 	// invoke static constructors
2657 	new(&sAddOns) AddOnList;
2658 
2659 	sSem = create_sem(1, "runtime loader");
2660 	sSemOwner = -1;
2661 	sSemCount = 0;
2662 
2663 	// create the debug area
2664 	{
2665 		int32 size = TO_PAGE_SIZE(sizeof(runtime_loader_debug_area));
2666 
2667 		runtime_loader_debug_area *area;
2668 		area_id areaID = _kern_create_area(RUNTIME_LOADER_DEBUG_AREA_NAME,
2669 			(void **)&area, B_ANY_ADDRESS, size, B_NO_LOCK,
2670 			B_READ_AREA | B_WRITE_AREA);
2671 		if (areaID < B_OK) {
2672 			FATAL("Failed to create debug area.\n");
2673 			_kern_loading_app_failed(areaID);
2674 		}
2675 
2676 		area->loaded_images = &sLoadedImages;
2677 	}
2678 
2679 	// initialize error message if needed
2680 	if (report_errors()) {
2681 		void *buffer = malloc(1024);
2682 		if (buffer == NULL)
2683 			return;
2684 
2685 		sErrorMessage.SetTo(buffer, 1024, 'Rler');
2686 	}
2687 }
2688 
2689 
2690 status_t
2691 elf_reinit_after_fork(void)
2692 {
2693 	sSem = create_sem(1, "runtime loader");
2694 	if (sSem < 0)
2695 		return sSem;
2696 
2697 	// We also need to update the IDs of our images. We are the child and
2698 	// and have cloned images with different IDs. Since in most cases (fork()
2699 	// + exec*()) this would just increase the fork() overhead with no one
2700 	// caring, we do that lazily, when first doing something different.
2701 	sInvalidImageIDs = true;
2702 
2703 	return B_OK;
2704 }
2705