diff options
Diffstat (limited to 'assemble.c')
-rw-r--r-- | assemble.c | 239 |
1 files changed, 189 insertions, 50 deletions
@@ -115,8 +115,6 @@ uint64_t get_val(token *t, uint64_t addr, uint8_t size, uint8_t dbg) { } token *skip_expr(token *t, uint8_t dbg) { - /*if (t->next && t->next->id == TOK_EXPR && isexpr(t->next->type, dbg)) { - }*/ do { t = (t->id == TOK_EXPR) ? t->next : t; switch (t->id) { @@ -144,7 +142,7 @@ uint8_t get_directivesize(uint8_t type, uint8_t dbg) { } uint16_t handle_struct(line **ln, uint64_t address, uint16_t offset, uint8_t dbg) { - uint8_t type = 0; + uint8_t is_struct = 0; uint8_t done = 0; uint8_t ismember = 0; uint16_t size = 0; @@ -156,11 +154,11 @@ uint16_t handle_struct(line **ln, uint64_t address, uint16_t offset, uint8_t dbg for (uint8_t found = 0; tok && !found; tok = tok->next) { switch (tok->id) { case TOK_DIR: - type = (tok->type == DIR_UNION); + is_struct = (tok->type == DIR_STRUCT); found = (tok->type == DIR_STRUCT || tok->type == DIR_UNION); break; - case TOK_STRUCT: - case TOK_UNION : type = (tok->id == TOK_UNION); found = 1; break; + case TOK_STRUCT: is_struct = 1; + case TOK_UNION : found = 1; break; } } if (tok != NULL) { @@ -180,7 +178,7 @@ uint16_t handle_struct(line **ln, uint64_t address, uint16_t offset, uint8_t dbg case TOK_MEMBER: ismember = 1; member = t->sym; break; case TOK_DIR : ismember = (t->type == DIR_STRUCT || t->type == DIR_UNION) ? 1 : ismember; - done = ((!type && t->type == DIR_ENDSTRUCT) || (type && t->type == DIR_ENDUNION)); + done = ((is_struct && t->type == DIR_ENDSTRUCT) || (!is_struct && t->type == DIR_ENDUNION)); if (!done && ismember) { switch (t->type) { case DIR_BYTE : member_size = 1; break; @@ -194,11 +192,9 @@ uint16_t handle_struct(line **ln, uint64_t address, uint16_t offset, uint8_t dbg if (member && t->type != DIR_UNION && t->type != DIR_STRUCT) { member->val = offset; } - if (size < member_size) { - size = member_size; - } - if (!type) { - offset += size; + size += member_size; + if (is_struct) { + offset += member_size; } } ismember = 0; @@ -211,9 +207,9 @@ uint16_t handle_struct(line **ln, uint64_t address, uint16_t offset, uint8_t dbg } *ln = l; if (strct != NULL) { - strct->val = offset; + strct->val = size; } - return (!type) ? offset : size; + return size; } uint64_t handle_directive(token *t, bytecount *bc, uint8_t isasm, uint64_t address, uint8_t dbg) { @@ -619,6 +615,167 @@ void assemble(line *ln, bytecount *bc, uint8_t dbg) { } } +static void find_dupsym() { + symbol *root = symbols; + symbol *s = symbols; + for (; s; s = s->next) { + root = symbols; + for (int i = 0; root; root = root->next) { + if (root == s) { + i++; + } + if (i > 1) { + printf("Found duplicate symbol, s->name: %s, root->name: %s\n", s->name, root->name); + i = 0; + } + } + } +} + +static symbol *find_fixup(token *t) { + fixup* f = fixups; + for (; f && t != f->t; f = f->next); + return (f && t == f->t) ? f->s : NULL; +} + + +static void print_symval(symbol *s) { + if (s) { + if (s->down) { + print_symval(s->down); + } + if (s->name) { + printf("s->name: %s, s->val: $%"PRIX64"\n", s->name, s->val); + } + print_symval(s->next); + } +} + +static void print_symtree(symbol *s, int depth) { + if (s) { + if (s->name != NULL) { + for (int i = depth; i; i--) { + printf("|%s", (i > 1) ? " " : "--"); + } + printf("%s: $%"PRIX64"\n", s->name, s->val); + } + if (s->down != NULL) { + print_symtree(s->down, depth+1); + } + print_symtree(s->next, depth); + } +} + +static void fix_symtree(line *l) { + symbol *s = symbols; + symbol *cur_sym = NULL; + symbol *sym_struct = NULL; + symbols = NULL; + last_sym = NULL; + int islocal = 0; + int isanon = 0; + int is_struct = 0; + int is_structsym = 0; + for (; l; l = l->next) { + token *t = l->tok; + token *lt = NULL; + for (; t; t = t->next) { + int ismember = (t->id == TOK_MEMBER); + switch (t->id) { + case TOK_STRUCT: + case TOK_UNION : islocal = !(is_struct == 1 && lt && lt->id == TOK_DIR); + case TOK_SYM : + if (t->id == TOK_SYM && t != l->tok) { + break; + } + case TOK_MEMBER: + case TOK_LABEL : + if (symbols) { + (!islocal && s && !s->up) ? (last_sym = s) : (last_loc = s); + } + if (((t->type == 1 || ismember) && !islocal) || (islocal && ismember && is_structsym)) { + is_structsym = 0; + last_loc = NULL; + islocal = 1; + cur_sym = s; + s->down = t->sym; + s->down->up = s; + s = s->down; + if (s) { + s->next = NULL; + s->prev = NULL; + s->down = NULL; + } + locals = s; + } else if ((islocal || t->type == 0)) { + if (t->type == 0 && !is_struct && islocal && !ismember) { + islocal = 0; + if (s) { + s->up->down = locals; + s = s->up; + } + } + symbol *tmp = s; + s = t->sym; + if (s) { + s->prev = (tmp && tmp != s) ? tmp : NULL; + s->up = (s->prev) ? s->prev->up : s->up; + } + if (s && s->next) { + s->next = NULL; + } + } + if (!islocal) { + last_loc = NULL; + (last_sym) ? (last_sym->next = s) : (symbols = s); + cur_sym = s; + if (last_sym) { + last_sym->next->prev = last_sym; + last_sym->next->up = last_sym->up; + last_sym->next->down = NULL; + } + } else { + (last_loc) ? (last_loc->next = s) : (locals = s); + if (last_loc) { + last_loc->next->prev = last_loc; + last_loc->next->up = last_loc->up; + last_loc->next->down = NULL; + } else { + locals->prev = NULL; + locals->down = NULL; + } + } + break; + case TOK_DIR: + if (t->type == DIR_STRUCT || t->type == DIR_UNION) { + is_struct++; + is_structsym = (t->next && (t->next->id == TOK_STRUCT || t->next->id == TOK_UNION)); + if ((!is_structsym) || (isanon && is_structsym)) { + isanon++; + } + } else if (t->type == DIR_ENDSTRUCT || t->type == DIR_ENDUNION) { + is_struct--; + int skip = 0; + if (isanon > 0) { + if ((cur_sym->up && !cur_sym->up->isanon) || (sym_struct && sym_struct->isanon)) { + isanon--; + } + skip = (!isanon); + } + if ((int)(is_struct-isanon) > 0 && !skip && cur_sym->up) { + for (sym_struct = s->up; sym_struct->prev && !sym_struct->isanon; sym_struct = sym_struct->prev); + s = s->up; + cur_sym = (cur_sym->up != NULL) ? cur_sym->up : s; + } + } + break; + } + lt = t; + } + } +} + + static inline void free_tokens(token *t) { token *tok; if (t != NULL) { @@ -640,44 +797,11 @@ void free_lines(line *l) { } } -void print_symtree(symbol *s) { - int depth = 0; - int lol = 0; - while (s) { - for (int i = depth; i; i--) { - putchar('|'); - if (i > 1) { - printf(" "); - } - } - if (depth) { - printf("--"); - } - if (s->name != NULL) { - if (!strcmp(s->name, "printc")) { - lol = 1; - } - printf("%s\n", s->name); - } - if (s->down != NULL) { - s = s->down; - depth++; - continue; - } - if (s->next == NULL) { - if (s->up != NULL) { - for (; !s->next && s->up; s = s->up, depth--); - } - } - s = s->next; - } -} - -void free_symbols(symbol *s) { +static void free_symbols(symbol *s) { symbol *sym; sym = s; if (sym != NULL) { - if (s->down) { + if (s && s->down) { free_symbols(s->down); } if (sym->name != NULL) { @@ -702,14 +826,29 @@ static inline void free_fixups(fixup *f) { } } +uint64_t get_tokmem(token *t) { + uint64_t i = 0; + for (; t; t = t->next, i++); + return i*sizeof(token); +} + +void get_linemem(line *l) { + uint64_t i = 0; + uint64_t j = 0; + for (; l; j += get_tokmem(l->tok), l = l->next, i++); + printf("Bytes per line: %"PRIu64", Bytes per token: %"PRIu64", Total size of line table in bytes: %"PRIu64"\n", sizeof(line), sizeof(token), j+(i*sizeof(line))); +} + void cleanup() { uint16_t i; if (lines) { + /*get_linemem(lines);*/ + /*fix_symtree(lines);*/ free_lines(lines); lines = NULL; } if (symbols) { - /*print_symtree(symbols);*/ + /*print_symtree(symbols, 0);*/ free_symbols(symbols); symbols = NULL; } |