os

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

commit 93e946da7e115b1cfbf118fdfac6e4c21c41a848
parent 85d2774262cd010da637bf06c3cb5c42abe6d000
Author: erai <erai@omiltem.net>
Date:   Sat, 28 Sep 2024 10:14:16 -0400

add undefined evaluation order check

Diffstat:
Mcc0.c | 45+++++++++++++++++++++++++++++++++++++++++++++
Mcc1.c | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mkernel.c | 2+-
Msha256.c | 12++++--------
Msha512.c | 8++++----
5 files changed, 116 insertions(+), 13 deletions(-)

diff --git a/cc0.c b/cc0.c @@ -529,6 +529,7 @@ void( my_as_rex)(struct my_assembler* my_a,unsigned long my_op,unsigned long my_ void( my_assert)(unsigned long my_x,unsigned char* my_msg); unsigned long( my_bind)(unsigned long my_fd,unsigned char* my_addr,unsigned long my_len); void( my_bzero)(unsigned char* my_s,unsigned long my_size); +unsigned long( my_call_check)(struct my_compiler* my_c,struct my_node* my_n); void( my_cdie)(struct my_compiler* my_c,unsigned char* my_msg); unsigned long( my_charset)(struct my_peg* my_c,unsigned char* my_s); void( my_choice)(struct my_peg* my_c); @@ -1448,6 +1449,47 @@ void( my_bzero)(unsigned char* my_s,unsigned long my_size){ (my_i)=((unsigned long)(((unsigned long)(my_i))+((unsigned long)(1UL)))); } } +unsigned long( my_call_check)(struct my_compiler* my_c,struct my_node* my_n){ + unsigned long my_result = 0; + unsigned long my_ret = 0; + (my_result)=(0UL); + if ((unsigned long)(!(my_n))) { + return my_result; + } + if ((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_CALL)))) { + (my_result)=((my_call_check)((my_c),((my_n)->my_a))); + (my_n)=((my_n)->my_b); + while (1) { + if ((unsigned long)(!(my_n))) { + break; + } + (my_ret)=((my_call_check)((my_c),((my_n)->my_a))); + if ((unsigned long)((my_result)&&(my_ret))) { + (my_cdie)((my_c),((unsigned char *)"multiple calls in call")); + } + (my_result)=((unsigned long)(((unsigned long)(my_result))|((unsigned long)(my_ret)))); + (my_n)=((my_n)->my_b); + } + (my_result)=(1UL); + } else if ((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_BOR))))||((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_BAND)))))) { + (my_result)=((my_call_check)((my_c),((my_n)->my_a))); + (my_result)=((unsigned long)(((unsigned long)(my_result))|((unsigned long)((my_call_check)((my_c),((my_n)->my_b)))))); + } else if ((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_ASSIGN))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_INDEX))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_LT))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_LE))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_GT))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_GE))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_EQ))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_NE))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_BNOT))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_ADD))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_SUB))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_MUL))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_DIV))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_MOD))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_LSH))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_RSH))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_AND))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_OR))))||((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_XOR)))))))))))))))))))))))))))))))))))))))) { + (my_result)=((my_call_check)((my_c),((my_n)->my_a))); + (my_ret)=((my_call_check)((my_c),((my_n)->my_b))); + if ((unsigned long)((my_result)&&(my_ret))) { + (my_cdie)((my_c),((unsigned char *)"multiple calls in expression")); + } + (my_result)=((unsigned long)(((unsigned long)(my_result))|((unsigned long)(my_ret)))); + } else if ((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_REF))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_DEREF))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_POS))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_NEG))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_NOT))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_CAST))))||((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_DOT)))))))))))))))) { + (my_result)=((my_call_check)((my_c),((my_n)->my_a))); + } else if ((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_STR))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_NUM))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_CHAR))))||((unsigned long)(((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_IDENT))))||((unsigned long)(((long)((my_n)->my_kind))==((long)(my_N_SIZEOF)))))))))))) { + } else { + (my_fdputd)((2UL),((my_n)->my_kind)); + (my_die)(((unsigned char *)"invalid expr")); + } + return my_result; +} void( my_cdie)(struct my_compiler* my_c,unsigned char* my_msg){ (my_cshow_context)((my_c)); (my_fdputs)((2UL),((unsigned char *)"cdie: ")); @@ -2145,6 +2187,7 @@ void( my_compile_stmt)(struct my_compiler* my_c,struct my_decl* my_d,struct my_n } (my_no)=((my_mklabel)(((my_c)->my_as))); if (((my_n)->my_a)->my_a) { + (my_call_check)((my_c),(((my_n)->my_a)->my_a)); (my_compile_expr)((my_c),(my_d),(((my_n)->my_a)->my_a),(1UL)); (my_emit_jz)(((my_c)->my_as),(my_no)); } @@ -2183,6 +2226,7 @@ void( my_compile_stmt)(struct my_compiler* my_c,struct my_decl* my_d,struct my_n if ((unsigned long)(((long)((((my_d)->my_func_type)->my_val)->my_kind))==((long)(my_TY_VOID)))) { (my_cdie)((my_c),((unsigned char *)"returning a value in a void function")); } + (my_call_check)((my_c),((my_n)->my_a)); (my_compile_expr)((my_c),(my_d),((my_n)->my_a),(1UL)); (my_unify)((my_c),(((my_n)->my_a)->my_t),(((my_d)->my_func_type)->my_val)); } else { @@ -2202,6 +2246,7 @@ void( my_compile_stmt)(struct my_compiler* my_c,struct my_decl* my_d,struct my_n } (my_emit_jmp)(((my_c)->my_as),((my_v)->my_goto_label)); } else if ((unsigned long)(((long)(my_kind))!=((long)(my_N_VARDECL)))) { + (my_call_check)((my_c),(my_n)); (my_compile_expr)((my_c),(my_d),(my_n),(1UL)); (my_emit_pop)(((my_c)->my_as),(1UL)); } diff --git a/cc1.c b/cc1.c @@ -1103,6 +1103,65 @@ compile_expr(c: *compiler, d: *decl, n: *node, rhs: int) { } } +call_check(c: *compiler, n: *node): int { + var result: int; + var ret: int; + + result = 0; + + if !n { + return result; + } + + if n.kind == N_CALL { + result = call_check(c, n.a); + n = n.b; + loop { + if !n { + break; + } + ret = call_check(c, n.a); + if result && ret { + cdie(c, "multiple calls in call"); + } + result = result | ret; + n = n.b; + } + result = 1; + } else if n.kind == N_BOR || n.kind == N_BAND { + // Side effects okay in both positions + result = call_check(c, n.a); + result = result | call_check(c, n.b); + } else if n.kind == N_ASSIGN || n.kind == N_INDEX || n.kind == N_LT + || n.kind == N_LE || n.kind == N_GT || n.kind == N_GE + || n.kind == N_EQ || n.kind == N_NE || n.kind == N_BNOT + || n.kind == N_ADD || n.kind == N_SUB || n.kind == N_MUL + || n.kind == N_DIV || n.kind == N_MOD || n.kind == N_LSH + || n.kind == N_RSH || n.kind == N_AND || n.kind == N_OR + || n.kind == N_XOR { + // Possible side effects in both positions + result = call_check(c, n.a); + ret = call_check(c, n.b); + if result && ret { + cdie(c, "multiple calls in expression"); + } + result = result | ret; + } else if n.kind == N_REF || n.kind == N_DEREF || n.kind == N_POS + || n.kind == N_NEG || n.kind == N_NOT || n.kind == N_CAST + || n.kind == N_DOT { + // Possible side effect in the first position + result = call_check(c, n.a); + } else if n.kind == N_STR || n.kind == N_NUM || n.kind == N_CHAR + || n.kind == N_IDENT || n.kind == N_SIZEOF { + // No side effects + } else { + fdputd(2, n.kind); + die("invalid expr"); + } + + return result; +} + // Compile a statement compile_stmt(c: *compiler, d: *decl, n: *node, top: *label, out: *label) { var no: *label; @@ -1134,6 +1193,7 @@ compile_stmt(c: *compiler, d: *decl, n: *node, top: *label, out: *label) { no = mklabel(c.as); if (n.a.a) { + call_check(c, n.a.a); compile_expr(c, d, n.a.a, 1); emit_jz(c.as, no); } @@ -1174,6 +1234,7 @@ compile_stmt(c: *compiler, d: *decl, n: *node, top: *label, out: *label) { if (d.func_type.val.kind == TY_VOID) { cdie(c, "returning a value in a void function"); } + call_check(c, n.a); compile_expr(c, d, n.a, 1); unify(c, n.a.t, d.func_type.val); } else { @@ -1193,6 +1254,7 @@ compile_stmt(c: *compiler, d: *decl, n: *node, top: *label, out: *label) { } emit_jmp(c.as, v.goto_label); } else if (kind != N_VARDECL) { + call_check(c, n); compile_expr(c, d, n, 1); emit_pop(c.as, 1); } diff --git a/kernel.c b/kernel.c @@ -1241,7 +1241,7 @@ init_realtek(dev: *pcidev) { var mac: int; realtek_port = alloc():*realtek_port; realtek_port.io = io; - mac = ind(io) + (ind(io + 4) << 32); + mac = ind(io); mac = mac + (ind(io + 4) << 32); realtek_port.mac = ((mac >> 40) & 0xff) + (((mac >> 32) & 0xff) << 8) + (((mac >> 24) & 0xff) << 16) diff --git a/sha256.c b/sha256.c @@ -65,19 +65,15 @@ sha256_round(ctx: *sha256_ctx, w: *int, k: int) { var maj: int; var w16: int; - s1 = ror32(ctx.e, 6) ^ ror32(ctx.e, 11) ^ ror32(ctx.e, 25); + s1 = ror32(ctx.e, 6); s1 = s1 ^ ror32(ctx.e, 11); s1 = s1 ^ ror32(ctx.e, 25); ch = (ctx.e & ctx.f) ^ ((~ctx.e) & ctx.g); t1 = (ctx.h + s1 + ch + k + w[0]) & (-1 >> 32); - s0 = ror32(ctx.a, 2) ^ ror32(ctx.a, 13) ^ ror32(ctx.a, 22); + s0 = ror32(ctx.a, 2); s0 = s0 ^ ror32(ctx.a, 13); s0 = s0 ^ ror32(ctx.a, 22); maj = (ctx.a & ctx.b) ^ (ctx.a & ctx.c) ^ (ctx.b & ctx.c); t2 = (s0 + maj) & (-1 >> 32); - s0 = ror32(w[16 - 15], 7) - ^ ror32(w[16 - 15], 18) - ^ (w[16 - 15] >> 3); - s1 = ror32(w[16 - 2], 17) - ^ ror32(w[16 - 2], 19) - ^ (w[16 - 2] >> 10); + s0 = ror32(w[16 - 15], 7); s0 = s0 ^ ror32(w[16 - 15], 18); s0 = s0 ^ (w[16 - 15] >> 3); + s1 = ror32(w[16 - 2], 17); s1 = s1 ^ ror32(w[16 - 2], 19); s1 = s1 ^ (w[16 - 2] >> 10); w16 = (w[16 - 16] + s0 + w[16 - 7] + s1) & (-1 >> 32); w[0] = w[1]; diff --git a/sha512.c b/sha512.c @@ -62,10 +62,10 @@ sha512_round(r: *sha512_ctx, w: *int, k: int) { var w16: int; var i: int; - s1 = ror64(r.e, 14) ^ ror64(r.e, 18) ^ ror64(r.e, 41); + s1 = ror64(r.e, 14); s1 = s1 ^ ror64(r.e, 18); s1 = s1 ^ ror64(r.e, 41); ch = (r.e & r.f) ^ ((~r.e) & r.g); t1 = r.h + s1 + ch + k + w[0]; - s0 = ror64(r.a, 28) ^ ror64(r.a, 34) ^ ror64(r.a, 39); + s0 = ror64(r.a, 28); s0 = s0 ^ ror64(r.a, 34); s0 = s0 ^ ror64(r.a, 39); maj = (r.a & r.b) ^ (r.a & r.c) ^ (r.b & r.c); t2 = s0 + maj; @@ -78,8 +78,8 @@ sha512_round(r: *sha512_ctx, w: *int, k: int) { r.b = r.a; r.a = t1 + t2; - s0 = ror64(w[1], 1) ^ ror64(w[1], 8) ^ (w[1] >> 7); - s1 = ror64(w[14], 19) ^ ror64(w[14], 61) ^ (w[14] >> 6); + s0 = ror64(w[1], 1); s0 = s0 ^ ror64(w[1], 8); s0 = s0 ^ (w[1] >> 7); + s1 = ror64(w[14], 19); s1 = s1 ^ ror64(w[14], 61); s1 = s1 ^ (w[14] >> 6); w16 = w[0] + s0 + w[9] + s1; i = 0;