libroot_debug: Merge guarded heap into libroot_debug.
[haiku.git] / src / system / runtime_loader / runtime_loader.cpp
blobfa507eba7e5d2395e60666d947133c71ec5461db
1 /*
2 * Copyright 2005-2009, Axel Dörfler, axeld@pinc-software.de.
3 * Distributed under the terms of the MIT License.
5 * Copyright 2002, Manuel J. Petit. All rights reserved.
6 * Distributed under the terms of the NewOS License.
7 */
10 #include "runtime_loader_private.h"
12 #include <string.h>
13 #include <stdlib.h>
14 #include <sys/stat.h>
16 #include <algorithm>
18 #include <ByteOrder.h>
20 #include <directories.h>
21 #include <find_directory_private.h>
22 #include <image_defs.h>
23 #include <syscalls.h>
24 #include <user_runtime.h>
25 #include <vm_defs.h>
27 #include "elf_symbol_lookup.h"
28 #include "pe.h"
31 struct user_space_program_args *gProgramArgs;
32 void *__gCommPageAddress;
33 void *__dso_handle;
35 int32 __gCPUCount = 1;
37 const directory_which kLibraryDirectories[] = {
38 B_SYSTEM_LIB_DIRECTORY,
39 B_SYSTEM_NONPACKAGED_LIB_DIRECTORY,
40 B_USER_LIB_DIRECTORY,
41 B_USER_NONPACKAGED_LIB_DIRECTORY
45 static const char *
46 search_path_for_type(image_type type)
48 const char *path = NULL;
50 // TODO: The *PATH variables should not include the standard system paths.
51 // Instead those paths should always be used after the directories specified
52 // via the variables.
53 switch (type) {
54 case B_APP_IMAGE:
55 path = getenv("PATH");
56 break;
57 case B_LIBRARY_IMAGE:
58 path = getenv("LIBRARY_PATH");
59 break;
60 case B_ADD_ON_IMAGE:
61 path = getenv("ADDON_PATH");
62 break;
64 default:
65 return NULL;
68 if (path != NULL)
69 return path;
71 // The environment variables may not have been set yet - in that case,
72 // we're returning some useful defaults.
73 // Since the kernel does not set any variables, this is also needed
74 // to start the root shell.
76 // TODO: The user specific paths should not be used by default.
77 switch (type) {
78 case B_APP_IMAGE:
79 return kUserNonpackagedBinDirectory
80 ":" kUserBinDirectory
81 // TODO: Remove!
82 ":" kSystemNonpackagedBinDirectory
83 ":" kGlobalBinDirectory
84 ":" kSystemAppsDirectory
85 ":" kSystemPreferencesDirectory;
87 case B_LIBRARY_IMAGE:
88 return kAppLocalLibDirectory
89 ":" kUserNonpackagedLibDirectory
90 ":" kUserLibDirectory
91 // TODO: Remove!
92 ":" kSystemNonpackagedLibDirectory
93 ":" kSystemLibDirectory;
95 case B_ADD_ON_IMAGE:
96 return kAppLocalAddonsDirectory
97 ":" kUserNonpackagedAddonsDirectory
98 ":" kUserAddonsDirectory
99 // TODO: Remove!
100 ":" kSystemNonpackagedAddonsDirectory
101 ":" kSystemAddonsDirectory;
103 default:
104 return NULL;
109 static bool
110 replace_executable_path_placeholder(const char*& dir, int& dirLength,
111 const char* placeholder, size_t placeholderLength,
112 const char* replacementSubPath, char*& buffer, size_t& bufferSize,
113 status_t& _error)
115 if (dirLength < (int)placeholderLength
116 || strncmp(dir, placeholder, placeholderLength) != 0) {
117 return false;
120 if (replacementSubPath == NULL) {
121 _error = B_ENTRY_NOT_FOUND;
122 return true;
125 char* lastSlash = strrchr(replacementSubPath, '/');
127 // Copy replacementSubPath without the last component (the application file
128 // name, respectively the requesting executable file name).
129 size_t toCopy;
130 if (lastSlash != NULL) {
131 toCopy = lastSlash - replacementSubPath;
132 strlcpy(buffer, replacementSubPath,
133 std::min((ssize_t)bufferSize, lastSlash + 1 - replacementSubPath));
134 } else {
135 replacementSubPath = ".";
136 toCopy = 1;
137 strlcpy(buffer, ".", bufferSize);
140 if (toCopy >= bufferSize) {
141 _error = B_NAME_TOO_LONG;
142 return true;
145 memcpy(buffer, replacementSubPath, toCopy);
146 buffer[toCopy] = '\0';
148 buffer += toCopy;
149 bufferSize -= toCopy;
150 dir += placeholderLength;
151 dirLength -= placeholderLength;
153 _error = B_OK;
154 return true;
158 static int
159 try_open_executable(const char *dir, int dirLength, const char *name,
160 const char *programPath, const char *requestingObjectPath,
161 const char *abiSpecificSubDir, char *path, size_t pathLength)
163 size_t nameLength = strlen(name);
164 struct stat stat;
165 status_t status;
167 // construct the path
168 if (dirLength > 0) {
169 char *buffer = path;
170 size_t subDirLen = 0;
172 if (programPath == NULL)
173 programPath = gProgramArgs->program_path;
175 if (replace_executable_path_placeholder(dir, dirLength, "%A", 2,
176 programPath, buffer, pathLength, status)
177 || replace_executable_path_placeholder(dir, dirLength, "$ORIGIN", 7,
178 requestingObjectPath, buffer, pathLength, status)) {
179 if (status != B_OK)
180 return status;
181 } else if (abiSpecificSubDir != NULL) {
182 // We're looking for a library or an add-on and the executable has
183 // not been compiled with a compiler using the same ABI as the one
184 // the OS has been built with. Thus we only look in subdirs
185 // specific to that ABI.
186 // However, only if it's a known library location
187 for (int i = 0; i < 4; ++i) {
188 char buffer[PATH_MAX];
189 status_t result = __find_directory(kLibraryDirectories[i], -1,
190 false, buffer, PATH_MAX);
191 if (result == B_OK && strncmp(dir, buffer, dirLength) == 0) {
192 subDirLen = strlen(abiSpecificSubDir) + 1;
193 break;
198 if (dirLength + 1 + subDirLen + nameLength >= pathLength)
199 return B_NAME_TOO_LONG;
201 memcpy(buffer, dir, dirLength);
202 buffer[dirLength] = '/';
203 if (subDirLen > 0) {
204 memcpy(buffer + dirLength + 1, abiSpecificSubDir, subDirLen - 1);
205 buffer[dirLength + subDirLen] = '/';
207 strcpy(buffer + dirLength + 1 + subDirLen, name);
208 } else {
209 if (nameLength >= pathLength)
210 return B_NAME_TOO_LONG;
212 strcpy(path + dirLength + 1, name);
215 TRACE(("runtime_loader: try_open_container(): %s\n", path));
217 // Test if the target is a symbolic link, and correct the path in this case
219 status = _kern_read_stat(-1, path, false, &stat, sizeof(struct stat));
220 if (status < B_OK)
221 return status;
223 if (S_ISLNK(stat.st_mode)) {
224 char buffer[PATH_MAX];
225 size_t length = PATH_MAX - 1;
226 char *lastSlash;
228 // it's a link, indeed
229 status = _kern_read_link(-1, path, buffer, &length);
230 if (status < B_OK)
231 return status;
232 buffer[length] = '\0';
234 lastSlash = strrchr(path, '/');
235 if (buffer[0] != '/' && lastSlash != NULL) {
236 // relative path
237 strlcpy(lastSlash + 1, buffer, lastSlash + 1 - path + pathLength);
238 } else
239 strlcpy(path, buffer, pathLength);
242 return _kern_open(-1, path, O_RDONLY, 0);
246 static int
247 search_executable_in_path_list(const char *name, const char *pathList,
248 int pathListLen, const char *programPath, const char *requestingObjectPath,
249 const char *abiSpecificSubDir, char *pathBuffer, size_t pathBufferLength)
251 const char *pathListEnd = pathList + pathListLen;
252 status_t status = B_ENTRY_NOT_FOUND;
254 TRACE(("runtime_loader: search_container_in_path_list() %s in %.*s\n", name,
255 pathListLen, pathList));
257 while (pathListLen > 0) {
258 const char *pathEnd = pathList;
259 int fd;
261 // find the next ':' or run till the end of the string
262 while (pathEnd < pathListEnd && *pathEnd != ':')
263 pathEnd++;
265 fd = try_open_executable(pathList, pathEnd - pathList, name,
266 programPath, requestingObjectPath, abiSpecificSubDir, pathBuffer,
267 pathBufferLength);
268 if (fd >= 0) {
269 // see if it's a dir
270 struct stat stat;
271 status = _kern_read_stat(fd, NULL, true, &stat, sizeof(struct stat));
272 if (status == B_OK) {
273 if (!S_ISDIR(stat.st_mode))
274 return fd;
275 status = B_IS_A_DIRECTORY;
277 _kern_close(fd);
280 pathListLen = pathListEnd - pathEnd - 1;
281 pathList = pathEnd + 1;
284 return status;
289 open_executable(char *name, image_type type, const char *rpath,
290 const char *programPath, const char *requestingObjectPath,
291 const char *abiSpecificSubDir)
293 char buffer[PATH_MAX];
294 int fd = B_ENTRY_NOT_FOUND;
296 if (strchr(name, '/')) {
297 // the name already contains a path, we don't have to search for it
298 fd = _kern_open(-1, name, O_RDONLY, 0);
299 if (fd >= 0 || type == B_APP_IMAGE)
300 return fd;
302 // can't search harder an absolute path add-on name!
303 if (type == B_ADD_ON_IMAGE && name[0] == '/')
304 return fd;
306 // Even though ELF specs don't say this, we give shared libraries
307 // and relative path based add-ons another chance and look
308 // them up in the usual search paths - at
309 // least that seems to be what BeOS does, and since it doesn't hurt...
310 if (type == B_LIBRARY_IMAGE) {
311 // For library (but not add-on), strip any path from name.
312 // Relative path of add-on is kept.
313 const char* paths = strrchr(name, '/') + 1;
314 memmove(name, paths, strlen(paths) + 1);
318 // try rpath (DT_RPATH)
319 if (rpath != NULL) {
320 // It consists of a colon-separated search path list. Optionally a
321 // second search path list follows, separated from the first by a
322 // semicolon.
323 const char *semicolon = strchr(rpath, ';');
324 const char *firstList = (semicolon ? rpath : NULL);
325 const char *secondList = (semicolon ? semicolon + 1 : rpath);
326 // If there is no ';', we set only secondList to simplify things.
327 if (firstList) {
328 fd = search_executable_in_path_list(name, firstList,
329 semicolon - firstList, programPath, requestingObjectPath, NULL,
330 buffer, sizeof(buffer));
332 if (fd < 0) {
333 fd = search_executable_in_path_list(name, secondList,
334 strlen(secondList), programPath, requestingObjectPath, NULL,
335 buffer, sizeof(buffer));
339 // If not found yet, let's evaluate the system path variables to find the
340 // shared object.
341 if (fd < 0) {
342 if (const char *paths = search_path_for_type(type)) {
343 fd = search_executable_in_path_list(name, paths, strlen(paths),
344 programPath, NULL, abiSpecificSubDir, buffer, sizeof(buffer));
348 if (fd >= 0) {
349 // we found it, copy path!
350 TRACE(("runtime_loader: open_executable(%s): found at %s\n", name, buffer));
351 strlcpy(name, buffer, PATH_MAX);
354 return fd;
359 Applies haiku-specific fixes to a shebang line.
361 static void
362 fixup_shebang(char *invoker)
364 char *current = invoker;
365 while (*current == ' ' || *current == '\t') {
366 ++current;
369 char *commandStart = current;
370 while (*current != ' ' && *current != '\t' && *current != '\0') {
371 ++current;
374 // replace /usr/bin/env with /bin/env
375 if (memcmp(commandStart, "/usr/bin/env", current - commandStart) == 0)
376 memmove(commandStart, commandStart + 4, strlen(commandStart + 4) + 1);
381 Tests if there is an executable file at the provided path. It will
382 also test if the file has a valid ELF header or is a shell script.
383 Even if the runtime loader does not need to be able to deal with
384 both types, the caller will give scripts a proper treatment.
386 status_t
387 test_executable(const char *name, char *invoker)
389 char path[B_PATH_NAME_LENGTH];
390 char buffer[B_FILE_NAME_LENGTH];
391 // must be large enough to hold the ELF header
392 status_t status;
393 ssize_t length;
394 int fd;
396 if (name == NULL)
397 return B_BAD_VALUE;
399 strlcpy(path, name, sizeof(path));
401 fd = open_executable(path, B_APP_IMAGE, NULL, NULL, NULL, NULL);
402 if (fd < B_OK)
403 return fd;
405 // see if it's executable at all
406 status = _kern_access(-1, path, X_OK, false);
407 if (status != B_OK)
408 goto out;
410 // read and verify the ELF header
412 length = _kern_read(fd, 0, buffer, sizeof(buffer));
413 if (length < 0) {
414 status = length;
415 goto out;
418 status = elf_verify_header(buffer, length);
419 if (status == B_NOT_AN_EXECUTABLE) {
420 if (!strncmp(buffer, "#!", 2)) {
421 // test for shell scripts
422 char *end;
423 buffer[min_c((size_t)length, sizeof(buffer) - 1)] = '\0';
425 end = strchr(buffer, '\n');
426 if (end == NULL) {
427 status = E2BIG;
428 goto out;
429 } else
430 end[0] = '\0';
432 if (invoker) {
433 strcpy(invoker, buffer + 2);
434 fixup_shebang(invoker);
437 status = B_OK;
438 } else {
439 // Something odd like a PE?
440 status = pe_verify_header(buffer, length);
442 // It is a PE, throw B_UNKNOWN_EXECUTABLE
443 // likely win32 at this point
444 if (status == B_OK)
445 status = B_UNKNOWN_EXECUTABLE;
447 } else if (status == B_OK) {
448 elf_ehdr *elfHeader = (elf_ehdr *)buffer;
449 if (elfHeader->e_entry == 0) {
450 // we don't like to open shared libraries
451 status = B_NOT_AN_EXECUTABLE;
452 } else if (invoker)
453 invoker[0] = '\0';
456 out:
457 _kern_close(fd);
458 return status;
462 static bool
463 determine_x86_abi(int fd, const Elf32_Ehdr& elfHeader, bool& _isGcc2)
465 // Unless we're a little-endian CPU, don't bother. We're not x86, so it
466 // doesn't matter all that much whether we can determine the correct gcc
467 // ABI. This saves the code below from having to deal with endianess
468 // conversion.
469 #if B_HOST_IS_LENDIAN
471 // Since we don't want to load the complete image, we can't use the
472 // functions that normally determine the Haiku version and ABI. Instead
473 // we'll load the symbol and string tables and resolve the ABI symbol
474 // manually.
476 // map the file into memory
477 struct stat st;
478 if (_kern_read_stat(fd, NULL, true, &st, sizeof(st)) != B_OK)
479 return false;
481 void* fileBaseAddress;
482 area_id area = _kern_map_file("mapped file", &fileBaseAddress,
483 B_ANY_ADDRESS, st.st_size, B_READ_AREA, REGION_NO_PRIVATE_MAP, false,
484 fd, 0);
485 if (area < 0)
486 return false;
488 struct AreaDeleter {
489 AreaDeleter(area_id area)
491 fArea(area)
495 ~AreaDeleter()
497 _kern_delete_area(fArea);
500 private:
501 area_id fArea;
502 } areaDeleter(area);
504 // get the section headers
505 if (elfHeader.e_shoff == 0 || elfHeader.e_shentsize < sizeof(Elf32_Shdr))
506 return false;
508 size_t sectionHeadersSize = elfHeader.e_shentsize * elfHeader.e_shnum;
509 if (elfHeader.e_shoff + (off_t)sectionHeadersSize > st.st_size)
510 return false;
512 void* sectionHeaders = (uint8*)fileBaseAddress + elfHeader.e_shoff;
514 // find the sections we need
515 uint32* symbolHash = NULL;
516 uint32 symbolHashSize = 0;
517 uint32 symbolHashChainSize = 0;
518 Elf32_Sym* symbolTable = NULL;
519 uint32 symbolTableSize = 0;
520 const char* stringTable = NULL;
521 off_t stringTableSize = 0;
523 for (int32 i = 0; i < elfHeader.e_shnum; i++) {
524 Elf32_Shdr* sectionHeader
525 = (Elf32_Shdr*)((uint8*)sectionHeaders + i * elfHeader.e_shentsize);
526 if ((off_t)sectionHeader->sh_offset + (off_t)sectionHeader->sh_size
527 > st.st_size) {
528 continue;
531 void* sectionAddress = (uint8*)fileBaseAddress
532 + sectionHeader->sh_offset;
534 switch (sectionHeader->sh_type) {
535 case SHT_HASH:
536 symbolHash = (uint32*)sectionAddress;
537 if (sectionHeader->sh_size < (off_t)sizeof(symbolHash[0]))
538 return false;
539 symbolHashSize = symbolHash[0];
540 symbolHashChainSize
541 = sectionHeader->sh_size / sizeof(symbolHash[0]);
542 if (symbolHashChainSize < symbolHashSize + 2)
543 return false;
544 symbolHashChainSize -= symbolHashSize + 2;
545 break;
546 case SHT_DYNSYM:
547 symbolTable = (Elf32_Sym*)sectionAddress;
548 symbolTableSize = sectionHeader->sh_size;
549 break;
550 case SHT_STRTAB:
551 // .shstrtab has the same type as .dynstr, but it isn't loaded
552 // into memory.
553 if (sectionHeader->sh_addr == 0)
554 continue;
555 stringTable = (const char*)sectionAddress;
556 stringTableSize = (off_t)sectionHeader->sh_size;
557 break;
558 default:
559 continue;
563 if (symbolHash == NULL || symbolTable == NULL || stringTable == NULL)
564 return false;
565 uint32 symbolCount
566 = std::min(symbolTableSize / (uint32)sizeof(Elf32_Sym),
567 symbolHashChainSize);
568 if (symbolCount < symbolHashSize)
569 return false;
571 // look up the ABI symbol
572 const char* name = B_SHARED_OBJECT_HAIKU_ABI_VARIABLE_NAME;
573 size_t nameLength = strlen(name);
574 uint32 bucket = elf_hash(name) % symbolHashSize;
576 for (uint32 i = symbolHash[bucket + 2]; i < symbolCount && i != STN_UNDEF;
577 i = symbolHash[2 + symbolHashSize + i]) {
578 Elf32_Sym* symbol = symbolTable + i;
579 if (symbol->st_shndx != SHN_UNDEF
580 && ((symbol->Bind() == STB_GLOBAL) || (symbol->Bind() == STB_WEAK))
581 && symbol->Type() == STT_OBJECT
582 && (off_t)symbol->st_name + (off_t)nameLength < stringTableSize
583 && strcmp(stringTable + symbol->st_name, name) == 0) {
584 if (symbol->st_value > 0 && symbol->st_size >= sizeof(uint32)
585 && symbol->st_shndx < elfHeader.e_shnum) {
586 Elf32_Shdr* sectionHeader = (Elf32_Shdr*)((uint8*)sectionHeaders
587 + symbol->st_shndx * elfHeader.e_shentsize);
588 if (symbol->st_value >= sectionHeader->sh_addr
589 && symbol->st_value
590 <= sectionHeader->sh_addr + sectionHeader->sh_size) {
591 off_t fileOffset = symbol->st_value - sectionHeader->sh_addr
592 + sectionHeader->sh_offset;
593 if (fileOffset + (off_t)sizeof(uint32) <= st.st_size) {
594 uint32 abi
595 = *(uint32*)((uint8*)fileBaseAddress + fileOffset);
596 _isGcc2 = (abi & B_HAIKU_ABI_MAJOR)
597 == B_HAIKU_ABI_GCC_2;
598 return true;
603 return false;
607 // ABI symbol not found. That means the object pre-dates its introduction
608 // in Haiku. So this is most likely gcc 2. We don't fall back to reading
609 // the comment sections to verify.
610 _isGcc2 = true;
611 return true;
612 #else // not little endian
613 return false;
614 #endif
618 static status_t
619 get_executable_architecture(int fd, const char** _architecture)
621 // Read the ELF header. We read the 32 bit header. Generally the e_machine
622 // field is the last one that interests us and the 64 bit header is still
623 // identical at that point.
624 Elf32_Ehdr elfHeader;
625 ssize_t bytesRead = _kern_read(fd, 0, &elfHeader, sizeof(elfHeader));
626 if (bytesRead < 0)
627 return bytesRead;
628 if ((size_t)bytesRead != sizeof(elfHeader))
629 return B_NOT_AN_EXECUTABLE;
631 // check whether this is indeed an ELF file
632 if (memcmp(elfHeader.e_ident, ELF_MAGIC, 4) != 0)
633 return B_NOT_AN_EXECUTABLE;
635 // check the architecture
636 uint16 machine = elfHeader.e_machine;
637 if ((elfHeader.e_ident[EI_DATA] == ELFDATA2LSB) != (B_HOST_IS_LENDIAN != 0))
638 machine = (machine >> 8) | (machine << 8);
640 const char* architecture = NULL;
641 switch (machine) {
642 case EM_386:
643 case EM_486:
645 bool isGcc2;
646 if (determine_x86_abi(fd, elfHeader, isGcc2) && isGcc2)
647 architecture = "x86_gcc2";
648 else
649 architecture = "x86";
650 break;
652 case EM_68K:
653 architecture = "m68k";
654 break;
655 case EM_PPC:
656 architecture = "ppc";
657 break;
658 case EM_ARM:
659 architecture = "arm";
660 break;
661 case EM_X86_64:
662 architecture = "x86_64";
663 break;
666 if (architecture == NULL)
667 return B_NOT_SUPPORTED;
669 *_architecture = architecture;
670 return B_OK;
674 status_t
675 get_executable_architecture(const char* path, const char** _architecture)
677 int fd = _kern_open(-1, path, O_RDONLY, 0);
678 if (fd < 0)
679 return fd;
681 status_t error = get_executable_architecture(fd, _architecture);
683 _kern_close(fd);
684 return error;
689 This is the main entry point of the runtime loader as
690 specified by its ld-script.
693 runtime_loader(void* _args, void* commpage)
695 void *entry = NULL;
696 int returnCode;
698 gProgramArgs = (struct user_space_program_args *)_args;
699 __gCommPageAddress = commpage;
701 // Relocate the args and env arrays -- they are organized in a contiguous
702 // buffer which the kernel just copied into user space without adjusting the
703 // pointers.
705 int32 i;
706 addr_t relocationOffset = 0;
708 if (gProgramArgs->arg_count > 0)
709 relocationOffset = (addr_t)gProgramArgs->args[0];
710 else if (gProgramArgs->env_count > 0)
711 relocationOffset = (addr_t)gProgramArgs->env[0];
713 // That's basically: <new buffer address> - <old buffer address>.
714 // It looks a little complicated, since we don't have the latter one at
715 // hand and thus need to reconstruct it (<first string pointer> -
716 // <arguments + environment array sizes>).
717 relocationOffset = (addr_t)gProgramArgs->args - relocationOffset
718 + (gProgramArgs->arg_count + gProgramArgs->env_count + 2)
719 * sizeof(char*);
721 for (i = 0; i < gProgramArgs->arg_count; i++)
722 gProgramArgs->args[i] += relocationOffset;
724 for (i = 0; i < gProgramArgs->env_count; i++)
725 gProgramArgs->env[i] += relocationOffset;
728 #if DEBUG_RLD
729 close(0); open("/dev/console", 0); /* stdin */
730 close(1); open("/dev/console", 0); /* stdout */
731 close(2); open("/dev/console", 0); /* stderr */
732 #endif
734 if (heap_init() < B_OK)
735 return 1;
737 rldexport_init();
738 rldelf_init();
740 load_program(gProgramArgs->program_path, &entry);
742 if (entry == NULL)
743 return -1;
745 // call the program entry point (usually _start())
746 returnCode = ((int (*)(int, void *, void *))entry)(gProgramArgs->arg_count,
747 gProgramArgs->args, gProgramArgs->env);
749 terminate_program();
751 return returnCode;