mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-07 06:53:33 +00:00
Add syscalls to Blinkenlights and fix bugs
This commit is contained in:
parent
f6df29cc3d
commit
578cb21591
25 changed files with 187 additions and 108 deletions
|
@ -16,6 +16,7 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/bits/safemacros.internal.h"
|
||||||
#include "libc/intrin/kprintf.h"
|
#include "libc/intrin/kprintf.h"
|
||||||
#include "libc/log/color.internal.h"
|
#include "libc/log/color.internal.h"
|
||||||
#include "libc/log/internal.h"
|
#include "libc/log/internal.h"
|
||||||
|
@ -30,5 +31,6 @@ relegated void __start_fatal(const char *file, int line) {
|
||||||
__restore_tty();
|
__restore_tty();
|
||||||
kprintf("%r%serror%s:%s:%d:%s%s: ", !__nocolor ? "\e[J\e[30;101m" : "",
|
kprintf("%r%serror%s:%s:%d:%s%s: ", !__nocolor ? "\e[J\e[30;101m" : "",
|
||||||
!__nocolor ? "\e[94;49m" : "", file, line,
|
!__nocolor ? "\e[94;49m" : "", file, line,
|
||||||
program_invocation_short_name, !__nocolor ? "\e[0m" : "");
|
firstnonnull(program_invocation_short_name, "unknown"),
|
||||||
|
!__nocolor ? "\e[0m" : "");
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/bits/safemacros.internal.h"
|
||||||
#include "libc/log/bsd.h"
|
#include "libc/log/bsd.h"
|
||||||
#include "libc/log/color.internal.h"
|
#include "libc/log/color.internal.h"
|
||||||
#include "libc/log/internal.h"
|
#include "libc/log/internal.h"
|
||||||
|
@ -23,8 +24,9 @@
|
||||||
#include "libc/stdio/stdio.h"
|
#include "libc/stdio/stdio.h"
|
||||||
|
|
||||||
wontreturn void(verr)(int eval, const char *fmt, va_list va) {
|
wontreturn void(verr)(int eval, const char *fmt, va_list va) {
|
||||||
fprintf(stderr, "%s: %s%s%s[%m]: ", program_invocation_name, RED2, "ERROR",
|
fprintf(stderr,
|
||||||
RESET);
|
"%s: %s%s%s[%m]: ", firstnonnull(program_invocation_name, "unknown"),
|
||||||
|
RED2, "ERROR", RESET);
|
||||||
if (fmt) (vfprintf)(stderr, fmt, va);
|
if (fmt) (vfprintf)(stderr, fmt, va);
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
exit(eval);
|
exit(eval);
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/bits/bits.h"
|
#include "libc/bits/bits.h"
|
||||||
|
#include "libc/bits/safemacros.internal.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/strace.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/calls/struct/stat.h"
|
#include "libc/calls/struct/stat.h"
|
||||||
|
@ -96,7 +97,7 @@ void(vflogf)(unsigned level, const char *file, int line, FILE *f,
|
||||||
vflogf_ts.tv_nsec = nsec;
|
vflogf_ts.tv_nsec = nsec;
|
||||||
localtime_r(&secs, &tm);
|
localtime_r(&secs, &tm);
|
||||||
strcpy(iso8601(buf32, &tm), issamesecond ? "+" : ".");
|
strcpy(iso8601(buf32, &tm), issamesecond ? "+" : ".");
|
||||||
prog = basename(program_invocation_name);
|
prog = basename(firstnonnull(program_invocation_name, "unknown"));
|
||||||
bufmode = f->bufmode;
|
bufmode = f->bufmode;
|
||||||
if (bufmode == _IOLBF) f->bufmode = _IOFBF;
|
if (bufmode == _IOLBF) f->bufmode = _IOFBF;
|
||||||
if ((fprintf)(f, "%r%c%s%06ld:%s:%d:%.*s:%d] ", "FEWIVDNT"[level & 7], buf32,
|
if ((fprintf)(f, "%r%c%s%06ld:%s:%d:%.*s:%d] ", "FEWIVDNT"[level & 7], buf32,
|
||||||
|
|
|
@ -18,8 +18,13 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
|
|
||||||
// Supplies argv[0] the GNU way.
|
|
||||||
.initbss 300,_init_program_invocation_name
|
.initbss 300,_init_program_invocation_name
|
||||||
|
// Supplies argv[0] the GNU way.
|
||||||
|
//
|
||||||
|
// If argv[0] isn't supplied, this value will be null.
|
||||||
|
//
|
||||||
|
// @see program_invocation_short_name
|
||||||
|
// @see GetProgramExecutableName()
|
||||||
program_invocation_name:
|
program_invocation_name:
|
||||||
.quad 0
|
.quad 0
|
||||||
.endobj program_invocation_name,globl
|
.endobj program_invocation_name,globl
|
||||||
|
|
|
@ -344,6 +344,7 @@ static noasan inline void *Mmap(void *addr, size_t size, int prot, int flags,
|
||||||
return MAP_FAILED;
|
return MAP_FAILED;
|
||||||
}
|
}
|
||||||
f |= MAP_STACK_openbsd;
|
f |= MAP_STACK_openbsd;
|
||||||
|
needguard = true;
|
||||||
} else if (IsLinux()) {
|
} else if (IsLinux()) {
|
||||||
// by default MAP_GROWSDOWN will auto-allocate 10mb of pages. it's
|
// by default MAP_GROWSDOWN will auto-allocate 10mb of pages. it's
|
||||||
// supposed to stop growing if an adjacent allocation exists, to
|
// supposed to stop growing if an adjacent allocation exists, to
|
||||||
|
|
|
@ -36,7 +36,8 @@ void __paginate(int fd, const char *s) {
|
||||||
((args[0] = commandv("less", progpath, sizeof(progpath))) ||
|
((args[0] = commandv("less", progpath, sizeof(progpath))) ||
|
||||||
(args[0] = commandv("more", progpath, sizeof(progpath))))) {
|
(args[0] = commandv("more", progpath, sizeof(progpath))))) {
|
||||||
snprintf(tmppath, sizeof(tmppath), "%s%s-%s-%d.txt", kTmpPath,
|
snprintf(tmppath, sizeof(tmppath), "%s%s-%s-%d.txt", kTmpPath,
|
||||||
program_invocation_short_name, "paginate", getpid());
|
firstnonnull(program_invocation_short_name, "unknown"), "paginate",
|
||||||
|
getpid());
|
||||||
if ((tfd = open(tmppath, O_WRONLY | O_CREAT | O_TRUNC, 0644)) != -1) {
|
if ((tfd = open(tmppath, O_WRONLY | O_CREAT | O_TRUNC, 0644)) != -1) {
|
||||||
write(tfd, s, strlen(s));
|
write(tfd, s, strlen(s));
|
||||||
close(tfd);
|
close(tfd);
|
||||||
|
|
|
@ -155,15 +155,18 @@
|
||||||
││ ││ │││ │ │ ││ ││││││││││
|
││ ││ │││ │ │ ││ ││││││││││
|
||||||
6666555555555544444444443333333333222222222211111111110000000000
|
6666555555555544444444443333333333222222222211111111110000000000
|
||||||
3210987654321098765432109876543210987654321098765432109876543210*/
|
3210987654321098765432109876543210987654321098765432109876543210*/
|
||||||
#define PAGE_V /* */ 0b000000001
|
#define PAGE_V /* */ 0b000000000001
|
||||||
#define PAGE_RW /* */ 0b000000010
|
#define PAGE_RW /* */ 0b000000000010
|
||||||
#define PAGE_U /* */ 0b000000100
|
#define PAGE_U /* */ 0b000000000100
|
||||||
#define PAGE_4KB /* */ 0b010000000
|
#define PAGE_4KB /* */ 0b000010000000
|
||||||
#define PAGE_2MB /* */ 0b110000000
|
#define PAGE_2MB /* */ 0b000110000000
|
||||||
#define PAGE_1GB /* */ 0b110000000
|
#define PAGE_1GB /* */ 0b000110000000
|
||||||
#define PAGE_TA 0x00007ffffffff000
|
#define PAGE_IGN1 /* */ 0b111000000000
|
||||||
#define PAGE_PA2 0x00007fffffe00000
|
#define PAGE_RSRV /* blinkenlights reservation */ 0b001000000000
|
||||||
#define PAGE_XD 0x8000000000000000
|
#define PAGE_GROD /* blinkenlights MAP_GROWSDOWN */ 0b010000000000
|
||||||
|
#define PAGE_TA 0x00007ffffffff000
|
||||||
|
#define PAGE_PA2 0x00007fffffe00000
|
||||||
|
#define PAGE_XD 0x8000000000000000
|
||||||
|
|
||||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||||
|
|
||||||
|
|
|
@ -18,8 +18,13 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
|
|
||||||
// Supplies basename(argv[0]) The GNU Way.
|
|
||||||
.initbss 400,_init_program_invocation_short_name
|
.initbss 400,_init_program_invocation_short_name
|
||||||
|
// Supplies basename(argv[0]) The GNU Way.
|
||||||
|
//
|
||||||
|
// If argv[0] isn't supplied, this value will be null.
|
||||||
|
//
|
||||||
|
// @see GetProgramExecutableName()
|
||||||
|
// @see program_invocation_name
|
||||||
program_invocation_short_name:
|
program_invocation_short_name:
|
||||||
.quad 0
|
.quad 0
|
||||||
.endobj program_invocation_short_name,globl
|
.endobj program_invocation_short_name,globl
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/bits/safemacros.internal.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/weirdtypes.h"
|
#include "libc/calls/weirdtypes.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
|
@ -288,7 +289,7 @@ void openlog(const char *ident, int opt, int facility) {
|
||||||
__initlog();
|
__initlog();
|
||||||
}
|
}
|
||||||
if (!ident) {
|
if (!ident) {
|
||||||
ident = program_invocation_short_name;
|
ident = firstnonnull(program_invocation_short_name, "unknown");
|
||||||
}
|
}
|
||||||
tprecode8to16(log_ident, ARRAYLEN(log_ident), ident);
|
tprecode8to16(log_ident, ARRAYLEN(log_ident), ident);
|
||||||
log_opt = opt;
|
log_opt = opt;
|
||||||
|
|
|
@ -36,7 +36,8 @@ FILE *tmpfile(void) {
|
||||||
tmp = firstnonnull(getenv("TMPDIR"), kTmpPath);
|
tmp = firstnonnull(getenv("TMPDIR"), kTmpPath);
|
||||||
sep = !isempty(tmp) && !endswith(tmp, "/") ? "/" : "";
|
sep = !isempty(tmp) && !endswith(tmp, "/") ? "/" : "";
|
||||||
if ((snprintf)(tpl, PATH_MAX, "%s%stmp.%s.XXXXXX", tmp, sep,
|
if ((snprintf)(tpl, PATH_MAX, "%s%stmp.%s.XXXXXX", tmp, sep,
|
||||||
program_invocation_short_name) <= PATH_MAX) {
|
firstnonnull(program_invocation_short_name, "unknown")) <=
|
||||||
|
PATH_MAX) {
|
||||||
if ((fd = mkostemps(tpl, 0, 0)) != -1) {
|
if ((fd = mkostemps(tpl, 0, 0)) != -1) {
|
||||||
return fdopen(fd, "w+");
|
return fdopen(fd, "w+");
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/bits/bits.h"
|
#include "libc/bits/bits.h"
|
||||||
#include "libc/fmt/magnumstrs.internal.h"
|
#include "libc/fmt/magnumstrs.internal.h"
|
||||||
|
#include "libc/log/libfatal.internal.h"
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
|
|
||||||
|
@ -26,7 +27,7 @@ static char g_strsignal[12];
|
||||||
/**
|
/**
|
||||||
* Returns string describing signal code.
|
* Returns string describing signal code.
|
||||||
*
|
*
|
||||||
* This returns SIGUNKNOWN for 0 which is the empty value. Textual names
|
* This returns SIGZERO for 0 which is the empty value. Textual names
|
||||||
* should be available for signals 1 through 32. Signals in the range 33
|
* should be available for signals 1 through 32. Signals in the range 33
|
||||||
* and 128 are returned as a `SIG%03d` string. Everything else is SIGWUT
|
* and 128 are returned as a `SIG%03d` string. Everything else is SIGWUT
|
||||||
*
|
*
|
||||||
|
@ -34,24 +35,36 @@ static char g_strsignal[12];
|
||||||
* @return pointer to static memory that mutates on subsequent calls
|
* @return pointer to static memory that mutates on subsequent calls
|
||||||
* @see sigaction()
|
* @see sigaction()
|
||||||
*/
|
*/
|
||||||
char *strsignal(int sig) {
|
noasan noinstrument char *strsignal(int sig) {
|
||||||
|
char *p;
|
||||||
const char *s;
|
const char *s;
|
||||||
strcpy(g_strsignal, "SIG");
|
p = g_strsignal;
|
||||||
|
p[0] = 'S';
|
||||||
|
p[1] = 'I';
|
||||||
|
p[2] = 'G';
|
||||||
|
p[3] = 0;
|
||||||
if (sig) {
|
if (sig) {
|
||||||
if ((s = GetMagnumStr(kSignalNames, sig))) {
|
if ((s = GetMagnumStr(kSignalNames, sig))) {
|
||||||
strcpy(g_strsignal + 3, s);
|
__stpcpy(p + 3, s);
|
||||||
return g_strsignal;
|
return p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!sig) {
|
if (!sig) {
|
||||||
strcpy(g_strsignal + 3, "UNKNOWN");
|
p[3] = 'Z';
|
||||||
|
p[4] = 'E';
|
||||||
|
p[5] = 'R';
|
||||||
|
p[6] = 'O';
|
||||||
|
p[7] = 0;
|
||||||
} else if (1 <= sig && sig <= 128) {
|
} else if (1 <= sig && sig <= 128) {
|
||||||
g_strsignal[3] = '0' + sig / 100;
|
p[3] = '0' + sig / 100;
|
||||||
g_strsignal[4] = '0' + sig / 10 % 10;
|
p[4] = '0' + sig / 10 % 10;
|
||||||
g_strsignal[5] = '0' + sig % 10;
|
p[5] = '0' + sig % 10;
|
||||||
g_strsignal[6] = 0;
|
p[6] = 0;
|
||||||
} else {
|
} else {
|
||||||
strcpy(g_strsignal + 3, "WUT");
|
p[3] = 'W';
|
||||||
|
p[4] = 'U';
|
||||||
|
p[5] = 'T';
|
||||||
|
p[6] = 0;
|
||||||
}
|
}
|
||||||
return g_strsignal;
|
return g_strsignal;
|
||||||
}
|
}
|
|
@ -88,8 +88,8 @@ testonly void testlib_showerror_(int line, const char *wantcode,
|
||||||
}
|
}
|
||||||
kprintf("\t%s%s%s\n"
|
kprintf("\t%s%s%s\n"
|
||||||
"\t%s%s @ %s%s\n",
|
"\t%s%s @ %s%s\n",
|
||||||
SUBTLE, strerror(e), RESET, SUBTLE, program_invocation_name, hostname,
|
SUBTLE, strerror(e), RESET, SUBTLE,
|
||||||
RESET);
|
firstnonnull(program_invocation_name, "unknown"), hostname, RESET);
|
||||||
free_s(&FREED_want);
|
free_s(&FREED_want);
|
||||||
free_s(&FREED_got);
|
free_s(&FREED_got);
|
||||||
++g_testlib_failed;
|
++g_testlib_failed;
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include "libc/log/log.h"
|
#include "libc/log/log.h"
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
|
#include "libc/nexgen32e/vendor.internal.h"
|
||||||
#include "libc/nexgen32e/x86feature.h"
|
#include "libc/nexgen32e/x86feature.h"
|
||||||
#include "libc/runtime/internal.h"
|
#include "libc/runtime/internal.h"
|
||||||
#include "libc/runtime/memtrack.internal.h"
|
#include "libc/runtime/memtrack.internal.h"
|
||||||
|
@ -71,7 +72,7 @@ static bool runbenchmarks_;
|
||||||
|
|
||||||
void PrintUsage(int rc, FILE *f) {
|
void PrintUsage(int rc, FILE *f) {
|
||||||
fputs("Usage: ", f);
|
fputs("Usage: ", f);
|
||||||
fputs(program_invocation_name, f);
|
fputs(firstnonnull(program_invocation_name, "unknown"), f);
|
||||||
fputs(USAGE, f);
|
fputs(USAGE, f);
|
||||||
exit(rc);
|
exit(rc);
|
||||||
}
|
}
|
||||||
|
@ -102,17 +103,26 @@ static void EmptySignalMask(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void FixIrregularFds(void) {
|
static void FixIrregularFds(void) {
|
||||||
int i;
|
int i, fd;
|
||||||
struct pollfd pfds[64];
|
struct pollfd pfds[64];
|
||||||
for (i = 0; i < 3; ++i) {
|
for (i = 0; i < 3; ++i) {
|
||||||
if (fcntl(0, F_GETFL) == -1) {
|
if (fcntl(i, F_GETFL) == -1) {
|
||||||
CHECK_EQ(0, open("/dev/null", O_RDWR));
|
errno = 0;
|
||||||
|
fd = open("/dev/null", O_RDWR);
|
||||||
|
CHECK_NE(-1, fd);
|
||||||
|
if (fd != i) {
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (i = 0; i < ARRAYLEN(pfds); ++i) {
|
for (i = 0; i < ARRAYLEN(pfds); ++i) {
|
||||||
pfds[i].fd = i + 3;
|
pfds[i].fd = i + 3;
|
||||||
pfds[i].events = POLLIN;
|
pfds[i].events = POLLIN;
|
||||||
}
|
}
|
||||||
|
if (IsGenuineCosmo()) {
|
||||||
|
// TODO(jart): Fix Blinkenlights poll() / close()
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (poll(pfds, ARRAYLEN(pfds), 0) != -1) {
|
if (poll(pfds, ARRAYLEN(pfds), 0) != -1) {
|
||||||
for (i = 0; i < ARRAYLEN(pfds); ++i) {
|
for (i = 0; i < ARRAYLEN(pfds); ++i) {
|
||||||
if (pfds[i].revents & POLLNVAL) continue;
|
if (pfds[i].revents & POLLNVAL) continue;
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/bits/safemacros.internal.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/struct/stat.h"
|
#include "libc/calls/struct/stat.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
|
@ -33,7 +34,9 @@ const char *path;
|
||||||
TEST(ftruncate, test) {
|
TEST(ftruncate, test) {
|
||||||
mkdir("o", 0755);
|
mkdir("o", 0755);
|
||||||
mkdir("o/tmp", 0755);
|
mkdir("o/tmp", 0755);
|
||||||
path = gc(xasprintf("o/tmp/%s.%d", program_invocation_short_name, getpid()));
|
path = gc(xasprintf("o/tmp/%s.%d",
|
||||||
|
firstnonnull(program_invocation_short_name, "unknown"),
|
||||||
|
getpid()));
|
||||||
ASSERT_NE(-1, (fd = creat(path, 0755)));
|
ASSERT_NE(-1, (fd = creat(path, 0755)));
|
||||||
ASSERT_EQ(5, write(fd, "hello", 5));
|
ASSERT_EQ(5, write(fd, "hello", 5));
|
||||||
errno = 31337;
|
errno = 31337;
|
||||||
|
|
|
@ -98,7 +98,7 @@ TEST(setrlimit, testFileSizeLimit) {
|
||||||
ASSERT_EQ(0, setrlimit(RLIMIT_FSIZE, &rlim));
|
ASSERT_EQ(0, setrlimit(RLIMIT_FSIZE, &rlim));
|
||||||
snprintf(tmpname, sizeof(tmpname), "%s/%s.%d",
|
snprintf(tmpname, sizeof(tmpname), "%s/%s.%d",
|
||||||
firstnonnull(getenv("TMPDIR"), "/tmp"),
|
firstnonnull(getenv("TMPDIR"), "/tmp"),
|
||||||
program_invocation_short_name, getpid());
|
firstnonnull(program_invocation_short_name, "unknown"), getpid());
|
||||||
ASSERT_NE(-1, (fd = open(tmpname, O_RDWR | O_CREAT | O_TRUNC)));
|
ASSERT_NE(-1, (fd = open(tmpname, O_RDWR | O_CREAT | O_TRUNC)));
|
||||||
rngset(junkdata, 512, rand64, -1);
|
rngset(junkdata, 512, rand64, -1);
|
||||||
for (i = 0; i < 5 * 1024 * 1024 / 512; ++i) {
|
for (i = 0; i < 5 * 1024 * 1024 / 512; ++i) {
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#include "libc/testlib/testlib.h"
|
#include "libc/testlib/testlib.h"
|
||||||
|
|
||||||
TEST(strsignal, test) {
|
TEST(strsignal, test) {
|
||||||
EXPECT_STREQ("SIGUNKNOWN", strsignal(0));
|
EXPECT_STREQ("SIGZERO", strsignal(0));
|
||||||
EXPECT_STREQ("SIGINT", strsignal(SIGINT));
|
EXPECT_STREQ("SIGINT", strsignal(SIGINT));
|
||||||
EXPECT_STREQ("SIGQUIT", strsignal(SIGQUIT));
|
EXPECT_STREQ("SIGQUIT", strsignal(SIGQUIT));
|
||||||
EXPECT_STREQ("SIGALRM", strsignal(SIGALRM));
|
EXPECT_STREQ("SIGALRM", strsignal(SIGALRM));
|
||||||
|
|
6
third_party/getopt/getopt.c
vendored
6
third_party/getopt/getopt.c
vendored
|
@ -79,8 +79,10 @@ hidden char *getopt_place;
|
||||||
char kGetoptEmsg[1] hidden;
|
char kGetoptEmsg[1] hidden;
|
||||||
|
|
||||||
static void getopt_print_badch(const char *s) {
|
static void getopt_print_badch(const char *s) {
|
||||||
fputs(program_invocation_name, stderr);
|
if (program_invocation_name) {
|
||||||
fputs(": ", stderr);
|
fputs(program_invocation_name, stderr);
|
||||||
|
fputs(": ", stderr);
|
||||||
|
}
|
||||||
fputs(s, stderr);
|
fputs(s, stderr);
|
||||||
fputs(" -- ", stderr);
|
fputs(" -- ", stderr);
|
||||||
fputc(optopt, stderr);
|
fputc(optopt, stderr);
|
||||||
|
|
3
third_party/make/getprogname.c
vendored
3
third_party/make/getprogname.c
vendored
|
@ -17,12 +17,13 @@
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
#include "third_party/make/config.h"
|
#include "third_party/make/config.h"
|
||||||
#include "third_party/make/getprogname.h"
|
#include "third_party/make/getprogname.h"
|
||||||
|
#include "libc/bits/safemacros.internal.h"
|
||||||
#include "third_party/make/dirname.h"
|
#include "third_party/make/dirname.h"
|
||||||
|
|
||||||
char const *
|
char const *
|
||||||
getprogname (void)
|
getprogname (void)
|
||||||
{
|
{
|
||||||
return program_invocation_short_name;
|
return firstnonnull(program_invocation_short_name, "unknown");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
5
third_party/mbedtls/test/lib.c
vendored
5
third_party/mbedtls/test/lib.c
vendored
|
@ -16,6 +16,7 @@
|
||||||
*/
|
*/
|
||||||
#include "libc/assert.h"
|
#include "libc/assert.h"
|
||||||
#include "libc/bits/bits.h"
|
#include "libc/bits/bits.h"
|
||||||
|
#include "libc/bits/safemacros.internal.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/fmt/conv.h"
|
#include "libc/fmt/conv.h"
|
||||||
|
@ -1011,8 +1012,8 @@ int execute_tests(int argc, const char **argv, const char *default_filename) {
|
||||||
file = fopen(test_filename, "r");
|
file = fopen(test_filename, "r");
|
||||||
if (file == NULL) {
|
if (file == NULL) {
|
||||||
WRITE("%s (%s) failed to open test file: %s %m\n",
|
WRITE("%s (%s) failed to open test file: %s %m\n",
|
||||||
program_invocation_short_name, GetProgramExecutableName(),
|
firstnonnull(program_invocation_short_name, "unknown"),
|
||||||
test_filename);
|
GetProgramExecutableName(), test_filename);
|
||||||
if (outcome_file != NULL) fclose(outcome_file);
|
if (outcome_file != NULL) fclose(outcome_file);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,26 +25,21 @@ int MachineFdAdd(struct MachineFds *mf) {
|
||||||
int fd;
|
int fd;
|
||||||
struct MachineFdClosed *closed;
|
struct MachineFdClosed *closed;
|
||||||
if ((closed = mf->closed)) {
|
if ((closed = mf->closed)) {
|
||||||
DCHECK_LT(closed->fd, mf->i);
|
|
||||||
fd = closed->fd;
|
fd = closed->fd;
|
||||||
mf->closed = closed->next;
|
mf->closed = closed->next;
|
||||||
free(closed);
|
free(closed);
|
||||||
} else {
|
} else {
|
||||||
DCHECK_LE(mf->i, mf->n);
|
fd = mf->i;
|
||||||
if (mf->i == mf->n) {
|
if (mf->i++ == mf->n) {
|
||||||
if (!__grow(&mf->p, &mf->n, sizeof(struct MachineFd), 0)) {
|
mf->n = mf->i + (mf->i >> 1);
|
||||||
return -1;
|
mf->p = realloc(mf->p, mf->n * sizeof(*mf->p));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
fd = mf->i++;
|
|
||||||
}
|
}
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MachineFdRemove(struct MachineFds *mf, int fd) {
|
void MachineFdRemove(struct MachineFds *mf, int fd) {
|
||||||
struct MachineFdClosed *closed;
|
struct MachineFdClosed *closed;
|
||||||
DCHECK_GE(fd, 0);
|
|
||||||
DCHECK_LT(fd, mf->i);
|
|
||||||
mf->p[fd].cb = NULL;
|
mf->p[fd].cb = NULL;
|
||||||
if ((closed = malloc(sizeof(struct MachineFdClosed)))) {
|
if ((closed = malloc(sizeof(struct MachineFdClosed)))) {
|
||||||
closed->fd = fd;
|
closed->fd = fd;
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "libc/log/log.h"
|
#include "libc/log/log.h"
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
#include "libc/nexgen32e/vendor.internal.h"
|
#include "libc/nexgen32e/vendor.internal.h"
|
||||||
|
#include "libc/runtime/pc.internal.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
#include "libc/stdio/stdio.h"
|
#include "libc/stdio/stdio.h"
|
||||||
#include "libc/sysv/consts/fileno.h"
|
#include "libc/sysv/consts/fileno.h"
|
||||||
|
@ -65,9 +66,12 @@ static void LoadElfLoadSegment(struct Machine *m, void *code, size_t codesize,
|
||||||
CHECK_GE(vend - vstart, fstart - fend);
|
CHECK_GE(vend - vstart, fstart - fend);
|
||||||
CHECK_LE(phdr->p_filesz, phdr->p_memsz);
|
CHECK_LE(phdr->p_filesz, phdr->p_memsz);
|
||||||
CHECK_EQ(felf + phdr->p_offset - fstart, phdr->p_vaddr - vstart);
|
CHECK_EQ(felf + phdr->p_offset - fstart, phdr->p_vaddr - vstart);
|
||||||
CHECK_NE(-1, ReserveVirtual(m, vstart, fend - fstart, 0x0207));
|
CHECK_NE(-1, ReserveVirtual(m, vstart, fend - fstart,
|
||||||
|
PAGE_V | PAGE_RW | PAGE_U | PAGE_RSRV));
|
||||||
VirtualRecv(m, vstart, (void *)fstart, fend - fstart);
|
VirtualRecv(m, vstart, (void *)fstart, fend - fstart);
|
||||||
if (bsssize) CHECK_NE(-1, ReserveVirtual(m, vbss, bsssize, 0x0207));
|
if (bsssize)
|
||||||
|
CHECK_NE(-1, ReserveVirtual(m, vbss, bsssize,
|
||||||
|
PAGE_V | PAGE_RW | PAGE_U | PAGE_RSRV));
|
||||||
if (phdr->p_memsz - phdr->p_filesz > bsssize) {
|
if (phdr->p_memsz - phdr->p_filesz > bsssize) {
|
||||||
VirtualSet(m, phdr->p_vaddr + phdr->p_filesz, 0,
|
VirtualSet(m, phdr->p_vaddr + phdr->p_filesz, 0,
|
||||||
phdr->p_memsz - phdr->p_filesz - bsssize);
|
phdr->p_memsz - phdr->p_filesz - bsssize);
|
||||||
|
@ -158,7 +162,8 @@ void LoadProgram(struct Machine *m, const char *prog, char **args, char **vars,
|
||||||
sp = 0x800000000000;
|
sp = 0x800000000000;
|
||||||
Write64(m->sp, sp);
|
Write64(m->sp, sp);
|
||||||
m->cr3 = AllocateLinearPage(m);
|
m->cr3 = AllocateLinearPage(m);
|
||||||
CHECK_NE(-1, ReserveVirtual(m, sp - STACKSIZE, STACKSIZE, 0x0207));
|
CHECK_NE(-1, ReserveVirtual(m, sp - STACKSIZE, STACKSIZE,
|
||||||
|
PAGE_V | PAGE_RW | PAGE_U | PAGE_RSRV));
|
||||||
LoadArgv(m, prog, args, vars);
|
LoadArgv(m, prog, args, vars);
|
||||||
if (memcmp(elf->map, "\177ELF", 4) == 0) {
|
if (memcmp(elf->map, "\177ELF", 4) == 0) {
|
||||||
elf->ehdr = (void *)elf->map;
|
elf->ehdr = (void *)elf->map;
|
||||||
|
|
|
@ -46,13 +46,18 @@ void SetWriteAddr(struct Machine *m, int64_t addr, uint32_t size) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t HandlePageFault(struct Machine *m, uint64_t entry, uint64_t table,
|
uint64_t HandlePageFault(struct Machine *m, int64_t virt, uint64_t entry,
|
||||||
unsigned index) {
|
uint64_t table, unsigned index) {
|
||||||
long page;
|
long page;
|
||||||
if ((page = AllocateLinearPage(m)) != -1) {
|
if ((page = AllocateLinearPage(m)) != -1) {
|
||||||
--m->memstat.reserved;
|
--m->memstat.reserved;
|
||||||
|
if (entry & PAGE_GROD) {
|
||||||
|
ReserveVirtual(m, virt - 4096, 4096,
|
||||||
|
PAGE_GROD | PAGE_RSRV |
|
||||||
|
(entry & (PAGE_XD | PAGE_U | PAGE_RW | PAGE_V)));
|
||||||
|
}
|
||||||
return (*(uint64_t *)(m->real.p + table + index * 8) =
|
return (*(uint64_t *)(m->real.p + table + index * 8) =
|
||||||
page | entry & ~0x7ffffffffe00);
|
page | entry & ~(PAGE_TA | PAGE_IGN1));
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -61,7 +66,7 @@ uint64_t HandlePageFault(struct Machine *m, uint64_t entry, uint64_t table,
|
||||||
uint64_t FindPage(struct Machine *m, int64_t virt) {
|
uint64_t FindPage(struct Machine *m, int64_t virt) {
|
||||||
uint64_t table, entry;
|
uint64_t table, entry;
|
||||||
unsigned level, index, i;
|
unsigned level, index, i;
|
||||||
virt &= -0x1000;
|
virt &= -4096;
|
||||||
for (i = 0; i < ARRAYLEN(m->tlb); ++i) {
|
for (i = 0; i < ARRAYLEN(m->tlb); ++i) {
|
||||||
if (m->tlb[i].virt == virt && (m->tlb[i].entry & 1)) {
|
if (m->tlb[i].virt == virt && (m->tlb[i].entry & 1)) {
|
||||||
return m->tlb[i].entry;
|
return m->tlb[i].entry;
|
||||||
|
@ -76,8 +81,8 @@ uint64_t FindPage(struct Machine *m, int64_t virt) {
|
||||||
entry = *(uint64_t *)(m->real.p + table + index * 8);
|
entry = *(uint64_t *)(m->real.p + table + index * 8);
|
||||||
if (!(entry & 1)) return 0;
|
if (!(entry & 1)) return 0;
|
||||||
} while ((level -= 9) >= 12);
|
} while ((level -= 9) >= 12);
|
||||||
if ((entry & 0x0e00) &&
|
if ((entry & PAGE_RSRV) &&
|
||||||
(entry = HandlePageFault(m, entry, table, index)) == -1) {
|
(entry = HandlePageFault(m, virt, entry, table, index)) == -1) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
m->tlbindex = (m->tlbindex + 1) & (ARRAYLEN(m->tlb) - 1);
|
m->tlbindex = (m->tlbindex + 1) & (ARRAYLEN(m->tlb) - 1);
|
||||||
|
@ -113,21 +118,21 @@ void *ResolveAddress(struct Machine *m, int64_t v) {
|
||||||
void VirtualSet(struct Machine *m, int64_t v, char c, uint64_t n) {
|
void VirtualSet(struct Machine *m, int64_t v, char c, uint64_t n) {
|
||||||
char *p;
|
char *p;
|
||||||
uint64_t k;
|
uint64_t k;
|
||||||
k = 0x1000 - (v & 0xfff);
|
k = 4096 - (v & 0xfff);
|
||||||
while (n) {
|
while (n) {
|
||||||
k = MIN(k, n);
|
k = MIN(k, n);
|
||||||
p = ResolveAddress(m, v);
|
p = ResolveAddress(m, v);
|
||||||
memset(p, c, k);
|
memset(p, c, k);
|
||||||
n -= k;
|
n -= k;
|
||||||
v += k;
|
v += k;
|
||||||
k = 0x1000;
|
k = 4096;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VirtualCopy(struct Machine *m, int64_t v, char *r, uint64_t n, bool d) {
|
void VirtualCopy(struct Machine *m, int64_t v, char *r, uint64_t n, bool d) {
|
||||||
char *p;
|
char *p;
|
||||||
uint64_t k;
|
uint64_t k;
|
||||||
k = 0x1000 - (v & 0xfff);
|
k = 4096 - (v & 0xfff);
|
||||||
while (n) {
|
while (n) {
|
||||||
k = MIN(k, n);
|
k = MIN(k, n);
|
||||||
p = ResolveAddress(m, v);
|
p = ResolveAddress(m, v);
|
||||||
|
@ -139,7 +144,7 @@ void VirtualCopy(struct Machine *m, int64_t v, char *r, uint64_t n, bool d) {
|
||||||
n -= k;
|
n -= k;
|
||||||
r += k;
|
r += k;
|
||||||
v += k;
|
v += k;
|
||||||
k = 0x1000;
|
k = 4096;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,7 +170,7 @@ void VirtualRecvWrite(struct Machine *m, int64_t addr, void *src, uint64_t n) {
|
||||||
void *ReserveAddress(struct Machine *m, int64_t v, size_t n) {
|
void *ReserveAddress(struct Machine *m, int64_t v, size_t n) {
|
||||||
void *r;
|
void *r;
|
||||||
DCHECK_LE(n, sizeof(m->stash));
|
DCHECK_LE(n, sizeof(m->stash));
|
||||||
if ((v & 0xfff) + n <= 0x1000) return ResolveAddress(m, v);
|
if ((v & 0xfff) + n <= 4096) return ResolveAddress(m, v);
|
||||||
m->stashaddr = v;
|
m->stashaddr = v;
|
||||||
m->stashsize = n;
|
m->stashsize = n;
|
||||||
r = m->stash;
|
r = m->stash;
|
||||||
|
@ -177,11 +182,11 @@ void *AccessRam(struct Machine *m, int64_t v, size_t n, void *p[2],
|
||||||
uint8_t *tmp, bool copy) {
|
uint8_t *tmp, bool copy) {
|
||||||
unsigned k;
|
unsigned k;
|
||||||
uint8_t *a, *b;
|
uint8_t *a, *b;
|
||||||
DCHECK_LE(n, 0x1000);
|
DCHECK_LE(n, 4096);
|
||||||
if ((v & 0xfff) + n <= 0x1000) return ResolveAddress(m, v);
|
if ((v & 0xfff) + n <= 4096) return ResolveAddress(m, v);
|
||||||
k = 0x1000;
|
k = 4096;
|
||||||
k -= v & 0xfff;
|
k -= v & 0xfff;
|
||||||
DCHECK_LE(k, 0x1000);
|
DCHECK_LE(k, 4096);
|
||||||
a = ResolveAddress(m, v);
|
a = ResolveAddress(m, v);
|
||||||
b = ResolveAddress(m, v + k);
|
b = ResolveAddress(m, v + k);
|
||||||
if (copy) {
|
if (copy) {
|
||||||
|
@ -220,9 +225,9 @@ void *BeginLoadStore(struct Machine *m, int64_t v, size_t n, void *p[2],
|
||||||
void EndStore(struct Machine *m, int64_t v, size_t n, void *p[2], uint8_t *b) {
|
void EndStore(struct Machine *m, int64_t v, size_t n, void *p[2], uint8_t *b) {
|
||||||
uint8_t *a;
|
uint8_t *a;
|
||||||
unsigned k;
|
unsigned k;
|
||||||
DCHECK_LE(n, 0x1000);
|
DCHECK_LE(n, 4096);
|
||||||
if ((v & 0xfff) + n <= 0x1000) return;
|
if ((v & 0xfff) + n <= 4096) return;
|
||||||
k = 0x1000;
|
k = 4096;
|
||||||
k -= v & 0xfff;
|
k -= v & 0xfff;
|
||||||
DCHECK_GT(k, n);
|
DCHECK_GT(k, n);
|
||||||
DCHECK_NOTNULL(p[0]);
|
DCHECK_NOTNULL(p[0]);
|
||||||
|
@ -239,7 +244,7 @@ void EndStoreNp(struct Machine *m, int64_t v, size_t n, void *p[2],
|
||||||
void *LoadStr(struct Machine *m, int64_t addr) {
|
void *LoadStr(struct Machine *m, int64_t addr) {
|
||||||
size_t have;
|
size_t have;
|
||||||
char *copy, *page, *p;
|
char *copy, *page, *p;
|
||||||
have = 0x1000 - (addr & 0xfff);
|
have = 4096 - (addr & 0xfff);
|
||||||
if (!addr) return NULL;
|
if (!addr) return NULL;
|
||||||
if (!(page = FindReal(m, addr))) return NULL;
|
if (!(page = FindReal(m, addr))) return NULL;
|
||||||
if ((p = memchr(page, '\0', have))) {
|
if ((p = memchr(page, '\0', have))) {
|
||||||
|
@ -247,16 +252,16 @@ void *LoadStr(struct Machine *m, int64_t addr) {
|
||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
CHECK_LT(m->freelist.i, ARRAYLEN(m->freelist.p));
|
CHECK_LT(m->freelist.i, ARRAYLEN(m->freelist.p));
|
||||||
if (!(copy = malloc(have + 0x1000))) return NULL;
|
if (!(copy = malloc(have + 4096))) return NULL;
|
||||||
memcpy(copy, page, have);
|
memcpy(copy, page, have);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (!(page = FindReal(m, addr + have))) break;
|
if (!(page = FindReal(m, addr + have))) break;
|
||||||
if ((p = memccpy(copy + have, page, '\0', 0x1000))) {
|
if ((p = memccpy(copy + have, page, '\0', 4096))) {
|
||||||
SetReadAddr(m, addr, have + (p - (copy + have)) + 1);
|
SetReadAddr(m, addr, have + (p - (copy + have)) + 1);
|
||||||
return (m->freelist.p[m->freelist.i++] = copy);
|
return (m->freelist.p[m->freelist.i++] = copy);
|
||||||
}
|
}
|
||||||
have += 0x1000;
|
have += 4096;
|
||||||
if (!(p = realloc(copy, have + 0x1000))) break;
|
if (!(p = realloc(copy, have + 4096))) break;
|
||||||
copy = p;
|
copy = p;
|
||||||
}
|
}
|
||||||
free(copy);
|
free(copy);
|
||||||
|
@ -266,7 +271,7 @@ void *LoadStr(struct Machine *m, int64_t addr) {
|
||||||
void *LoadBuf(struct Machine *m, int64_t addr, size_t size) {
|
void *LoadBuf(struct Machine *m, int64_t addr, size_t size) {
|
||||||
size_t have, need;
|
size_t have, need;
|
||||||
char *buf, *copy, *page;
|
char *buf, *copy, *page;
|
||||||
have = 0x1000 - (addr & 0xfff);
|
have = 4096 - (addr & 0xfff);
|
||||||
if (!addr) return NULL;
|
if (!addr) return NULL;
|
||||||
if (!(buf = FindReal(m, addr))) return NULL;
|
if (!(buf = FindReal(m, addr))) return NULL;
|
||||||
if (size > have) {
|
if (size > have) {
|
||||||
|
@ -274,7 +279,7 @@ void *LoadBuf(struct Machine *m, int64_t addr, size_t size) {
|
||||||
if (!(copy = malloc(size))) return NULL;
|
if (!(copy = malloc(size))) return NULL;
|
||||||
buf = memcpy(copy, buf, have);
|
buf = memcpy(copy, buf, have);
|
||||||
do {
|
do {
|
||||||
need = MIN(0x1000, size - have);
|
need = MIN(4096, size - have);
|
||||||
if ((page = FindReal(m, addr + have))) {
|
if ((page = FindReal(m, addr + have))) {
|
||||||
memcpy(copy + have, page, need);
|
memcpy(copy + have, page, need);
|
||||||
have += need;
|
have += need;
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "libc/log/check.h"
|
#include "libc/log/check.h"
|
||||||
#include "libc/log/log.h"
|
#include "libc/log/log.h"
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
|
#include "libc/runtime/pc.internal.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "libc/sysv/errfuns.h"
|
#include "libc/sysv/errfuns.h"
|
||||||
|
@ -66,7 +67,7 @@ void ResetMem(struct Machine *m) {
|
||||||
long AllocateLinearPage(struct Machine *m) {
|
long AllocateLinearPage(struct Machine *m) {
|
||||||
long page;
|
long page;
|
||||||
if ((page = AllocateLinearPageRaw(m)) != -1) {
|
if ((page = AllocateLinearPageRaw(m)) != -1) {
|
||||||
bzero(m->real.p + page, 0x1000);
|
bzero(m->real.p + page, 4096);
|
||||||
}
|
}
|
||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
|
@ -77,12 +78,12 @@ long AllocateLinearPageRaw(struct Machine *m) {
|
||||||
struct MachineRealFree *rf;
|
struct MachineRealFree *rf;
|
||||||
if ((rf = m->realfree)) {
|
if ((rf = m->realfree)) {
|
||||||
DCHECK(rf->n);
|
DCHECK(rf->n);
|
||||||
DCHECK_EQ(0, rf->i & 0xfff);
|
DCHECK_EQ(0, rf->i & 4095);
|
||||||
DCHECK_EQ(0, rf->n & 0xfff);
|
DCHECK_EQ(0, rf->n & 4095);
|
||||||
DCHECK_LE(rf->i + rf->n, m->real.i);
|
DCHECK_LE(rf->i + rf->n, m->real.i);
|
||||||
i = rf->i;
|
i = rf->i;
|
||||||
rf->i += 0x1000;
|
rf->i += 4096;
|
||||||
if (!(rf->n -= 0x1000)) {
|
if (!(rf->n -= 4096)) {
|
||||||
m->realfree = rf->next;
|
m->realfree = rf->next;
|
||||||
free(rf);
|
free(rf);
|
||||||
}
|
}
|
||||||
|
@ -96,9 +97,9 @@ long AllocateLinearPageRaw(struct Machine *m) {
|
||||||
if (n) {
|
if (n) {
|
||||||
n += n >> 1;
|
n += n >> 1;
|
||||||
} else {
|
} else {
|
||||||
n = 0x10000;
|
n = 65536;
|
||||||
}
|
}
|
||||||
n = ROUNDUP(n, 0x1000);
|
n = ROUNDUP(n, 4096);
|
||||||
if ((p = realloc(p, n))) {
|
if ((p = realloc(p, n))) {
|
||||||
m->real.p = p;
|
m->real.p = p;
|
||||||
m->real.n = n;
|
m->real.n = n;
|
||||||
|
@ -108,10 +109,10 @@ long AllocateLinearPageRaw(struct Machine *m) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DCHECK_EQ(0, i & 0xfff);
|
DCHECK_EQ(0, i & 4095);
|
||||||
DCHECK_EQ(0, n & 0xfff);
|
DCHECK_EQ(0, n & 4095);
|
||||||
DCHECK_LE(i + 0x1000, n);
|
DCHECK_LE(i + 4096, n);
|
||||||
m->real.i += 0x1000;
|
m->real.i += 4096;
|
||||||
++m->memstat.allocated;
|
++m->memstat.allocated;
|
||||||
}
|
}
|
||||||
++m->memstat.committed;
|
++m->memstat.committed;
|
||||||
|
@ -130,7 +131,7 @@ static void MachineWrite64(struct Machine *m, unsigned long i, uint64_t x) {
|
||||||
|
|
||||||
int ReserveReal(struct Machine *m, size_t n) {
|
int ReserveReal(struct Machine *m, size_t n) {
|
||||||
uint8_t *p;
|
uint8_t *p;
|
||||||
DCHECK_EQ(0, n & 0xfff);
|
DCHECK_EQ(0, n & 4095);
|
||||||
if (m->real.n < n) {
|
if (m->real.n < n) {
|
||||||
if ((p = realloc(m->real.p, n))) {
|
if ((p = realloc(m->real.p, n))) {
|
||||||
m->real.p = p;
|
m->real.p = p;
|
||||||
|
@ -148,9 +149,9 @@ int ReserveVirtual(struct Machine *m, int64_t virt, size_t size, uint64_t key) {
|
||||||
int64_t ti, mi, pt, end, level;
|
int64_t ti, mi, pt, end, level;
|
||||||
for (end = virt + size;;) {
|
for (end = virt + size;;) {
|
||||||
for (pt = m->cr3, level = 39; level >= 12; level -= 9) {
|
for (pt = m->cr3, level = 39; level >= 12; level -= 9) {
|
||||||
pt = pt & 0x7ffffffff000;
|
pt = pt & PAGE_TA;
|
||||||
ti = (virt >> level) & 511;
|
ti = (virt >> level) & 511;
|
||||||
mi = (pt & 0x7ffffffff000) + ti * 8;
|
mi = (pt & PAGE_TA) + ti * 8;
|
||||||
pt = MachineRead64(m, mi);
|
pt = MachineRead64(m, mi);
|
||||||
if (level > 12) {
|
if (level > 12) {
|
||||||
if (!(pt & 1)) {
|
if (!(pt & 1)) {
|
||||||
|
@ -165,7 +166,7 @@ int ReserveVirtual(struct Machine *m, int64_t virt, size_t size, uint64_t key) {
|
||||||
MachineWrite64(m, mi, key);
|
MachineWrite64(m, mi, key);
|
||||||
++m->memstat.reserved;
|
++m->memstat.reserved;
|
||||||
}
|
}
|
||||||
if ((virt += 0x1000) >= end) return 0;
|
if ((virt += 4096) >= end) return 0;
|
||||||
if (++ti == 512) break;
|
if (++ti == 512) break;
|
||||||
pt = MachineRead64(m, (mi += 8));
|
pt = MachineRead64(m, (mi += 8));
|
||||||
}
|
}
|
||||||
|
@ -179,13 +180,13 @@ int64_t FindVirtual(struct Machine *m, int64_t virt, size_t size) {
|
||||||
do {
|
do {
|
||||||
if (virt >= 0x800000000000) return enomem();
|
if (virt >= 0x800000000000) return enomem();
|
||||||
for (pt = m->cr3, i = 39; i >= 12; i -= 9) {
|
for (pt = m->cr3, i = 39; i >= 12; i -= 9) {
|
||||||
pt = MachineRead64(m, (pt & 0x7ffffffff000) + ((virt >> i) & 511) * 8);
|
pt = MachineRead64(m, (pt & PAGE_TA) + ((virt >> i) & 511) * 8);
|
||||||
if (!(pt & 1)) break;
|
if (!(pt & 1)) break;
|
||||||
}
|
}
|
||||||
if (i >= 12) {
|
if (i >= 12) {
|
||||||
got += 1ull << i;
|
got += 1ull << i;
|
||||||
} else {
|
} else {
|
||||||
virt += 0x1000;
|
virt += 4096;
|
||||||
got = 0;
|
got = 0;
|
||||||
}
|
}
|
||||||
} while (got < size);
|
} while (got < size);
|
||||||
|
@ -195,10 +196,10 @@ int64_t FindVirtual(struct Machine *m, int64_t virt, size_t size) {
|
||||||
static void AppendRealFree(struct Machine *m, uint64_t real) {
|
static void AppendRealFree(struct Machine *m, uint64_t real) {
|
||||||
struct MachineRealFree *rf;
|
struct MachineRealFree *rf;
|
||||||
if (m->realfree && real == m->realfree->i + m->realfree->n) {
|
if (m->realfree && real == m->realfree->i + m->realfree->n) {
|
||||||
m->realfree->n += 0x1000;
|
m->realfree->n += 4096;
|
||||||
} else if ((rf = malloc(sizeof(struct MachineRealFree)))) {
|
} else if ((rf = malloc(sizeof(struct MachineRealFree)))) {
|
||||||
rf->i = real;
|
rf->i = real;
|
||||||
rf->n = 0x1000;
|
rf->n = 4096;
|
||||||
rf->next = m->realfree;
|
rf->next = m->realfree;
|
||||||
m->realfree = rf;
|
m->realfree = rf;
|
||||||
}
|
}
|
||||||
|
@ -208,17 +209,17 @@ int FreeVirtual(struct Machine *m, int64_t base, size_t size) {
|
||||||
uint64_t i, mi, pt, end, virt;
|
uint64_t i, mi, pt, end, virt;
|
||||||
for (virt = base, end = virt + size; virt < end; virt += 1ull << i) {
|
for (virt = base, end = virt + size; virt < end; virt += 1ull << i) {
|
||||||
for (pt = m->cr3, i = 39;; i -= 9) {
|
for (pt = m->cr3, i = 39;; i -= 9) {
|
||||||
mi = (pt & 0x7ffffffff000) + ((virt >> i) & 511) * 8;
|
mi = (pt & PAGE_TA) + ((virt >> i) & 511) * 8;
|
||||||
pt = MachineRead64(m, mi);
|
pt = MachineRead64(m, mi);
|
||||||
if (!(pt & 1)) {
|
if (!(pt & 1)) {
|
||||||
break;
|
break;
|
||||||
} else if (i == 12) {
|
} else if (i == 12) {
|
||||||
++m->memstat.freed;
|
++m->memstat.freed;
|
||||||
if (pt & 0x0e00) {
|
if (pt & PAGE_RSRV) {
|
||||||
--m->memstat.reserved;
|
--m->memstat.reserved;
|
||||||
} else {
|
} else {
|
||||||
--m->memstat.committed;
|
--m->memstat.committed;
|
||||||
AppendRealFree(m, pt & 0x7ffffffff000);
|
AppendRealFree(m, pt & PAGE_TA);
|
||||||
}
|
}
|
||||||
MachineWrite64(m, mi, 0);
|
MachineWrite64(m, mi, 0);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
#include "libc/nexgen32e/vendor.internal.h"
|
#include "libc/nexgen32e/vendor.internal.h"
|
||||||
#include "libc/runtime/gc.internal.h"
|
#include "libc/runtime/gc.internal.h"
|
||||||
|
#include "libc/runtime/pc.internal.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
#include "libc/sock/select.h"
|
#include "libc/sock/select.h"
|
||||||
#include "libc/sock/sock.h"
|
#include "libc/sock/sock.h"
|
||||||
|
@ -221,6 +222,7 @@ static int XlatMapFlags(int x) {
|
||||||
if (x & 2) res |= MAP_PRIVATE;
|
if (x & 2) res |= MAP_PRIVATE;
|
||||||
if (x & 16) res |= MAP_FIXED;
|
if (x & 16) res |= MAP_FIXED;
|
||||||
if (x & 32) res |= MAP_ANONYMOUS;
|
if (x & 32) res |= MAP_ANONYMOUS;
|
||||||
|
if (x & 256) res |= MAP_GROWSDOWN;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -522,7 +524,8 @@ static int OpMadvise(struct Machine *m, int64_t addr, size_t length,
|
||||||
static int64_t OpBrk(struct Machine *m, int64_t addr) {
|
static int64_t OpBrk(struct Machine *m, int64_t addr) {
|
||||||
addr = ROUNDUP(addr, PAGESIZE);
|
addr = ROUNDUP(addr, PAGESIZE);
|
||||||
if (addr > m->brk) {
|
if (addr > m->brk) {
|
||||||
if (ReserveVirtual(m, m->brk, addr - m->brk, 0x0207) != -1) {
|
if (ReserveVirtual(m, m->brk, addr - m->brk,
|
||||||
|
PAGE_V | PAGE_RW | PAGE_U | PAGE_RSRV) != -1) {
|
||||||
m->brk = addr;
|
m->brk = addr;
|
||||||
}
|
}
|
||||||
} else if (addr < m->brk) {
|
} else if (addr < m->brk) {
|
||||||
|
@ -545,9 +548,10 @@ static int64_t OpMmap(struct Machine *m, int64_t virt, size_t size, int prot,
|
||||||
VERBOSEF("MMAP%s %012lx %,ld %#x %#x %d %#lx", GetSimulated(), virt, size,
|
VERBOSEF("MMAP%s %012lx %,ld %#x %#x %d %#lx", GetSimulated(), virt, size,
|
||||||
prot, flags, fd, offset);
|
prot, flags, fd, offset);
|
||||||
if (prot & PROT_READ) {
|
if (prot & PROT_READ) {
|
||||||
key = 0x0205;
|
key = PAGE_RSRV | PAGE_U | PAGE_V;
|
||||||
if (prot & PROT_WRITE) key |= 2;
|
if (prot & PROT_WRITE) key |= PAGE_RW;
|
||||||
if (!(prot & PROT_EXEC)) key |= 0x8000000000000000;
|
if (!(prot & PROT_EXEC)) key |= PAGE_XD;
|
||||||
|
if (flags & 256 /* MAP_GROWSDOWN */) key |= PAGE_GROD;
|
||||||
flags = XlatMapFlags(flags);
|
flags = XlatMapFlags(flags);
|
||||||
if (fd != -1 && (fd = XlatFd(m, fd)) == -1) return -1;
|
if (fd != -1 && (fd = XlatFd(m, fd)) == -1) return -1;
|
||||||
if (!(flags & MAP_FIXED)) {
|
if (!(flags & MAP_FIXED)) {
|
||||||
|
@ -1127,6 +1131,21 @@ static int OpGetrlimit(struct Machine *m, int resource, int64_t rlimitaddr) {
|
||||||
return enosys();
|
return enosys();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ssize_t OpReadlinkat(struct Machine *m, int dirfd, int64_t pathaddr,
|
||||||
|
int64_t bufaddr, size_t size) {
|
||||||
|
char *buf;
|
||||||
|
ssize_t rc;
|
||||||
|
const char *path;
|
||||||
|
if ((dirfd = XlatAfd(m, dirfd)) == -1) return -1;
|
||||||
|
path = LoadStr(m, pathaddr);
|
||||||
|
if (!(buf = malloc(size))) return enomem();
|
||||||
|
if ((rc = readlinkat(dirfd, path, buf, size)) != -1) {
|
||||||
|
VirtualRecvWrite(m, bufaddr, buf, rc);
|
||||||
|
}
|
||||||
|
free(buf);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
static int64_t OpGetcwd(struct Machine *m, int64_t bufaddr, size_t size) {
|
static int64_t OpGetcwd(struct Machine *m, int64_t bufaddr, size_t size) {
|
||||||
size_t n;
|
size_t n;
|
||||||
char *buf;
|
char *buf;
|
||||||
|
@ -1437,6 +1456,7 @@ void OpSyscall(struct Machine *m, uint32_t rde) {
|
||||||
SYSCALL(0x106, OpFstatat(m, di, si, dx, r0));
|
SYSCALL(0x106, OpFstatat(m, di, si, dx, r0));
|
||||||
SYSCALL(0x107, OpUnlinkat(m, di, si, dx));
|
SYSCALL(0x107, OpUnlinkat(m, di, si, dx));
|
||||||
SYSCALL(0x108, OpRenameat(m, di, si, dx, r0));
|
SYSCALL(0x108, OpRenameat(m, di, si, dx, r0));
|
||||||
|
SYSCALL(0x10B, OpReadlinkat(m, di, si, dx, r0));
|
||||||
SYSCALL(0x10D, OpFaccessat(m, di, si, dx, r0));
|
SYSCALL(0x10D, OpFaccessat(m, di, si, dx, r0));
|
||||||
SYSCALL(0x113, splice(di, P(si), dx, P(r0), r8, XlatAtf(r9)));
|
SYSCALL(0x113, splice(di, P(si), dx, P(r0), r8, XlatAtf(r9)));
|
||||||
SYSCALL(0x115, sync_file_range(di, si, dx, XlatAtf(r0)));
|
SYSCALL(0x115, sync_file_range(di, si, dx, XlatAtf(r0)));
|
||||||
|
|
|
@ -521,7 +521,8 @@ static bool OpenSpeaker(void) {
|
||||||
if (sox_) tryspeakerfns_[i++] = TrySox;
|
if (sox_) tryspeakerfns_[i++] = TrySox;
|
||||||
}
|
}
|
||||||
snprintf(fifopath_, sizeof(fifopath_), "%s%s.%d.%d.wav", kTmpPath,
|
snprintf(fifopath_, sizeof(fifopath_), "%s%s.%d.%d.wav", kTmpPath,
|
||||||
program_invocation_short_name, getpid(), count);
|
firstnonnull(program_invocation_short_name, "unknown"), getpid(),
|
||||||
|
count);
|
||||||
for (i = 0; i < ARRAYLEN(tryspeakerfns_); ++i) {
|
for (i = 0; i < ARRAYLEN(tryspeakerfns_); ++i) {
|
||||||
if (tryspeakerfns_[i]) {
|
if (tryspeakerfns_[i]) {
|
||||||
if (++speakerfails_ <= 2 && tryspeakerfns_[i]()) {
|
if (++speakerfails_ <= 2 && tryspeakerfns_[i]()) {
|
||||||
|
@ -1363,7 +1364,7 @@ static void PrintUsage(int rc, FILE *f) {
|
||||||
static void GetOpts(int argc, char *argv[]) {
|
static void GetOpts(int argc, char *argv[]) {
|
||||||
int opt;
|
int opt;
|
||||||
snprintf(logpath_, sizeof(logpath_), "%s%s.log", kTmpPath,
|
snprintf(logpath_, sizeof(logpath_), "%s%s.log", kTmpPath,
|
||||||
program_invocation_short_name);
|
firstnonnull(program_invocation_short_name, "unknown"));
|
||||||
while ((opt = getopt(argc, argv, "?34AGSTVYabdfhnpstxyzvL:")) != -1) {
|
while ((opt = getopt(argc, argv, "?34AGSTVYabdfhnpstxyzvL:")) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'y':
|
case 'y':
|
||||||
|
|
Loading…
Reference in a new issue