Write tests for new APE loader and fix bugs

- Add FreeBSD-specific mmap() flags
- Reduce size of the APE loader from 8kb to 4kb
- Work towards fixing the Makefile build on WSL
- Automate testing of APE no-modify-self behaviors
- Make the ape.S shell script code cleaner and tinier
- Improve the APE sanity check to test behavior better
- Fixed issue with ShowCrashReports() sigaltstack() on BSDs
- Delete symbols for S_MODE magnums which wasted compile time

If you checked out yesterday's APE commit, please run:

    rm -f /usr/bin/ape o/tmp/ape /tmp/ape "${TMPDIR:-/tmp}/ape"

Because this change fixes certain aspects of the new ABI. We don't have
automated migrations for APE loader versions yet. Thanks! You can also
download prebuilt binaries here:

- https://justine.lol/ape.elf    (Linux/FreeBSD/NetBSD/OpenBSD)
- https://justine.lol/ape.macho  (Apple)

Install the appropriate one as `/usr/bin/ape`.
This commit is contained in:
Justine Tunney 2022-05-22 04:51:02 -07:00
parent 056dc5f554
commit 4e9662cbc7
75 changed files with 759 additions and 443 deletions

View file

@ -34,12 +34,22 @@
char program_executable_name[PATH_MAX];
static inline char *StrCat(char buf[PATH_MAX], const char *a, const char *b) {
char *p, *e;
p = buf;
e = buf + PATH_MAX;
while (*a && p < e) *p++ = *a++;
while (*b && p < e) *p++ = *b++;
return buf;
}
static inline void GetProgramExecutableNameImpl(char *p, char *e) {
char *q;
ssize_t rc;
size_t i, n;
union {
int cmd[4];
char path[PATH_MAX];
char16_t path16[PATH_MAX];
} u;
@ -61,7 +71,11 @@ static inline void GetProgramExecutableNameImpl(char *p, char *e) {
return;
}
if (__argc && (q = __argv[0]) && !sys_faccessat(AT_FDCWD, q, F_OK, 0)) {
// if argv[0] exists then turn it into an absolute path. we also try
// adding a .com suffix since the ape auto-appends it when resolving
if (__argc && (((q = __argv[0]) && !sys_faccessat(AT_FDCWD, q, F_OK, 0)) ||
((q = StrCat(u.path, __argv[0], ".com")) &&
!sys_faccessat(AT_FDCWD, q, F_OK, 0)))) {
if (*q != '/') {
if (q[0] == '.' && q[1] == '/') {
q += 2;
@ -78,12 +92,12 @@ static inline void GetProgramExecutableNameImpl(char *p, char *e) {
return;
}
// if argv[0] doesn't exist, then fallback to interpreter name
if ((rc = sys_readlinkat(AT_FDCWD, "/proc/self/exe", p, e - p - 1)) > 0 ||
(rc = sys_readlinkat(AT_FDCWD, "/proc/curproc/file", p, e - p - 1)) > 0) {
p[rc] = 0;
return;
}
if (IsFreebsd() || IsNetbsd()) {
u.cmd[0] = CTL_KERN;
u.cmd[1] = KERN_PROC;
@ -101,7 +115,7 @@ static inline void GetProgramExecutableNameImpl(char *p, char *e) {
}
/**
* Returns absolute path of executable.
* Returns absolute path of program.
*/
char *GetProgramExecutableName(void) {
int e;