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];