commit c67390f2b74b07d576675fd6165e2132af0b79c4
parent 992236e47e3d81d906a71fae6d05cce2dc2ef08f
Author: William Djupström <william@deepztream.com>
Date: Fri, 1 Mar 2019 00:46:58 +0100
More of better and some of worse
Diffstat:
3 files changed, 533 insertions(+), 344 deletions(-)
diff --git a/examples/example.6 b/examples/example.6
@@ -1,7 +1,7 @@
_start() {
decl c = 64;
while (c < 64+26)
- putc(c = c + 1);
+ putc(c = 1 + c);
putc(10);
exit(0);
}
diff --git a/examples/example.7 b/examples/example.7
@@ -0,0 +1,15 @@
+strlen(s) {
+ decl i = 0;
+ while (s[i] & 255)
+ i = i + 1;
+ return i;
+}
+
+print(s) {
+ write(strlen(s), s);
+}
+
+_start() {
+ print("Hello There!\n");
+ exit(0);
+}
diff --git a/parse.y b/parse.y
@@ -168,6 +168,69 @@ struct expression *copy(struct expression *e)
memcpy(r, e, sizeof(struct expression));
return r;
}
+
+char *expand_str(char *str) {
+ int i, j = 0, l = strlen(str);
+ for (i = 0; i < l; i++) {
+ if (str[i] == '\\') {
+ switch (str[i+1]) {
+ case 'n':
+ j = 1;
+ str[i+j] = '\n';
+ break;
+ case 'r':
+ j = 1;
+ str[i+j] = '\r';
+ break;
+ case 't':
+ j = 1;
+ str[i+j] = '\t';
+ break;
+ case '\\':
+ i++;
+ default:
+ j = 0;
+ break;
+ }
+ l -= j;
+ if (j) memmove(&str[i], &str[i+j], l - i + 1);
+ }
+ }
+ return str;
+}
+
+char *escape_str(char *str) {
+ int i, j, l = strlen(str);
+ char *r;
+ for (i = 0, j = 1; i < l; i++)
+ if (str[i] == '\\' || str[i] == '\n' || str[i] == '\r' || str[i] == '\t')
+ j++;
+ r = calloc(l + j, 1);
+ for (i = 0, j = 0; i < l; i++, j++) {
+ switch (str[i]) {
+ case '\n':
+ r[j++] = '\\';
+ r[j] = 'n';
+ break;
+ case '\r':
+ r[j++] = '\\';
+ r[j] = 'r';
+ break;
+ case '\t':
+ r[j++] = '\\';
+ r[j] = 't';
+ break;
+ case '\\':
+ r[j++] = '\\';
+ r[j] = '\\';
+ break;
+ default:
+ r[j] = str[i];
+ break;
+ }
+ }
+ return r;
+}
%}
%union {struct expression *expr; char *str; int64_t i;}
@@ -237,7 +300,7 @@ if_stmt: "if" '(' expression ')' statement {$$ = e(ifnz, $3, $5, 0);}
;
comp_stmt: '{' {$$ = e(comma, NULL, NULL, 1);}
-| comp_stmt statement {$$ = move($1); append($$, $2);}/*$$ = e(comma, $1, $2, 0);}*/
+| comp_stmt statement {$$ = move($1); append($$, $2);}
;
var_defs: "decl" var_def {$$ = e(comma, $2, NULL, 0);}
@@ -261,8 +324,8 @@ c_expr: expression {$$ = move($1);}
expression: IDENTIFIER {$$ = copy(find_idnt($1));}
| NUMBER {$$ = e(number, (void *)$1, NULL, 1);}
-| str {$$ = e(string, (void *)$1, NULL, 0);}
-| expression '[' expression ']' {printf("uh-oh\n");$$ = NULL;}
+| str {$$ = e(string, (void *)expand_str($1), NULL, 0);}
+| expression '[' expression ']' {$$ = e(deref, e(add, $1, $3, 0), NULL, 0);}
| '(' exprs ')' {$$ = move($2);}
| expression '(' ')' {$$ = e(fcall, $1, NULL, 0);}
| expression '(' c_expr ')' {$$ = e(fcall, $1, $3, 0);}
@@ -273,7 +336,7 @@ expression: IDENTIFIER {$$ = copy(find_idnt($1));}
| expression '*' expression {$$ = e(mul, $1, $3, 0);}
| expression '/' expression {$$ = e(divide, $1, $3, 0);}
| expression '%' expression {$$ = e(mod, $1, $3, 0);}
-| expression '&' expression {printf("uh-oh\n");$$ = NULL;}
+| expression '&' expression {$$ = e(b_and, $1, $3, 0);}
| expression '|' expression {printf("uh-oh\n");$$ = NULL;}
| expression '^' expression {printf("uh-oh\n");$$ = NULL;}
| expression "<<" expression {$$ = e(shift_l, $1, $3, 0);}
@@ -289,12 +352,12 @@ expression: IDENTIFIER {$$ = copy(find_idnt($1));}
| expression "^=" expression {printf("uh-oh\n");$$ = NULL;}
| expression "<<=" expression {printf("uh-oh\n");$$ = NULL;}
| expression ">>=" expression {printf("uh-oh\n");$$ = NULL;}
-| expression "==" expression {printf("uh-oh\n");$$ = NULL;}
-| expression "!=" expression {printf("uh-oh\n");$$ = NULL;}
+| expression "==" expression {$$ = e(l_eq, $1, $3, 0);}
+| expression "!=" expression {$$ = e(l_not, e(l_eq, $1, $3, 0), NULL, 0);}
| expression '<' expression {$$ = e(l_lt, $1, $3, 0);}
| expression '>' expression {$$ = e(l_lt, $3, $1, 0);}
-| expression "<=" expression {printf("uh-oh\n");$$ = NULL;}
-| expression ">=" expression {printf("uh-oh\n");$$ = NULL;}
+| expression "<=" expression {$$ = e(l_not, e(l_lt, $3, $1, 0), NULL, 0);}
+| expression ">=" expression {$$ = e(l_not, e(l_lt, $1, $3, 0), NULL, 0);}
| '!' expression {$$ = e(l_not, $2, NULL, 0);}
| '~' expression {printf("uh-oh\n");$$ = NULL;}
| '*' expression %prec REF {$$ = e(deref, $2, NULL, 0);}
@@ -313,6 +376,7 @@ str: str STRING {$$ = calloc(strlen($1) + strl
%%
#include <stdio.h>
+#include <fcntl.h>
char *exp_str[] = {
#define f(e) #e,
@@ -323,12 +387,15 @@ EXPRESSION_TYPES(f)
void stringify(struct expression *e, int p_indent, int last, char *name, uint64_t idmap)
{
int i, indent = p_indent + 3;
+ char *str;
if (last) idmap |= (1 << p_indent/3);
for (i = 0; i < p_indent; i+=3) fprintf(stderr, "%s ", (idmap & (1 << (i/3))) ? " " : "│");
if (p_indent >= 0) fprintf(stderr, "%s━ ", last ? "┕": "┝");
switch(e->type) {
case string:
- fprintf(stderr, "%s: \"%s\"\n", name ? name : "string", e->str);
+ str = escape_str(e->str);
+ fprintf(stderr, "%s: \"%s\"\n", name ? name : "string", str);
+ free(str);
break;
case idnt:
fprintf(stderr, "%s: %s\n", name ? name : "ident", e->str);
@@ -366,13 +433,62 @@ int entry_addr = -1;
long start_addr, rodata_addr;
int func_declares;
-int arg_order[16] = {7, 6, 2, 1, 8, 9, 0, 10, 11, 12, 13, 14, 15, 3, 5};
-int caller_save = 0b0000000011001111;
+int arg_order[16] = {7, 6, 2, 1, 8, 9, 1, 0, 11, 12, 13, 14, 15, 3, 5};
+int syscall_arg[16] = {7, 6, 2, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1};
+int caller_save = 0b0000111111001111;
+
+int get_free_reg(int mark_used)
+{
+ int i;
+ for (i = 0; i < registers; i++) {
+ if (!(used_regs & (1 << i))) {
+ if (mark_used) used_regs |= (1 << i);
+ return i;
+ break;
+ }
+ }
+ fprintf(stderr, "Out of registers?!? fix me\n");
+ exit(1);
+}
+
+void push(int reg, int *pushed, char *order) {
+ int i;
+ if (used_regs & (1 << reg)) {
+ machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 1 : 0);
+ machine_code[mc_ptr++] = 0x50 + (reg % 8);
+ for (i = 0; i < registers; i++) {
+ if (order[i] == -1) {
+ order[i] = reg;
+ used_regs &= ~(1 << reg);
+ *pushed |= (1 << reg);
+ next_rbp += 8;
+ return;
+ }
+ }
+ fprintf(stderr, "Unable to push any more registers\n");
+ exit(1);
+ }
+}
+
+void pop(int reg, int *pushed) {
+ if (!(*pushed & (1 << reg))) {
+ fprintf(stderr, "Trying to pop a register which hasn't been pushed\n");
+ exit(1);
+ }
+ machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 1 : 0);
+ machine_code[mc_ptr++] = 0x58 + (reg % 8);
+ *pushed &= ~(1 << reg);
+ used_regs |= (1 << reg);
+ next_rbp -= 8;
+}
int compile_tree(FILE *output, struct expression *tree, int discard_result, int out_reg)
{
int i, j, k, l, reg = -1;
- char out[1024];
+ char push_order[16] = { -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ -1, -1, -1, -1 };
int pushed = 0;
struct expression *tmp;
fprintf(stderr, "Type: %s\n", exp_str[tree->type]);
@@ -444,64 +560,38 @@ int compile_tree(FILE *output, struct expression *tree, int discard_result, int
}
}
}
- compile_tree(output, &tree->args[tree->args_count-1], 1, 0);
- if (strcmp(tree->args->str, "_start")) {
+ j = compile_tree(output, &tree->args[tree->args_count-1], 1, 0);
+ if (strcmp(tree->args->str, "_start") && j != -3 && j != -2) {
machine_code[mc_ptr++] = 0xc9;
machine_code[mc_ptr++] = 0xc3;
}
break;
case comma:
for (i = 0; i < tree->args_count; i++) {
- j = compile_tree(output, &tree->args[i], (i+1 == tree->args_count ? discard_result : 1), out_reg);
+ j = compile_tree(output, &tree->args[i], (i+1 == tree->args_count ? discard_result : 1), (i+1 == tree->args_count ? out_reg : -1));
+ if (j == -2 || j == -3) return j;
}
if (!discard_result) reg = j;
break;
case fcall:
for (i = 0; i < registers; i++) {
- if ((1 << i) & caller_save && (1 << i) & used_regs) {
+ if (caller_save & (1 << i)) {
+ push(i, &pushed, push_order);
+ /*
machine_code[mc_ptr++] = 0x48 | (i > 7 ? 1 : 0);
machine_code[mc_ptr++] = 0x50 + (i % 8);
next_rbp += 8;
pushed |= (1 << i);
+ */
}
}
if (tree->args_count == 2) {
if (tree->args[1].type == comma) {
for (i = 0; i < tree->args[1].args_count; i++) {
j = compile_tree(output, &tree->args[1].args[i], 0, arg_order[i]);
- if (j != arg_order[i]) {
- if (j >= registers) {
- machine_code[mc_ptr++] = 0x48 | (arg_order[i] > 7 ? 1 : 0);
- machine_code[mc_ptr++] = 0x8b;
- machine_code[mc_ptr++] = 0x45 + (arg_order[i] % 8) * 8;
- machine_code[mc_ptr++] = -regs[j].rbp;
- } else {
- machine_code[mc_ptr++] = 0x48 | (j > 7 ? 4 : 0) | (arg_order[i] > 7 ? 1 : 0);
- machine_code[mc_ptr++] = 0x89;
- machine_code[mc_ptr++] = 0xC0 + (j % 8) * 8 + arg_order[i];
- used_regs &= ~(1 << j);
- }
- }
- used_regs |= (1 << arg_order[i]);
}
- k = i;
} else {
j = compile_tree(output, &tree->args[1], 0, arg_order[0]);
- if (j != arg_order[0]) {
- used_regs |= (1 << arg_order[0]);
- if (j >= registers) {
- machine_code[mc_ptr++] = 0x48 | (arg_order[0] > 7 ? 1 : 0);
- machine_code[mc_ptr++] = 0x8b;
- machine_code[mc_ptr++] = 0x45 + (arg_order[0] % 8) * 8;
- machine_code[mc_ptr++] = -regs[j].rbp;
- } else {
- machine_code[mc_ptr++] = 0x48 | (j > 7 ? 4 : 0) | (arg_order[0] > 7 ? 1 : 0);
- machine_code[mc_ptr++] = 0x89;
- machine_code[mc_ptr++] = 0xC0 + (j % 8) * 8 + arg_order[0];
- used_regs &= ~(1 << j);
- }
- }
- k = 1;
}
}
if (!(pushed & 1)) {
@@ -512,22 +602,26 @@ int compile_tree(FILE *output, struct expression *tree, int discard_result, int
*(int32_t *) &machine_code[mc_ptr] = j - start_addr - mc_ptr - 4;
mc_ptr += 4;
- if (!discard_result) reg = 0;
- if (pushed & 1 && !discard_result) {
- for (i = 0; i < registers; i++) {
- if (!(used_regs & (1 << i))) {
- reg = i;
- used_regs |= (1 << reg);
- break;
+ if (!discard_result) {
+ if (pushed & 1 && (out_reg < 0 || out_reg >= registers)) {
+ for (i = 0; i < registers; i++) {
+ if (!(used_regs & (1 << i))) {
+ reg = i;
+ used_regs |= (1 << reg);
+ break;
+ }
}
+ if (i == registers) {
+ fprintf(stderr, "Out of registers?!? fix me\n");
+ exit(1);
+ }
+
+ } else if (out_reg >= 0 && out_reg < registers){
+ reg = out_reg;
+ machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 1 : 0);
+ machine_code[mc_ptr++] = 0x89;
+ machine_code[mc_ptr++] = 0xC0 + (reg % 8);
}
- if (i == registers) {
- fprintf(stderr, "Out of registers?!? fix me\n");
- exit(1);
- }
- machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 1 : 0);
- machine_code[mc_ptr++] = 0x89;
- machine_code[mc_ptr++] = 0xC0 + (reg % 8);
}
for (i = registers - 1; i >= 0; i--) {
if (pushed & (1 << i)) {
@@ -550,19 +644,9 @@ int compile_tree(FILE *output, struct expression *tree, int discard_result, int
}
reg = j;
if (reg >= registers) {
- for (i = 0; i < registers; i++) {
- if (!(used_regs & (1 << i))) {
- reg = i;
- used_regs |= (1 << reg);
- break;
- }
- }
- if (i == registers) {
- fprintf(stderr, "Out of registers?!? fix me\n");
- exit(1);
- }
+ reg = get_free_reg(1);
}
- if (tree->args->type == idnt) {
+ if (j >= registers) {
machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 4 : 0);
machine_code[mc_ptr++] = 0x8b;
machine_code[mc_ptr++] = 0x45 + (reg % 8) * 8;
@@ -851,6 +935,43 @@ int compile_tree(FILE *output, struct expression *tree, int discard_result, int
if (k < registers) used_regs &= ~(1 << k);
break;
+ case b_and:
+ j = compile_tree(output, tree->args, discard_result, out_reg);
+ k = compile_tree(output, &tree->args[1], discard_result, -1);
+ if (discard_result) {
+ if (j < registers) used_regs &= ~(1 << j);
+ if (k < registers) used_regs &= ~(1 << k);
+ break;
+ }
+ reg = j;
+ if (reg >= registers) {
+ for (i = 0; i < registers; i++) {
+ if (!(used_regs & (1 << i))) {
+ reg = i;
+ used_regs |= (1 << reg);
+ break;
+ }
+ }
+ if (i == registers) {
+ fprintf(stderr, "Out of registers?!? fix me\n");
+ exit(1);
+ }
+ machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 4 : 0);
+ machine_code[mc_ptr++] = 0x8b;
+ machine_code[mc_ptr++] = 0x45 + (reg % 8) * 8;
+ machine_code[mc_ptr++] = -regs[j].rbp;
+ }
+ machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 4 : 0);
+ machine_code[mc_ptr++] = 0x23;
+ if (tree->args[1].type == idnt) {
+ machine_code[mc_ptr++] = 0x45 + (reg % 8) * 8;
+ machine_code[mc_ptr++] = -regs[k].rbp;
+ } else {
+ machine_code[mc_ptr-2] |= k > 7 ? 1 : 0;
+ machine_code[mc_ptr++] = 0xC0 + (reg % 8) * 8 + k;
+ }
+ if (k < registers) used_regs &= ~(1 << k);
+ break;
case decl:
reg = next_reg++;
regs[reg].type = 1;
@@ -860,41 +981,43 @@ int compile_tree(FILE *output, struct expression *tree, int discard_result, int
break;
case set:
reg = compile_tree(output, tree->args, 0, -1);
- j = compile_tree(output, &tree->args[1], 0, out_reg);
+ j = compile_tree(output, &tree->args[1], 0, reg);
+ /*
if (j < 0) {
fprintf(stderr, "No rvalue for assignment\n");
exit(1);
}
used_regs &= ~(1 << j);
- if (reg >= registers) {
- if (j >= registers) {
- for (i = 0; i < registers; i++) {
- if (!(used_regs & (1 << i))) {
- k = i;
- break;
- }
- }
- if (i == registers) {
- fprintf(stderr, "Out of registers?!? fix me\n");
- exit(1);
+ if (j >= registers) {
+ for (i = 0; i < registers; i++) {
+ if (!(used_regs & (1 << i))) {
+ k = i;
+ break;
}
- machine_code[mc_ptr++] = 0x48 | (k > 7 ? 4 : 0);
- machine_code[mc_ptr++] = 0x8b;
- machine_code[mc_ptr++] = 0x45 + (k % 8) * 8;
- machine_code[mc_ptr++] = -regs[j].rbp;
-
- machine_code[mc_ptr++] = 0x48 | (k > 7 ? 4 : 0);
- machine_code[mc_ptr++] = 0x89;
- machine_code[mc_ptr++] = 0x45 + (k % 8) * 8;
- machine_code[mc_ptr++] = -regs[reg].rbp;
- } else {
- machine_code[mc_ptr++] = 0x48 | (j > 7 ? 4 : 0);
- machine_code[mc_ptr++] = 0x89;
- machine_code[mc_ptr++] = 0x45 + (j % 8) * 8;
- machine_code[mc_ptr++] = -regs[reg].rbp;
}
+ if (i == registers) {
+ fprintf(stderr, "Out of registers?!? fix me\n");
+ exit(1);
+ }
+ machine_code[mc_ptr++] = 0x48 | (k > 7 ? 4 : 0);
+ machine_code[mc_ptr++] = 0x8b;
+ machine_code[mc_ptr++] = 0x45 + (k % 8) * 8;
+ machine_code[mc_ptr++] = -regs[j].rbp;
+ } else {
+ k = j;
+ }
+ if (reg >= registers) {
+ machine_code[mc_ptr++] = 0x48 | (k > 7 ? 4 : 0);
+ machine_code[mc_ptr++] = 0x89;
+ machine_code[mc_ptr++] = 0x45 + (k % 8) * 8;
+ machine_code[mc_ptr++] = -regs[reg].rbp;
+ } else if (tree->args->type == deref) {
+ machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 1 : 0) | (k > 7 ? 4 : 0);
+ machine_code[mc_ptr++] = 0x89;
+ machine_code[mc_ptr++] = 0x00 + (reg % 8) + (k % 8) * 8;
}
if (discard_result) reg = -1;
+ */
break;
case ref:
if (tree->args->type != idnt) {
@@ -923,17 +1046,44 @@ int compile_tree(FILE *output, struct expression *tree, int discard_result, int
machine_code[mc_ptr++] = -regs[j].rbp;
break;
case deref:
+ j = compile_tree(output, tree->args, discard_result, out_reg);
+ if (discard_result) {
+ if (used_regs & (1 << j)) used_regs &= ~(1 << j);
+ break;
+ }
+ reg = j;
+ if (j >= registers) {
+ for (i = 0; i < registers; i++) {
+ if (!(used_regs & (1 << i))) {
+ reg = i;
+ break;
+ }
+ }
+ if (i == registers) {
+ fprintf(stderr, "Out of registers?!? fix me\n");
+ exit(1);
+ }
+ used_regs |= (1 << reg);
+ machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 4 : 0);
+ machine_code[mc_ptr++] = 0x8b;
+ machine_code[mc_ptr++] = 0x45 + (reg % 8) * 8;
+ machine_code[mc_ptr++] = -regs[j].rbp;
+ }
+ machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 5 : 0);
+ machine_code[mc_ptr++] = 0x8b;
+ machine_code[mc_ptr++] = 0x00 + (reg % 8) + (reg % 8) * 8;
break;
case idnt:
if (discard_result) break;
- for (i = registers; i < 1024; i++) {
- if (regs[i].type != 1) continue;
- if (!strcmp(regs[i].var, tree->str)) break;
+ for (reg = registers; reg < 1024; reg++) {
+ if (regs[reg].type != 1) continue;
+ if (!strcmp(regs[reg].var, tree->str)) break;
}
- if (i == 1024) {
+ if (reg == 1024) {
fprintf(stderr, "Unable to locate identifier <%s>\n", tree->str);
exit(1);
}
+ /*
if (out_reg != -1 && out_reg < registers) {
reg = out_reg;
machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 4 : 0);
@@ -944,6 +1094,7 @@ int compile_tree(FILE *output, struct expression *tree, int discard_result, int
} else {
reg = i;
}
+ */
break;
case number:
if (discard_result) break;
@@ -1003,7 +1154,6 @@ int compile_tree(FILE *output, struct expression *tree, int discard_result, int
case loop:
machine_code[mc_ptr++] = 0xe9;
k = mc_ptr;
- //*(int32_t *) &machine_code[mc_ptr] = 0x00;
mc_ptr += 4;
compile_tree(output, &tree->args[1], 1, -1);
*(int32_t *) &machine_code[k] = mc_ptr - k - 4;
@@ -1041,7 +1191,6 @@ int compile_tree(FILE *output, struct expression *tree, int discard_result, int
machine_code[mc_ptr++] = 0x0f;
machine_code[mc_ptr++] = 0x84;
k = mc_ptr;
- //*(int32_t *) &machine_code[mc_ptr] = 0x00; //Offset
mc_ptr += 4;
// True
used_regs = (1 << 5) | (1 << 4);
@@ -1103,6 +1252,80 @@ int compile_tree(FILE *output, struct expression *tree, int discard_result, int
*(int64_t *) &machine_code[mc_ptr] = 1;
mc_ptr += 8;
break;
+ case l_eq:
+ j = compile_tree(output, tree->args, discard_result, -1);
+ k = compile_tree(output, &tree->args[1], discard_result, out_reg);
+ if (discard_result) {
+ if (j < registers) used_regs &= ~(1 << j);
+ if (k < registers) used_regs &= ~(1 << k);
+ break;
+ }
+ reg = k;
+
+ if (j >= registers) {
+ if (k >= registers) {
+ for (i = 0; i < registers; i++) {
+ if (!(used_regs & (1 << i))) {
+ reg = i;
+ used_regs |= (1 << reg);
+ break;
+ }
+ }
+ if (i == registers) {
+ fprintf(stderr, "Out of registers?!? fix me\n");
+ exit(1);
+ }
+ machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 4 : 0);
+ machine_code[mc_ptr++] = 0x8b;
+ machine_code[mc_ptr++] = 0x45 + (reg % 8) * 8;
+ machine_code[mc_ptr++] = -regs[k].rbp;
+ k = reg;
+ }
+ machine_code[mc_ptr++] = 0x48 | (k > 7 ? 4 : 0);
+ machine_code[mc_ptr++] = 0x39;
+ machine_code[mc_ptr++] = 0x45 + (k % 8) * 8;
+ machine_code[mc_ptr++] = -regs[j].rbp;
+ } else if (k >= registers) {
+ for (i = 0; i < registers; i++) {
+ if (!(used_regs & (1 << i))) {
+ reg = i;
+ used_regs |= (1 << reg);
+ break;
+ }
+ }
+ if (i == registers) {
+ fprintf(stderr, "Out of registers?!? fix me\n");
+ exit(1);
+ }
+ machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 4 : 0);
+ machine_code[mc_ptr++] = 0x8b;
+ machine_code[mc_ptr++] = 0x45 + (reg % 8) * 8;
+ machine_code[mc_ptr++] = -regs[k].rbp;
+
+ k = reg;
+ machine_code[mc_ptr++] = 0x48 | (j > 7 ? 1 : 0) | (k > 7 ? 4 : 0);
+ machine_code[mc_ptr++] = 0x39;
+ machine_code[mc_ptr++] = 0xc0 + (j % 8) + (k % 8) * 8;
+ } else {
+ machine_code[mc_ptr++] = 0x48 | (j > 7 ? 1 : 0) | (k > 7 ? 4 : 0);
+ machine_code[mc_ptr++] = 0x39;
+ machine_code[mc_ptr++] = 0xc0 + (j % 8) + (k % 8) * 8;
+ used_regs &= ~(1 << k);
+ }
+ machine_code[mc_ptr++] = 0x74;
+ machine_code[mc_ptr++] = 0x05; //Offset
+ // Not less than:
+ machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 5 : 0);
+ machine_code[mc_ptr++] = 0x33;
+ machine_code[mc_ptr++] = 0xc0 + (reg % 8) + (reg % 8) * 8;
+ machine_code[mc_ptr++] = 0xeb;
+ machine_code[mc_ptr++] = 0x0a;
+ // Less than:
+ machine_code[mc_ptr++] = 0x48 + (reg > 7 ? 1 : 0);
+ machine_code[mc_ptr++] = 0xb8 + (reg % 8);
+ *(int64_t *) &machine_code[mc_ptr] = 1;
+ mc_ptr += 8;
+ break;
case l_lt:
j = compile_tree(output, tree->args, discard_result, out_reg);
k = compile_tree(output, &tree->args[1], discard_result, -1);
@@ -1195,110 +1418,74 @@ int compile_tree(FILE *output, struct expression *tree, int discard_result, int
}
machine_code[mc_ptr++] = 0xc9;
machine_code[mc_ptr++] = 0xc3;
- break;
+ return -3;
case writestring:
- if (used_regs & (1 << 0)) {
- machine_code[mc_ptr++] = 0x48;
- machine_code[mc_ptr++] = 0x50;
- next_rbp += 8;
- pushed |= (1 << 0);
- }
- if (used_regs & (1 << arg_order[0])) {
- machine_code[mc_ptr++] = 0x48 | (arg_order[0] > 7 ? 1 : 0);
- machine_code[mc_ptr++] = 0x50 + (arg_order[0] % 8);
- next_rbp += 8;
- pushed |= (1 << arg_order[0]);
- }
- if (used_regs & (1 << arg_order[1])) {
- machine_code[mc_ptr++] = 0x48 | (arg_order[1] > 7 ? 1 : 0);
- machine_code[mc_ptr++] = 0x50 + (arg_order[1] % 8);
- next_rbp += 8;
- pushed |= (1 << arg_order[1]);
- }
- if (used_regs & (1 << arg_order[2])) {
- machine_code[mc_ptr++] = 0x48 | (arg_order[2] > 7 ? 1 : 0);
- machine_code[mc_ptr++] = 0x50 + (arg_order[2] % 8);
- next_rbp += 8;
- pushed |= (1 << arg_order[2]);
- }
+ push(syscall_arg[2], &pushed, push_order);
+ compile_tree(output, tree->args, 0, syscall_arg[2]);
+
+ push(syscall_arg[1], &pushed, push_order);
+ compile_tree(output, &tree->args[1], 0, syscall_arg[1]);
+
+ push(syscall_arg[0], &pushed, push_order);
+ push(0, &pushed, push_order);
machine_code[mc_ptr++] = 0x48;
machine_code[mc_ptr++] = 0xb8;
*(int64_t *) &machine_code[mc_ptr] = 0x01;
mc_ptr += 8;
- machine_code[mc_ptr++] = 0x48 | (arg_order[0] > 7 ? 1 : 0);
- machine_code[mc_ptr++] = 0x89;
- machine_code[mc_ptr++] = 0xc0 + (arg_order[0] % 8);
- /*
- machine_code[mc_ptr++] = 0x48 | (arg_order[2] > 7 ? 1 : 0);
- machine_code[mc_ptr++] = 0x89;
- machine_code[mc_ptr++] = 0xc0 + (arg_order[2] % 8);
- */
- used_regs |= (1 << 0) | (1 << arg_order[0]);
-
- compile_tree(output, tree->args, 0, arg_order[2]);
- j = compile_tree(output, &tree->args[1], 0, arg_order[1]);
+ machine_code[mc_ptr++] = 0x48 | (syscall_arg[0] > 7 ? 1 : 0);
+ machine_code[mc_ptr++] = 0x89;
+ machine_code[mc_ptr++] = 0xc0 + (syscall_arg[0] % 8);
/*
- if (used_regs & (1 << arg_order[1]) && j != arg_order[1]) {
- machine_code[mc_ptr++] = 0x48 | (arg_order[1] > 7 ? 1 : 0);
- machine_code[mc_ptr++] = 0x50 + (arg_order[1] % 8);
+ if (used_regs & (1 << 0)) {
+ machine_code[mc_ptr++] = 0x48;
+ machine_code[mc_ptr++] = 0x50;
next_rbp += 8;
- pushed |= (1 << arg_order[1]);
+ pushed |= (1 << 0);
}
- if (j >= registers) {
- k = 0;
- machine_code[mc_ptr++] = 0x48 | (arg_order[1] > 7 ? 1 : 0);
- machine_code[mc_ptr++] = 0x8d;
- machine_code[mc_ptr++] = 0x45 + (arg_order[1] % 8) * 8;
- machine_code[mc_ptr++] = -regs[j].rbp;
- } else {
- k = 1;
- machine_code[mc_ptr++] = 0x48 | (j > 7 ? 4 : 0);
- machine_code[mc_ptr++] = 0x89;
- machine_code[mc_ptr++] = 0x45 + (j % 8) * 8;
- machine_code[mc_ptr++] = -next_rbp;
-
- machine_code[mc_ptr++] = 0x48 | (arg_order[1] > 7 ? 1 : 0);
- machine_code[mc_ptr++] = 0x8d;
- machine_code[mc_ptr++] = 0x45 + (arg_order[1] % 8) * 8;
- machine_code[mc_ptr++] = -next_rbp;
- used_regs &= ~(1 << j);
+ for (int i = 0; i <= 2; i++) {
+ if (used_regs & (1 << arg_order[i])) {
+ machine_code[mc_ptr++] = 0x48 | (arg_order[i] > 7 ? 1 : 0);
+ machine_code[mc_ptr++] = 0x50 + (arg_order[i] % 8);
+ next_rbp += 8;
+ pushed |= (1 << arg_order[i]);
+ }
}
*/
+
+ //used_regs |= (1 << 0) | (1 << syscall_arg[0]);
+
machine_code[mc_ptr++] = 0x0F;
machine_code[mc_ptr++] = 0x05;
+ reg = 0;
// Reset saved variables
- if (pushed & (1 << arg_order[2])) {
- machine_code[mc_ptr++] = 0x48 | (arg_order[2] > 7 ? 1 : 0);
- machine_code[mc_ptr++] = 0x58 + (arg_order[2] % 8);
- next_rbp -= 8;
- pushed &= ~(1 << arg_order[2]);
- }
- if (pushed & (1 << arg_order[1])) {
- machine_code[mc_ptr++] = 0x48 | (arg_order[1] > 7 ? 1 : 0);
- machine_code[mc_ptr++] = 0x58 + (arg_order[1] % 8);
- next_rbp -= 8;
- pushed &= ~(1 << arg_order[1]);
- }
- if (pushed & (1 << arg_order[0])) {
- machine_code[mc_ptr++] = 0x48 | (arg_order[0] > 7 ? 1 : 0);
- machine_code[mc_ptr++] = 0x58 + (arg_order[0] % 8);
- next_rbp -= 8;
- pushed &= ~(1 << arg_order[0]);
+ /*
+ for (i = 2; i >= 0; i--) {
+ if (pushed & (1 << arg_order[i])) {
+ machine_code[mc_ptr++] = 0x48 | (arg_order[i] > 7 ? 1 : 0);
+ machine_code[mc_ptr++] = 0x58 + (arg_order[i] % 8);
+ next_rbp -= 8;
+ pushed &= ~(1 << arg_order[i]);
+ } else {
+ used_regs &= ~(1 << arg_order[i]);
+ }
}
if (pushed & (1 << 0)) {
if (!discard_result) {
- for (i = 0; i < registers; i++) {
- if (!(used_regs & (1 << i))) {
- reg = i;
- used_regs |= (1 << reg);
- break;
+ reg = out_reg;
+ if (reg < 0 || reg >= registers) {
+ for (i = 0; i < registers; i++) {
+ if (!(used_regs & (1 << i))) {
+ reg = i;
+ used_regs |= (1 << reg);
+ break;
+ }
+ }
+ if (i == registers) {
+ fprintf(stderr, "Out of registers?!? fix me\n");
+ exit(1);
}
- }
- if (i == registers) {
- fprintf(stderr, "Out of registers?!? fix me\n");
- exit(1);
}
machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 1 : 0);
machine_code[mc_ptr++] = 0x8b;
@@ -1309,41 +1496,15 @@ int compile_tree(FILE *output, struct expression *tree, int discard_result, int
machine_code[mc_ptr++] = 0x58;
next_rbp -= 8;
pushed &= ~(1 << 0);
+ } else {
+ if (discard_result) used_regs &= ~(1 << 0);
}
+ */
break;
case printchar:
- if (used_regs & (1 << 0)) {
- machine_code[mc_ptr++] = 0x48;
- machine_code[mc_ptr++] = 0x50;
- next_rbp += 8;
- pushed |= (1 << 0);
- }
- if (used_regs & (1 << arg_order[0])) {
- machine_code[mc_ptr++] = 0x48 | (arg_order[0] > 7 ? 1 : 0);
- machine_code[mc_ptr++] = 0x50 + (arg_order[0] % 8);
- next_rbp += 8;
- pushed |= (1 << arg_order[0]);
- }
- if (used_regs & (1 << arg_order[2])) {
- machine_code[mc_ptr++] = 0x48 | (arg_order[2] > 7 ? 1 : 0);
- machine_code[mc_ptr++] = 0x50 + (arg_order[2] % 8);
- next_rbp += 8;
- pushed |= (1 << arg_order[2]);
- }
- machine_code[mc_ptr++] = 0x48;
- machine_code[mc_ptr++] = 0xb8;
- *(int64_t *) &machine_code[mc_ptr] = 0x01;
- mc_ptr += 8;
- machine_code[mc_ptr++] = 0x48 | (arg_order[0] > 7 ? 1 : 0);
- machine_code[mc_ptr++] = 0x89;
- machine_code[mc_ptr++] = 0xc0 + (arg_order[0] % 8);
- machine_code[mc_ptr++] = 0x48 | (arg_order[2] > 7 ? 1 : 0);
- machine_code[mc_ptr++] = 0x89;
- machine_code[mc_ptr++] = 0xc0 + (arg_order[2] % 8);
-
- used_regs |= (1 << 0) | (1 << arg_order[0]) | (1 << arg_order[2]);
-
- j = compile_tree(output, tree->args, 0, -1);
+ push(arg_order[1], &pushed, push_order);
+ j = compile_tree(output, tree->args, 0, syscall_arg[1]);
+ /*
if (used_regs & (1 << arg_order[1]) && j != arg_order[1]) {
machine_code[mc_ptr++] = 0x48 | (arg_order[1] > 7 ? 1 : 0);
machine_code[mc_ptr++] = 0x50 + (arg_order[1] % 8);
@@ -1361,13 +1522,11 @@ int compile_tree(FILE *output, struct expression *tree, int discard_result, int
// Allocate extra space on the stack for the character
// Because of scratch space, this might be unnecessary
- /*
machine_code[mc_ptr++] = 0x48;
machine_code[mc_ptr++] = 0x81;
machine_code[mc_ptr++] = 0xEC;
*(int *) &machine_code[mc_ptr] = 0x08;
mc_ptr += 4;
- */
machine_code[mc_ptr++] = 0x48 | (j > 7 ? 4 : 0);
machine_code[mc_ptr++] = 0x89;
@@ -1380,27 +1539,72 @@ int compile_tree(FILE *output, struct expression *tree, int discard_result, int
machine_code[mc_ptr++] = -next_rbp;
used_regs &= ~(1 << j);
}
- machine_code[mc_ptr++] = 0x0F;
+ */
+ push(0, &pushed, push_order);
+ push(syscall_arg[0], &pushed, push_order);
+ push(syscall_arg[2], &pushed, push_order);
+
+ machine_code[mc_ptr++] = 0x48;
+ machine_code[mc_ptr++] = 0xb8;
+ *(int64_t *) &machine_code[mc_ptr] = 0x01;
+ mc_ptr += 8;
+ machine_code[mc_ptr++] = 0x48 | (arg_order[0] > 7 ? 1 : 0);
+ machine_code[mc_ptr++] = 0x89;
+ machine_code[mc_ptr++] = 0xc0 + (arg_order[0] % 8);
+ machine_code[mc_ptr++] = 0x48 | (arg_order[2] > 7 ? 1 : 0);
+ machine_code[mc_ptr++] = 0x89;
+ machine_code[mc_ptr++] = 0xc0 + (arg_order[2] % 8);
+
+ // Allocate extra space on the stack for the character
+ // Because of scratch space, this might be unnecessary
+ machine_code[mc_ptr++] = 0x48;
+ machine_code[mc_ptr++] = 0x83;
+ machine_code[mc_ptr++] = 0xec;
+ machine_code[mc_ptr++] = 0x08;
+
+ machine_code[mc_ptr++] = 0x48 | (j > 7 ? 4 : 0);
+ machine_code[mc_ptr++] = 0x89;
+ machine_code[mc_ptr++] = 0x45 + (j % 8) * 8;
+ machine_code[mc_ptr++] = -next_rbp;
+
+ machine_code[mc_ptr++] = 0x48 | (j > 7 ? 1 : 0);
+ machine_code[mc_ptr++] = 0x8d;
+ machine_code[mc_ptr++] = 0x45 + (j % 8) * 8;
+ machine_code[mc_ptr++] = -next_rbp;
+ used_regs &= ~(1 << j);
+
+ machine_code[mc_ptr++] = 0x0f;
machine_code[mc_ptr++] = 0x05;
+ machine_code[mc_ptr++] = 0x48;
+ machine_code[mc_ptr++] = 0x83;
+ machine_code[mc_ptr++] = 0xc4;
+ machine_code[mc_ptr++] = 0x08;
// Reset saved variables
+ /*
if (pushed & (1 << arg_order[1])) {
machine_code[mc_ptr++] = 0x48 | (arg_order[1] > 7 ? 1 : 0);
machine_code[mc_ptr++] = 0x58 + (arg_order[1] % 8);
next_rbp -= 8;
pushed &= ~(1 << arg_order[1]);
+ } else {
+ used_regs &= ~(1 << arg_order[1]);
}
if (pushed & (1 << arg_order[2])) {
machine_code[mc_ptr++] = 0x48 | (arg_order[2] > 7 ? 1 : 0);
machine_code[mc_ptr++] = 0x58 + (arg_order[2] % 8);
next_rbp -= 8;
pushed &= ~(1 << arg_order[2]);
+ } else {
+ used_regs &= ~(1 << arg_order[2]);
}
if (pushed & (1 << arg_order[0])) {
machine_code[mc_ptr++] = 0x48 | (arg_order[0] > 7 ? 1 : 0);
machine_code[mc_ptr++] = 0x58 + (arg_order[0] % 8);
next_rbp -= 8;
pushed &= ~(1 << arg_order[0]);
+ } else {
+ used_regs &= ~(1 << arg_order[0]);
}
if (pushed & (1 << 0)) {
if (!discard_result) {
@@ -1425,18 +1629,61 @@ int compile_tree(FILE *output, struct expression *tree, int discard_result, int
next_rbp -= 8;
pushed &= ~(1 << 0);
}
+ if (discard_result) used_regs &= ~(1 << 0);
+ */
+ reg = 0;
break;
case exit_p:
- j = compile_tree(output, tree->args, 0, arg_order[0]);
+ j = compile_tree(output, tree->args, 0, syscall_arg[0]);
machine_code[mc_ptr++] = 0x48;
machine_code[mc_ptr++] = 0xb8;
*(int64_t *) &machine_code[mc_ptr] = 0x3c;
mc_ptr += 8;
machine_code[mc_ptr++] = 0x0F;
machine_code[mc_ptr++] = 0x05;
- break;
+ return -2;
}
- return reg;
+ if (!discard_result) {
+ if (reg < 0) {
+ fprintf(stderr, "No value in <reg>\n");
+ exit(1);
+ }
+ if (out_reg < 0) return reg;
+ if (reg == out_reg) goto end;
+ if (reg >= registers && out_reg >= registers) {
+ j = get_free_reg(0);
+ machine_code[mc_ptr++] = 0x48 | (j > 7 ? 4 : 0);
+ machine_code[mc_ptr++] = 0x8b;
+ machine_code[mc_ptr++] = 0x45 + (j % 8) * 8;
+ machine_code[mc_ptr++] = -regs[reg].rbp;
+ reg = j;
+ machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 4 : 0);
+ machine_code[mc_ptr++] = 0x89;
+ machine_code[mc_ptr++] = 0x45 + (reg % 8) * 8;
+ machine_code[mc_ptr++] = -regs[out_reg].rbp;
+ } else if (reg >= registers && out_reg < registers) {
+ machine_code[mc_ptr++] = 0x48 | (out_reg > 7 ? 4 : 0);
+ machine_code[mc_ptr++] = 0x8b;
+ machine_code[mc_ptr++] = 0x45 + (out_reg % 8) * 8;
+ machine_code[mc_ptr++] = -regs[reg].rbp;
+ } else {
+ machine_code[mc_ptr++] = 0x48 | (reg > 7 ? 4 : 0);
+ machine_code[mc_ptr++] = 0x89;
+ if (out_reg >= registers) {
+ machine_code[mc_ptr++] = 0x45 + (reg % 8) * 8;
+ machine_code[mc_ptr++] = -regs[out_reg].rbp;
+ } else {
+ machine_code[mc_ptr-2] |= (out_reg > 7 ? 1 : 0);
+ machine_code[mc_ptr++] = 0xc0 + (out_reg % 8) + (reg % 8) * 8;
+ }
+ used_regs &= ~(1 << reg);
+ }
+ }
+ if (pushed)
+ for (i = 0; pushed && i < registers; i++)
+ pop(push_order[i], &pushed);
+end:
+ return out_reg;
}
struct elf_hdr {
@@ -1492,80 +1739,31 @@ struct prg_hdr load_rodata = { 1, 4, 0, 0, 0, 0, 0, 1 };
struct sec_hdr null_section = { 0 };
struct sec_hdr text_section = { 1, 1, 6, 0, 0, 0, 0, 0, 1, 0 };
struct sec_hdr rodata_section = { 7, 1, 2, 0, 0, 0, 0, 0, 1, 0 };
-struct sec_hdr strtab_section = { 15, 3, 0x20, 0, 0, 0, 0, 0, 1, 0 };
+struct sec_hdr strtab_section = { 15, 3, 0, 0, 0, 0, 0, 0, 1, 0 };
char strtab[] = "\0.text\0.rodata\0.strtab";
+char padding[4096] = { 0 };
+
int main(int argc, char **argv)
{
- int i;
- char hdr1[] = { // ELF Header
- 0x7f, 'E' , 'L' , 'F' , 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x02, 0x00, 0x3E, 0x00, 0x01, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x38, 0x00, 0x02, 0x00, 0x40, 0x00, 0x03, 0x00, 0x02, 0x00,
- // LOAD TEXT
- 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xb0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
- // LOAD RODATA
- 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xb0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- /*
- // GNU_STACK
- 0x51, 0xe5, 0x74, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- */
- };
- char phdr[] = { // Program Headers
- // LOAD TEXT
- 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xb0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
- // LOAD RODATA
- 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xb0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- };
- char hdr2[] = { // Section Header
- // NULL shdr
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- // TEXT shdr
- 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xb0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- /*
- // RODATA shdr
- 0x0f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- */
- // STRTAB shdr
- 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcf, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- };
- if (argc == 1) fname = "stdin";
- else {
+ int i, outfd;
+
+ if (argc < 3) {
+ fprintf(stderr, "Too few arguments\nUsage: %s <in-file> <out-file>\n", *argv);
+ exit(1);
+ } else {
fname = argv[1];
yyin = fopen(fname, "r");
+ outfd = open(argv[2], O_TRUNC | O_WRONLY | O_CREAT, (S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) & 0x1ff);
+ if (outfd == -1) {
+ fprintf(stderr, "Unable to open out-file\n");
+ exit(1);
+ }
}
+
yyparse();
- breakpoint();
+
stringify(final, -3, 0, NULL, 0);
- //start_addr = 0x400000 + sizeof(hdr1);
elf_hdr.phcount = 2;
elf_hdr.shcount = 4;
@@ -1573,8 +1771,8 @@ int main(int argc, char **argv)
int hdr1_size = sizeof(elf_hdr) + sizeof(struct prg_hdr) * elf_hdr.phcount;
start_addr = 0x400000 + hdr1_size;
- rodata_addr = 0x600000 + sizeof(hdr1) + 0xbb;
- fprintf(stderr, "final args: %i\n", final->args_count);
+ rodata_addr = 0x600000;
+
for (i = 0; i < final->args_count; i++) {
compile_tree(stdout, &final->args[i], 1, -1);
}
@@ -1582,73 +1780,49 @@ int main(int argc, char **argv)
fprintf(stderr, "No _start symbol found!\n");
exit(1);
}
- *(int64_t *) &hdr1[0x18] = start_addr + entry_addr;
- *(int64_t *) &hdr1[0x28] = sizeof(hdr1) + mc_ptr + rd_ptr;
+
+ int rodata_offset = sizeof(elf_hdr) + sizeof(load_text) + sizeof(load_rodata)
+ + mc_ptr + sizeof(null_section) + sizeof(text_section)
+ + sizeof(rodata_section) + sizeof(strtab_section)
+ + sizeof(strtab);
+ int rodata_pad_len = 4096 - (rodata_offset % 4096);
+ rodata_offset += rodata_pad_len;
+
elf_hdr.entry = start_addr + entry_addr;
- elf_hdr.shoff = hdr1_size + mc_ptr + rd_ptr;
+ elf_hdr.shoff = hdr1_size + mc_ptr;
- *(int64_t *) &hdr1[0x48] = 0;//sizeof(hdr1);
- *(int64_t *) &hdr1[0x50] = start_addr - sizeof(hdr1);
- *(int64_t *) &hdr1[0x58] = start_addr - sizeof(hdr1);
- *(int64_t *) &hdr1[0x60] = rd_ptr + mc_ptr + sizeof(hdr1);
- *(int64_t *) &hdr1[0x68] = rd_ptr + mc_ptr + sizeof(hdr1);
load_text.offset = 0;
load_text.vaddr = 0x400000;
load_text.paddr = 0x400000;
load_text.fsize = hdr1_size + mc_ptr;
load_text.msize = hdr1_size + mc_ptr;
- *(int64_t *) &hdr1[0x80] = sizeof(hdr1) + mc_ptr;
- *(int64_t *) &hdr1[0x88] = rodata_addr;
- *(int64_t *) &hdr1[0x90] = rodata_addr;
- *(int64_t *) &hdr1[0x98] = rd_ptr;
- *(int64_t *) &hdr1[0xa0] = rd_ptr;
- load_rodata.offset = hdr1_size + mc_ptr;
+ load_rodata.offset = rodata_offset;
load_rodata.vaddr = 0x600000;
load_rodata.paddr = 0x600000;
- //load_rodata.fsize = rd_ptr;
load_rodata.fsize = rd_ptr;
- load_rodata.msize = rd_ptr + load_rodata.offset;
-
- *(int64_t *) &hdr2[0x50] = start_addr;
- *(int64_t *) &hdr2[0x58] = sizeof(hdr1);
- *(int64_t *) &hdr2[0x60] = mc_ptr;
- /*
- *(int64_t *) &hdr2[0x90] = rodata_addr;
- *(int64_t *) &hdr2[0x98] = sizeof(hdr1) + mc_ptr;
- *(int64_t *) &hdr2[0xa0] = rd_ptr;
- *(int64_t *) &hdr2[0xd8] = sizeof(hdr1) + mc_ptr + rd_ptr + sizeof(hdr2);
- *(int64_t *) &hdr2[0xe0] = sizeof(strtab);
- */
- *(int64_t *) &hdr2[0x98] = sizeof(hdr1) + mc_ptr + rd_ptr + sizeof(hdr2);
- *(int64_t *) &hdr2[0xa0] = sizeof(strtab);
+ load_rodata.msize = rd_ptr;
+
text_section.addr = start_addr;
text_section.offset = hdr1_size;
text_section.size = mc_ptr;
rodata_section.addr = load_rodata.vaddr;
rodata_section.offset = load_rodata.offset;
- rodata_section.size = rd_ptr;
+ rodata_section.size = load_rodata.fsize;
- //strtab_section.addr = 0;
- strtab_section.offset = hdr1_size + mc_ptr + rd_ptr + sizeof(struct sec_hdr) * elf_hdr.shcount;
+ strtab_section.offset = hdr1_size + mc_ptr + sizeof(struct sec_hdr) * elf_hdr.shcount;
strtab_section.size = sizeof(strtab);
- write(1, &elf_hdr, sizeof(elf_hdr));
- write(1, &load_text, sizeof(load_text));
- write(1, &load_rodata, sizeof(load_rodata));
- write(1, machine_code, mc_ptr);
- write(1, rodata, rd_ptr);
- write(1, &null_section, sizeof(null_section));
- write(1, &text_section, sizeof(text_section));
- write(1, &rodata_section, sizeof(rodata_section));
- write(1, &strtab_section, sizeof(strtab_section));
- write(1, strtab, sizeof(strtab));
- /*
- write(1, hdr1, sizeof(hdr1));
- write(1, machine_code, mc_ptr);
- write(1, rodata, rd_ptr);
- write(1, hdr2, sizeof(hdr2));
- write(1, strtab, sizeof(strtab));
- */
+ write(outfd, &elf_hdr, sizeof(elf_hdr));
+ write(outfd, &load_text, sizeof(load_text));
+ write(outfd, &load_rodata, sizeof(load_rodata));
+ write(outfd, machine_code, mc_ptr);
+ write(outfd, &null_section, sizeof(null_section));
+ write(outfd, &text_section, sizeof(text_section));
+ write(outfd, &rodata_section, sizeof(rodata_section));
+ write(outfd, &strtab_section, sizeof(strtab_section));
+ write(outfd, strtab, sizeof(strtab));
+ write(outfd, padding, rodata_pad_len);
+ write(outfd, rodata, rd_ptr);
}