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.
10 #include "runtime_loader_private.h"
18 #include <ByteOrder.h>
20 #include <directories.h>
21 #include <find_directory_private.h>
22 #include <image_defs.h>
24 #include <user_runtime.h>
27 #include "elf_symbol_lookup.h"
31 struct user_space_program_args
*gProgramArgs
;
32 void *__gCommPageAddress
;
35 int32 __gCPUCount
= 1;
37 const directory_which kLibraryDirectories
[] = {
38 B_SYSTEM_LIB_DIRECTORY
,
39 B_SYSTEM_NONPACKAGED_LIB_DIRECTORY
,
41 B_USER_NONPACKAGED_LIB_DIRECTORY
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
55 path
= getenv("PATH");
58 path
= getenv("LIBRARY_PATH");
61 path
= getenv("ADDON_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.
79 return kUserNonpackagedBinDirectory
82 ":" kSystemNonpackagedBinDirectory
83 ":" kGlobalBinDirectory
84 ":" kSystemAppsDirectory
85 ":" kSystemPreferencesDirectory
;
88 return kAppLocalLibDirectory
89 ":" kUserNonpackagedLibDirectory
92 ":" kSystemNonpackagedLibDirectory
93 ":" kSystemLibDirectory
;
96 return kAppLocalAddonsDirectory
97 ":" kUserNonpackagedAddonsDirectory
98 ":" kUserAddonsDirectory
100 ":" kSystemNonpackagedAddonsDirectory
101 ":" kSystemAddonsDirectory
;
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
,
115 if (dirLength
< (int)placeholderLength
116 || strncmp(dir
, placeholder
, placeholderLength
) != 0) {
120 if (replacementSubPath
== NULL
) {
121 _error
= B_ENTRY_NOT_FOUND
;
125 char* lastSlash
= strrchr(replacementSubPath
, '/');
127 // Copy replacementSubPath without the last component (the application file
128 // name, respectively the requesting executable file name).
130 if (lastSlash
!= NULL
) {
131 toCopy
= lastSlash
- replacementSubPath
;
132 strlcpy(buffer
, replacementSubPath
,
133 std::min((ssize_t
)bufferSize
, lastSlash
+ 1 - replacementSubPath
));
135 replacementSubPath
= ".";
137 strlcpy(buffer
, ".", bufferSize
);
140 if (toCopy
>= bufferSize
) {
141 _error
= B_NAME_TOO_LONG
;
145 memcpy(buffer
, replacementSubPath
, toCopy
);
146 buffer
[toCopy
] = '\0';
149 bufferSize
-= toCopy
;
150 dir
+= placeholderLength
;
151 dirLength
-= placeholderLength
;
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
);
167 // construct the 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
)) {
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;
198 if (dirLength
+ 1 + subDirLen
+ nameLength
>= pathLength
)
199 return B_NAME_TOO_LONG
;
201 memcpy(buffer
, dir
, dirLength
);
202 buffer
[dirLength
] = '/';
204 memcpy(buffer
+ dirLength
+ 1, abiSpecificSubDir
, subDirLen
- 1);
205 buffer
[dirLength
+ subDirLen
] = '/';
207 strcpy(buffer
+ dirLength
+ 1 + subDirLen
, name
);
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
));
223 if (S_ISLNK(stat
.st_mode
)) {
224 char buffer
[PATH_MAX
];
225 size_t length
= PATH_MAX
- 1;
228 // it's a link, indeed
229 status
= _kern_read_link(-1, path
, buffer
, &length
);
232 buffer
[length
] = '\0';
234 lastSlash
= strrchr(path
, '/');
235 if (buffer
[0] != '/' && lastSlash
!= NULL
) {
237 strlcpy(lastSlash
+ 1, buffer
, lastSlash
+ 1 - path
+ pathLength
);
239 strlcpy(path
, buffer
, pathLength
);
242 return _kern_open(-1, path
, O_RDONLY
, 0);
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
;
261 // find the next ':' or run till the end of the string
262 while (pathEnd
< pathListEnd
&& *pathEnd
!= ':')
265 fd
= try_open_executable(pathList
, pathEnd
- pathList
, name
,
266 programPath
, requestingObjectPath
, abiSpecificSubDir
, pathBuffer
,
271 status
= _kern_read_stat(fd
, NULL
, true, &stat
, sizeof(struct stat
));
272 if (status
== B_OK
) {
273 if (!S_ISDIR(stat
.st_mode
))
275 status
= B_IS_A_DIRECTORY
;
280 pathListLen
= pathListEnd
- pathEnd
- 1;
281 pathList
= pathEnd
+ 1;
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
)
302 // can't search harder an absolute path add-on name!
303 if (type
== B_ADD_ON_IMAGE
&& name
[0] == '/')
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)
320 // It consists of a colon-separated search path list. Optionally a
321 // second search path list follows, separated from the first by a
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.
328 fd
= search_executable_in_path_list(name
, firstList
,
329 semicolon
- firstList
, programPath
, requestingObjectPath
, NULL
,
330 buffer
, sizeof(buffer
));
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
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
));
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
);
359 Applies haiku-specific fixes to a shebang line.
362 fixup_shebang(char *invoker
)
364 char *current
= invoker
;
365 while (*current
== ' ' || *current
== '\t') {
369 char *commandStart
= current
;
370 while (*current
!= ' ' && *current
!= '\t' && *current
!= '\0') {
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.
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
399 strlcpy(path
, name
, sizeof(path
));
401 fd
= open_executable(path
, B_APP_IMAGE
, NULL
, NULL
, NULL
, NULL
);
405 // see if it's executable at all
406 status
= _kern_access(-1, path
, X_OK
, false);
410 // read and verify the ELF header
412 length
= _kern_read(fd
, 0, buffer
, sizeof(buffer
));
418 status
= elf_verify_header(buffer
, length
);
419 if (status
== B_NOT_AN_EXECUTABLE
) {
420 if (!strncmp(buffer
, "#!", 2)) {
421 // test for shell scripts
423 buffer
[min_c((size_t)length
, sizeof(buffer
) - 1)] = '\0';
425 end
= strchr(buffer
, '\n');
433 strcpy(invoker
, buffer
+ 2);
434 fixup_shebang(invoker
);
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
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
;
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
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
476 // map the file into memory
478 if (_kern_read_stat(fd
, NULL
, true, &st
, sizeof(st
)) != B_OK
)
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,
489 AreaDeleter(area_id area
)
497 _kern_delete_area(fArea
);
504 // get the section headers
505 if (elfHeader
.e_shoff
== 0 || elfHeader
.e_shentsize
< sizeof(Elf32_Shdr
))
508 size_t sectionHeadersSize
= elfHeader
.e_shentsize
* elfHeader
.e_shnum
;
509 if (elfHeader
.e_shoff
+ (off_t
)sectionHeadersSize
> st
.st_size
)
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
531 void* sectionAddress
= (uint8
*)fileBaseAddress
532 + sectionHeader
->sh_offset
;
534 switch (sectionHeader
->sh_type
) {
536 symbolHash
= (uint32
*)sectionAddress
;
537 if (sectionHeader
->sh_size
< (off_t
)sizeof(symbolHash
[0]))
539 symbolHashSize
= symbolHash
[0];
541 = sectionHeader
->sh_size
/ sizeof(symbolHash
[0]);
542 if (symbolHashChainSize
< symbolHashSize
+ 2)
544 symbolHashChainSize
-= symbolHashSize
+ 2;
547 symbolTable
= (Elf32_Sym
*)sectionAddress
;
548 symbolTableSize
= sectionHeader
->sh_size
;
551 // .shstrtab has the same type as .dynstr, but it isn't loaded
553 if (sectionHeader
->sh_addr
== 0)
555 stringTable
= (const char*)sectionAddress
;
556 stringTableSize
= (off_t
)sectionHeader
->sh_size
;
563 if (symbolHash
== NULL
|| symbolTable
== NULL
|| stringTable
== NULL
)
566 = std::min(symbolTableSize
/ (uint32
)sizeof(Elf32_Sym
),
567 symbolHashChainSize
);
568 if (symbolCount
< symbolHashSize
)
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
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
) {
595 = *(uint32
*)((uint8
*)fileBaseAddress
+ fileOffset
);
596 _isGcc2
= (abi
& B_HAIKU_ABI_MAJOR
)
597 == B_HAIKU_ABI_GCC_2
;
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.
612 #else // not little endian
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
));
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
;
646 if (determine_x86_abi(fd
, elfHeader
, isGcc2
) && isGcc2
)
647 architecture
= "x86_gcc2";
649 architecture
= "x86";
653 architecture
= "m68k";
656 architecture
= "ppc";
659 architecture
= "arm";
662 architecture
= "x86_64";
666 if (architecture
== NULL
)
667 return B_NOT_SUPPORTED
;
669 *_architecture
= architecture
;
675 get_executable_architecture(const char* path
, const char** _architecture
)
677 int fd
= _kern_open(-1, path
, O_RDONLY
, 0);
681 status_t error
= get_executable_architecture(fd
, _architecture
);
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
)
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
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)
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
;
729 close(0); open("/dev/console", 0); /* stdin */
730 close(1); open("/dev/console", 0); /* stdout */
731 close(2); open("/dev/console", 0); /* stderr */
734 if (heap_init() < B_OK
)
740 load_program(gProgramArgs
->program_path
, &entry
);
745 // call the program entry point (usually _start())
746 returnCode
= ((int (*)(int, void *, void *))entry
)(gProgramArgs
->arg_count
,
747 gProgramArgs
->args
, gProgramArgs
->env
);