FreeCalypso > hg > freecalypso-reveng
changeset 136:81fc8da9a29c
tiobjd: disasm hints work now
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Mon, 07 Apr 2014 04:56:29 +0000 |
parents | df432a4b1b84 |
children | 038258d5312c |
files | leo-obj/tool/disasm.c leo-obj/tool/hints.c |
diffstat | 2 files changed, 101 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/leo-obj/tool/disasm.c Mon Apr 07 04:06:17 2014 +0000 +++ b/leo-obj/tool/disasm.c Mon Apr 07 04:56:29 2014 +0000 @@ -118,14 +118,57 @@ } void +disasm_emit_asciz(sec, pos, len) + struct internal_scnhdr *sec; + unsigned pos, len; +{ + int c; + unsigned endpos = pos + len; + + fputs("\t.asciz\t\"", stdout); + for (; pos < endpos; pos++) { + c = filemap[sec->data_offset + pos]; + switch (c) { + case '\b': + fputs("\\b", stdout); + continue; + case '\t': + fputs("\\t", stdout); + continue; + case '\n': + fputs("\\n", stdout); + continue; + case '\r': + fputs("\\r", stdout); + continue; + case '"': + fputs("\\\"", stdout); + continue; + case '\\': + fputs("\\\\", stdout); + continue; + } + if (c >= ' ' && c <= '~') + putchar(c); + else + printf("\\%03o", c); + } + putchar('"'); + putchar('\n'); +} + +void disasm_codedata_section(sec) struct internal_scnhdr *sec; { unsigned symnum, relnum; unsigned pos, incr, headroom; - int state = -1, linebrk = 0; + int state = -1, linebrk = 0, gothint; struct internal_syment *sym; struct internal_reloc *rel; + struct hint *hint = sec->hints; + u_char *asciz_end; + unsigned asciz_len; if (sec->nreloc) get_relocs_of_sec(sec); @@ -154,7 +197,54 @@ } } else rel = 0; + if (hint) { + if (pos >= hint->pos) + gothint++; + else { + gothint = 0; + if (hint->pos - pos < headroom) + headroom = hint->pos - pos; + } + } else + gothint = 0; + if (gothint && pos == hint->pos && hint->linebrk) + putchar('\n'); printf("%8x:\t", pos); + if (gothint && hint->type) { + if (rel) { + printf("error: hint/reloc conflict\n"); + return; + } + switch (hint->type) { + case HINT_D8: + printf("%02x\n", + filemap[sec->data_offset + pos]); + incr = 1; + break; + case HINT_D16: + printf("%04x\n", + get_u16(filemap+sec->data_offset+pos)); + incr = 2; + break; + case HINT_D32: + printf("%08x\n", + get_u32(filemap+sec->data_offset+pos)); + incr = 4; + break; + case HINT_ASCIZ: + asciz_end = memchr(filemap+sec->data_offset+pos, + 0, headroom); + if (!asciz_end) { + printf("bad asciz hint: no 0 found\n"); + return; + } + asciz_len = asciz_end - filemap - + sec->data_offset - pos; + disasm_emit_asciz(sec, pos, asciz_len); + incr = asciz_len + 1; + } + goto next; + } if (rel) { if (rel->type == RTYPE_LONG) { if (pos & 3) { @@ -235,6 +325,8 @@ incr, headroom); return; } + if (hint && pos >= hint->endpos) + hint = hint->next; } if (symnum == sec->nsymbols) return;
--- a/leo-obj/tool/hints.c Mon Apr 07 04:06:17 2014 +0000 +++ b/leo-obj/tool/hints.c Mon Apr 07 04:56:29 2014 +0000 @@ -135,8 +135,15 @@ hint->linebrk = 1; while (isspace(*cp)) cp++; - if (!*cp || *cp == '#') + if (!*cp || *cp == '#') { + if (hint->endpos != hint->pos) { + fprintf(stderr, + "%s line %d: no range allowed for linebrk hints\n", + filename_for_err, lineno); + exit(1); + } goto out; + } for (np = cp; *cp && !isspace(*cp); cp++) ; if (*cp)