commit df3145130f30f5a6499f50e5a1111cb58b6ab40c
parent 5bf8ba671da36de6e837384bf20b59ad0511eca6
Author: erai <erai@omiltem.net>
Date: Fri, 31 Jan 2025 21:00:32 +0000
use rodata for strings
Diffstat:
M | as.om | | | 120 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- |
M | cc0.c | | | 144 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------- |
M | ir.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);
}