FreeCalypso > hg > freecalypso-reveng
comparison leo-obj/tool/disasm.c @ 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 | acdf75463e30 |
comparison
equal
deleted
inserted
replaced
135:df432a4b1b84 | 136:81fc8da9a29c |
---|---|
116 } | 116 } |
117 printf("%s:\t; %s\n", sym->name, sym_comment); | 117 printf("%s:\t; %s\n", sym->name, sym_comment); |
118 } | 118 } |
119 | 119 |
120 void | 120 void |
121 disasm_emit_asciz(sec, pos, len) | |
122 struct internal_scnhdr *sec; | |
123 unsigned pos, len; | |
124 { | |
125 int c; | |
126 unsigned endpos = pos + len; | |
127 | |
128 fputs("\t.asciz\t\"", stdout); | |
129 for (; pos < endpos; pos++) { | |
130 c = filemap[sec->data_offset + pos]; | |
131 switch (c) { | |
132 case '\b': | |
133 fputs("\\b", stdout); | |
134 continue; | |
135 case '\t': | |
136 fputs("\\t", stdout); | |
137 continue; | |
138 case '\n': | |
139 fputs("\\n", stdout); | |
140 continue; | |
141 case '\r': | |
142 fputs("\\r", stdout); | |
143 continue; | |
144 case '"': | |
145 fputs("\\\"", stdout); | |
146 continue; | |
147 case '\\': | |
148 fputs("\\\\", stdout); | |
149 continue; | |
150 } | |
151 if (c >= ' ' && c <= '~') | |
152 putchar(c); | |
153 else | |
154 printf("\\%03o", c); | |
155 } | |
156 putchar('"'); | |
157 putchar('\n'); | |
158 } | |
159 | |
160 void | |
121 disasm_codedata_section(sec) | 161 disasm_codedata_section(sec) |
122 struct internal_scnhdr *sec; | 162 struct internal_scnhdr *sec; |
123 { | 163 { |
124 unsigned symnum, relnum; | 164 unsigned symnum, relnum; |
125 unsigned pos, incr, headroom; | 165 unsigned pos, incr, headroom; |
126 int state = -1, linebrk = 0; | 166 int state = -1, linebrk = 0, gothint; |
127 struct internal_syment *sym; | 167 struct internal_syment *sym; |
128 struct internal_reloc *rel; | 168 struct internal_reloc *rel; |
169 struct hint *hint = sec->hints; | |
170 u_char *asciz_end; | |
171 unsigned asciz_len; | |
129 | 172 |
130 if (sec->nreloc) | 173 if (sec->nreloc) |
131 get_relocs_of_sec(sec); | 174 get_relocs_of_sec(sec); |
132 symnum = relnum = 0; | 175 symnum = relnum = 0; |
133 for (pos = 0; pos < sec->size; pos += incr) { | 176 for (pos = 0; pos < sec->size; pos += incr) { |
152 headroom = rel->location - pos; | 195 headroom = rel->location - pos; |
153 rel = 0; /* no reloc for current pos */ | 196 rel = 0; /* no reloc for current pos */ |
154 } | 197 } |
155 } else | 198 } else |
156 rel = 0; | 199 rel = 0; |
200 if (hint) { | |
201 if (pos >= hint->pos) | |
202 gothint++; | |
203 else { | |
204 gothint = 0; | |
205 if (hint->pos - pos < headroom) | |
206 headroom = hint->pos - pos; | |
207 } | |
208 } else | |
209 gothint = 0; | |
210 if (gothint && pos == hint->pos && hint->linebrk) | |
211 putchar('\n'); | |
157 printf("%8x:\t", pos); | 212 printf("%8x:\t", pos); |
213 if (gothint && hint->type) { | |
214 if (rel) { | |
215 printf("error: hint/reloc conflict\n"); | |
216 return; | |
217 } | |
218 switch (hint->type) { | |
219 case HINT_D8: | |
220 printf("%02x\n", | |
221 filemap[sec->data_offset + pos]); | |
222 incr = 1; | |
223 break; | |
224 case HINT_D16: | |
225 printf("%04x\n", | |
226 get_u16(filemap+sec->data_offset+pos)); | |
227 incr = 2; | |
228 break; | |
229 case HINT_D32: | |
230 printf("%08x\n", | |
231 get_u32(filemap+sec->data_offset+pos)); | |
232 incr = 4; | |
233 break; | |
234 case HINT_ASCIZ: | |
235 asciz_end = memchr(filemap+sec->data_offset+pos, | |
236 0, headroom); | |
237 if (!asciz_end) { | |
238 printf("bad asciz hint: no 0 found\n"); | |
239 return; | |
240 } | |
241 asciz_len = asciz_end - filemap - | |
242 sec->data_offset - pos; | |
243 disasm_emit_asciz(sec, pos, asciz_len); | |
244 incr = asciz_len + 1; | |
245 } | |
246 goto next; | |
247 } | |
158 if (rel) { | 248 if (rel) { |
159 if (rel->type == RTYPE_LONG) { | 249 if (rel->type == RTYPE_LONG) { |
160 if (pos & 3) { | 250 if (pos & 3) { |
161 printf("MISALIGNED pos for word32 reloc, aborting\n"); | 251 printf("MISALIGNED pos for word32 reloc, aborting\n"); |
162 return; | 252 return; |
233 if (incr > headroom) { | 323 if (incr > headroom) { |
234 printf("error: increment %u > headroom %u, aborting\n", | 324 printf("error: increment %u > headroom %u, aborting\n", |
235 incr, headroom); | 325 incr, headroom); |
236 return; | 326 return; |
237 } | 327 } |
328 if (hint && pos >= hint->endpos) | |
329 hint = hint->next; | |
238 } | 330 } |
239 if (symnum == sec->nsymbols) | 331 if (symnum == sec->nsymbols) |
240 return; | 332 return; |
241 while (symnum < sec->nsymbols) { | 333 while (symnum < sec->nsymbols) { |
242 sym = sec->sorted_symbols[symnum]; | 334 sym = sec->sorted_symbols[symnum]; |