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