[metal] Set argv[0] to "/ape.com" & allow opening it (kind of)

This commit is contained in:
tkchia 2022-10-17 16:26:37 +00:00
parent 14d036b68d
commit 7e80df6f69
3 changed files with 33 additions and 10 deletions

View file

@ -35,6 +35,7 @@
#include "ape/macros.internal.h"
#include "ape/notice.inc"
#include "ape/relocations.h"
#include "libc/calls/metalfile.internal.h"
#include "libc/dce.h"
#include "libc/elf/def.h"
#include "libc/macho.internal.h"
@ -1565,19 +1566,19 @@ kernel: movabs $ape_stack_vaddr,%rsp
#endif
push $_HOSTMETAL # sets __hostos in crt.S
pop %rcx
push $0
pushq .Lenv0(%rip) # envp[0][0]
mov %rsp,%rbp
mov .Lenv0(%rip),%rax
mov %rax,(%rbp) # envp[0][0]
push $0 # argv[0][0]
pushq .Largv0+8(%rip) # argv[0][8]
pushq .Largv0(%rip) # argv[0][0]
mov %rsp,%rax
push $0 # auxv[1][1]
push $0 # auxv[1][0]
push %rbp # auxv[0][1]
push %rax # auxv[0][1]
push $31 # auxv[0][0] AT_EXECFN
push $0 # envp[1]
push $.Lenv0 # envp[0]
push %rbp # envp[0]
push $0 # argv[1]
push %rbp # argv[0]
push %rax # argv[0]
push $1 # argc
xor %ebp,%ebp
xor %eax,%eax
@ -1593,6 +1594,9 @@ kernel: movabs $ape_stack_vaddr,%rsp
.rodata
.Lenv0: .asciz "METAL=1"
.Largv0:
.asciz APE_COM_NAME
.org .Largv0+16
.previous
#endif /* SupportsMetal() */

View file

@ -11,4 +11,7 @@ struct MetalFile {
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#define APE_COM_NAME "/ape.com"
#endif /* COSMOPOLITAN_LIBC_CALLS_METALFILE_INTERNAL_H_ */

View file

@ -20,18 +20,34 @@
#include "libc/calls/internal.h"
#include "libc/calls/metalfile.internal.h"
#include "libc/intrin/weaken.h"
#include "libc/macros.internal.h"
#include "libc/mem/mem.h"
#include "libc/runtime/directmap.internal.h"
#include "libc/runtime/runtime.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/at.h"
#include "libc/sysv/consts/map.h"
#include "libc/sysv/consts/o.h"
#include "libc/sysv/consts/prot.h"
#include "libc/sysv/errfuns.h"
int sys_openat_metal(int dirfd, const char *file, int flags, unsigned mode) {
int fd;
struct MetalFile *state;
if (strcmp(file, "ape.com")) return enoent();
if (!_weaken(calloc)) return enomem();
if (dirfd != AT_FDCWD || strcmp(file, APE_COM_NAME)) return enoent();
if (flags != O_RDONLY) return eacces();
if ((fd = __reservefd(-1)) == -1) return -1;
state = _weaken(calloc)(1, sizeof(struct MetalFile));
if (!_weaken(calloc) || !_weaken(free)) {
struct DirectMap dm;
dm = sys_mmap_metal(NULL, ROUNDUP(sizeof(struct MetalFile), 4096),
PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS,
-1, 0);
state = dm.addr;
if (state == (void *)-1) return -1;
} else {
state = _weaken(calloc)(1, sizeof(struct MetalFile));
if (!state) return -1;
}
state->base = (char *)_base;
state->size = _end - _base;
g_fds.p[fd].kind = kFdFile;