summaryrefslogtreecommitdiff
path: root/utils/disassembler/arm/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'utils/disassembler/arm/main.c')
-rw-r--r--utils/disassembler/arm/main.c118
1 files changed, 118 insertions, 0 deletions
diff --git a/utils/disassembler/arm/main.c b/utils/disassembler/arm/main.c
new file mode 100644
index 0000000000..834dc5ff93
--- /dev/null
+++ b/utils/disassembler/arm/main.c
@@ -0,0 +1,118 @@
1#include <stdio.h>
2#include <string.h>
3#include <stdlib.h>
4
5#define ULONG unsigned long
6#define USHORT unsigned short
7#define UCHAR unsigned char
8
9ULONG isdata[1000000]; /* each bit defines one byte as: code=0, data=1 */
10
11extern void dis_asm(ULONG off, ULONG val, char *stg);
12
13void main(int argc, char **argv)
14{
15 FILE *in, *out;
16 char *ptr, stg[256];
17 ULONG pos, sz, val, loop;
18 int offset, offset1;
19 USHORT regid;
20
21 if(argc == 1 || strcmp(argv[1], "--help") == 0)
22 { printf("Usage: arm_disass [input file]\n");
23 printf(" disassembles input file to 'disasm.txt'");
24 exit(-1);
25 }
26
27 in = fopen(argv[1], "rb");
28 if(in == NULL)
29 { printf("Cannot open %s", argv[1]);
30 exit(-1);
31 }
32
33 out = fopen("disasm.txt", "w");
34 if(out == NULL) exit(-1);
35
36 fseek(in, 0, SEEK_END);
37 sz = ftell(in);
38
39 /* first loop only sets data/code tags */
40 for(loop=0; loop<2; loop++)
41 {
42 for(pos=0; pos<sz; pos+=4)
43 {
44 /* clear disassembler string start */
45 memset(stg, 0, 40);
46 /* read next code dword */
47 fseek(in, pos, SEEK_SET);
48 fread(&val, 4, 1, in);
49
50 /* check for data tag set: if 1 byte out of 4 is marked => assume data */
51 if((isdata[pos>>5] & (0xf << (pos & 31))) || (val & 0xffff0000) == 0)
52 {
53 sprintf(stg, "%6x: %08x", pos, val);
54 }
55 else
56 {
57 dis_asm(pos, val, stg);
58
59 /* check for instant mov operation */
60 if(memcmp(stg+17, "mov ", 4) == 0 && (ptr=strstr(stg, "0x")) != NULL)
61 {
62 regid = *(USHORT*)(stg+22);
63
64 sscanf(ptr+2, "%x", &offset);
65 if(ptr[-1] == '-')
66 offset = -offset;
67 }
68 else
69 /* check for add/sub operation */
70 if((ptr=strstr(stg, "0x")) != NULL
71 && (memcmp(stg+17, "add ", 4) == 0 || memcmp(stg+17, "sub ", 4) == 0))
72 {
73 if(regid == *(USHORT*)(stg+22) && regid == *(USHORT*)(stg+26))
74 {
75 sscanf(ptr+2, "%x", &offset1);
76 if(ptr[-1] == '-')
77 offset1 = -offset1;
78
79 if(memcmp(stg+17, "add ", 4) == 0) offset += offset1;
80 else offset -= offset1;
81
82 /* add result to disassembler string */
83 sprintf(stg+strlen(stg), " <- 0x%x", offset);
84 }
85 else
86 regid = 0;
87 }
88 else
89 regid = 0;
90
91 /* check for const data */
92 if(memcmp(stg+26, "[pc, ", 5) == 0 && (ptr=strstr(stg, "0x")) != NULL)
93 {
94 sscanf(ptr+2, "%x", &offset);
95 if(ptr[-1] == '-')
96 offset = -offset;
97
98 /* add data tag */
99 isdata[(pos+offset+8)>>5] |= 1 << ((pos+offset+8) & 31);
100
101 /* add const data to disassembler string */
102 fseek(in, pos+offset+8, SEEK_SET);
103 fread(&offset, 4, 1, in);
104 sprintf(stg+strlen(stg), " <- 0x%x", offset);
105 }
106 }
107
108 /* remove trailing spaces */
109 while(stg[strlen(stg)-1] == 32)
110 stg[strlen(stg)-1] = 0;
111
112 if(loop == 1)
113 fprintf(out, "%s\n", stg);
114 }
115 }
116
117 fclose(in);
118} \ No newline at end of file