# HG changeset patch # User Michael Spacefalcon # Date 1396846589 0 # Node ID 81fc8da9a29ca4646df164556a4393a7b4b16153 # Parent df432a4b1b843b2c8380c2adc1b7384b2fef2a12 tiobjd: disasm hints work now diff -r df432a4b1b84 -r 81fc8da9a29c leo-obj/tool/disasm.c --- 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; diff -r df432a4b1b84 -r 81fc8da9a29c leo-obj/tool/hints.c --- 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)