forked from len0rd/rockbox
Initial version of ARM disassembler by Antonius Hellman.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@14126 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
705ca703e3
commit
307d2ddce9
2 changed files with 493 additions and 0 deletions
118
utils/disassembler/arm/main.c
Normal file
118
utils/disassembler/arm/main.c
Normal file
|
@ -0,0 +1,118 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define ULONG unsigned long
|
||||
#define USHORT unsigned short
|
||||
#define UCHAR unsigned char
|
||||
|
||||
ULONG isdata[1000000]; /* each bit defines one byte as: code=0, data=1 */
|
||||
|
||||
extern void dis_asm(ULONG off, ULONG val, char *stg);
|
||||
|
||||
void main(int argc, char **argv)
|
||||
{
|
||||
FILE *in, *out;
|
||||
char *ptr, stg[256];
|
||||
ULONG pos, sz, val, loop;
|
||||
int offset, offset1;
|
||||
USHORT regid;
|
||||
|
||||
if(argc == 1 || strcmp(argv[1], "--help") == 0)
|
||||
{ printf("Usage: arm_disass [input file]\n");
|
||||
printf(" disassembles input file to 'disasm.txt'");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
in = fopen(argv[1], "rb");
|
||||
if(in == NULL)
|
||||
{ printf("Cannot open %s", argv[1]);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
out = fopen("disasm.txt", "w");
|
||||
if(out == NULL) exit(-1);
|
||||
|
||||
fseek(in, 0, SEEK_END);
|
||||
sz = ftell(in);
|
||||
|
||||
/* first loop only sets data/code tags */
|
||||
for(loop=0; loop<2; loop++)
|
||||
{
|
||||
for(pos=0; pos<sz; pos+=4)
|
||||
{
|
||||
/* clear disassembler string start */
|
||||
memset(stg, 0, 40);
|
||||
/* read next code dword */
|
||||
fseek(in, pos, SEEK_SET);
|
||||
fread(&val, 4, 1, in);
|
||||
|
||||
/* check for data tag set: if 1 byte out of 4 is marked => assume data */
|
||||
if((isdata[pos>>5] & (0xf << (pos & 31))) || (val & 0xffff0000) == 0)
|
||||
{
|
||||
sprintf(stg, "%6x: %08x", pos, val);
|
||||
}
|
||||
else
|
||||
{
|
||||
dis_asm(pos, val, stg);
|
||||
|
||||
/* check for instant mov operation */
|
||||
if(memcmp(stg+17, "mov ", 4) == 0 && (ptr=strstr(stg, "0x")) != NULL)
|
||||
{
|
||||
regid = *(USHORT*)(stg+22);
|
||||
|
||||
sscanf(ptr+2, "%x", &offset);
|
||||
if(ptr[-1] == '-')
|
||||
offset = -offset;
|
||||
}
|
||||
else
|
||||
/* check for add/sub operation */
|
||||
if((ptr=strstr(stg, "0x")) != NULL
|
||||
&& (memcmp(stg+17, "add ", 4) == 0 || memcmp(stg+17, "sub ", 4) == 0))
|
||||
{
|
||||
if(regid == *(USHORT*)(stg+22) && regid == *(USHORT*)(stg+26))
|
||||
{
|
||||
sscanf(ptr+2, "%x", &offset1);
|
||||
if(ptr[-1] == '-')
|
||||
offset1 = -offset1;
|
||||
|
||||
if(memcmp(stg+17, "add ", 4) == 0) offset += offset1;
|
||||
else offset -= offset1;
|
||||
|
||||
/* add result to disassembler string */
|
||||
sprintf(stg+strlen(stg), " <- 0x%x", offset);
|
||||
}
|
||||
else
|
||||
regid = 0;
|
||||
}
|
||||
else
|
||||
regid = 0;
|
||||
|
||||
/* check for const data */
|
||||
if(memcmp(stg+26, "[pc, ", 5) == 0 && (ptr=strstr(stg, "0x")) != NULL)
|
||||
{
|
||||
sscanf(ptr+2, "%x", &offset);
|
||||
if(ptr[-1] == '-')
|
||||
offset = -offset;
|
||||
|
||||
/* add data tag */
|
||||
isdata[(pos+offset+8)>>5] |= 1 << ((pos+offset+8) & 31);
|
||||
|
||||
/* add const data to disassembler string */
|
||||
fseek(in, pos+offset+8, SEEK_SET);
|
||||
fread(&offset, 4, 1, in);
|
||||
sprintf(stg+strlen(stg), " <- 0x%x", offset);
|
||||
}
|
||||
}
|
||||
|
||||
/* remove trailing spaces */
|
||||
while(stg[strlen(stg)-1] == 32)
|
||||
stg[strlen(stg)-1] = 0;
|
||||
|
||||
if(loop == 1)
|
||||
fprintf(out, "%s\n", stg);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(in);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue