xref: /haiku/src/system/runtime_loader/elf.cpp (revision 9f3bdf3d039430b5172c424def20ce5d9f7367d4)
1 /*
2  * Copyright 2008-2010, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Copyright 2003-2011, 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 <syscalls.h>
22 #include <util/kernel_cpp.h>
23 
24 #include <locks.h>
25 
26 #include "add_ons.h"
27 #include "elf_load_image.h"
28 #include "elf_symbol_lookup.h"
29 #include "elf_tls.h"
30 #include "elf_versioning.h"
31 #include "errors.h"
32 #include "images.h"
33 
34 
35 // TODO: implement better locking strategy
36 // TODO: implement lazy binding
37 
38 // a handle returned by load_library() (dlopen())
39 #define RLD_GLOBAL_SCOPE	((void*)-2l)
40 
41 static const char* const kLockName = "runtime loader";
42 
43 
44 typedef void (*init_term_function)(image_id);
45 typedef void (*initfini_array_function)();
46 
47 bool gProgramLoaded = false;
48 image_t* gProgramImage;
49 
50 static image_t** sPreloadedAddons = NULL;
51 static uint32 sPreloadedAddonCount = 0;
52 
53 static recursive_lock sLock = RECURSIVE_LOCK_INITIALIZER(kLockName);
54 
55 
56 static const char *
57 find_dt_string(image_t *image, int32 d_tag)
58 {
59 	int i;
60 	elf_dyn *d = (elf_dyn *)image->dynamic_ptr;
61 
62 	for (i = 0; d[i].d_tag != DT_NULL; i++) {
63 		if (d[i].d_tag == d_tag)
64 			return STRING(image, d[i].d_un.d_val);
65 	}
66 
67 	return NULL;
68 }
69 
70 
71 static const char *
72 find_dt_rpath(image_t *image)
73 {
74 	return find_dt_string(image, DT_RPATH);
75 }
76 
77 
78 static const char *
79 find_dt_runpath(image_t *image)
80 {
81 	return find_dt_string(image, DT_RUNPATH);
82 }
83 
84 
85 image_id
86 preload_image(char const* path, image_t **image)
87 {
88 	if (path == NULL)
89 		return B_BAD_VALUE;
90 
91 	KTRACE("rld: preload_image(\"%s\")", path);
92 
93 	status_t status = load_image(path, B_LIBRARY_IMAGE, NULL, NULL, NULL, image);
94 	if (status < B_OK) {
95 		KTRACE("rld: preload_image(\"%s\") failed to load container: %s", path,
96 			strerror(status));
97 		return status;
98 	}
99 
100 	if ((*image)->find_undefined_symbol == NULL)
101 		(*image)->find_undefined_symbol = find_undefined_symbol_global;
102 
103 	KTRACE("rld: preload_image(\"%s\") done: id: %" B_PRId32, path, (*image)->id);
104 
105 	return (*image)->id;
106 }
107 
108 
109 static void
110 preload_images(image_t **image, int32 *_count = NULL)
111 {
112 	const char* imagePaths = getenv("LD_PRELOAD");
113 	if (imagePaths == NULL) {
114 		if (_count != NULL)
115 			*_count = 0;
116 		return;
117 	}
118 
119 	int32 count = 0;
120 
121 	while (*imagePaths != '\0') {
122 		// find begin of image path
123 		while (*imagePaths != '\0' && isspace(*imagePaths))
124 			imagePaths++;
125 
126 		if (*imagePaths == '\0')
127 			break;
128 
129 		// find end of image path
130 		const char* imagePath = imagePaths;
131 		while (*imagePaths != '\0' && !isspace(*imagePaths))
132 			imagePaths++;
133 
134 		// extract the path
135 		char path[B_PATH_NAME_LENGTH];
136 		size_t pathLen = imagePaths - imagePath;
137 		if (pathLen > sizeof(path) - 1)
138 			continue;
139 
140 		if (image == NULL) {
141 			count++;
142 			continue;
143 		}
144 		memcpy(path, imagePath, pathLen);
145 		path[pathLen] = '\0';
146 
147 		// load the image
148 		preload_image(path, &image[count++]);
149 	}
150 
151 	KTRACE("rld: preload_images count: %d", count);
152 
153 	if (_count != NULL)
154 		*_count = count;
155 }
156 
157 
158 static status_t
159 load_immediate_dependencies(image_t *image, bool preload)
160 {
161 	elf_dyn *d = (elf_dyn *)image->dynamic_ptr;
162 	bool reportErrors = report_errors();
163 	status_t status = B_OK;
164 	uint32 i, j;
165 	const char *rpath = NULL, *runpath;
166 	if (!d || (image->flags & RFLAG_DEPENDENCIES_LOADED))
167 		return B_OK;
168 
169 	image->flags |= RFLAG_DEPENDENCIES_LOADED;
170 
171 	int32 preloadedCount = 0;
172 	if (preload) {
173 		preload_images(NULL, &preloadedCount);
174 		image->num_needed += preloadedCount;
175 	}
176 	if (image->num_needed == 0)
177 		return B_OK;
178 
179 	KTRACE("rld: load_dependencies(\"%s\", id: %" B_PRId32 ")", image->name,
180 		image->id);
181 
182 	image->needed = (image_t**)malloc(image->num_needed * sizeof(image_t *));
183 	if (image->needed == NULL) {
184 		FATAL("%s: Failed to allocate needed struct\n", image->path);
185 		KTRACE("rld: load_dependencies(\"%s\", id: %" B_PRId32
186 			") failed: no memory", image->name, image->id);
187 		return B_NO_MEMORY;
188 	}
189 
190 	memset(image->needed, 0, image->num_needed * sizeof(image_t *));
191 	if (preload)
192 		preload_images(image->needed);
193 	runpath = find_dt_runpath(image);
194 	if (runpath == NULL)
195 		rpath = find_dt_rpath(image);
196 
197 	for (i = 0, j = preloadedCount; d[i].d_tag != DT_NULL; i++) {
198 		switch (d[i].d_tag) {
199 			case DT_NEEDED:
200 			{
201 				int32 neededOffset = d[i].d_un.d_val;
202 				const char *name = STRING(image, neededOffset);
203 
204 				status_t loadStatus = load_image(name, B_LIBRARY_IMAGE,
205 					rpath, runpath, image->path, &image->needed[j]);
206 				if (loadStatus < B_OK) {
207 					status = loadStatus;
208 					// correct error code in case the file could not been found
209 					if (status == B_ENTRY_NOT_FOUND) {
210 						status = B_MISSING_LIBRARY;
211 
212 						if (reportErrors)
213 							gErrorMessage.AddString("missing library", name);
214 					}
215 
216 					// Collect all missing libraries in case we report back
217 					if (!reportErrors) {
218 						KTRACE("rld: load_dependencies(\"%s\", id: %" B_PRId32
219 							") failed: %s", image->name, image->id,
220 							strerror(status));
221 						return status;
222 					}
223 				}
224 
225 				j += 1;
226 				break;
227 			}
228 
229 			default:
230 				// ignore any other tag
231 				continue;
232 		}
233 	}
234 
235 	if (status < B_OK) {
236 		KTRACE("rld: load_dependencies(\"%s\", id: %" B_PRId32 ") "
237 			"failed: %s", image->name, image->id,
238 			strerror(status));
239 		return status;
240 	}
241 
242 	if (j != image->num_needed) {
243 		FATAL("Internal error at load_dependencies()");
244 		KTRACE("rld: load_dependencies(\"%s\", id: %" B_PRId32 ") "
245 			"failed: internal error", image->name, image->id);
246 		return B_ERROR;
247 	}
248 
249 	KTRACE("rld: load_dependencies(\"%s\", id: %" B_PRId32 ") done",
250 		image->name, image->id);
251 
252 	return B_OK;
253 }
254 
255 
256 static status_t
257 load_dependencies(image_t* image, bool preload = false)
258 {
259 	// load dependencies (breadth-first)
260 	for (image_t* otherImage = image; otherImage != NULL;
261 			otherImage = otherImage->next) {
262 		status_t status = load_immediate_dependencies(otherImage, preload);
263 		if (status != B_OK)
264 			return status;
265 		preload = false;
266 	}
267 
268 	// Check the needed versions for the given image and all newly loaded
269 	// dependencies.
270 	for (image_t* otherImage = image; otherImage != NULL;
271 			otherImage = otherImage->next) {
272 		status_t status = check_needed_image_versions(otherImage);
273 		if (status != B_OK)
274 			return status;
275 	}
276 
277 	return B_OK;
278 }
279 
280 
281 static status_t
282 relocate_image(image_t *rootImage, image_t *image)
283 {
284 	SymbolLookupCache cache(image);
285 
286 	status_t status = arch_relocate_image(rootImage, image, &cache);
287 	if (status < B_OK) {
288 		FATAL("%s: Troubles relocating: %s\n", image->path, strerror(status));
289 		return status;
290 	}
291 
292 	_kern_image_relocated(image->id);
293 	image_event(image, IMAGE_EVENT_RELOCATED);
294 	return B_OK;
295 }
296 
297 
298 static status_t
299 relocate_dependencies(image_t *image)
300 {
301 	// get the images that still have to be relocated
302 	image_t **list;
303 	ssize_t count = get_sorted_image_list(image, &list, RFLAG_RELOCATED);
304 	if (count < B_OK)
305 		return count;
306 
307 	// relocate
308 	for (ssize_t i = 0; i < count; i++) {
309 		status_t status = relocate_image(image, list[i]);
310 		if (status < B_OK) {
311 			free(list);
312 			return status;
313 		}
314 	}
315 
316 	free(list);
317 	return B_OK;
318 }
319 
320 
321 static void
322 init_dependencies(image_t *image, bool initHead)
323 {
324 	image_t **initList = NULL;
325 	ssize_t count, i;
326 
327 	if (initHead && image->preinit_array) {
328 		uint count_preinit = image->preinit_array_len / sizeof(addr_t);
329 		for (uint j = 0; j < count_preinit; j++)
330 			((initfini_array_function)image->preinit_array[j])();
331 	}
332 
333 	count = get_sorted_image_list(image, &initList, RFLAG_INITIALIZED);
334 	if (count <= 0) {
335 		free(initList);
336 		return;
337 	}
338 
339 	if (!initHead) {
340 		// this removes the "calling" image
341 		image->flags &= ~RFLAG_INITIALIZED;
342 		initList[--count] = NULL;
343 	}
344 
345 	TRACE(("%ld: init dependencies\n", find_thread(NULL)));
346 	for (i = 0; i < count; i++) {
347 		image = initList[i];
348 
349 		TRACE(("%ld:  init: %s\n", find_thread(NULL), image->name));
350 
351 		init_term_function before;
352 		if (find_symbol(image,
353 				SymbolLookupInfo(B_INIT_BEFORE_FUNCTION_NAME, B_SYMBOL_TYPE_TEXT),
354 				(void**)&before) == B_OK) {
355 			before(image->id);
356 		}
357 
358 		if (image->init_routine != 0)
359 			((init_term_function)image->init_routine)(image->id);
360 
361 		if (image->init_array) {
362 			uint count_init = image->init_array_len / sizeof(addr_t);
363 			for (uint j = 0; j < count_init; j++)
364 				((initfini_array_function)image->init_array[j])();
365 		}
366 
367 		init_term_function after;
368 		if (find_symbol(image,
369 				SymbolLookupInfo(B_INIT_AFTER_FUNCTION_NAME, B_SYMBOL_TYPE_TEXT),
370 				(void**)&after) == B_OK) {
371 			after(image->id);
372 		}
373 
374 		image_event(image, IMAGE_EVENT_INITIALIZED);
375 	}
376 	TRACE(("%ld: init done.\n", find_thread(NULL)));
377 
378 	free(initList);
379 }
380 
381 
382 static void
383 call_term_functions(image_t* image)
384 {
385 	init_term_function before;
386 	if (find_symbol(image,
387 			SymbolLookupInfo(B_TERM_BEFORE_FUNCTION_NAME, B_SYMBOL_TYPE_TEXT),
388 			(void**)&before) == B_OK) {
389 		before(image->id);
390 	}
391 
392 	if (image->term_array) {
393 		uint count_term = image->term_array_len / sizeof(addr_t);
394 		for (uint i = count_term; i-- > 0;)
395 			((initfini_array_function)image->term_array[i])();
396 	}
397 
398 	if (image->term_routine)
399 		((init_term_function)image->term_routine)(image->id);
400 
401 	init_term_function after;
402 	if (find_symbol(image,
403 			SymbolLookupInfo(B_TERM_AFTER_FUNCTION_NAME, B_SYMBOL_TYPE_TEXT),
404 			(void**)&after) == B_OK) {
405 		after(image->id);
406 	}
407 }
408 
409 
410 static void
411 inject_runtime_loader_api(image_t* rootImage)
412 {
413 	// We patch any exported __gRuntimeLoader symbols to point to our private
414 	// API.
415 	image_t* image;
416 	void* _export;
417 	if (find_symbol_breadth_first(rootImage,
418 			SymbolLookupInfo("__gRuntimeLoader", B_SYMBOL_TYPE_DATA), &image,
419 			&_export) == B_OK) {
420 		*(void**)_export = &gRuntimeLoader;
421 	}
422 }
423 
424 
425 static status_t
426 add_preloaded_addon(image_t* image)
427 {
428 	// We realloc() everytime -- not particularly efficient, but good enough for
429 	// small number of preloaded addons.
430 	image_t** newArray = (image_t**)realloc(sPreloadedAddons,
431 		sizeof(image_t*) * (sPreloadedAddonCount + 1));
432 	if (newArray == NULL)
433 		return B_NO_MEMORY;
434 
435 	sPreloadedAddons = newArray;
436 	newArray[sPreloadedAddonCount++] = image;
437 
438 	return B_OK;
439 }
440 
441 
442 image_id
443 preload_addon(char const* path)
444 {
445 	if (path == NULL)
446 		return B_BAD_VALUE;
447 
448 	KTRACE("rld: preload_addon(\"%s\")", path);
449 
450 	image_t *image = NULL;
451 	status_t status = load_image(path, B_LIBRARY_IMAGE, NULL, NULL, NULL, &image);
452 	if (status < B_OK) {
453 		KTRACE("rld: preload_addon(\"%s\") failed to load container: %s", path,
454 			strerror(status));
455 		return status;
456 	}
457 
458 	if (image->find_undefined_symbol == NULL)
459 		image->find_undefined_symbol = find_undefined_symbol_global;
460 
461 	status = load_dependencies(image);
462 	if (status < B_OK)
463 		goto err;
464 
465 	set_image_flags_recursively(image, RTLD_GLOBAL);
466 
467 	status = relocate_dependencies(image);
468 	if (status < B_OK)
469 		goto err;
470 
471 	status = add_preloaded_addon(image);
472 	if (status < B_OK)
473 		goto err;
474 
475 	inject_runtime_loader_api(image);
476 
477 	remap_images();
478 	init_dependencies(image, true);
479 
480 	// if the image contains an add-on, register it
481 	runtime_loader_add_on* addOnStruct;
482 	if (find_symbol(image,
483 			SymbolLookupInfo("__gRuntimeLoaderAddOn", B_SYMBOL_TYPE_DATA),
484 			(void**)&addOnStruct) == B_OK) {
485 		add_add_on(image, addOnStruct);
486 	}
487 
488 	KTRACE("rld: preload_addon(\"%s\") done: id: %" B_PRId32, path, image->id);
489 
490 	return image->id;
491 
492 err:
493 	KTRACE("rld: preload_addon(\"%s\") failed: %s", path, strerror(status));
494 
495 	dequeue_loaded_image(image);
496 	delete_image(image);
497 	return status;
498 }
499 
500 
501 static void
502 preload_addons()
503 {
504 	const char* imagePaths = getenv("LD_PRELOAD_ADDONS");
505 	if (imagePaths == NULL)
506 		return;
507 
508 	while (*imagePaths != '\0') {
509 		// find begin of image path
510 		while (*imagePaths != '\0' && isspace(*imagePaths))
511 			imagePaths++;
512 
513 		if (*imagePaths == '\0')
514 			break;
515 
516 		// find end of image path
517 		const char* imagePath = imagePaths;
518 		while (*imagePaths != '\0' && !isspace(*imagePaths))
519 			imagePaths++;
520 
521 		// extract the path
522 		char path[B_PATH_NAME_LENGTH];
523 		size_t pathLen = imagePaths - imagePath;
524 		if (pathLen > sizeof(path) - 1)
525 			continue;
526 		memcpy(path, imagePath, pathLen);
527 		path[pathLen] = '\0';
528 
529 		// load the image
530 		preload_addon(path);
531 	}
532 }
533 
534 
535 //	#pragma mark - libroot.so exported functions
536 
537 
538 image_id
539 load_program(char const *path, void **_entry)
540 {
541 	status_t status;
542 	image_t *image;
543 
544 	KTRACE("rld: load_program(\"%s\")", path);
545 
546 	RecursiveLocker _(sLock);
547 		// for now, just do stupid simple global locking
548 
549 	preload_addons();
550 
551 	TRACE(("rld: load %s\n", path));
552 
553 	status = load_image(path, B_APP_IMAGE, NULL, NULL, NULL, &gProgramImage);
554 	if (status < B_OK)
555 		goto err;
556 
557 	if (gProgramImage->find_undefined_symbol == NULL)
558 		gProgramImage->find_undefined_symbol = find_undefined_symbol_global;
559 
560 	status = load_dependencies(gProgramImage, true);
561 	if (status < B_OK)
562 		goto err;
563 
564 	// Set RTLD_GLOBAL on all libraries including the program.
565 	// This results in the desired symbol resolution for dlopen()ed libraries.
566 	set_image_flags_recursively(gProgramImage, RTLD_GLOBAL);
567 
568 	status = relocate_dependencies(gProgramImage);
569 	if (status < B_OK)
570 		goto err;
571 
572 	inject_runtime_loader_api(gProgramImage);
573 
574 	remap_images();
575 	init_dependencies(gProgramImage, true);
576 
577 	// Since the images are initialized now, we no longer should use our
578 	// getenv(), but use the one from libroot.so
579 	find_symbol_breadth_first(gProgramImage,
580 		SymbolLookupInfo("getenv", B_SYMBOL_TYPE_TEXT), &image,
581 		(void**)&gGetEnv);
582 
583 	if (gProgramImage->entry_point == 0) {
584 		status = B_NOT_AN_EXECUTABLE;
585 		goto err;
586 	}
587 
588 	*_entry = (void *)(gProgramImage->entry_point);
589 
590 	gProgramLoaded = true;
591 
592 	KTRACE("rld: load_program(\"%s\") done: entry: %p, id: %" B_PRId32 , path,
593 		*_entry, gProgramImage->id);
594 
595 	return gProgramImage->id;
596 
597 err:
598 	KTRACE("rld: load_program(\"%s\") failed: %s", path, strerror(status));
599 
600 	delete_image(gProgramImage);
601 
602 	if (report_errors()) {
603 		// send error message
604 		gErrorMessage.AddInt32("error", status);
605 		gErrorMessage.SetDeliveryInfo(gProgramArgs->error_token,
606 			-1, 0, find_thread(NULL));
607 
608 		_kern_write_port_etc(gProgramArgs->error_port, 'KMSG',
609 			gErrorMessage.Buffer(), gErrorMessage.ContentSize(), 0, 0);
610 	}
611 	_kern_loading_app_failed(status);
612 
613 	return status;
614 }
615 
616 
617 image_id
618 load_library(char const *path, uint32 flags, bool addOn, void* caller,
619 	void** _handle)
620 {
621 	image_t *image = NULL;
622 	image_type type = (addOn ? B_ADD_ON_IMAGE : B_LIBRARY_IMAGE);
623 	status_t status;
624 	const char* rpath = NULL, *runpath = NULL;
625 	const char* requestingObjectPath = NULL;
626 
627 	if (path == NULL && addOn)
628 		return B_BAD_VALUE;
629 
630 	KTRACE("rld: load_library(\"%s\", %#" B_PRIx32 ", %d)", path, flags, addOn);
631 
632 	RecursiveLocker _(sLock);
633 		// for now, just do stupid simple global locking
634 
635 	// have we already loaded this library?
636 	// Checking it at this stage saves loading its dependencies again
637 	if (!addOn) {
638 		// a NULL path is fine -- it means the global scope shall be opened
639 		if (path == NULL) {
640 			*_handle = RLD_GLOBAL_SCOPE;
641 			return 0;
642 		}
643 
644 		image = find_loaded_image_by_name(path, APP_OR_LIBRARY_TYPE);
645 		if (image != NULL && (flags & RTLD_GLOBAL) != 0)
646 			set_image_flags_recursively(image, RTLD_GLOBAL);
647 
648 		if (image) {
649 			atomic_add(&image->ref_count, 1);
650 			KTRACE("rld: load_library(\"%s\"): already loaded: %" B_PRId32,
651 				path, image->id);
652 			*_handle = image;
653 			return image->id;
654 		}
655 
656 		// First of all, find the caller image.
657 		image_t* callerImage = get_loaded_images().head;
658 		for (; callerImage != NULL; callerImage = callerImage->next) {
659 			elf_region_t& text = callerImage->regions[0];
660 			if ((addr_t)caller >= text.vmstart
661 				&& (addr_t)caller < text.vmstart + text.vmsize) {
662 				// found the image
663 				break;
664 			}
665 		}
666 		if (callerImage != NULL) {
667 			runpath = find_dt_runpath(callerImage);
668 			if (runpath == NULL)
669 				rpath = find_dt_rpath(callerImage);
670 			requestingObjectPath = callerImage->path;
671 		}
672 	}
673 
674 	status = load_image(path, type, rpath, runpath, requestingObjectPath, &image);
675 	if (status < B_OK) {
676 		KTRACE("rld: load_library(\"%s\") failed to load container: %s", path,
677 			strerror(status));
678 		return status;
679 	}
680 
681 	if (image->find_undefined_symbol == NULL) {
682 		if (addOn)
683 			image->find_undefined_symbol = find_undefined_symbol_add_on;
684 		else
685 			image->find_undefined_symbol = find_undefined_symbol_global;
686 	}
687 
688 	status = load_dependencies(image);
689 	if (status < B_OK)
690 		goto err;
691 
692 	// If specified, set the RTLD_GLOBAL flag recursively on this image and all
693 	// dependencies. If not specified, we temporarily set
694 	// RFLAG_USE_FOR_RESOLVING so that the dependencies will correctly be used
695 	// for undefined symbol resolution.
696 	if ((flags & RTLD_GLOBAL) != 0)
697 		set_image_flags_recursively(image, RTLD_GLOBAL);
698 	else
699 		set_image_flags_recursively(image, RFLAG_USE_FOR_RESOLVING);
700 
701 	status = relocate_dependencies(image);
702 	if (status < B_OK)
703 		goto err;
704 
705 	if ((flags & RTLD_GLOBAL) == 0)
706 		clear_image_flags_recursively(image, RFLAG_USE_FOR_RESOLVING);
707 
708 	remap_images();
709 	init_dependencies(image, true);
710 
711 	KTRACE("rld: load_library(\"%s\") done: id: %" B_PRId32, path, image->id);
712 
713 	*_handle = image;
714 	return image->id;
715 
716 err:
717 	KTRACE("rld: load_library(\"%s\") failed: %s", path, strerror(status));
718 
719 	dequeue_loaded_image(image);
720 	delete_image(image);
721 	return status;
722 }
723 
724 
725 status_t
726 unload_library(void* handle, image_id imageID, bool addOn)
727 {
728 	image_t *image;
729 	image_type type = addOn ? B_ADD_ON_IMAGE : B_LIBRARY_IMAGE;
730 
731 	if (handle == NULL && imageID < 0)
732 		return B_BAD_IMAGE_ID;
733 
734 	if (handle == RLD_GLOBAL_SCOPE)
735 		return B_OK;
736 
737 	RecursiveLocker _(sLock);
738 		// for now, just do stupid simple global locking
739 
740 	if (gInvalidImageIDs) {
741 		// After fork, we lazily rebuild the image IDs of all loaded images
742 		update_image_ids();
743 	}
744 
745 	// we only check images that have been already initialized
746 
747 	status_t status = B_BAD_IMAGE_ID;
748 
749 	if (handle != NULL) {
750 		image = (image_t*)handle;
751 		put_image(image);
752 		status = B_OK;
753 	} else {
754 		image = find_loaded_image_by_id(imageID, true);
755 		if (image != NULL) {
756 			// unload image
757 			if (type == image->type) {
758 				put_image(image);
759 				status = B_OK;
760 			} else
761 				status = B_BAD_VALUE;
762 		}
763 	}
764 
765 	if (status == B_OK) {
766 		while ((image = get_disposable_images().head) != NULL) {
767 			dequeue_disposable_image(image);
768 
769 			// Call the exit hooks that live in this image.
770 			// Note: With the Itanium ABI this shouldn't really be done this
771 			// way anymore, since global destructors are registered via
772 			// __cxa_atexit() (the ones that are registered dynamically) and the
773 			// termination routine should call __cxa_finalize() for the image.
774 			// The reason why we still do it is that hooks registered with
775 			// atexit() aren't associated with the image. We could find out
776 			// there which image the hooks lives in and register it
777 			// respectively, but since that would be done always, that's
778 			// probably more expensive than calling
779 			// call_atexit_hooks_for_range() only here, which happens only when
780 			// libraries are unloaded dynamically.
781 			if (gRuntimeLoader.call_atexit_hooks_for_range) {
782 				gRuntimeLoader.call_atexit_hooks_for_range(
783 					image->regions[0].vmstart, image->regions[0].vmsize);
784 			}
785 
786 			image_event(image, IMAGE_EVENT_UNINITIALIZING);
787 
788 			call_term_functions(image);
789 
790 			TLSBlockTemplates::Get().Unregister(image->dso_tls_id);
791 
792 			unmap_image(image);
793 
794 			image_event(image, IMAGE_EVENT_UNLOADING);
795 
796 			delete_image(image);
797 		}
798 	}
799 
800 	return status;
801 }
802 
803 
804 status_t
805 get_nth_symbol(image_id imageID, int32 num, char *nameBuffer,
806 	int32 *_nameLength, int32 *_type, void **_location)
807 {
808 	int32 count = 0, j;
809 	uint32 i;
810 	image_t *image;
811 
812 	RecursiveLocker _(sLock);
813 
814 	// get the image from those who have been already initialized
815 	image = find_loaded_image_by_id(imageID, false);
816 	if (image == NULL)
817 		return B_BAD_IMAGE_ID;
818 
819 	// iterate through all the hash buckets until we've found the one
820 	for (i = 0; i < HASHTABSIZE(image); i++) {
821 		for (j = HASHBUCKETS(image)[i]; j != STN_UNDEF; j = HASHCHAINS(image)[j]) {
822 			elf_sym *symbol = &image->syms[j];
823 
824 			if (count == num) {
825 				const char* symbolName = SYMNAME(image, symbol);
826 				strlcpy(nameBuffer, symbolName, *_nameLength);
827 				*_nameLength = strlen(symbolName);
828 
829 				void* location = (void*)(symbol->st_value
830 					+ image->regions[0].delta);
831 				int32 type;
832 				if (symbol->Type() == STT_FUNC)
833 					type = B_SYMBOL_TYPE_TEXT;
834 				else if (symbol->Type() == STT_OBJECT)
835 					type = B_SYMBOL_TYPE_DATA;
836 				else
837 					type = B_SYMBOL_TYPE_ANY;
838 					// TODO: check with the return types of that BeOS function
839 
840 				patch_defined_symbol(image, symbolName, &location, &type);
841 
842 				if (_type != NULL)
843 					*_type = type;
844 				if (_location != NULL)
845 					*_location = location;
846 				goto out;
847 			}
848 			count++;
849 		}
850 	}
851 out:
852 	if (num != count)
853 		return B_BAD_INDEX;
854 
855 	return B_OK;
856 }
857 
858 
859 status_t
860 get_nearest_symbol_at_address(void* address, image_id* _imageID,
861 	char** _imagePath, char** _imageName, char** _symbolName, int32* _type,
862 	void** _location, bool* _exactMatch)
863 {
864 	RecursiveLocker _(sLock);
865 
866 	image_t* image = find_loaded_image_by_address((addr_t)address);
867 	if (image == NULL)
868 		return B_BAD_VALUE;
869 
870 	if (_imageID != NULL)
871 		*_imageID = image->id;
872 	if (_imagePath != NULL)
873 		*_imagePath = image->path;
874 	if (_imageName != NULL)
875 		*_imageName = image->name;
876 
877 	// If the caller does not want the actual symbol name, only the image,
878 	// we can just return immediately.
879 	if (_symbolName == NULL && _type == NULL && _location == NULL)
880 		return B_OK;
881 
882 	bool exactMatch = false;
883 	elf_sym* foundSymbol = NULL;
884 	addr_t foundLocation = (addr_t)NULL;
885 
886 	for (uint32 i = 0; i < HASHTABSIZE(image) && !exactMatch; i++) {
887 		for (int32 j = HASHBUCKETS(image)[i]; j != STN_UNDEF;
888 				j = HASHCHAINS(image)[j]) {
889 			elf_sym *symbol = &image->syms[j];
890 			addr_t location = symbol->st_value + image->regions[0].delta;
891 
892 			if (location <= (addr_t)address	&& location >= foundLocation) {
893 				foundSymbol = symbol;
894 				foundLocation = location;
895 
896 				// jump out if we have an exact match
897 				if (location + symbol->st_size > (addr_t)address) {
898 					exactMatch = true;
899 					break;
900 				}
901 			}
902 		}
903 	}
904 
905 	if (_exactMatch != NULL)
906 		*_exactMatch = exactMatch;
907 
908 	if (foundSymbol != NULL) {
909 		*_symbolName = SYMNAME(image, foundSymbol);
910 
911 		if (_type != NULL) {
912 			if (foundSymbol->Type() == STT_FUNC)
913 				*_type = B_SYMBOL_TYPE_TEXT;
914 			else if (foundSymbol->Type() == STT_OBJECT)
915 				*_type = B_SYMBOL_TYPE_DATA;
916 			else
917 				*_type = B_SYMBOL_TYPE_ANY;
918 			// TODO: check with the return types of that BeOS function
919 		}
920 
921 		if (_location != NULL)
922 			*_location = (void*)foundLocation;
923 	} else {
924 		*_symbolName = NULL;
925 		if (_location != NULL)
926 			*_location = NULL;
927 	}
928 
929 	return B_OK;
930 }
931 
932 
933 status_t
934 get_symbol(image_id imageID, char const *symbolName, int32 symbolType,
935 	bool recursive, image_id *_inImage, void **_location)
936 {
937 	status_t status = B_OK;
938 	image_t *image;
939 
940 	if (imageID < B_OK)
941 		return B_BAD_IMAGE_ID;
942 	if (symbolName == NULL)
943 		return B_BAD_VALUE;
944 
945 	// Previously, these functions were called in __haiku_init_before
946 	// and __haiku_init_after. Now we call them inside runtime_loader,
947 	// so we prevent applications from fetching them.
948 	if (strcmp(symbolName, B_INIT_BEFORE_FUNCTION_NAME) == 0
949 		|| strcmp(symbolName, B_INIT_AFTER_FUNCTION_NAME) == 0
950 		|| strcmp(symbolName, B_TERM_BEFORE_FUNCTION_NAME) == 0
951 		|| strcmp(symbolName, B_TERM_AFTER_FUNCTION_NAME) == 0)
952 		return B_BAD_VALUE;
953 
954 	RecursiveLocker _(sLock);
955 		// for now, just do stupid simple global locking
956 
957 	// get the image from those who have been already initialized
958 	image = find_loaded_image_by_id(imageID, false);
959 	if (image != NULL) {
960 		if (recursive) {
961 			// breadth-first search in the given image and its dependencies
962 			status = find_symbol_breadth_first(image,
963 				SymbolLookupInfo(symbolName, symbolType, NULL,
964 					LOOKUP_FLAG_DEFAULT_VERSION),
965 				&image, _location);
966 		} else {
967 			status = find_symbol(image,
968 				SymbolLookupInfo(symbolName, symbolType, NULL,
969 					LOOKUP_FLAG_DEFAULT_VERSION),
970 				_location);
971 		}
972 
973 		if (status == B_OK && _inImage != NULL)
974 			*_inImage = image->id;
975 	} else
976 		status = B_BAD_IMAGE_ID;
977 
978 	return status;
979 }
980 
981 
982 status_t
983 get_library_symbol(void* handle, void* caller, const char* symbolName,
984 	void **_location)
985 {
986 	status_t status = B_ENTRY_NOT_FOUND;
987 
988 	if (symbolName == NULL)
989 		return B_BAD_VALUE;
990 
991 	RecursiveLocker _(sLock);
992 		// for now, just do stupid simple global locking
993 
994 	if (handle == RTLD_DEFAULT || handle == RLD_GLOBAL_SCOPE) {
995 		// look in the default scope
996 		image_t* image;
997 		elf_sym* symbol = find_undefined_symbol_global(gProgramImage,
998 			gProgramImage,
999 			SymbolLookupInfo(symbolName, B_SYMBOL_TYPE_ANY, NULL,
1000 				LOOKUP_FLAG_DEFAULT_VERSION),
1001 			&image);
1002 		if (symbol != NULL) {
1003 			*_location = (void*)(symbol->st_value + image->regions[0].delta);
1004 			int32 symbolType = symbol->Type() == STT_FUNC
1005 				? B_SYMBOL_TYPE_TEXT : B_SYMBOL_TYPE_DATA;
1006 			patch_defined_symbol(image, symbolName, _location, &symbolType);
1007 			status = B_OK;
1008 		}
1009 	} else if (handle == RTLD_NEXT) {
1010 		// Look in the default scope, but also in the dependencies of the
1011 		// calling image. Return the next after the caller symbol.
1012 
1013 		// First of all, find the caller image.
1014 		image_t* callerImage = get_loaded_images().head;
1015 		for (; callerImage != NULL; callerImage = callerImage->next) {
1016 			elf_region_t& text = callerImage->regions[0];
1017 			if ((addr_t)caller >= text.vmstart
1018 				&& (addr_t)caller < text.vmstart + text.vmsize) {
1019 				// found the image
1020 				break;
1021 			}
1022 		}
1023 
1024 		if (callerImage != NULL) {
1025 			// found the caller -- now search the global scope until we find
1026 			// the next symbol
1027 			bool hitCallerImage = false;
1028 			set_image_flags_recursively(callerImage, RFLAG_USE_FOR_RESOLVING);
1029 
1030 			elf_sym* candidateSymbol = NULL;
1031 			image_t* candidateImage = NULL;
1032 
1033 			image_t* image = get_loaded_images().head;
1034 			for (; image != NULL; image = image->next) {
1035 				// skip the caller image
1036 				if (image == callerImage) {
1037 					hitCallerImage = true;
1038 					continue;
1039 				}
1040 
1041 				// skip all images up to the caller image; also skip add-on
1042 				// images and those not marked above for resolution
1043 				if (!hitCallerImage || image->type == B_ADD_ON_IMAGE
1044 					|| (image->flags
1045 						& (RTLD_GLOBAL | RFLAG_USE_FOR_RESOLVING)) == 0) {
1046 					continue;
1047 				}
1048 
1049 				elf_sym *symbol = find_symbol(image,
1050 					SymbolLookupInfo(symbolName, B_SYMBOL_TYPE_TEXT, NULL,
1051 						LOOKUP_FLAG_DEFAULT_VERSION));
1052 				if (symbol == NULL)
1053 					continue;
1054 
1055 				// found a symbol
1056 				bool isWeak = symbol->Bind() == STB_WEAK;
1057 				if (candidateImage == NULL || !isWeak) {
1058 					candidateSymbol = symbol;
1059 					candidateImage = image;
1060 
1061 					if (!isWeak)
1062 						break;
1063 				}
1064 
1065 				// symbol is weak, so we need to continue
1066 			}
1067 
1068 			if (candidateSymbol != NULL) {
1069 				// found the symbol
1070 				*_location = (void*)(candidateSymbol->st_value
1071 					+ candidateImage->regions[0].delta);
1072 				int32 symbolType = B_SYMBOL_TYPE_TEXT;
1073 				patch_defined_symbol(candidateImage, symbolName, _location,
1074 					&symbolType);
1075 				status = B_OK;
1076 			}
1077 
1078 			clear_image_flags_recursively(callerImage, RFLAG_USE_FOR_RESOLVING);
1079 		}
1080 	} else {
1081 		// breadth-first search in the given image and its dependencies
1082 		image_t* inImage;
1083 		status = find_symbol_breadth_first((image_t*)handle,
1084 			SymbolLookupInfo(symbolName, B_SYMBOL_TYPE_ANY, NULL,
1085 				LOOKUP_FLAG_DEFAULT_VERSION),
1086 			&inImage, _location);
1087 	}
1088 
1089 	return status;
1090 }
1091 
1092 
1093 status_t
1094 get_next_image_dependency(image_id id, uint32 *cookie, const char **_name)
1095 {
1096 	uint32 i, j, searchIndex = *cookie;
1097 	elf_dyn *dynamicSection;
1098 	image_t *image;
1099 
1100 	if (_name == NULL)
1101 		return B_BAD_VALUE;
1102 
1103 	RecursiveLocker _(sLock);
1104 
1105 	image = find_loaded_image_by_id(id, false);
1106 	if (image == NULL)
1107 		return B_BAD_IMAGE_ID;
1108 
1109 	dynamicSection = (elf_dyn *)image->dynamic_ptr;
1110 	if (dynamicSection == NULL || image->num_needed <= searchIndex)
1111 		return B_ENTRY_NOT_FOUND;
1112 
1113 	for (i = 0, j = 0; dynamicSection[i].d_tag != DT_NULL; i++) {
1114 		if (dynamicSection[i].d_tag != DT_NEEDED)
1115 			continue;
1116 
1117 		if (j++ == searchIndex) {
1118 			int32 neededOffset = dynamicSection[i].d_un.d_val;
1119 
1120 			*_name = STRING(image, neededOffset);
1121 			*cookie = searchIndex + 1;
1122 			return B_OK;
1123 		}
1124 	}
1125 
1126 	return B_ENTRY_NOT_FOUND;
1127 }
1128 
1129 
1130 //	#pragma mark - runtime_loader private exports
1131 
1132 
1133 /*! Read and verify the ELF header */
1134 status_t
1135 elf_verify_header(void *header, size_t length)
1136 {
1137 	int32 programSize, sectionSize;
1138 
1139 	if (length < sizeof(elf_ehdr))
1140 		return B_NOT_AN_EXECUTABLE;
1141 
1142 	return parse_elf_header((elf_ehdr *)header, &programSize, &sectionSize);
1143 }
1144 
1145 
1146 #ifdef _COMPAT_MODE
1147 #ifdef __x86_64__
1148 status_t
1149 elf32_verify_header(void *header, size_t length)
1150 {
1151 	int32 programSize, sectionSize;
1152 
1153 	if (length < sizeof(Elf32_Ehdr))
1154 		return B_NOT_AN_EXECUTABLE;
1155 
1156 	return parse_elf32_header((Elf32_Ehdr *)header, &programSize, &sectionSize);
1157 }
1158 #else
1159 status_t
1160 elf64_verify_header(void *header, size_t length)
1161 {
1162 	int32 programSize, sectionSize;
1163 
1164 	if (length < sizeof(Elf64_Ehdr))
1165 		return B_NOT_AN_EXECUTABLE;
1166 
1167 	return parse_elf64_header((Elf64_Ehdr *)header, &programSize, &sectionSize);
1168 }
1169 #endif	// __x86_64__
1170 #endif	// _COMPAT_MODE
1171 
1172 
1173 void
1174 terminate_program(void)
1175 {
1176 	image_t **termList;
1177 	ssize_t count, i;
1178 
1179 	count = get_sorted_image_list(NULL, &termList, RFLAG_TERMINATED);
1180 	if (count < B_OK)
1181 		return;
1182 
1183 	if (gInvalidImageIDs) {
1184 		// After fork, we lazily rebuild the image IDs of all loaded images
1185 		update_image_ids();
1186 	}
1187 
1188 	TRACE(("%ld: terminate dependencies\n", find_thread(NULL)));
1189 	for (i = count; i-- > 0;) {
1190 		image_t *image = termList[i];
1191 
1192 		TRACE(("%ld:  term: %s\n", find_thread(NULL), image->name));
1193 
1194 		image_event(image, IMAGE_EVENT_UNINITIALIZING);
1195 
1196 		call_term_functions(image);
1197 
1198 		image_event(image, IMAGE_EVENT_UNLOADING);
1199 	}
1200 	TRACE(("%ld:  term done.\n", find_thread(NULL)));
1201 
1202 	free(termList);
1203 }
1204 
1205 
1206 void
1207 rldelf_init(void)
1208 {
1209 	init_add_ons();
1210 
1211 	// create the debug area
1212 	{
1213 		size_t size = TO_PAGE_SIZE(sizeof(runtime_loader_debug_area));
1214 
1215 		runtime_loader_debug_area *area;
1216 		area_id areaID = _kern_create_area(RUNTIME_LOADER_DEBUG_AREA_NAME,
1217 			(void **)&area, B_RANDOMIZED_ANY_ADDRESS, size, B_NO_LOCK,
1218 			B_READ_AREA | B_WRITE_AREA | B_CLONEABLE_AREA);
1219 		if (areaID < B_OK) {
1220 			FATAL("Failed to create debug area.\n");
1221 			_kern_loading_app_failed(areaID);
1222 		}
1223 
1224 		area->loaded_images = &get_loaded_images();
1225 	}
1226 
1227 	// initialize error message if needed
1228 	if (report_errors()) {
1229 		void *buffer = malloc(1024);
1230 		if (buffer == NULL)
1231 			return;
1232 
1233 		gErrorMessage.SetTo(buffer, 1024, 'Rler');
1234 	}
1235 }
1236 
1237 
1238 status_t
1239 elf_reinit_after_fork(void)
1240 {
1241 	recursive_lock_init(&sLock, kLockName);
1242 
1243 	// We also need to update the IDs of our images. We are the child and
1244 	// and have cloned images with different IDs. Since in most cases (fork()
1245 	// + exec*()) this would just increase the fork() overhead with no one
1246 	// caring, we do that lazily, when first doing something different.
1247 	gInvalidImageIDs = true;
1248 
1249 	return B_OK;
1250 }
1251