os

An operating system
git clone https://erai.gay/code/os/
Log | Files | Refs | README | LICENSE

commit 1a41782c6970d2f794df42b7805dccd7ed8a6bbd
parent f70c013813990eded0b7ca3cf923fa3b956f454d
Author: erai <erai@omiltem.net>
Date:   Sat, 16 Mar 2024 11:39:46 -0400

multiple sources

Diffstat:
M.gitignore | 1+
Mbootstrap.sh | 4++--
Mcc0.c | 471++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------
Mcc1.c | 396+++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------
Dcc2 | 0
5 files changed, 542 insertions(+), 330 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -1,3 +1,4 @@ cc0 cc1 +cc2 lex diff --git a/bootstrap.sh b/bootstrap.sh @@ -10,11 +10,11 @@ set -ue ${CC} ${CFLAGS} -o cc0 ./cc0.c || exit 1 # Then use the bootstrap to compile the compiler -timeout 1 sh -c ./cc0 < cc1.c > cc1 || { echo "cc0 failed"; exit 1; } +timeout 1 sh -c './cc0 cc1.c -o cc1' || { echo "cc0 failed"; exit 1; } chmod +x cc1 # Then compile the compiler with itself -timeout 1 sh -c ./cc1 < cc1.c > cc2 || { echo "cc1 failed"; exit 1; } +timeout 1 sh -c './cc1 cc1.c -o cc2' || { echo "cc1 failed"; exit 1; } chmod +x cc2 # And check our work diff --git a/cc0.c b/cc0.c @@ -1,10 +1,18 @@ +#define _POSIX_C_SOURCE 1 #include <stdlib.h> #include <stdio.h> +#include <fcntl.h> +#include <unistd.h> /////////////////////////////////////////////////////////////////////////////// // Forward Declarations // /////////////////////////////////////////////////////////////////////////////// +FILE *fin; +FILE *fout; + +int nc; +unsigned char *filename; int lineno; struct node; struct type; @@ -12,6 +20,7 @@ struct label; struct fix; struct sdecl; +void feed(void); struct node *type(void); struct node *stmt_list(void); struct node *expr(void); @@ -27,10 +36,64 @@ void addfixup(struct label *l); void die(char *msg) { - fprintf(stderr, "die(%d): %s\n", lineno, msg); + fprintf(stderr, "die(%s:%d): %s\n", filename, lineno, msg); exit(1); } +void +open_output(unsigned char *name) +{ + int fd; + + filename = name; + + if (fout != stdout) { + die("multiple output files"); + } + + unlink((char *)name); + + fd = open((char *)name, 64 + 1, (7 << 6) + (7 << 3) + 7); + if (fd < 0) { + die("failed to open output"); + } + + fout = fdopen(fd, "wb"); +} + +void +open_source(unsigned char *name) +{ + int fd; + + if (fin != stdin) { + die("invalid"); + } + + filename = name; + + fd = open((char *)name, 0, 0); + if (fd < 0) { + die("failed to open file"); + } + + fin = fdopen(fd, "rb"); + lineno = 1; + + nc = fgetc(fin); + feed(); +} + +void +close_source(void) +{ + if (fin != stdin) { + fclose(fin); + fin = stdin; + } + fin = stdin; +} + // strlen-ish int slen(unsigned char *s) @@ -147,7 +210,7 @@ feed_ident(void) } token[tlen] = nc; tlen = tlen + 1; - nc = getchar(); + nc = fgetc(fin); } token[tlen] = 0; } @@ -178,7 +241,7 @@ feed_escape(void) { int hex; - nc = getchar(); + nc = fgetc(fin); if (nc == 't') { nc = '\t'; } else if (nc == 'r') { @@ -186,10 +249,10 @@ feed_escape(void) } else if (nc == 'n') { nc = '\n'; } else if (nc == 'x') { - nc = getchar(); + nc = fgetc(fin); hex = hexdig(nc) * 16; - nc = getchar(); + nc = fgetc(fin); hex = hex + hexdig(nc); nc = hex; @@ -203,11 +266,11 @@ void feed_str(void) { tt = T_STR; - nc = getchar(); + nc = fgetc(fin); while (1) { if (nc == '"') { token[tlen] = 0; - nc = getchar(); + nc = fgetc(fin); return; } @@ -229,7 +292,7 @@ feed_str(void) token[tlen] = nc; tlen = tlen + 1; - nc = getchar(); + nc = fgetc(fin); } } @@ -238,7 +301,7 @@ void feed_char(void) { tt = T_CHAR; - nc = getchar(); + nc = fgetc(fin); if (nc == 0 || nc == EOF || nc == '\'' || nc == '\n') { die("invalid char"); @@ -250,14 +313,14 @@ feed_char(void) token[tlen] = nc; tlen = tlen + 1; - nc = getchar(); + nc = fgetc(fin); if (nc != '\'') { die("expected '"); } token[tlen] = 0; - nc = getchar(); + nc = fgetc(fin); } // Read a hex number @@ -278,7 +341,7 @@ feed_hex(void) } token[tlen] = nc; tlen = tlen + 1; - nc = getchar(); + nc = fgetc(fin); } if (!tlen) { @@ -297,10 +360,10 @@ feed_num(void) if (nc == '0') { token[tlen] = nc; tlen = tlen + 1; - nc = getchar(); + nc = fgetc(fin); if (nc == 'x') { - nc = getchar(); + nc = fgetc(fin); feed_hex(); return; } @@ -315,7 +378,7 @@ feed_num(void) } token[tlen] = nc; tlen = tlen + 1; - nc = getchar(); + nc = fgetc(fin); } token[tlen] = 0; } @@ -334,21 +397,21 @@ feed(void) return; } else if (nc == ' ' || nc == '\t' || nc == '\r') { // Whitespace - nc = getchar(); + nc = fgetc(fin); } else if (nc == '\n') { // Line end - nc = getchar(); + nc = fgetc(fin); lineno = lineno + 1; } else if (nc == '/') { // Comment - nc = getchar(); + nc = fgetc(fin); if (nc == '/') { // Read until the end of the comment while (1) { if (nc == '\n' || nc == EOF) { break; } - nc = getchar(); + nc = fgetc(fin); } } else { tt = T_DIV; @@ -387,100 +450,100 @@ feed(void) // Single character tokens if (nc == '(') { tt = T_LPAR; - nc = getchar(); + nc = fgetc(fin); } else if (nc == ')') { tt = T_RPAR; - nc = getchar(); + nc = fgetc(fin); } else if (nc == '{') { tt = T_LBRA; - nc = getchar(); + nc = fgetc(fin); } else if (nc == '}') { tt = T_RBRA; - nc = getchar(); + nc = fgetc(fin); } else if (nc == ',') { tt = T_COMMA; - nc = getchar(); + nc = fgetc(fin); } else if (nc == ';') { tt = T_SEMI; - nc = getchar(); + nc = fgetc(fin); } else if (nc == ':') { tt = T_COLON; - nc = getchar(); + nc = fgetc(fin); } else if (nc == '*') { tt = T_STAR; - nc = getchar(); + nc = fgetc(fin); } else if (nc == '.') { tt = T_DOT; - nc = getchar(); + nc = fgetc(fin); } else if (nc == '=') { tt = T_ASSIGN; - nc = getchar(); + nc = fgetc(fin); if (nc == '=') { tt = T_EQ; - nc = getchar(); + nc = fgetc(fin); } } else if (nc == '&') { tt = T_AMP; - nc = getchar(); + nc = fgetc(fin); if (nc == '&') { tt = T_BAND; - nc = getchar(); + nc = fgetc(fin); } } else if (nc == '~') { tt = T_NOT; - nc = getchar(); + nc = fgetc(fin); } else if (nc == '|') { tt = T_OR; - nc = getchar(); + nc = fgetc(fin); if (nc == '|') { tt = T_BOR; - nc = getchar(); + nc = fgetc(fin); } } else if (nc == '^') { tt = T_XOR; - nc = getchar(); + nc = fgetc(fin); } else if (nc == '!') { tt = T_BANG; - nc = getchar(); + nc = fgetc(fin); if (nc == '=') { tt = T_NE; - nc = getchar(); + nc = fgetc(fin); } } else if (nc == '<') { tt = T_LT; - nc = getchar(); + nc = fgetc(fin); if (nc == '<') { tt = T_LSH; - nc = getchar(); + nc = fgetc(fin); } else if (nc == '=') { tt = T_LE; - nc = getchar(); + nc = fgetc(fin); } } else if (nc == '>') { tt = T_GT; - nc = getchar(); + nc = fgetc(fin); if (nc == '>') { tt = T_RSH; - nc = getchar(); + nc = fgetc(fin); } else if (nc == '=') { tt = T_GE; - nc = getchar(); + nc = fgetc(fin); } } else if (nc == '[') { tt = T_LSQ; - nc = getchar(); + nc = fgetc(fin); } else if (nc == ']') { tt = T_RSQ; - nc = getchar(); + nc = fgetc(fin); } else if (nc == '+') { tt = T_ADD; - nc = getchar(); + nc = fgetc(fin); } else if (nc == '-') { tt = T_SUB; - nc = getchar(); + nc = fgetc(fin); } else if (nc == '%') { tt = T_MOD; - nc = getchar(); + nc = fgetc(fin); } else { die("invalid char"); } @@ -498,6 +561,7 @@ struct node { int n; unsigned char *s; int offset; + unsigned char *filename; int lineno; }; @@ -577,6 +641,7 @@ mknode(int kind, struct node *a, struct node *b) n->n = 0; n->s = 0; n->offset = 0; + n->filename = filename; n->lineno = lineno; return n; @@ -1971,9 +2036,11 @@ program(void) void setup(void) { + filename = (unsigned char *)"<stdin>"; + fin = stdin; + fout = stdout; lineno = 1; - nc = getchar(); - feed(); + nc = 0; } /////////////////////////////////////////////////////////////////////////////// @@ -2449,6 +2516,7 @@ declare(struct node *n) struct type *t; d = find(n->a->s); t = prototype(n->b); + filename = n->filename; lineno = n->lineno; if (d->ftype) { unify(d->ftype, t); @@ -2891,6 +2959,7 @@ typestmt(struct node *n) return; } + filename = n->filename; lineno = n->lineno; kind = n->kind; @@ -4008,194 +4077,194 @@ writeout(void) } // magic - putchar(0x7f); - putchar('E'); - putchar('L'); - putchar('F'); + fputc(0x7f, fout); + fputc('E', fout); + fputc('L', fout); + fputc('F', fout); // class - putchar(2); + fputc(2, fout); // endian - putchar(1); + fputc(1, fout); // version - putchar(1); + fputc(1, fout); // abi - putchar(0); + fputc(0, fout); // abi version - putchar(0); + fputc(0, fout); // padding - putchar(0); - putchar(0); - putchar(0); - putchar(0); - putchar(0); - putchar(0); - putchar(0); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); // type - putchar(2); - putchar(0); + fputc(2, fout); + fputc(0, fout); // machine - putchar(62); - putchar(0); + fputc(62, fout); + fputc(0, fout); // version - putchar(1); - putchar(0); - putchar(0); - putchar(0); + fputc(1, fout); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); entry = load_addr + d->label->at + 128; // entry point - putchar(entry); - putchar(entry >> 8); - putchar(entry >> 16); - putchar(entry >> 24); - putchar(0); - putchar(0); - putchar(0); - putchar(0); + fputc(entry, fout); + fputc(entry >> 8, fout); + fputc(entry >> 16, fout); + fputc(entry >> 24, fout); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); // phoff - putchar(64); - putchar(0); - putchar(0); - putchar(0); - putchar(0); - putchar(0); - putchar(0); - putchar(0); + fputc(64, fout); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); // shoff - putchar(0); - putchar(0); - putchar(0); - putchar(0); - putchar(0); - putchar(0); - putchar(0); - putchar(0); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); // flags - putchar(0); - putchar(0); - putchar(0); - putchar(0); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); // ehsize - putchar(64); - putchar(0); + fputc(64, fout); + fputc(0, fout); // phentsize - putchar(56); - putchar(0); + fputc(56, fout); + fputc(0, fout); // phnum - putchar(1); - putchar(0); + fputc(1, fout); + fputc(0, fout); // shentsize - putchar(64); - putchar(0); + fputc(64, fout); + fputc(0, fout); // shnum - putchar(0); - putchar(0); + fputc(0, fout); + fputc(0, fout); // shstrndx - putchar(0); - putchar(0); + fputc(0, fout); + fputc(0, fout); // phdr[0].type - putchar(1); - putchar(0); - putchar(0); - putchar(0); + fputc(1, fout); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); // phdr[0].flags - putchar(5); - putchar(0); - putchar(0); - putchar(0); + fputc(5, fout); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); // phdr[0].offset - putchar(0); - putchar(0); - putchar(0); - putchar(0); - putchar(0); - putchar(0); - putchar(0); - putchar(0); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); // phdr[0].vaddr - putchar(load_addr); - putchar(load_addr >> 8); - putchar(load_addr >> 16); - putchar(load_addr >> 24); - putchar(0); - putchar(0); - putchar(0); - putchar(0); + fputc(load_addr, fout); + fputc(load_addr >> 8, fout); + fputc(load_addr >> 16, fout); + fputc(load_addr >> 24, fout); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); // phdr[0].paddr - putchar(0); - putchar(0); - putchar(0); - putchar(0); - putchar(0); - putchar(0); - putchar(0); - putchar(0); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); at = at + 128; // phdr[0].filesize - putchar(at); - putchar(at >> 8); - putchar(at >> 16); - putchar(at >> 24); - putchar(0); - putchar(0); - putchar(0); - putchar(0); + fputc(at, fout); + fputc(at >> 8, fout); + fputc(at >> 16, fout); + fputc(at >> 24, fout); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); // phdr[0].memsize - putchar(at); - putchar(at >> 8); - putchar(at >> 16); - putchar(at >> 24); - putchar(0); - putchar(0); - putchar(0); - putchar(0); + fputc(at, fout); + fputc(at >> 8, fout); + fputc(at >> 16, fout); + fputc(at >> 24, fout); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); // phdr[0].align - putchar(0); - putchar(0); - putchar(0); - putchar(0); - putchar(0); - putchar(0); - putchar(0); - putchar(0); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); + fputc(0, fout); // nop sled - putchar(0x90); - putchar(0x90); - putchar(0x90); - putchar(0x90); - putchar(0x90); - putchar(0x90); - putchar(0x90); - putchar(0x90); + fputc(0x90, fout); + fputc(0x90, fout); + fputc(0x90, fout); + fputc(0x90, fout); + fputc(0x90, fout); + fputc(0x90, fout); + fputc(0x90, fout); + fputc(0x90, fout); // text b = text; @@ -4208,7 +4277,7 @@ writeout(void) if (i >= b->fill) { break; } - putchar(b->buf[i]); + fputc(b->buf[i], fout); i = i + 1; } b = b->next; @@ -4721,18 +4790,48 @@ int main(int argc, char **argv) { struct node *p; + int i; // Setup the compiler setup(); - // Parse the program - p = program(); + i = 1; + while (1) { + if (i >= argc) { + break; + } + + if (!cmp((unsigned char *)argv[i], (unsigned char *)"-o")) { + i = i + 1; + if (i >= argc) { + die("invalid -o at end of argument list"); + } - // Verify types - typecheck(p); + open_output((unsigned char *)argv[i]); - // Generate code - translate(p); + i = i + 1; + continue; + } + + open_source((unsigned char *)argv[i]); + + // Parse the program + p = program(); + + // Verify types + typecheck(p); + + // Generate code + translate(p); + + close_source(); + + i = i + 1; + } + + if (fout == stdout) { + open_output((unsigned char *)"a.out"); + } // Define _start, syscall add_stdlib(); diff --git a/cc1.c b/cc1.c @@ -10,6 +10,7 @@ struct node { kind: int; a: *node; b: *node; + filename: *byte; lineno: int; colno: int; n: int; @@ -83,7 +84,9 @@ struct compiler { page: *page; // Lexer + fdin: int; nc: int; + filename: *byte; lineno: int; colno: int; tt: int; @@ -92,6 +95,7 @@ struct compiler { tmax: int; // Assembler + fdout: int; at: int; text: *chunk; text_end: *chunk; @@ -227,6 +231,30 @@ write(fd: int, buf: *byte, n: int): int { return syscall(1, fd, buf: int, n, 0, 0, 0); } +open(name: *byte, flags: int, mode: int): int { + return syscall(2, name: int, flags, mode, 0, 0, 0); +} + +lseek(fd: int, offset: int, whence: int): int { + return syscall(8, fd, offset, whence, 0, 0, 0); +} + +close(fd: int): int { + return syscall(3, fd, 0, 0, 0, 0, 0); +} + +fchmod(fd: int, mode: int): int { + return syscall(91, fd, mode, 0, 0, 0, 0); +} + +rename(oldname: *byte, newname: *byte): int { + return syscall(82, oldname: int, newname: int, 0, 0, 0, 0); +} + +unlink(name: *byte): int { + return syscall(87, name: int, 0, 0, 0, 0, 0); +} + mmap(addr: int, len: int, prot: int, flags: int, fd: int, off: int): int { return syscall(9, addr, len, prot, flags, fd, off); } @@ -280,10 +308,10 @@ alloc(c: *compiler, size: int): *byte { return ret; } -getchar(): int { +getchar(c: *compiler): int { var b: byte; var ret: int; - ret = read(0, &b, 1); + ret = read(c.fdin, &b, 1); if (ret < 0) { exit(3); } @@ -293,11 +321,11 @@ getchar(): int { return b: int; } -putchar(ch: int) { +putchar(c: *compiler, ch: int) { var b: byte; var ret: int; b = ch: byte; - ret = write(1, &b, 1); + ret = write(c.fdout, &b, 1); if (ret != 1) { exit(3); } @@ -416,7 +444,11 @@ fdputd(fd: int, n: int) { } show_context(c: *compiler) { - fdput(2, "on -:"); + fdput(2, "on "); + if (c.filename) { + fdput(2, c.filename); + } + fdput(2, ":"); fdputd(2, c.lineno); fdput(2, ":"); fdputd(2, c.colno); @@ -431,10 +463,59 @@ die(c: *compiler, msg: *byte) { exit(1); } +open_output(c: *compiler, filename: *byte) { + var fd: int; + + c.filename = filename; + + if (c.fdout != 1) { + die(c, "multiple output files"); + } + + unlink(filename); + + fd = open(filename, 64 + 1, (7 << 6) + (7 << 3) + 7); + if (fd < 0) { + die(c, "failed to open output"); + } + + c.fdout = fd; +} + +open_source(c: *compiler, filename: *byte) { + var fd: int; + + c.filename = filename; + c.nc = 0; + c.lineno = 1; + c.colno = 1; + c.tlen = 0; + c.tt = 0; + + fd = open(filename, 0, 0); + if (fd < 0) { + die(c, "failed to open file"); + } + + c.fdin = fd; + c.nc = getchar(c); + + feed(c); +} + +close_source(c: *compiler) { + if (c.fdin != 0) { + close(c.fdin); + } + c.fdin = 0; +} + comp_setup(c: *compiler) { c.page = 0:*page; - c.nc = getchar(); + c.fdin = 0; + c.nc = 0; + c.filename = 0:*byte; c.lineno = 1; c.colno = 1; c.tlen = 0; @@ -442,17 +523,16 @@ comp_setup(c: *compiler) { c.token = alloc(c, c.tmax); c.tt = 0; + c.fdout = 1; c.at = 0; c.text = 0:*chunk; c.text_end = 0:*chunk; c.decls = 0:*decl; - - feed(c); } feedc(c: *compiler) { - c.nc = getchar(); + c.nc = getchar(c); if (c.nc == '\n') { c.lineno = c.lineno + 1; c.colno = 0; @@ -676,10 +756,10 @@ feed_escape(c: *compiler) { } else if (c.nc == 'n') { c.nc = '\n'; } else if (c.nc == 'x') { - c.nc = getchar(); + c.nc = getchar(c); hex = hexdig(c) * 16; - c.nc = getchar(); + c.nc = getchar(c); hex = hex + hexdig(c); c.nc = hex; @@ -785,6 +865,7 @@ mknode(c: *compiler, kind: int, a: *node, b: *node): *node { ret.kind = kind; ret.a = a; ret.b = b; + ret.filename = c.filename; ret.lineno = c.lineno; ret.colno = c.colno; ret.n = 0; @@ -2568,6 +2649,7 @@ compile_expr(c: *compiler, d: *decl, n: *node, rhs: int) { var v: *decl; var kind: int; + c.filename = n.filename; c.lineno = n.lineno; c.colno = 0; @@ -3181,6 +3263,7 @@ compile_stmt(c: *compiler, d: *decl, n: *node, top: *label, out: *label) { return; } + c.filename = n.filename; c.lineno = n.lineno; c.colno = 0; @@ -4218,190 +4301,190 @@ writeout(c: *compiler) { text_size = text_size + 128; // magic - putchar(0x7f); - putchar('E'); - putchar('L'); - putchar('F'); + putchar(c, 0x7f); + putchar(c, 'E'); + putchar(c, 'L'); + putchar(c, 'F'); // class - putchar(2); + putchar(c, 2); // endian - putchar(1); + putchar(c, 1); // version - putchar(1); + putchar(c, 1); // abi - putchar(0); + putchar(c, 0); // abi version - putchar(0); + putchar(c, 0); // padding - putchar(0); - putchar(0); - putchar(0); - putchar(0); - putchar(0); - putchar(0); - putchar(0); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); // type - putchar(2); - putchar(0); + putchar(c, 2); + putchar(c, 0); // machine - putchar(62); - putchar(0); + putchar(c, 62); + putchar(c, 0); // version - putchar(1); - putchar(0); - putchar(0); - putchar(0); + putchar(c, 1); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); // entry point - putchar(entry); - putchar(entry >> 8); - putchar(entry >> 16); - putchar(entry >> 24); - putchar(0); - putchar(0); - putchar(0); - putchar(0); + putchar(c, entry); + putchar(c, entry >> 8); + putchar(c, entry >> 16); + putchar(c, entry >> 24); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); // phoff - putchar(64); - putchar(0); - putchar(0); - putchar(0); - putchar(0); - putchar(0); - putchar(0); - putchar(0); + putchar(c, 64); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); // shoff - putchar(0); - putchar(0); - putchar(0); - putchar(0); - putchar(0); - putchar(0); - putchar(0); - putchar(0); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); // flags - putchar(0); - putchar(0); - putchar(0); - putchar(0); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); // ehsize - putchar(64); - putchar(0); + putchar(c, 64); + putchar(c, 0); // phentsize - putchar(56); - putchar(0); + putchar(c, 56); + putchar(c, 0); // phnum - putchar(1); - putchar(0); + putchar(c, 1); + putchar(c, 0); // shentsize - putchar(64); - putchar(0); + putchar(c, 64); + putchar(c, 0); // shnum - putchar(0); - putchar(0); + putchar(c, 0); + putchar(c, 0); // shstrndx - putchar(0); - putchar(0); + putchar(c, 0); + putchar(c, 0); // phdr[0].type - putchar(1); - putchar(0); - putchar(0); - putchar(0); + putchar(c, 1); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); // phdr[0].flags - putchar(5); - putchar(0); - putchar(0); - putchar(0); + putchar(c, 5); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); // phdr[0].offset - putchar(0); - putchar(0); - putchar(0); - putchar(0); - putchar(0); - putchar(0); - putchar(0); - putchar(0); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); // phdr[0].vaddr - putchar(0); - putchar(0); - putchar(0x10); - putchar(0); - putchar(0); - putchar(0); - putchar(0); - putchar(0); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0x10); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); // phdr[0].paddr - putchar(0); - putchar(0); - putchar(0); - putchar(0); - putchar(0); - putchar(0); - putchar(0); - putchar(0); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); // phdr[0].filesize - putchar(text_size); - putchar(text_size >> 8); - putchar(text_size >> 16); - putchar(text_size >> 24); - putchar(0); - putchar(0); - putchar(0); - putchar(0); + putchar(c, text_size); + putchar(c, text_size >> 8); + putchar(c, text_size >> 16); + putchar(c, text_size >> 24); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); // phdr[0].memsize - putchar(text_size); - putchar(text_size >> 8); - putchar(text_size >> 16); - putchar(text_size >> 24); - putchar(0); - putchar(0); - putchar(0); - putchar(0); + putchar(c, text_size); + putchar(c, text_size >> 8); + putchar(c, text_size >> 16); + putchar(c, text_size >> 24); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); // phdr[0].align - putchar(0); - putchar(0); - putchar(0); - putchar(0); - putchar(0); - putchar(0); - putchar(0); - putchar(0); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); + putchar(c, 0); // nop sled - putchar(0x90); - putchar(0x90); - putchar(0x90); - putchar(0x90); - putchar(0x90); - putchar(0x90); - putchar(0x90); - putchar(0x90); + putchar(c, 0x90); + putchar(c, 0x90); + putchar(c, 0x90); + putchar(c, 0x90); + putchar(c, 0x90); + putchar(c, 0x90); + putchar(c, 0x90); + putchar(c, 0x90); b = c.text; loop { @@ -4413,7 +4496,7 @@ writeout(c: *compiler) { if (i >= b.fill) { break; } - putchar(b.buf[i]: int); + putchar(c, b.buf[i]: int); i = i + 1; } b = b.next; @@ -4423,9 +4506,38 @@ writeout(c: *compiler) { main(argc: int, argv: **byte, envp: **byte) { var c: compiler; var p: *node; + var i: int; + comp_setup(&c); - p = parse_program(&c); - compile(&c, p); + + i = 1; + loop { + if (i >= argc) { + break; + } + + if (!strcmp(argv[i], "-o")) { + i = i + 1; + if (i >= argc) { + die(&c, "invalid -o at end of argument list"); + } + open_output(&c, argv[i]); + i = i + 1; + continue; + } + + open_source(&c, argv[i]); + p = parse_program(&c); + close_source(&c); + compile(&c, p); + + i = i + 1; + } + + if (c.fdout == 1) { + open_output(&c, "a.out"); + } + gen_builtins(&c); writeout(&c); } diff --git a/cc2 b/cc2 Binary files differ.