view arm7dis/common.c @ 406:1a852266ba74 default tip

tfo moved to gsm-net-reveng repository
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 24 May 2024 21:19:59 +0000
parents c883e60df239
children
line wrap: on
line source

/*
 * Lean and mean ARM7TDMI disassembler
 * Written by Spacefalcon the Outlaw
 */

#include <sys/types.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

char *binfilename;
u_char *filemap;
unsigned disasm_len, base_vma;

common_init(argc, argv, instr_size)
	char **argv;
{
	int fd;
	struct stat st;
	unsigned fileoff;

	if (argc < 2 || argc > 5) {
		fprintf(stderr,
			"usage: %s binfile [file-offset [len [vaddr]]]\n",
			argv[0]);
		exit(1);
	}
	binfilename = argv[1];
	fd = open(binfilename, O_RDONLY);
	if (fd < 0) {
		perror(binfilename);
		exit(1);
	}
	fstat(fd, &st);
	if (!S_ISREG(st.st_mode)) {
		fprintf(stderr, "error: %s is not a regular file\n",
			binfilename);
		exit(1);
	}
	if (argc > 2)
		fileoff = strtoul(argv[2], 0, 0);
	else
		fileoff = 0;
	if (fileoff > st.st_size) {
		fprintf(stderr,
		    "error: specified file offset is past the end of file\n");
		exit(1);
	}
	if (argc > 3) {
		disasm_len = strtoul(argv[3], 0, 0);
		if (disasm_len > st.st_size - fileoff) {
			fprintf(stderr,
			  "error: specified length is past the end of file\n");
			exit(1);
		}
	} else
		disasm_len = st.st_size - fileoff;
	if (disasm_len & (instr_size - 1)) {
		fprintf(stderr,
"error: length of region to be disassembled must be a multiple of %d bytes\n",
			instr_size);
		exit(1);
	}
	filemap = mmap(NULL, (size_t) disasm_len, PROT_READ, MAP_PRIVATE, fd,
			(off_t) fileoff);
	if (filemap == MAP_FAILED) {
		perror("mmap");
		exit(1);
	}
	close(fd);
	if (argc > 4)
		base_vma = strtoul(argv[4], 0, 0);
	else
		base_vma = fileoff;
	return(0);
}

unsigned
get_u16(ptr)
	u_char *ptr;
{
	return ptr[0] | ptr[1] << 8;
}

unsigned
get_u32(ptr)
	u_char *ptr;
{
	return ptr[0] | ptr[1] << 8 | ptr[2] << 16 | ptr[3] << 24;
}