comparison leo-obj/tool/disasm.c @ 135:df432a4b1b84

tiobjd: disasm of code and data sections unified
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Mon, 07 Apr 2014 04:06:17 +0000
parents daeaa5950d10
children 81fc8da9a29c
comparison
equal deleted inserted replaced
134:c131238c56bf 135:df432a4b1b84
76 printf("%08x R\t.word\t", word); 76 printf("%08x R\t.word\t", word);
77 disasm_reloc_target(sec, rel, word); 77 disasm_reloc_target(sec, rel, word);
78 putchar('\n'); 78 putchar('\n');
79 } 79 }
80 80
81 void 81 static void
82 disasm_end_of_section(sec, symnum) 82 handle_symbol(sym, statep, linebrkp)
83 struct internal_scnhdr *sec;
84 unsigned symnum;
85 {
86 struct internal_syment *sym; 83 struct internal_syment *sym;
84 int *statep, *linebrkp;
85 {
87 char *sym_comment; 86 char *sym_comment;
88 87
89 putchar('\n'); 88 if (sym->class == C_FCN && !strcmp(sym->name, ".ef")) {
90 while (symnum < sec->nsymbols) { 89 printf("; End function\n");
91 sym = sec->sorted_symbols[symnum]; 90 return;
92 if (sym->value != sec->size) { 91 }
93 printf("error: expecting symbol at end of section\n"); 92 if (!*linebrkp) {
94 return; 93 putchar('\n');
95 } 94 *linebrkp = 1;
96 switch (sym->class) { 95 }
97 case C_EXT: 96 if (sym->class == C_FCN && !strcmp(sym->name, ".bf")) {
98 sym_comment = "Global"; 97 printf("; Begin function\n");
99 break; 98 return;
100 case C_STAT: 99 }
101 sym_comment = "static"; 100 switch (sym->class) {
102 break; 101 case C_EXT:
103 case C_LABEL: 102 sym_comment = "Global";
104 sym_comment = "label"; 103 break;
105 break; 104 case C_STAT:
106 default: 105 sym_comment = "static";
107 sym_comment = "unexpected class!"; 106 break;
108 } 107 case C_LABEL:
109 printf("%s:\t; %s\n", sym->name, sym_comment); 108 sym_comment = "label";
110 symnum++; 109 if (!strcmp(sym->name, "$CODE16"))
111 } 110 *statep = 1;
112 printf("%8x:\t<end of section>\n", sec->size); 111 else if (!strcmp(sym->name, "$CODE32"))
113 } 112 *statep = 0;
114 113 break;
115 void 114 default:
116 disasm_text_section(sec) 115 sym_comment = "unexpected class!";
116 }
117 printf("%s:\t; %s\n", sym->name, sym_comment);
118 }
119
120 void
121 disasm_codedata_section(sec)
117 struct internal_scnhdr *sec; 122 struct internal_scnhdr *sec;
118 { 123 {
119 unsigned symnum, relnum; 124 unsigned symnum, relnum;
120 unsigned pos, incr, headroom; 125 unsigned pos, incr, headroom;
121 int state = -1, linebrk = 0; 126 int state = -1, linebrk = 0;
122 struct internal_syment *sym; 127 struct internal_syment *sym;
123 struct internal_reloc *rel; 128 struct internal_reloc *rel;
124 char *sym_comment; 129
125
126 printf("Disassembling code section:\n");
127 if (sec->nsymbols)
128 sort_symbols_of_sec(sec);
129 if (sec->nreloc) 130 if (sec->nreloc)
130 get_relocs_of_sec(sec); 131 get_relocs_of_sec(sec);
131 symnum = relnum = 0; 132 symnum = relnum = 0;
132 for (pos = 0; pos < sec->size; pos += incr) { 133 for (pos = 0; pos < sec->size; pos += incr) {
133 headroom = sec->size - pos; 134 headroom = sec->size - pos;
137 if (sym->value - pos < headroom) 138 if (sym->value - pos < headroom)
138 headroom = sym->value - pos; 139 headroom = sym->value - pos;
139 break; 140 break;
140 } 141 }
141 /* hit symbol */ 142 /* hit symbol */
142 if (!linebrk) { 143 handle_symbol(sym, &state, &linebrk);
143 putchar('\n');
144 linebrk = 1;
145 }
146 switch (sym->class) {
147 case C_EXT:
148 sym_comment = "Global";
149 break;
150 case C_STAT:
151 sym_comment = "static";
152 break;
153 case C_LABEL:
154 sym_comment = "label";
155 if (!strcmp(sym->name, "$CODE16"))
156 state = 1;
157 else if (!strcmp(sym->name, "$CODE32"))
158 state = 0;
159 break;
160 default:
161 sym_comment = "unexpected class!";
162 }
163 printf("%s:\t; %s\n", sym->name, sym_comment);
164 symnum++; 144 symnum++;
165 } 145 }
166 if (relnum < sec->nreloc) { 146 if (relnum < sec->nreloc) {
167 rel = sec->int_relocs + relnum; 147 rel = sec->int_relocs + relnum;
168 if (rel->location == pos) 148 if (rel->location == pos)
173 rel = 0; /* no reloc for current pos */ 153 rel = 0; /* no reloc for current pos */
174 } 154 }
175 } else 155 } else
176 rel = 0; 156 rel = 0;
177 printf("%8x:\t", pos); 157 printf("%8x:\t", pos);
178 if (rel && rel->type == RTYPE_LONG) { 158 if (rel) {
179 if (pos & 3) { 159 if (rel->type == RTYPE_LONG) {
180 printf("MISALIGNED pos for word32 reloc, aborting\n"); 160 if (pos & 3) {
161 printf("MISALIGNED pos for word32 reloc, aborting\n");
162 return;
163 }
164 disasm_word32_reloc(sec, rel);
165 incr = 4;
166 goto next;
167 } else if (sec->disasm_mode == DISASM_MODE_DATA) {
168 printf("error: reloc other than word32 in data section\n");
181 return; 169 return;
182 } 170 }
183 disasm_word32_reloc(sec, rel);
184 incr = 4;
185 goto next;
186 } 171 }
187 if (pos & 1 || headroom < 2) { 172 if (pos & 1 || headroom < 2) {
188 if (rel) { 173 if (rel) {
189 printf("error: reloc at byte pos, aborting\n"); 174 printf("error: reloc at byte pos, aborting\n");
190 return; 175 return;
191 } 176 }
192 printf("%02x\n", filemap[sec->data_offset + pos]); 177 printf("%02x\n", filemap[sec->data_offset + pos]);
193 incr = 1; 178 incr = 1;
179 goto next;
180 }
181 if (sec->disasm_mode == DISASM_MODE_DATA) {
182 if (pos & 2 || headroom < 4) {
183 printf("%04x\n",
184 get_u16(filemap+sec->data_offset+pos));
185 incr = 2;
186 } else {
187 printf("%08x\n",
188 get_u32(filemap+sec->data_offset+pos));
189 incr = 4;
190 }
194 goto next; 191 goto next;
195 } 192 }
196 switch (state) { 193 switch (state) {
197 case 0: /* ARM */ 194 case 0: /* ARM */
198 if (pos & 3) { 195 if (pos & 3) {
237 printf("error: increment %u > headroom %u, aborting\n", 234 printf("error: increment %u > headroom %u, aborting\n",
238 incr, headroom); 235 incr, headroom);
239 return; 236 return;
240 } 237 }
241 } 238 }
242 if (symnum < sec->nsymbols) 239 if (symnum == sec->nsymbols)
243 disasm_end_of_section(sec, symnum); 240 return;
244 } 241 while (symnum < sec->nsymbols) {
245 242 sym = sec->sorted_symbols[symnum];
246 void 243 if (sym->value != sec->size) {
247 disasm_data_section(sec) 244 printf("error: expecting symbol at end of section\n");
248 struct internal_scnhdr *sec;
249 {
250 unsigned symnum, relnum;
251 unsigned pos, incr, headroom;
252 int linebrk = 0;
253 struct internal_syment *sym;
254 struct internal_reloc *rel;
255 char *sym_comment;
256
257 printf("Disassembling data section:\n");
258 if (sec->nsymbols)
259 sort_symbols_of_sec(sec);
260 if (sec->nreloc)
261 get_relocs_of_sec(sec);
262 symnum = relnum = 0;
263 for (pos = 0; pos < sec->size; pos += incr) {
264 headroom = sec->size - pos;
265 while (symnum < sec->nsymbols) {
266 sym = sec->sorted_symbols[symnum];
267 if (sym->value > pos) {
268 if (sym->value - pos < headroom)
269 headroom = sym->value - pos;
270 break;
271 }
272 /* hit symbol */
273 if (!linebrk) {
274 putchar('\n');
275 linebrk = 1;
276 }
277 switch (sym->class) {
278 case C_EXT:
279 sym_comment = "Global";
280 break;
281 case C_STAT:
282 sym_comment = "static";
283 break;
284 case C_LABEL:
285 sym_comment = "label";
286 break;
287 default:
288 sym_comment = "unexpected class!";
289 }
290 printf("%s:\t; %s\n", sym->name, sym_comment);
291 symnum++;
292 }
293 if (relnum < sec->nreloc) {
294 rel = sec->int_relocs + relnum;
295 if (rel->location == pos)
296 relnum++; /* it's ours */
297 else {
298 if (rel->location - pos < headroom)
299 headroom = rel->location - pos;
300 rel = 0; /* no reloc for current pos */
301 }
302 } else
303 rel = 0;
304 printf("%8x:\t", pos);
305 if (rel) {
306 if (rel->type != RTYPE_LONG) {
307 printf("error: reloc other than word32 in data section\n");
308 return;
309 }
310 if (pos & 3) {
311 printf("MISALIGNED pos for word32 reloc, aborting\n");
312 return;
313 }
314 disasm_word32_reloc(sec, rel);
315 incr = 4;
316 } else if (pos & 1 || headroom < 2) {
317 printf("%02x\n", filemap[sec->data_offset + pos]);
318 incr = 1;
319 } else if (pos & 2 || headroom < 4) {
320 printf("%04x\n",
321 get_u16(filemap + sec->data_offset + pos));
322 incr = 2;
323 } else {
324 printf("%08x\n",
325 get_u32(filemap + sec->data_offset + pos));
326 incr = 4;
327 }
328 linebrk = 0;
329 if (incr > headroom) {
330 printf("error: increment %u > headroom %u, aborting\n",
331 incr, headroom);
332 return; 245 return;
333 } 246 }
334 } 247 handle_symbol(sym, &state, &linebrk);
335 if (symnum < sec->nsymbols) 248 symnum++;
336 disasm_end_of_section(sec, symnum); 249 }
250 printf("%8x:\t<end of section>\n", sec->size);
337 } 251 }
338 252
339 void 253 void
340 disasm_bss(sec) 254 disasm_bss(sec)
341 struct internal_scnhdr *sec; 255 struct internal_scnhdr *sec;
358 disasm_sec_by_type(sec) 272 disasm_sec_by_type(sec)
359 struct internal_scnhdr *sec; 273 struct internal_scnhdr *sec;
360 { 274 {
361 switch (sec->disasm_mode) { 275 switch (sec->disasm_mode) {
362 case DISASM_MODE_CODE: 276 case DISASM_MODE_CODE:
363 disasm_text_section(sec); 277 printf("Disassembling code section:\n");
278 disasm_codedata_section(sec);
364 return; 279 return;
365 case DISASM_MODE_DATA: 280 case DISASM_MODE_DATA:
366 disasm_data_section(sec); 281 printf("Disassembling data section:\n");
282 disasm_codedata_section(sec);
367 return; 283 return;
368 case DISASM_MODE_BSS: 284 case DISASM_MODE_BSS:
369 disasm_bss(sec); 285 disasm_bss(sec);
370 return; 286 return;
371 default: 287 default: