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 Linux w/ Musl Libc
|
||||||
* - x86-64 FreeBSD
|
* - x86-64 FreeBSD
|
||||||
* - x86-64 Windows
|
* - x86-64 Windows
|
||||||
|
* - x86-64 NetBSD
|
||||||
* - aarch64 Linux w/ Glibc
|
* - aarch64 Linux w/ Glibc
|
||||||
* - aarch64 Linux w/ Musl Libc
|
* - aarch64 Linux w/ Musl Libc
|
||||||
* - aarch64 MacOS
|
* - aarch64 MacOS
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include "libc/fmt/itoa.h"
|
#include "libc/fmt/itoa.h"
|
||||||
#include "libc/intrin/atomic.h"
|
#include "libc/intrin/atomic.h"
|
||||||
#include "libc/intrin/bits.h"
|
#include "libc/intrin/bits.h"
|
||||||
|
#include "libc/intrin/kprintf.h"
|
||||||
#include "libc/intrin/strace.internal.h"
|
#include "libc/intrin/strace.internal.h"
|
||||||
#include "libc/limits.h"
|
#include "libc/limits.h"
|
||||||
#include "libc/nt/dll.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 (stat(other, &st2)) {
|
||||||
if (errno == ENOENT) {
|
if (errno == ENOENT) {
|
||||||
return true;
|
return 2;
|
||||||
} else {
|
} else {
|
||||||
return -1;
|
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 argsize = (1 + 2 + 1 + envc + 1 + auxc * 2 + 1 + 3) * 8;
|
||||||
size_t mapsize = (stksize + argsize + (pagesz - 1)) & -pagesz;
|
size_t mapsize = (stksize + argsize + (pagesz - 1)) & -pagesz;
|
||||||
size_t skew = (mapsize - argsize) & (stkalign - 1);
|
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 = __sys_mmap(0, mapsize, PROT_READ | PROT_WRITE,
|
||||||
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0, 0);
|
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0, 0);
|
||||||
if (map == MAP_FAILED) return;
|
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);
|
strlcat(exe, "dlopen-helper", PATH_MAX);
|
||||||
|
|
||||||
// skip build if helper exists and this program is older
|
// skip build if helper exists and this program is older
|
||||||
|
bool helper_exe_exists;
|
||||||
switch (is_file_newer_than(GetProgramExecutableName(), exe)) {
|
switch (is_file_newer_than(GetProgramExecutableName(), exe)) {
|
||||||
case -1:
|
case -1:
|
||||||
return false;
|
return false;
|
||||||
case false:
|
case 0:
|
||||||
return true;
|
return true;
|
||||||
case true:
|
case 1:
|
||||||
|
helper_exe_exists = true;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
helper_exe_exists = false;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
__builtin_unreachable();
|
__builtin_unreachable();
|
||||||
|
@ -586,6 +593,7 @@ static dontinline bool foreign_compile(char exe[hasatleast PATH_MAX]) {
|
||||||
char sauce[sizeof(HELPER)];
|
char sauce[sizeof(HELPER)];
|
||||||
strlcpy(src, exe, PATH_MAX);
|
strlcpy(src, exe, PATH_MAX);
|
||||||
strlcat(src, ".c", PATH_MAX);
|
strlcat(src, ".c", PATH_MAX);
|
||||||
|
if (helper_exe_exists) {
|
||||||
if ((fd = open(src, O_RDONLY | O_CLOEXEC)) != -1) {
|
if ((fd = open(src, O_RDONLY | O_CLOEXEC)) != -1) {
|
||||||
ssize_t got = pread(fd, sauce, sizeof(HELPER), 0);
|
ssize_t got = pread(fd, sauce, sizeof(HELPER), 0);
|
||||||
close(fd);
|
close(fd);
|
||||||
|
@ -594,6 +602,7 @@ static dontinline bool foreign_compile(char exe[hasatleast PATH_MAX]) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// create source file
|
// create source file
|
||||||
char tmp[PATH_MAX];
|
char tmp[PATH_MAX];
|
||||||
|
@ -623,7 +632,7 @@ static dontinline bool foreign_compile(char exe[hasatleast PATH_MAX]) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
int pid, ws;
|
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);
|
errno_t err = posix_spawnp(&pid, args[0], NULL, NULL, args, environ);
|
||||||
if (err) {
|
if (err) {
|
||||||
unlink(tmp);
|
unlink(tmp);
|
||||||
|
|
|
@ -33,7 +33,8 @@ LIBC_DLOPEN_A_DIRECTDEPS = \
|
||||||
LIBC_RUNTIME \
|
LIBC_RUNTIME \
|
||||||
LIBC_SYSV \
|
LIBC_SYSV \
|
||||||
LIBC_SYSV_CALLS \
|
LIBC_SYSV_CALLS \
|
||||||
LIBC_STR
|
LIBC_STR \
|
||||||
|
THIRD_PARTY_COMPILER_RT
|
||||||
|
|
||||||
LIBC_DLOPEN_A_DEPS := \
|
LIBC_DLOPEN_A_DEPS := \
|
||||||
$(call uniq,$(foreach x,$(LIBC_DLOPEN_A_DIRECTDEPS),$($(x))))
|
$(call uniq,$(foreach x,$(LIBC_DLOPEN_A_DIRECTDEPS),$($(x))))
|
||||||
|
|
Loading…
Add table
Reference in a new issue