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