comparison dis.c @ 631:de6f00204fa2

Add support for disassembling VOS program modules
author Michael Pavone <pavone@retrodev.com>
date Sat, 11 Oct 2014 20:32:17 -0700
parents 140af5509ce7
children 80e111b48d4b
comparison
equal deleted inserted replaced
630:47123183c336 631:de6f00204fa2
1 /* 1 /*
2 Copyright 2013 Michael Pavone 2 Copyright 2013 Michael Pavone
3 This file is part of BlastEm. 3 This file is part of BlastEm.
4 BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text. 4 BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text.
5 */ 5 */
6 #include "68kinst.h" 6 #include "68kinst.h"
7 #include <stdio.h> 7 #include <stdio.h>
8 #include <stdlib.h> 8 #include <stdlib.h>
9 #include <string.h>
10 #include "vos_program_module.h"
11 #include "tern.h"
9 12
10 uint8_t visited[(16*1024*1024)/16]; 13 uint8_t visited[(16*1024*1024)/16];
11 uint8_t label[(16*1024*1024)/8]; 14 uint8_t label[(16*1024*1024)/8];
12 15
13 void visit(uint32_t address) 16 void visit(uint32_t address)
31 34
32 uint8_t is_label(uint32_t address) 35 uint8_t is_label(uint32_t address)
33 { 36 {
34 address &= 0xFFFFFF; 37 address &= 0xFFFFFF;
35 return label[address/16] & (1 << (address % 8)); 38 return label[address/16] & (1 << (address % 8));
39 }
40
41 typedef struct {
42 uint32_t num_labels;
43 uint32_t storage;
44 char *labels[];
45 } label_names;
46
47 tern_node * add_label(tern_node * head, char * name, uint32_t address)
48 {
49 char key[MAX_INT_KEY_SIZE];
50 address &= 0xFFFFFF;
51 reference(address);
52 tern_int_key(address, key);
53 label_names * names = tern_find_ptr(head, key);
54 if (names)
55 {
56 if (names->num_labels == names->storage)
57 {
58 names->storage = names->storage + (names->storage >> 1);
59 names = realloc(names, sizeof(label_names) + names->storage * sizeof(char *));
60 }
61 } else {
62 names = malloc(sizeof(label_names) + 4 * sizeof(char *));
63 names->num_labels = 0;
64 names->storage = 4;
65 head = tern_insert_ptr(head, key, names);
66 }
67 names->labels[names->num_labels++] = strdup(name);
68 return head;
36 } 69 }
37 70
38 typedef struct deferred { 71 typedef struct deferred {
39 uint32_t address; 72 uint32_t address;
40 struct deferred *next; 73 struct deferred *next;
64 reference(op->params.immed); 97 reference(op->params.immed);
65 break; 98 break;
66 } 99 }
67 } 100 }
68 101
69 uint8_t labels = 0;
70 uint8_t addr = 0;
71 uint8_t only = 0;
72
73 int main(int argc, char ** argv) 102 int main(int argc, char ** argv)
74 { 103 {
75 long filesize; 104 long filesize;
76 unsigned short *filebuf; 105 unsigned short *filebuf;
77 char disbuf[1024]; 106 char disbuf[1024];
78 m68kinst instbuf; 107 m68kinst instbuf;
79 unsigned short * cur; 108 unsigned short * cur;
80 FILE * f = fopen(argv[1], "rb");
81 fseek(f, 0, SEEK_END);
82 filesize = ftell(f);
83 fseek(f, 0, SEEK_SET);
84 filebuf = malloc(filesize);
85 fread(filebuf, 2, filesize/2, f);
86 fclose(f);
87 deferred *def = NULL, *tmpd; 109 deferred *def = NULL, *tmpd;
110
111 uint8_t labels = 0, addr = 0, only = 0, vos = 0;
112
88 for(uint8_t opt = 2; opt < argc; ++opt) { 113 for(uint8_t opt = 2; opt < argc; ++opt) {
89 if (argv[opt][0] == '-') { 114 if (argv[opt][0] == '-') {
90 FILE * address_log; 115 FILE * address_log;
91 switch (argv[opt][1]) 116 switch (argv[opt][1])
92 { 117 {
97 addr = 1; 122 addr = 1;
98 break; 123 break;
99 case 'o': 124 case 'o':
100 only = 1; 125 only = 1;
101 break; 126 break;
127 case 'v':
128 vos = 1;
129 break;
102 case 'f': 130 case 'f':
103 opt++; 131 opt++;
104 if (opt >= argc) { 132 if (opt >= argc) {
105 fputs("-f must be followed by a filename\n", stderr); 133 fputs("-f must be followed by a filename\n", stderr);
106 exit(1); 134 exit(1);
124 uint32_t address = strtol(argv[opt], NULL, 16); 152 uint32_t address = strtol(argv[opt], NULL, 16);
125 def = defer(address, def); 153 def = defer(address, def);
126 reference(address); 154 reference(address);
127 } 155 }
128 } 156 }
129 for(cur = filebuf; cur - filebuf < (filesize/2); ++cur) 157
158 FILE * f = fopen(argv[1], "rb");
159 fseek(f, 0, SEEK_END);
160 filesize = ftell(f);
161 fseek(f, 0, SEEK_SET);
162
163 tern_node * named_labels = NULL;
164 char int_key[MAX_INT_KEY_SIZE];
165 uint32_t address_off, address_end;
166 if (vos)
130 { 167 {
131 *cur = (*cur >> 8) | (*cur << 8); 168 vos_program_module header;
132 } 169 vos_read_header(f, &header);
133 uint32_t start = filebuf[2] << 16 | filebuf[3], tmp_addr; 170 vos_read_alloc_module_map(f, &header);
134 uint32_t int_2 = filebuf[0x68/2] << 16 | filebuf[0x6A/2]; 171 address_off = header.user_boundary;
135 uint32_t int_4 = filebuf[0x70/2] << 16 | filebuf[0x72/2]; 172 address_end = address_off + filesize - 0x1000;
136 uint32_t int_6 = filebuf[0x78/2] << 16 | filebuf[0x7A/2]; 173 def = defer(header.main_entry_link.code_address, def);
174 named_labels = add_label(named_labels, "main_entry_link", header.main_entry_link.code_address);
175 for (int i = 0; i < header.n_modules; i++)
176 {
177 def = defer(header.module_map_entries[i].code_address, def);
178 named_labels = add_label(named_labels, header.module_map_entries[i].name.str, header.module_map_entries[i].code_address);
179 }
180 fseek(f, 0x1000, SEEK_SET);
181 filebuf = malloc(filesize - 0x1000);
182 if (fread(filebuf, 2, (filesize - 0x1000)/2, f) != (filesize - 0x1000)/2)
183 {
184 fprintf(stderr, "Failure while reading file %s\n", argv[1]);
185 }
186 fclose(f);
187 for(cur = filebuf; cur - filebuf < ((filesize - 0x1000)/2); ++cur)
188 {
189 *cur = (*cur >> 8) | (*cur << 8);
190 }
191 } else {
192 address_off = 0;
193 address_end = filesize;
194 filebuf = malloc(filesize);
195 if (fread(filebuf, 2, filesize/2, f) != filesize/2)
196 {
197 fprintf(stderr, "Failure while reading file %s\n", argv[1]);
198 }
199 fclose(f);
200 for(cur = filebuf; cur - filebuf < (filesize/2); ++cur)
201 {
202 *cur = (*cur >> 8) | (*cur << 8);
203 }
204 uint32_t start = filebuf[2] << 16 | filebuf[3];
205 uint32_t int_2 = filebuf[0x68/2] << 16 | filebuf[0x6A/2];
206 uint32_t int_4 = filebuf[0x70/2] << 16 | filebuf[0x72/2];
207 uint32_t int_6 = filebuf[0x78/2] << 16 | filebuf[0x7A/2];
208 named_labels = add_label(named_labels, "start", start);
209 named_labels = add_label(named_labels, "int_2", int_2);
210 named_labels = add_label(named_labels, "int_4", int_4);
211 named_labels = add_label(named_labels, "int_6", int_6);
212 if (!def || !only) {
213 def = defer(start, def);
214 def = defer(int_2, def);
215 def = defer(int_4, def);
216 def = defer(int_6, def);
217 }
218 }
137 uint16_t *encoded, *next; 219 uint16_t *encoded, *next;
138 uint32_t size; 220 uint32_t size, tmp_addr;
139 if (!def || !only) {
140 def = defer(start, def);
141 def = defer(int_2, def);
142 def = defer(int_4, def);
143 def = defer(int_6, def);
144 }
145 uint32_t address; 221 uint32_t address;
146 while(def) { 222 while(def) {
147 do { 223 do {
148 encoded = NULL; 224 encoded = NULL;
149 address = def->address; 225 address = def->address;
216 printf("ADR_%X equ $%X\n", address, address); 292 printf("ADR_%X equ $%X\n", address, address);
217 } 293 }
218 } 294 }
219 puts(""); 295 puts("");
220 } 296 }
221 for (address = 0; address < filesize; address+=2) { 297 for (address = address_off; address < filesize; address+=2) {
222 if (is_visited(address)) { 298 if (is_visited(address)) {
223 encoded = filebuf + address/2; 299 encoded = filebuf + (address-address_off)/2;
224 m68k_decode(encoded, &instbuf, address); 300 m68k_decode(encoded, &instbuf, address);
225 if (labels) { 301 if (labels) {
226 m68k_disasm_labels(&instbuf, disbuf); 302 m68k_disasm_labels(&instbuf, disbuf);
227 if (address == start) { 303 char keybuf[MAX_INT_KEY_SIZE];
228 puts("start:"); 304 label_names * names = tern_find_ptr(named_labels, tern_int_key(address, keybuf));
229 } 305 if (names)
230 if(address == int_2) { 306 {
231 puts("int_2:"); 307 for (int i = 0; i < names->num_labels; i++)
232 } 308 {
233 if(address == int_4) { 309 printf("%s:\n", names->labels[i]);
234 puts("int_4:"); 310 }
235 } 311 } else if (is_label(instbuf.address)) {
236 if(address == int_6) {
237 puts("int_6:");
238 }
239 if (is_label(instbuf.address)) {
240 printf("ADR_%X:\n", instbuf.address); 312 printf("ADR_%X:\n", instbuf.address);
241 } 313 }
242 if (addr) { 314 if (addr) {
243 printf("\t%s\t;%X\n", disbuf, instbuf.address); 315 printf("\t%s\t;%X\n", disbuf, instbuf.address);
244 } else { 316 } else {