xref: /haiku/src/system/runtime_loader/elf_load_image.cpp (revision ebeab0cf7032dd3f09d4588aa05e0618482999b8)
1 /*
2  * Copyright 2008-2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Copyright 2003-2012, 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 "elf_load_image.h"
12 
13 #include <stdio.h>
14 #include <string.h>
15 
16 #include <syscalls.h>
17 
18 #include "add_ons.h"
19 #include "elf_haiku_version.h"
20 #include "elf_symbol_lookup.h"
21 #include "elf_tls.h"
22 #include "elf_versioning.h"
23 #include "images.h"
24 #include "runtime_loader_private.h"
25 
26 
27 static const char* sSearchPathSubDir = NULL;
28 
29 
30 static const char*
31 get_program_path()
32 {
33 	return gProgramImage != NULL ? gProgramImage->path : NULL;
34 }
35 
36 
37 static int32
38 count_regions(const char* imagePath, char const* buff, int phnum, int phentsize)
39 {
40 	elf_phdr* pheaders;
41 	int32 count = 0;
42 	int i;
43 
44 	for (i = 0; i < phnum; i++) {
45 		pheaders = (elf_phdr*)(buff + i * phentsize);
46 
47 		switch (pheaders->p_type) {
48 			case PT_NULL:
49 				// NOP header
50 				break;
51 			case PT_LOAD:
52 				count += 1;
53 				if (pheaders->p_memsz != pheaders->p_filesz) {
54 					addr_t A = TO_PAGE_SIZE(pheaders->p_vaddr
55 						+ pheaders->p_memsz);
56 					addr_t B = TO_PAGE_SIZE(pheaders->p_vaddr
57 						+ pheaders->p_filesz);
58 
59 					if (A != B)
60 						count += 1;
61 				}
62 				break;
63 			case PT_DYNAMIC:
64 				// will be handled at some other place
65 				break;
66 			case PT_INTERP:
67 				// should check here for appropriate interpreter
68 				break;
69 			case PT_NOTE:
70 				// unsupported
71 				break;
72 			case PT_SHLIB:
73 				// undefined semantics
74 				break;
75 			case PT_PHDR:
76 				// we don't use it
77 				break;
78 			case PT_EH_FRAME:
79 			case PT_RELRO:
80 				// not implemented yet, but can be ignored
81 				break;
82 			case PT_STACK:
83 				// we don't use it
84 				break;
85 			case PT_TLS:
86 				// will be handled at some other place
87 				break;
88 			default:
89 				FATAL("%s: Unhandled pheader type in count 0x%" B_PRIx32 "\n",
90 					imagePath, pheaders->p_type);
91 				break;
92 		}
93 	}
94 
95 	return count;
96 }
97 
98 
99 static status_t
100 parse_program_headers(image_t* image, char* buff, int phnum, int phentsize)
101 {
102 	elf_phdr* pheader;
103 	int regcount;
104 	int i;
105 
106 	image->dso_tls_id = unsigned(-1);
107 
108 	regcount = 0;
109 	for (i = 0; i < phnum; i++) {
110 		pheader = (elf_phdr*)(buff + i * phentsize);
111 
112 		switch (pheader->p_type) {
113 			case PT_NULL:
114 				/* NOP header */
115 				break;
116 			case PT_LOAD:
117 				if (pheader->p_memsz == pheader->p_filesz) {
118 					/*
119 					 * everything in one area
120 					 */
121 					image->regions[regcount].start = pheader->p_vaddr;
122 					image->regions[regcount].size = pheader->p_memsz;
123 					image->regions[regcount].vmstart
124 						= PAGE_BASE(pheader->p_vaddr);
125 					image->regions[regcount].vmsize
126 						= TO_PAGE_SIZE(pheader->p_memsz
127 							+ PAGE_OFFSET(pheader->p_vaddr));
128 					image->regions[regcount].fdstart = pheader->p_offset;
129 					image->regions[regcount].fdsize = pheader->p_filesz;
130 					image->regions[regcount].delta = 0;
131 					image->regions[regcount].flags = 0;
132 					if (pheader->p_flags & PF_WRITE) {
133 						// this is a writable segment
134 						image->regions[regcount].flags |= RFLAG_RW;
135 					}
136 				} else {
137 					/*
138 					 * may require splitting
139 					 */
140 					addr_t A = TO_PAGE_SIZE(pheader->p_vaddr
141 						+ pheader->p_memsz);
142 					addr_t B = TO_PAGE_SIZE(pheader->p_vaddr
143 						+ pheader->p_filesz);
144 
145 					image->regions[regcount].start = pheader->p_vaddr;
146 					image->regions[regcount].size = pheader->p_filesz;
147 					image->regions[regcount].vmstart
148 						= PAGE_BASE(pheader->p_vaddr);
149 					image->regions[regcount].vmsize
150 						= TO_PAGE_SIZE(pheader->p_filesz
151 							+ PAGE_OFFSET(pheader->p_vaddr));
152 					image->regions[regcount].fdstart = pheader->p_offset;
153 					image->regions[regcount].fdsize = pheader->p_filesz;
154 					image->regions[regcount].delta = 0;
155 					image->regions[regcount].flags = 0;
156 					if (pheader->p_flags & PF_WRITE) {
157 						// this is a writable segment
158 						image->regions[regcount].flags |= RFLAG_RW;
159 					}
160 
161 					if (A != B) {
162 						/*
163 						 * yeah, it requires splitting
164 						 */
165 						regcount += 1;
166 						image->regions[regcount].start = pheader->p_vaddr;
167 						image->regions[regcount].size
168 							= pheader->p_memsz - pheader->p_filesz;
169 						image->regions[regcount].vmstart
170 							= image->regions[regcount-1].vmstart
171 								+ image->regions[regcount-1].vmsize;
172 						image->regions[regcount].vmsize
173 							= TO_PAGE_SIZE(pheader->p_memsz
174 									+ PAGE_OFFSET(pheader->p_vaddr))
175 								- image->regions[regcount-1].vmsize;
176 						image->regions[regcount].fdstart = 0;
177 						image->regions[regcount].fdsize = 0;
178 						image->regions[regcount].delta = 0;
179 						image->regions[regcount].flags = RFLAG_ANON;
180 						if (pheader->p_flags & PF_WRITE) {
181 							// this is a writable segment
182 							image->regions[regcount].flags |= RFLAG_RW;
183 						}
184 					}
185 				}
186 				regcount += 1;
187 				break;
188 			case PT_DYNAMIC:
189 				image->dynamic_ptr = pheader->p_vaddr;
190 				break;
191 			case PT_INTERP:
192 				// should check here for appropiate interpreter
193 				break;
194 			case PT_NOTE:
195 				// unsupported
196 				break;
197 			case PT_SHLIB:
198 				// undefined semantics
199 				break;
200 			case PT_PHDR:
201 				// we don't use it
202 				break;
203 			case PT_EH_FRAME:
204 			case PT_RELRO:
205 				// not implemented yet, but can be ignored
206 				break;
207 			case PT_STACK:
208 				// we don't use it
209 				break;
210 			case PT_TLS:
211 				image->dso_tls_id
212 					= TLSBlockTemplates::Get().Register(
213 						TLSBlockTemplate((void*)pheader->p_vaddr,
214 							pheader->p_filesz, pheader->p_memsz));
215 				break;
216 			default:
217 				FATAL("%s: Unhandled pheader type in parse 0x%" B_PRIx32 "\n",
218 					image->path, pheader->p_type);
219 				return B_BAD_DATA;
220 		}
221 	}
222 
223 	return B_OK;
224 }
225 
226 
227 static bool
228 assert_dynamic_loadable(image_t* image)
229 {
230 	uint32 i;
231 
232 	if (!image->dynamic_ptr)
233 		return true;
234 
235 	for (i = 0; i < image->num_regions; i++) {
236 		if (image->dynamic_ptr >= image->regions[i].start
237 			&& image->dynamic_ptr
238 				< image->regions[i].start + image->regions[i].size) {
239 			return true;
240 		}
241 	}
242 
243 	return false;
244 }
245 
246 
247 static bool
248 parse_dynamic_segment(image_t* image)
249 {
250 	elf_dyn* d;
251 	int i;
252 	int sonameOffset = -1;
253 
254 	image->symhash = 0;
255 	image->syms = 0;
256 	image->strtab = 0;
257 
258 	d = (elf_dyn*)image->dynamic_ptr;
259 	if (!d)
260 		return true;
261 
262 	for (i = 0; d[i].d_tag != DT_NULL; i++) {
263 		switch (d[i].d_tag) {
264 			case DT_NEEDED:
265 				image->num_needed += 1;
266 				break;
267 			case DT_HASH:
268 				image->symhash
269 					= (uint32*)(d[i].d_un.d_ptr + image->regions[0].delta);
270 				break;
271 			case DT_STRTAB:
272 				image->strtab
273 					= (char*)(d[i].d_un.d_ptr + image->regions[0].delta);
274 				break;
275 			case DT_SYMTAB:
276 				image->syms = (elf_sym*)
277 					(d[i].d_un.d_ptr + image->regions[0].delta);
278 				break;
279 			case DT_REL:
280 				image->rel = (elf_rel*)
281 					(d[i].d_un.d_ptr + image->regions[0].delta);
282 				break;
283 			case DT_RELSZ:
284 				image->rel_len = d[i].d_un.d_val;
285 				break;
286 			case DT_RELA:
287 				image->rela = (elf_rela*)
288 					(d[i].d_un.d_ptr + image->regions[0].delta);
289 				break;
290 			case DT_RELASZ:
291 				image->rela_len = d[i].d_un.d_val;
292 				break;
293 			case DT_JMPREL:
294 				// procedure linkage table relocations
295 				image->pltrel = (elf_rel*)
296 					(d[i].d_un.d_ptr + image->regions[0].delta);
297 				break;
298 			case DT_PLTRELSZ:
299 				image->pltrel_len = d[i].d_un.d_val;
300 				break;
301 			case DT_INIT:
302 				image->init_routine
303 					= (d[i].d_un.d_ptr + image->regions[0].delta);
304 				break;
305 			case DT_FINI:
306 				image->term_routine
307 					= (d[i].d_un.d_ptr + image->regions[0].delta);
308 				break;
309 			case DT_SONAME:
310 				sonameOffset = d[i].d_un.d_val;
311 				break;
312 			case DT_VERSYM:
313 				image->symbol_versions = (elf_versym*)
314 					(d[i].d_un.d_ptr + image->regions[0].delta);
315 				break;
316 			case DT_VERDEF:
317 				image->version_definitions = (elf_verdef*)
318 					(d[i].d_un.d_ptr + image->regions[0].delta);
319 				break;
320 			case DT_VERDEFNUM:
321 				image->num_version_definitions = d[i].d_un.d_val;
322 				break;
323 			case DT_VERNEED:
324 				image->needed_versions = (elf_verneed*)
325 					(d[i].d_un.d_ptr + image->regions[0].delta);
326 				break;
327 			case DT_VERNEEDNUM:
328 				image->num_needed_versions = d[i].d_un.d_val;
329 				break;
330 			case DT_SYMBOLIC:
331 				image->flags |= RFLAG_SYMBOLIC;
332 				break;
333 			case DT_FLAGS:
334 			{
335 				uint32 flags = d[i].d_un.d_val;
336 				if ((flags & DF_SYMBOLIC) != 0)
337 					image->flags |= RFLAG_SYMBOLIC;
338 				if ((flags & DF_STATIC_TLS) != 0) {
339 					FATAL("Static TLS model is not supported.\n");
340 					return false;
341 				}
342 				break;
343 			}
344 			case DT_INIT_ARRAY:
345 				// array of pointers to initialization functions
346 				image->init_array = (addr_t*)
347 					(d[i].d_un.d_ptr + image->regions[0].delta);
348 				break;
349 			case DT_INIT_ARRAYSZ:
350 				// size in bytes of the array of initialization functions
351 				image->init_array_len = d[i].d_un.d_val;
352 				break;
353 			case DT_PREINIT_ARRAY:
354 				// array of pointers to pre-initialization functions
355 				image->preinit_array = (addr_t*)
356 					(d[i].d_un.d_ptr + image->regions[0].delta);
357 				break;
358 			case DT_PREINIT_ARRAYSZ:
359 				// size in bytes of the array of pre-initialization functions
360 				image->preinit_array_len = d[i].d_un.d_val;
361 				break;
362 			case DT_FINI_ARRAY:
363 				// array of pointers to termination functions
364 				image->term_array = (addr_t*)
365 					(d[i].d_un.d_ptr + image->regions[0].delta);
366 				break;
367 			case DT_FINI_ARRAYSZ:
368 				// size in bytes of the array of termination functions
369 				image->term_array_len = d[i].d_un.d_val;
370 				break;
371 			default:
372 				continue;
373 
374 			// TODO: Implement:
375 			// DT_RELENT: The size of a DT_REL entry.
376 			// DT_RELAENT: The size of a DT_RELA entry.
377 			// DT_SYMENT: The size of a symbol table entry.
378 			// DT_PLTREL: The type of the PLT relocation entries (DT_JMPREL).
379 			// DT_BIND_NOW/DF_BIND_NOW: No lazy binding allowed.
380 			// DT_RUNPATH: Library search path (supersedes DT_RPATH).
381 			// DT_TEXTREL/DF_TEXTREL: Indicates whether text relocations are
382 			//		required (for optimization purposes only).
383 		}
384 	}
385 
386 	// lets make sure we found all the required sections
387 	if (!image->symhash || !image->syms || !image->strtab)
388 		return false;
389 
390 	if (sonameOffset >= 0)
391 		strlcpy(image->name, STRING(image, sonameOffset), sizeof(image->name));
392 
393 	return true;
394 }
395 
396 
397 // #pragma mark -
398 
399 
400 status_t
401 parse_elf_header(elf_ehdr* eheader, int32* _pheaderSize,
402 	int32* _sheaderSize)
403 {
404 	if (memcmp(eheader->e_ident, ELFMAG, 4) != 0)
405 		return B_NOT_AN_EXECUTABLE;
406 
407 	if (eheader->e_ident[4] != ELF_CLASS)
408 		return B_NOT_AN_EXECUTABLE;
409 
410 	if (eheader->e_phoff == 0)
411 		return B_NOT_AN_EXECUTABLE;
412 
413 	if (eheader->e_phentsize < sizeof(elf_phdr))
414 		return B_NOT_AN_EXECUTABLE;
415 
416 	*_pheaderSize = eheader->e_phentsize * eheader->e_phnum;
417 	*_sheaderSize = eheader->e_shentsize * eheader->e_shnum;
418 
419 	if (*_pheaderSize <= 0)
420 		return B_NOT_AN_EXECUTABLE;
421 
422 	return B_OK;
423 }
424 
425 
426 #if defined(_COMPAT_MODE)
427 #if defined(__x86_64__)
428 status_t
429 parse_elf32_header(Elf32_Ehdr* eheader, int32* _pheaderSize,
430 	int32* _sheaderSize)
431 {
432 	if (memcmp(eheader->e_ident, ELFMAG, 4) != 0)
433 		return B_NOT_AN_EXECUTABLE;
434 
435 	if (eheader->e_ident[4] != ELFCLASS32)
436 		return B_NOT_AN_EXECUTABLE;
437 
438 	if (eheader->e_phoff == 0)
439 		return B_NOT_AN_EXECUTABLE;
440 
441 	if (eheader->e_phentsize < sizeof(Elf32_Phdr))
442 		return B_NOT_AN_EXECUTABLE;
443 
444 	*_pheaderSize = eheader->e_phentsize * eheader->e_phnum;
445 	*_sheaderSize = eheader->e_shentsize * eheader->e_shnum;
446 
447 	if (*_pheaderSize <= 0)
448 		return B_NOT_AN_EXECUTABLE;
449 
450 	return B_OK;
451 }
452 #else
453 status_t
454 parse_elf64_header(Elf64_Ehdr* eheader, int32* _pheaderSize,
455 	int32* _sheaderSize)
456 {
457 	if (memcmp(eheader->e_ident, ELFMAG, 4) != 0)
458 		return B_NOT_AN_EXECUTABLE;
459 
460 	if (eheader->e_ident[4] != ELFCLASS64)
461 		return B_NOT_AN_EXECUTABLE;
462 
463 	if (eheader->e_phoff == 0)
464 		return B_NOT_AN_EXECUTABLE;
465 
466 	if (eheader->e_phentsize < sizeof(Elf64_Phdr))
467 		return B_NOT_AN_EXECUTABLE;
468 
469 	*_pheaderSize = eheader->e_phentsize * eheader->e_phnum;
470 	*_sheaderSize = eheader->e_shentsize * eheader->e_shnum;
471 
472 	if (*_pheaderSize <= 0)
473 		return B_NOT_AN_EXECUTABLE;
474 
475 	return B_OK;
476 }
477 #endif	// __x86_64__
478 #endif	// _COMPAT_MODE
479 
480 
481 status_t
482 load_image(char const* name, image_type type, const char* rpath,
483 	const char* requestingObjectPath, image_t** _image)
484 {
485 	int32 pheaderSize, sheaderSize;
486 	char path[PATH_MAX];
487 	ssize_t length;
488 	char pheaderBuffer[4096];
489 	int32 numRegions;
490 	image_t* found;
491 	image_t* image;
492 	status_t status;
493 	int fd;
494 
495 	elf_ehdr eheader;
496 
497 	// Have we already loaded that image? Don't check for add-ons -- we always
498 	// reload them.
499 	if (type != B_ADD_ON_IMAGE) {
500 		found = find_loaded_image_by_name(name, APP_OR_LIBRARY_TYPE);
501 
502 		if (found == NULL && type != B_APP_IMAGE && gProgramImage != NULL) {
503 			// Special case for add-ons that link against the application
504 			// executable, with the executable not having a soname set.
505 			if (const char* lastSlash = strrchr(name, '/')) {
506 				if (strcmp(gProgramImage->name, lastSlash + 1) == 0)
507 					found = gProgramImage;
508 			}
509 		}
510 
511 		if (found) {
512 			atomic_add(&found->ref_count, 1);
513 			*_image = found;
514 			KTRACE("rld: load_container(\"%s\", type: %d, rpath: \"%s\") "
515 				"already loaded", name, type, rpath);
516 			return B_OK;
517 		}
518 	}
519 
520 	KTRACE("rld: load_container(\"%s\", type: %d, rpath: \"%s\")", name, type,
521 		rpath);
522 
523 	strlcpy(path, name, sizeof(path));
524 
525 	// find and open the file
526 	fd = open_executable(path, type, rpath, get_program_path(),
527 		requestingObjectPath, sSearchPathSubDir);
528 	if (fd < 0) {
529 		FATAL("Cannot open file %s (needed by %s): %s\n", name, requestingObjectPath, strerror(fd));
530 		KTRACE("rld: load_container(\"%s\"): failed to open file", name);
531 		return fd;
532 	}
533 
534 	// normalize the image path
535 	status = _kern_normalize_path(path, true, path);
536 	if (status != B_OK)
537 		goto err1;
538 
539 	// Test again if this image has been registered already - this time,
540 	// we can check the full path, not just its name as noted.
541 	// You could end up loading an image twice with symbolic links, else.
542 	if (type != B_ADD_ON_IMAGE) {
543 		found = find_loaded_image_by_name(path, APP_OR_LIBRARY_TYPE);
544 		if (found) {
545 			atomic_add(&found->ref_count, 1);
546 			*_image = found;
547 			_kern_close(fd);
548 			KTRACE("rld: load_container(\"%s\"): already loaded after all",
549 				name);
550 			return B_OK;
551 		}
552 	}
553 
554 	length = _kern_read(fd, 0, &eheader, sizeof(eheader));
555 	if (length != sizeof(eheader)) {
556 		status = B_NOT_AN_EXECUTABLE;
557 		FATAL("%s: Troubles reading ELF header\n", path);
558 		goto err1;
559 	}
560 
561 	status = parse_elf_header(&eheader, &pheaderSize, &sheaderSize);
562 	if (status < B_OK) {
563 		FATAL("%s: Incorrect ELF header\n", path);
564 		goto err1;
565 	}
566 
567 	// ToDo: what to do about this restriction??
568 	if (pheaderSize > (int)sizeof(pheaderBuffer)) {
569 		FATAL("%s: Cannot handle program headers bigger than %lu\n",
570 			path, sizeof(pheaderBuffer));
571 		status = B_UNSUPPORTED;
572 		goto err1;
573 	}
574 
575 	length = _kern_read(fd, eheader.e_phoff, pheaderBuffer, pheaderSize);
576 	if (length != pheaderSize) {
577 		FATAL("%s: Could not read program headers: %s\n", path,
578 			strerror(length));
579 		status = B_BAD_DATA;
580 		goto err1;
581 	}
582 
583 	numRegions = count_regions(path, pheaderBuffer, eheader.e_phnum,
584 		eheader.e_phentsize);
585 	if (numRegions <= 0) {
586 		FATAL("%s: Troubles parsing Program headers, numRegions = %" B_PRId32
587 			"\n", path, numRegions);
588 		status = B_BAD_DATA;
589 		goto err1;
590 	}
591 
592 	image = create_image(name, path, numRegions);
593 	if (image == NULL) {
594 		FATAL("%s: Failed to allocate image_t object\n", path);
595 		status = B_NO_MEMORY;
596 		goto err1;
597 	}
598 
599 	status = parse_program_headers(image, pheaderBuffer, eheader.e_phnum,
600 		eheader.e_phentsize);
601 	if (status < B_OK)
602 		goto err2;
603 
604 	if (!assert_dynamic_loadable(image)) {
605 		FATAL("%s: Dynamic segment must be loadable (implementation "
606 			"restriction)\n", image->path);
607 		status = B_UNSUPPORTED;
608 		goto err2;
609 	}
610 
611 	status = map_image(fd, path, image, eheader.e_type == ET_EXEC);
612 	if (status < B_OK) {
613 		FATAL("%s: Could not map image: %s\n", image->path, strerror(status));
614 		status = B_ERROR;
615 		goto err2;
616 	}
617 
618 	if (!parse_dynamic_segment(image)) {
619 		FATAL("%s: Troubles handling dynamic section\n", image->path);
620 		status = B_BAD_DATA;
621 		goto err3;
622 	}
623 
624 	if (eheader.e_entry != 0)
625 		image->entry_point = eheader.e_entry + image->regions[0].delta;
626 
627 	analyze_image_haiku_version_and_abi(fd, image, eheader, sheaderSize,
628 		pheaderBuffer, sizeof(pheaderBuffer));
629 
630 	// If sSearchPathSubDir is unset (meaning, this is the first image we're
631 	// loading) we init the search path subdir if the compiler version doesn't
632 	// match ours.
633 	if (sSearchPathSubDir == NULL) {
634 		#if __GNUC__ == 2 || (defined(_COMPAT_MODE) && !defined(__x86_64__))
635 			if ((image->abi & B_HAIKU_ABI_MAJOR) == B_HAIKU_ABI_GCC_4)
636 				sSearchPathSubDir = "x86";
637 		#endif
638 		#if __GNUC__ >= 4 || (defined(_COMPAT_MODE) && !defined(__x86_64__))
639 			if ((image->abi & B_HAIKU_ABI_MAJOR) == B_HAIKU_ABI_GCC_2)
640 				sSearchPathSubDir = "x86_gcc2";
641 		#endif
642 	}
643 
644 	set_abi_api_version(image->abi, image->api_version);
645 
646 	// init gcc version dependent image flags
647 	// symbol resolution strategy
648 	if (image->abi == B_HAIKU_ABI_GCC_2_ANCIENT)
649 		image->find_undefined_symbol = find_undefined_symbol_beos;
650 
651 	// init version infos
652 	status = init_image_version_infos(image);
653 
654 	image->type = type;
655 	register_image(image, fd, path);
656 	image_event(image, IMAGE_EVENT_LOADED);
657 
658 	_kern_close(fd);
659 
660 	enqueue_loaded_image(image);
661 
662 	*_image = image;
663 
664 	KTRACE("rld: load_container(\"%s\"): done: id: %" B_PRId32 " (ABI: %#"
665 		B_PRIx32 ")", name, image->id, image->abi);
666 
667 	return B_OK;
668 
669 err3:
670 	unmap_image(image);
671 err2:
672 	delete_image_struct(image);
673 err1:
674 	_kern_close(fd);
675 
676 	KTRACE("rld: load_container(\"%s\"): failed: %s", name,
677 		strerror(status));
678 
679 	return status;
680 }
681