mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-22 21:32:31 +00:00
Get binaries closer to running without an o/s
blinkenlights now does a pretty good job emulating what happens when binaries boot from BIOS into long mode. So it's been much easier to debug the bare metal process and wrinkle out many issues.
This commit is contained in:
parent
feed0d2b0e
commit
2d80bbc802
50 changed files with 974 additions and 1062 deletions
|
@ -19,54 +19,52 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/hefty/ntspawn.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/nt/accounting.h"
|
||||
#include "libc/nt/enum/startf.h"
|
||||
#include "libc/nt/enum/status.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/process.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/startupinfo.h"
|
||||
#include "libc/nt/struct/processinformation.h"
|
||||
#include "libc/nt/synchronization.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/fileno.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/x/x.h"
|
||||
|
||||
#define SHELL_BIN "/bin/sh"
|
||||
#define SHELL_ARG "-c"
|
||||
#define CMD_C "CMD /C "
|
||||
|
||||
static int system$sysv(const char *cmdline) {
|
||||
int rc, n, wstatus;
|
||||
struct mem {
|
||||
char shell[sizeof(SHELL_BIN)];
|
||||
char arg[sizeof(SHELL_ARG)];
|
||||
char *args[4];
|
||||
char cmdline[];
|
||||
} * mem;
|
||||
if (cmdline != NULL) {
|
||||
int pid = fork$sysv();
|
||||
if (pid == 0) {
|
||||
struct mem {
|
||||
char shell[sizeof(SHELL_BIN)];
|
||||
char arg[sizeof(SHELL_ARG)];
|
||||
char *args[4];
|
||||
char cmdline[];
|
||||
} *mem = malloc(sizeof(struct mem) + (strlen(cmdline) + 1));
|
||||
if (!mem) return enomem();
|
||||
strcpy(mem->shell, SHELL_BIN);
|
||||
strcpy(mem->arg, SHELL_ARG);
|
||||
mem->args[0] = mem->shell;
|
||||
mem->args[1] = mem->arg;
|
||||
mem->args[2] = mem->cmdline;
|
||||
mem->args[3] = NULL;
|
||||
strcpy(mem->cmdline, cmdline);
|
||||
execve$sysv(mem->shell, mem->args, environ);
|
||||
abort();
|
||||
mem = malloc(sizeof(struct mem) + (strlen(cmdline) + 1));
|
||||
if (!mem) return enomem();
|
||||
strcpy(mem->shell, SHELL_BIN);
|
||||
strcpy(mem->arg, SHELL_ARG);
|
||||
mem->args[0] = mem->shell;
|
||||
mem->args[1] = mem->arg;
|
||||
mem->args[2] = mem->cmdline;
|
||||
mem->args[3] = NULL;
|
||||
strcpy(mem->cmdline, cmdline);
|
||||
if ((rc = vfork()) != -1) {
|
||||
if (rc == 0) {
|
||||
execve$sysv(mem->shell, mem->args, environ);
|
||||
abort();
|
||||
}
|
||||
if ((rc = wait4$sysv(rc, &wstatus, 0, NULL)) != -1) {
|
||||
rc = wstatus;
|
||||
}
|
||||
}
|
||||
int rc;
|
||||
int wstatus;
|
||||
if ((rc = wait4$sysv(pid, &wstatus, 0, NULL)) != -1) rc = wstatus;
|
||||
free(mem);
|
||||
return rc;
|
||||
} else {
|
||||
return fileexists(SHELL_BIN);
|
||||
|
@ -74,27 +72,32 @@ static int system$sysv(const char *cmdline) {
|
|||
}
|
||||
|
||||
static textwindows noinline int system$nt(const char *cmdline) {
|
||||
char *mem;
|
||||
int rc, status;
|
||||
uint32_t dwExitCode;
|
||||
struct NtStartupInfo startinfo;
|
||||
struct NtProcessInformation *info;
|
||||
uint16_t *cmdline16, *quotedcmdline16;
|
||||
unsigned len, dosquotemultiplier, cmdline16bytes, quotedcmdline16bytes;
|
||||
if (cmdline != NULL) {
|
||||
int rc = -1;
|
||||
unsigned dosquotemultiplier = 2;
|
||||
unsigned len = strlen(cmdline);
|
||||
unsigned cmdline16bytes = (len + 1) * sizeof(uint16_t);
|
||||
unsigned quotedcmdline16bytes =
|
||||
rc = -1;
|
||||
dosquotemultiplier = 2;
|
||||
len = strlen(cmdline);
|
||||
cmdline16bytes = (len + 1) * sizeof(uint16_t);
|
||||
quotedcmdline16bytes =
|
||||
strlen(CMD_C) * sizeof(uint16_t) + cmdline16bytes * dosquotemultiplier;
|
||||
void *mem = malloc(sizeof(struct NtProcessInformation) + cmdline16bytes +
|
||||
quotedcmdline16bytes);
|
||||
if (mem == NULL) return enomem();
|
||||
struct NtProcessInformation *info = mem;
|
||||
uint16_t *cmdline16 =
|
||||
(uint16_t *)((char *)mem + sizeof(struct NtProcessInformation));
|
||||
uint16_t *quotedcmdline16 =
|
||||
(uint16_t *)((char *)mem + sizeof(struct NtProcessInformation) +
|
||||
cmdline16bytes);
|
||||
if (!(mem = malloc(sizeof(struct NtProcessInformation) + cmdline16bytes +
|
||||
quotedcmdline16bytes))) {
|
||||
return enomem();
|
||||
}
|
||||
info = (struct NtProcessInformation *)mem;
|
||||
cmdline16 = (uint16_t *)(mem + sizeof(struct NtProcessInformation));
|
||||
quotedcmdline16 = (uint16_t *)(mem + sizeof(struct NtProcessInformation) +
|
||||
cmdline16bytes);
|
||||
strcpyzbw(cmdline16, cmdline);
|
||||
strcpyzbw(quotedcmdline16, CMD_C);
|
||||
if (escapedos(quotedcmdline16 + strlen(CMD_C), len * dosquotemultiplier,
|
||||
cmdline16, len)) {
|
||||
struct NtStartupInfo startinfo;
|
||||
memset(&startinfo, 0, sizeof(startinfo));
|
||||
startinfo.cb = sizeof(struct NtStartupInfo);
|
||||
startinfo.dwFlags = kNtStartfUsestdhandles;
|
||||
|
@ -112,8 +115,7 @@ static textwindows noinline int system$nt(const char *cmdline) {
|
|||
/* lpCurrentDirectory */ NULL,
|
||||
/* lpStartupInfo */ &startinfo,
|
||||
/* lpProcessInformation */ info)) {
|
||||
uint32_t dwExitCode = kNtStillActive;
|
||||
int status;
|
||||
dwExitCode = kNtStillActive;
|
||||
do {
|
||||
WaitForSingleObject(info->hProcess, 0xffffffff);
|
||||
} while ((status = GetExitCodeProcess(info->hProcess, &dwExitCode)) &&
|
||||
|
@ -130,7 +132,7 @@ static textwindows noinline int system$nt(const char *cmdline) {
|
|||
} else {
|
||||
rc = einval();
|
||||
}
|
||||
free(mem), mem = NULL;
|
||||
free(mem);
|
||||
return rc;
|
||||
} else {
|
||||
/* how could cmd.exe not exist? */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue