blob: 674696405cae9c81425427d3c6d315d1a4872657 [file] [log] [blame]
Rafaël Carréc0bd4172010-06-17 16:59:51 +00001#include <stdio.h>
2#include <string.h>
3#include <stdlib.h>
4#include <stdint.h>
5
6#define ULONG uint32_t
7#define USHORT uint16_t
8#define UCHAR uint8_t
9
10ULONG isdata[1000000]; /* each bit defines one byte as: code=0, data=1 */
11
12extern void dis_asm(ULONG off, ULONG val, char *stg);
13
14int static inline le2int(unsigned char* buf)
15{
16 int32_t res = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
17
18 return res;
19}
20
21int main(int argc, char **argv)
22{
23 FILE *in, *out;
24 char *ptr, stg[256];
25 unsigned char buf[4];
26 ULONG pos, sz, val, loop;
27 int offset, offset1;
28 USHORT regid;
29
30 if(argc == 1 || strcmp(argv[1], "--help") == 0)
31 { printf("Usage: arm_disass [input file]\n");
32 printf(" disassembles input file to 'disasm.txt'\n");
33 exit(-1);
34 }
35
36 in = fopen(argv[1], "rb");
37 if(in == NULL)
38 { printf("Cannot open %s", argv[1]);
39 exit(-1);
40 }
41
42 out = fopen("disasm.txt", "w");
43 if(out == NULL) exit(-1);
44
45 fseek(in, 0, SEEK_END);
46 sz = ftell(in);
47
48 /* first loop only sets data/code tags */
49 for(loop=0; loop<2; loop++)
50 {
51 for(pos=0; pos<sz; pos+=4)
52 {
53 /* clear disassembler string start */
54 memset(stg, 0, 40);
55 /* read next code dword */
56 fseek(in, pos, SEEK_SET);
57 fread(buf, 1, 4, in);
58
59 val = le2int(buf);
60
61 /* check for data tag set: if 1 byte out of 4 is marked => assume data */
62 if((isdata[pos>>5] & (0xf << (pos & 31))) || (val & 0xffff0000) == 0)
63 {
64 sprintf(stg, "%6x: %08x", pos, val);
65 }
66 else
67 {
68 dis_asm(pos, val, stg);
69
70 /* check for instant mov operation */
71 if(memcmp(stg+17, "mov ", 4) == 0 && (ptr=strstr(stg, "0x")) != NULL)
72 {
73 regid = *(USHORT*)(stg+22);
74
75 sscanf(ptr+2, "%x", &offset);
76 if(ptr[-1] == '-')
77 offset = -offset;
78 }
79 else
80 /* check for add/sub operation */
81 if((ptr=strstr(stg, "0x")) != NULL
82 && (memcmp(stg+17, "add ", 4) == 0 || memcmp(stg+17, "sub ", 4) == 0))
83 {
84 if(regid == *(USHORT*)(stg+22) && regid == *(USHORT*)(stg+26))
85 {
86 sscanf(ptr+2, "%x", &offset1);
87 if(ptr[-1] == '-')
88 offset1 = -offset1;
89
90 if(memcmp(stg+17, "add ", 4) == 0) offset += offset1;
91 else offset -= offset1;
92
93 /* add result to disassembler string */
94 sprintf(stg+strlen(stg), " <- 0x%x", offset);
95 }
96 else
97 regid = 0;
98 }
99 else
100 regid = 0;
101
102 /* check for const data */
103 if(memcmp(stg+26, "[pc, ", 5) == 0 && (ptr=strstr(stg, "0x")) != NULL)
104 {
105 sscanf(ptr+2, "%x", &offset);
106 if(ptr[-1] == '-')
107 offset = -offset;
108
109 /* add data tag */
110 isdata[(pos+offset+8)>>5] |= 1 << ((pos+offset+8) & 31);
111
112 /* add const data to disassembler string */
113 fseek(in, pos+offset+8, SEEK_SET);
114 fread(&buf, 1, 4, in);
115 offset = le2int(buf);
116
117 sprintf(stg+strlen(stg), " <- 0x%x", offset);
118 }
119 }
120
121 /* remove trailing spaces */
122 while(stg[strlen(stg)-1] == 32)
123 stg[strlen(stg)-1] = 0;
124
125 if(loop == 1)
126 fprintf(out, "%s\n", stg);
127 }
128 }
129
130 fclose(in);
131 return 0;
132}