mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-03-03 15:38:22 +00:00
Fix dlopen() for FreeBSD and NetBSD
This commit is contained in:
parent
2c1efd3d78
commit
f7cfe03888
3 changed files with 22 additions and 11 deletions
|
@ -22,6 +22,7 @@
|
|||
* - x86-64 Linux w/ Musl Libc
|
||||
* - x86-64 FreeBSD
|
||||
* - x86-64 Windows
|
||||
* - x86-64 NetBSD
|
||||
* - aarch64 Linux w/ Glibc
|
||||
* - aarch64 Linux w/ Musl Libc
|
||||
* - aarch64 MacOS
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "libc/fmt/itoa.h"
|
||||
#include "libc/intrin/atomic.h"
|
||||
#include "libc/intrin/bits.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/nt/dll.h"
|
||||
|
@ -147,7 +148,7 @@ static int is_file_newer_than(const char *path, const char *other) {
|
|||
}
|
||||
if (stat(other, &st2)) {
|
||||
if (errno == ENOENT) {
|
||||
return true;
|
||||
return 2;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
@ -347,6 +348,7 @@ static dontinline void elf_exec(const char *file, char **envp) {
|
|||
size_t argsize = (1 + 2 + 1 + envc + 1 + auxc * 2 + 1 + 3) * 8;
|
||||
size_t mapsize = (stksize + argsize + (pagesz - 1)) & -pagesz;
|
||||
size_t skew = (mapsize - argsize) & (stkalign - 1);
|
||||
if (IsFreebsd()) skew += 8; // FreeBSD calls _start() like a C function
|
||||
map = __sys_mmap(0, mapsize, PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0, 0);
|
||||
if (map == MAP_FAILED) return;
|
||||
|
@ -569,12 +571,17 @@ static dontinline bool foreign_compile(char exe[hasatleast PATH_MAX]) {
|
|||
strlcat(exe, "dlopen-helper", PATH_MAX);
|
||||
|
||||
// skip build if helper exists and this program is older
|
||||
bool helper_exe_exists;
|
||||
switch (is_file_newer_than(GetProgramExecutableName(), exe)) {
|
||||
case -1:
|
||||
return false;
|
||||
case false:
|
||||
case 0:
|
||||
return true;
|
||||
case true:
|
||||
case 1:
|
||||
helper_exe_exists = true;
|
||||
break;
|
||||
case 2:
|
||||
helper_exe_exists = false;
|
||||
break;
|
||||
default:
|
||||
__builtin_unreachable();
|
||||
|
@ -586,6 +593,7 @@ static dontinline bool foreign_compile(char exe[hasatleast PATH_MAX]) {
|
|||
char sauce[sizeof(HELPER)];
|
||||
strlcpy(src, exe, PATH_MAX);
|
||||
strlcat(src, ".c", PATH_MAX);
|
||||
if (helper_exe_exists) {
|
||||
if ((fd = open(src, O_RDONLY | O_CLOEXEC)) != -1) {
|
||||
ssize_t got = pread(fd, sauce, sizeof(HELPER), 0);
|
||||
close(fd);
|
||||
|
@ -594,6 +602,7 @@ static dontinline bool foreign_compile(char exe[hasatleast PATH_MAX]) {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// create source file
|
||||
char tmp[PATH_MAX];
|
||||
|
@ -623,7 +632,7 @@ static dontinline bool foreign_compile(char exe[hasatleast PATH_MAX]) {
|
|||
return false;
|
||||
}
|
||||
int pid, ws;
|
||||
char *args[] = {"cc", "-pie", "-fPIC", src, "-o", tmp, "-ldl", 0};
|
||||
char *args[] = {"cc", "-pie", "-fPIC", src, "-o", tmp, 0};
|
||||
errno_t err = posix_spawnp(&pid, args[0], NULL, NULL, args, environ);
|
||||
if (err) {
|
||||
unlink(tmp);
|
||||
|
|
|
@ -33,7 +33,8 @@ LIBC_DLOPEN_A_DIRECTDEPS = \
|
|||
LIBC_RUNTIME \
|
||||
LIBC_SYSV \
|
||||
LIBC_SYSV_CALLS \
|
||||
LIBC_STR
|
||||
LIBC_STR \
|
||||
THIRD_PARTY_COMPILER_RT
|
||||
|
||||
LIBC_DLOPEN_A_DEPS := \
|
||||
$(call uniq,$(foreach x,$(LIBC_DLOPEN_A_DIRECTDEPS),$($(x))))
|
||||
|
|
Loading…
Add table
Reference in a new issue