os

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

commit df3145130f30f5a6499f50e5a1111cb58b6ab40c
parent 5bf8ba671da36de6e837384bf20b59ad0511eca6
Author: erai <erai@omiltem.net>
Date:   Fri, 31 Jan 2025 21:00:32 +0000

use rodata for strings

Diffstat:
Mas.om | 120+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
Mcc0.c | 144++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------
Mir.om | 34+---------------------------------
3 files changed, 216 insertions(+), 82 deletions(-)

diff --git a/as.om b/as.om @@ -189,6 +189,15 @@ struct assembler { lineno: int; prevfilename: *byte; prevlineno: int; + blobs: *ablob; +} + +struct ablob { + left: *ablob; + right: *ablob; + label: *label; + s: *byte; + slen: int; } struct symbol { @@ -423,6 +432,79 @@ func fixup_label(c: *assembler, l: *label) { } } +func as_blob(c: *assembler, s: *byte, slen: int): *label { + var b: *ablob; + var link: **ablob; + var dir: int; + + link = &c.blobs; + loop { + b = *link; + if !b { + break; + } + + if b.slen < slen { + dir = memcmp(b.s, s, b.slen); + if dir == 0 { + dir = -1; + } + } else if b.slen > slen { + dir = memcmp(b.s, s, slen); + if dir == 0 { + dir = 1; + } + } else { + dir = memcmp(b.s, s, slen); + } + + if dir == 0 { + return b.label; + } else if dir > 0 { + link = &b.left; + } else { // dir < 0 + link = &b.right; + } + } + + b = alloc(c.a, sizeof(*b)) as *ablob; + + b.label = mklabel(c); + b.s = alloc(c.a, slen); + b.slen = slen; + + memcpy(b.s, s, slen); + + *link = b; + + return b.label; +} + +func emit_blobs(c: *assembler, b: *ablob) { + var i: int; + + if !b { + return; + } + + emit_blobs(c, b.left); + + fixup_label(c, b.label); + + i = 0; + loop { + if i == b.slen { + break; + } + + as_emit(c, b.s[i] as int); + + i = i + 1; + } + + emit_blobs(c, b.right); +} + func add_symbol(c: *assembler, name: *byte, l: *label) { var s: *symbol; @@ -471,6 +553,14 @@ func emit_sections(c: *assembler): int { s.start = 0; s.end = 0; + emit_align(c, 4096, OP_NOP); + + add_section(c, ".rodata", SHT_PROGBITS); + + emit_blobs(c, c.blobs); + + emit_align(c, 4096, 0); + add_section(c, ".strtab", SHT_STRTAB); y = c.symbols; @@ -598,14 +688,21 @@ func emit_sections(c: *assembler): int { as_emit(c, n >> 24); // Flags - as_emit(c, 6); - as_emit(c, 0); - as_emit(c, 0); - as_emit(c, 0); - as_emit(c, 0); - as_emit(c, 0); - as_emit(c, 0); - as_emit(c, 0); + if strcmp(s.name, ".text") == 0 { + n = 6; + } else if strcmp(s.name, ".rodata") == 0 { + n = 2; + } else { + n = 0; + } + as_emit(c, n); + as_emit(c, n >> 8); + as_emit(c, n >> 16); + as_emit(c, n >> 24); + as_emit(c, n >> 32); + as_emit(c, n >> 40); + as_emit(c, n >> 48); + as_emit(c, n >> 56); // Addr if s.start == s.end { @@ -709,7 +806,6 @@ func writeout(c: *assembler, start: *label, kstart: *label) { } load_addr = 0x100000; - text_size = c.at; if (!start || !start.fixed) { if !kstart { @@ -719,9 +815,6 @@ func writeout(c: *assembler, start: *label, kstart: *label) { entry = load_addr + start.at; } - text_size = text_size; - text_end = load_addr + text_size; - mb_magic = 0x1badb002; mb_flags = 0x00010003; mb_checksum = -(mb_magic + mb_flags); @@ -736,6 +829,9 @@ func writeout(c: *assembler, start: *label, kstart: *label) { shoff = emit_sections(c as *assembler); + text_size = c.at; + text_end = load_addr + text_size; + // magic putchar(c, 0x7f); putchar(c, 'E'); diff --git a/cc0.c b/cc0.c @@ -4,6 +4,7 @@ #ifndef my_syscall #define my_syscall syscall #endif +struct my_ablob; struct my_alloc; struct my_assembler; struct my_chunk; @@ -31,6 +32,13 @@ struct my_section; struct my_sigaction; struct my_symbol; struct my_type; +struct my_ablob { + struct my_ablob* my_left; + struct my_ablob* my_right; + struct my_label* my_label; + unsigned char* my_s; + unsigned long my_slen; +}; struct my_alloc { struct my_page* my_page; }; @@ -50,6 +58,7 @@ struct my_assembler { unsigned long my_lineno; unsigned char* my_prevfilename; unsigned long my_prevlineno; + struct my_ablob* my_blobs; }; struct my_chunk { struct my_chunk* my_next; @@ -664,6 +673,7 @@ void( my_addfixup)(struct my_assembler* my_c,struct my_label* my_l); unsigned char*( my_alloc)(struct my_alloc* my_c,unsigned long my_size); unsigned long( my_any)(struct my_peg* my_c); void( my_args_to_ir)(struct my_irfunc* my_ic,struct my_node* my_n); +struct my_label*( my_as_blob)(struct my_assembler* my_c,unsigned char* my_s,unsigned long my_slen); void( my_as_emit)(struct my_assembler* my_a,unsigned long my_b); void( my_as_jmp)(struct my_assembler* my_a,unsigned long my_op,struct my_label* my_l); void( my_as_modm)(struct my_assembler* my_a,unsigned long my_op,unsigned long my_b,unsigned long my_i,unsigned long my_s,unsigned long my_d); @@ -712,6 +722,7 @@ void( my_defunion)(struct my_compiler* my_c,struct my_node* my_n); void( my_die)(unsigned char* my_msg); void( my_emit)(struct my_assembler* my_c,unsigned long my_x); void( my_emit_align)(struct my_assembler* my_c,unsigned long my_n,unsigned long my_b); +void( my_emit_blobs)(struct my_assembler* my_c,struct my_ablob* my_b); void( my_emit_builtin)(struct my_compiler* my_c); void( my_emit_hook)(struct my_assembler* my_c); void( my_emit_isr)(struct my_compiler* my_c); @@ -771,6 +782,7 @@ void( my_main)(unsigned long my_argc,unsigned char** my_argv,unsigned char** my_ void( my_mark_expr_used)(struct my_compiler* my_c,struct my_decl* my_d,struct my_node* my_n); void( my_mark_func_used)(struct my_compiler* my_c,struct my_decl* my_d); void( my_mark_stmt_used)(struct my_compiler* my_c,struct my_decl* my_d,struct my_node* my_n); +unsigned long( my_memcmp)(unsigned char* my_a,unsigned char* my_b,unsigned long my_n); void( my_memcpy)(unsigned char* my_dest,unsigned char* my_src,unsigned long my_size); void( my_memset)(unsigned char* my_dest,unsigned long my_c,unsigned long my_size); struct my_irblock*( my_mkirblock)(struct my_irfunc* my_ic); @@ -1432,6 +1444,45 @@ void( my_args_to_ir)(struct my_irfunc* my_ic,struct my_node* my_n){ (my_n)=((my_n)->my_b); } } +struct my_label*( my_as_blob)(struct my_assembler* my_c,unsigned char* my_s,unsigned long my_slen){ + struct my_ablob* my_b = 0; + struct my_ablob** my_link = 0; + unsigned long my_dir = 0; + (my_link)=(&((my_c)->my_blobs)); + while (1) { + (my_b)=(*(my_link)); + if ((unsigned long)(!(my_b))) { + break; + } + if ((unsigned long)(((long)((my_b)->my_slen))<((long)(my_slen)))) { + (my_dir)=((my_memcmp)(((my_b)->my_s),(my_s),((my_b)->my_slen))); + if ((unsigned long)(((long)(my_dir))==((long)(0UL)))) { + (my_dir)=((unsigned long)(-(unsigned long)(1UL))); + } + } else if ((unsigned long)(((long)((my_b)->my_slen))>((long)(my_slen)))) { + (my_dir)=((my_memcmp)(((my_b)->my_s),(my_s),(my_slen))); + if ((unsigned long)(((long)(my_dir))==((long)(0UL)))) { + (my_dir)=(1UL); + } + } else { + (my_dir)=((my_memcmp)(((my_b)->my_s),(my_s),(my_slen))); + } + if ((unsigned long)(((long)(my_dir))==((long)(0UL)))) { + return (my_b)->my_label; + } else if ((unsigned long)(((long)(my_dir))>((long)(0UL)))) { + (my_link)=(&((my_b)->my_left)); + } else { + (my_link)=(&((my_b)->my_right)); + } + } + (my_b)=((struct my_ablob*)(my_alloc)(((my_c)->my_a),(40UL))); + ((my_b)->my_label)=((my_mklabel)((my_c))); + ((my_b)->my_s)=((my_alloc)(((my_c)->my_a),(my_slen))); + ((my_b)->my_slen)=(my_slen); + (my_memcpy)(((my_b)->my_s),(my_s),(my_slen)); + (*(my_link))=(my_b); + return (my_b)->my_label; +} void( my_as_emit)(struct my_assembler* my_a,unsigned long my_b){ (my_emit)((my_a),(my_b)); } @@ -2713,6 +2764,23 @@ void( my_emit_align)(struct my_assembler* my_c,unsigned long my_n,unsigned long (my_pad)=((unsigned long)(((unsigned long)(my_pad))+((unsigned long)(1UL)))); } } +void( my_emit_blobs)(struct my_assembler* my_c,struct my_ablob* my_b){ + unsigned long my_i = 0; + if ((unsigned long)(!(my_b))) { + return; + } + (my_emit_blobs)((my_c),((my_b)->my_left)); + (my_fixup_label)((my_c),((my_b)->my_label)); + (my_i)=(0UL); + while (1) { + if ((unsigned long)(((long)(my_i))==((long)((my_b)->my_slen)))) { + break; + } + (my_as_emit)((my_c),((unsigned long)((my_b)->my_s)[my_i])); + (my_i)=((unsigned long)(((unsigned long)(my_i))+((unsigned long)(1UL)))); + } + (my_emit_blobs)((my_c),((my_b)->my_right)); +} void( my_emit_builtin)(struct my_compiler* my_c){ struct my_decl* my_d = 0; (my_d)=((my_find)((my_c),((unsigned char *)"syscall"),((void *)0),(1UL))); @@ -3378,6 +3446,10 @@ unsigned long( my_emit_sections)(struct my_assembler* my_c){ (my_s)=((my_find_section)((my_c),((unsigned char *)""))); ((my_s)->my_start)=(0UL); ((my_s)->my_end)=(0UL); + (my_emit_align)((my_c),(4096UL),(my_OP_NOP)); + (my_add_section)((my_c),((unsigned char *)".rodata"),(my_SHT_PROGBITS)); + (my_emit_blobs)((my_c),((my_c)->my_blobs)); + (my_emit_align)((my_c),(4096UL),(0UL)); (my_add_section)((my_c),((unsigned char *)".strtab"),(my_SHT_STRTAB)); (my_y)=((my_c)->my_symbols); while (1) { @@ -3471,14 +3543,21 @@ unsigned long( my_emit_sections)(struct my_assembler* my_c){ (my_as_emit)((my_c),((unsigned long)(((unsigned long)(my_n))>>((unsigned long)(8UL))))); (my_as_emit)((my_c),((unsigned long)(((unsigned long)(my_n))>>((unsigned long)(16UL))))); (my_as_emit)((my_c),((unsigned long)(((unsigned long)(my_n))>>((unsigned long)(24UL))))); - (my_as_emit)((my_c),(6UL)); - (my_as_emit)((my_c),(0UL)); - (my_as_emit)((my_c),(0UL)); - (my_as_emit)((my_c),(0UL)); - (my_as_emit)((my_c),(0UL)); - (my_as_emit)((my_c),(0UL)); - (my_as_emit)((my_c),(0UL)); - (my_as_emit)((my_c),(0UL)); + if ((unsigned long)(((long)((my_strcmp)(((my_s)->my_name),((unsigned char *)".text"))))==((long)(0UL)))) { + (my_n)=(6UL); + } else if ((unsigned long)(((long)((my_strcmp)(((my_s)->my_name),((unsigned char *)".rodata"))))==((long)(0UL)))) { + (my_n)=(2UL); + } else { + (my_n)=(0UL); + } + (my_as_emit)((my_c),(my_n)); + (my_as_emit)((my_c),((unsigned long)(((unsigned long)(my_n))>>((unsigned long)(8UL))))); + (my_as_emit)((my_c),((unsigned long)(((unsigned long)(my_n))>>((unsigned long)(16UL))))); + (my_as_emit)((my_c),((unsigned long)(((unsigned long)(my_n))>>((unsigned long)(24UL))))); + (my_as_emit)((my_c),((unsigned long)(((unsigned long)(my_n))>>((unsigned long)(32UL))))); + (my_as_emit)((my_c),((unsigned long)(((unsigned long)(my_n))>>((unsigned long)(40UL))))); + (my_as_emit)((my_c),((unsigned long)(((unsigned long)(my_n))>>((unsigned long)(48UL))))); + (my_as_emit)((my_c),((unsigned long)(((unsigned long)(my_n))>>((unsigned long)(56UL))))); if ((unsigned long)(((long)((my_s)->my_start))==((long)((my_s)->my_end)))) { (my_n)=(0UL); } else { @@ -5074,6 +5153,22 @@ void( my_mark_stmt_used)(struct my_compiler* my_c,struct my_decl* my_d,struct my return; } } +unsigned long( my_memcmp)(unsigned char* my_a,unsigned char* my_b,unsigned long my_n){ + unsigned long my_i = 0; + (my_i)=(0UL); + while (1) { + if ((unsigned long)(((long)(my_i))==((long)(my_n)))) { + return 0UL; + } + if ((unsigned long)(((long)((my_a)[my_i]))>((long)((my_b)[my_i])))) { + return 1UL; + } + if ((unsigned long)(((long)((my_a)[my_i]))<((long)((my_b)[my_i])))) { + return (unsigned long)(-(unsigned long)(1UL)); + } + (my_i)=((unsigned long)(((unsigned long)(my_i))+((unsigned long)(1UL)))); + } +} void( my_memcpy)(unsigned char* my_dest,unsigned char* my_src,unsigned long my_size){ unsigned long my_i = 0; if ((unsigned long)(((long)(my_size))<((long)(0UL)))) { @@ -5854,31 +5949,7 @@ void( my_output_irstmt)(struct my_irfunc* my_ic,struct my_irblock* my_b,struct m } void( my_output_irstr)(struct my_irfunc* my_ic,struct my_irblock* my_b,struct my_irop* my_o){ struct my_label* my_s = 0; - struct my_label* my_out = 0; - unsigned long my_i = 0; - (my_s)=((my_mklabel)(((my_ic)->my_s))); - (my_out)=((my_mklabel)(((my_ic)->my_s))); - (my_as_jmp)(((my_ic)->my_s),(my_OP_JMP),(my_out)); - (my_fixup_label)(((my_ic)->my_s),(my_s)); - (my_i)=(0UL); - while (1) { - if ((unsigned long)(((long)(my_i))==((long)((my_o)->my_slen)))) { - break; - } - (my_as_emit)(((my_ic)->my_s),((unsigned long)((my_o)->my_s)[my_i])); - (my_i)=((unsigned long)(((unsigned long)(my_i))+((unsigned long)(1UL)))); - } - (my_as_emit)(((my_ic)->my_s),(0UL)); - (my_as_op)(((my_ic)->my_s),(my_OP_NOP)); - (my_as_op)(((my_ic)->my_s),(my_OP_NOP)); - (my_as_op)(((my_ic)->my_s),(my_OP_NOP)); - (my_as_op)(((my_ic)->my_s),(my_OP_NOP)); - (my_as_op)(((my_ic)->my_s),(my_OP_NOP)); - (my_as_op)(((my_ic)->my_s),(my_OP_NOP)); - (my_as_op)(((my_ic)->my_s),(my_OP_NOP)); - (my_as_op)(((my_ic)->my_s),(my_OP_NOP)); - (my_fixup_label)(((my_ic)->my_s),(my_out)); - (my_reserve)(((my_ic)->my_s),(16UL)); + (my_s)=((my_as_blob)(((my_ic)->my_s),((my_o)->my_s),((unsigned long)(((unsigned long)((my_o)->my_slen))+((unsigned long)(1UL)))))); (my_as_modrm)(((my_ic)->my_s),(my_OP_LEA),(my_R_RAX),(my_R_RIP),(0UL),(0UL),(128UL)); (my_addfixup)(((my_ic)->my_s),(my_s)); } @@ -9974,7 +10045,7 @@ void( my_setup_alloc)(struct my_alloc* my_c){ } struct my_assembler*( my_setup_assembler)(struct my_alloc* my_a){ struct my_assembler* my_c = 0; - (my_c)=((struct my_assembler*)(my_alloc)((my_a),(120UL))); + (my_c)=((struct my_assembler*)(my_alloc)((my_a),(128UL))); ((my_c)->my_a)=(my_a); ((my_c)->my_out)=((void *)0); ((my_c)->my_at)=(160UL); @@ -11043,7 +11114,6 @@ void( my_writeout)(struct my_assembler* my_c,struct my_label* my_start,struct my (my_die)(((unsigned char *)"output not opened")); } (my_load_addr)=(1048576UL); - (my_text_size)=((my_c)->my_at); if ((unsigned long)(((unsigned long)(!(my_start)))||((unsigned long)(!((my_start)->my_fixed))))) { if ((unsigned long)(!(my_kstart))) { (my_die)(((unsigned char *)"_start is not defined")); @@ -11051,8 +11121,6 @@ void( my_writeout)(struct my_assembler* my_c,struct my_label* my_start,struct my } else { (my_entry)=((unsigned long)(((unsigned long)(my_load_addr))+((unsigned long)((my_start)->my_at)))); } - (my_text_size)=(my_text_size); - (my_text_end)=((unsigned long)(((unsigned long)(my_load_addr))+((unsigned long)(my_text_size)))); (my_mb_magic)=(464367618UL); (my_mb_flags)=(65539UL); (my_mb_checksum)=((unsigned long)(-(unsigned long)((unsigned long)(((unsigned long)(my_mb_magic))+((unsigned long)(my_mb_flags)))))); @@ -11064,6 +11132,8 @@ void( my_writeout)(struct my_assembler* my_c,struct my_label* my_start,struct my (my_kentry)=(0UL); } (my_shoff)=((my_emit_sections)(((struct my_assembler*)my_c))); + (my_text_size)=((my_c)->my_at); + (my_text_end)=((unsigned long)(((unsigned long)(my_load_addr))+((unsigned long)(my_text_size)))); (my_putchar)((my_c),(127UL)); (my_putchar)((my_c),(69)); (my_putchar)((my_c),(76)); diff --git a/ir.om b/ir.om @@ -1889,40 +1889,8 @@ func output_irretval(ic: *irfunc, b: *irblock, o: *irop) { func output_irstr(ic: *irfunc, b: *irblock, o: *irop) { var s: *label; - var out: *label; - var i: int; - - s = mklabel(ic.s); - out = mklabel(ic.s); - - as_jmp(ic.s, OP_JMP, out); - - fixup_label(ic.s, s); - - i = 0; - loop { - if i == o.slen { - break; - } - - as_emit(ic.s, o.s[i] as int); - - i = i + 1; - } - as_emit(ic.s, 0); - - as_op(ic.s, OP_NOP); - as_op(ic.s, OP_NOP); - as_op(ic.s, OP_NOP); - as_op(ic.s, OP_NOP); - as_op(ic.s, OP_NOP); - as_op(ic.s, OP_NOP); - as_op(ic.s, OP_NOP); - as_op(ic.s, OP_NOP); - fixup_label(ic.s, out); - - reserve(ic.s, 16); + s = as_blob(ic.s, o.s, o.slen + 1); as_modrm(ic.s, OP_LEA, R_RAX, R_RIP, 0, 0, 128); addfixup(ic.s, s); }