From 9229d32d410280e19914cd10f95c6c1ae7a6ebb4 Mon Sep 17 00:00:00 2001 From: Pierre Pronchery Date: Sun, 24 Apr 2011 04:57:13 +0000 Subject: [PATCH] Improving disassembly support for the amd64 architecture --- Makefile | 1 + src/arch/Makefile | 2 +- src/arch/amd64.c | 2 ++ src/arch/amd64.ins | 23 +++++++++++++++++++++++ src/arch/i386.h | 38 ++++++++++++++++++++++++++------------ src/arch/i386.ins | 10 ++++++++++ src/arch/project.conf | 4 ++-- 7 files changed, 65 insertions(+), 15 deletions(-) create mode 100644 src/arch/amd64.ins diff --git a/Makefile b/Makefile index 95113ad..2062daa 100644 --- a/Makefile +++ b/Makefile @@ -61,6 +61,7 @@ dist: $(PACKAGE)-$(VERSION)/src/arch/sparc.c \ $(PACKAGE)-$(VERSION)/src/arch/sparc64.c \ $(PACKAGE)-$(VERSION)/src/arch/Makefile \ + $(PACKAGE)-$(VERSION)/src/arch/amd64.ins \ $(PACKAGE)-$(VERSION)/src/arch/amd64.reg \ $(PACKAGE)-$(VERSION)/src/arch/common.ins \ $(PACKAGE)-$(VERSION)/src/arch/dalvik.ins \ diff --git a/src/arch/Makefile b/src/arch/Makefile index 57fe45c..eec1156 100644 --- a/src/arch/Makefile +++ b/src/arch/Makefile @@ -88,7 +88,7 @@ sparc64_LDFLAGS = $(LDFLAGSF) $(LDFLAGS) sparc64.so: $(sparc64_OBJS) $(LD) -o sparc64.so $(sparc64_OBJS) $(sparc64_LDFLAGS) -amd64.o: amd64.c amd64.reg common.ins null.ins i386.h i386.ins i386.reg i486.ins i686.ins i686.reg +amd64.o: amd64.c amd64.ins amd64.reg common.ins null.ins i386.h i386.ins i386.reg i486.ins i686.ins i686.reg $(CC) $(amd64_CFLAGS) -c amd64.c dalvik.o: dalvik.c common.ins null.ins dalvik.ins dalvik.reg diff --git a/src/arch/amd64.c b/src/arch/amd64.c index c87dbd6..9a582e7 100644 --- a/src/arch/amd64.c +++ b/src/arch/amd64.c @@ -18,6 +18,7 @@ #include #include #include "Asm.h" +#define ARCH_amd64 /* amd64 */ @@ -60,6 +61,7 @@ static ArchInstruction _amd64_instructions[] = #include "i386.ins" #include "i486.ins" #include "i686.ins" +#include "amd64.ins" #include "common.ins" #include "null.ins" }; diff --git a/src/arch/amd64.ins b/src/arch/amd64.ins new file mode 100644 index 0000000..fec35f2 --- /dev/null +++ b/src/arch/amd64.ins @@ -0,0 +1,23 @@ +/* $Id$ */ +/* Copyright (c) 2011 Pierre Pronchery */ +/* This file is part of DeforaOS Devel asm */ +/* This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ + + + +/* instructions */ +/* FIXME fix and complete */ +/* MOV 0x4989 2 */ +{ "mov", 0x4989, OP2F, AOT_NONE, AOT_NONE, AOT_NONE }, +/* SUB 0x4883 2 */ +{ "sub", 0x4883, OP2F, AOT_NONE, AOT_NONE, AOT_NONE }, diff --git a/src/arch/i386.h b/src/arch/i386.h index 60ec443..a2d8f8a 100644 --- a/src/arch/i386.h +++ b/src/arch/i386.h @@ -43,32 +43,46 @@ static int _i386_decode(ArchPlugin * plugin, ArchInstructionCall * call) { ArchPluginHelper * helper = plugin->helper; ArchInstruction * ai = NULL; - uint8_t opcode; + uint8_t u8; + uint16_t u16; size_t i; /* FIXME detect end of input */ - if(helper->read(helper->arch, &opcode, sizeof(opcode)) - != sizeof(opcode)) + if(helper->read(helper->arch, &u8, sizeof(u8)) != sizeof(u8)) return -1; call->operands[0].type = AOT_NONE; call->operands[1].type = AOT_NONE; call->operands[2].type = AOT_NONE; - if((ai = helper->get_instruction_by_opcode(helper->arch, 8, opcode)) + if((ai = helper->get_instruction_by_opcode(helper->arch, 8, u8)) == NULL) { - /* FIXME check if it's a longer instruction */ - call->name = "db"; - call->operands[0].type = AO_IMMEDIATE(0, 0, 8); - call->operands[0].value.immediate.value = opcode; - call->operands[0].value.immediate.negative = 0; - call->operands_cnt = 1; - return 0; + u16 = u8; + if(helper->read(helper->arch, &u8, sizeof(u8)) != sizeof(u8)) + { + call->name = "db"; + call->operands[0].type = AO_IMMEDIATE(0, 0, 8); + call->operands[0].value.immediate.value = u8; + call->operands[0].value.immediate.negative = 0; + call->operands_cnt = 1; + return 0; + } + u16 = _htol16((u16 << 8) | u8); + if((ai = helper->get_instruction_by_opcode(helper->arch, 16, + u16)) == NULL) + { + call->name = "dw"; + call->operands[0].type = AO_IMMEDIATE(0, 0, 16); + call->operands[0].value.immediate.value = u16; + call->operands[0].value.immediate.negative = 0; + call->operands_cnt = 1; + return 0; + } } call->name = ai->name; call->operands[0].type = ai->op1; call->operands[1].type = ai->op2; call->operands[2].type = ai->op3; - for(i = 0; AO_GET_TYPE(call->operands[i].type) != 0; i++) + for(i = 0; i < 3 && AO_GET_TYPE(call->operands[i].type) != 0; i++) if(_decode_operand(plugin, call, i) != 0) return -1; call->operands_cnt = i; diff --git a/src/arch/i386.ins b/src/arch/i386.ins index 9246385..9fcf870 100644 --- a/src/arch/i386.ins +++ b/src/arch/i386.ins @@ -114,12 +114,16 @@ /* instructions */ +#ifndef ARCH_amd64 { "aaa", 0x37, OP1F, AOT_NONE, AOT_NONE, AOT_NONE }, +#endif { "aad", 0xd50a, OP2F, AOT_NONE, AOT_NONE, AOT_NONE }, { "aad", 0xd5, OP1F, OP_U8, AOT_NONE, AOT_NONE }, { "aam", 0xd40a, OP2F, AOT_NONE, AOT_NONE, AOT_NONE }, { "aam", 0xd4, OP1F, OP_U8, AOT_NONE, AOT_NONE }, +#ifndef ARCH_amd64 { "aas", 0x3f, OP1F, AOT_NONE, AOT_NONE, AOT_NONE }, +#endif /* ADC 0x14 ib 1 al imm8 */ { "adc", 0x14, OP1F, OP_al, OP_S8, AOT_NONE }, /* ADC 0x15 iW 1 AX immW */ @@ -337,10 +341,15 @@ /* CDQ 0x99 1 */ { "cdq", 0x99, OP1F, AOT_NONE, AOT_NONE, AOT_NONE }, #endif +#ifndef ARCH_amd64 /* DAA 0x27 1 */ { "daa", 0x27, OP1F, AOT_NONE, AOT_NONE, AOT_NONE }, +#endif +#ifndef ARCH_amd64 /* DAS 0x2f 1 */ { "das", 0x2f, OP1F, AOT_NONE, AOT_NONE, AOT_NONE }, +#endif +#ifndef ARCH_amd64 /* DEC 0x48 +rd 1 */ { "dec", 0x48, OP1F, OP_AX, AOT_NONE, AOT_NONE }, { "dec", 0x49, OP1F, OP_CX, AOT_NONE, AOT_NONE }, @@ -350,6 +359,7 @@ { "dec", 0x4d, OP1F, OP_BP, AOT_NONE, AOT_NONE }, { "dec", 0x4e, OP1F, OP_SI, AOT_NONE, AOT_NONE }, { "dec", 0x4f, OP1F, OP_DI, AOT_NONE, AOT_NONE }, +#endif /* DEC 0xfe /1 1 r/m8 */ { "decb", 0xfe, OP1F, OP_RM8_D0+1,AOT_NONE, AOT_NONE }, { "decb", 0xfe, OP1F, OP_RM8_D8+1,AOT_NONE, AOT_NONE }, diff --git a/src/arch/project.conf b/src/arch/project.conf index 5fb2c35..59a0e0b 100644 --- a/src/arch/project.conf +++ b/src/arch/project.conf @@ -2,7 +2,7 @@ targets=amd64,dalvik,i386,i386_real,i486,i586,i686,java,sparc,sparc64 cppflags_force=-I ../../include cflags_force=-W `pkg-config --cflags libSystem` cflags=-Wall -g -O2 -fPIC -pedantic -dist=Makefile,amd64.reg,common.ins,dalvik.ins,dalvik.reg,i386.h,i386.ins,i386.reg,i486.ins,i586.ins,i686.ins,i686.reg,null.ins,sparc.h,sparc.ins,sparc.reg +dist=Makefile,amd64.ins,amd64.reg,common.ins,dalvik.ins,dalvik.reg,i386.h,i386.ins,i386.reg,i486.ins,i586.ins,i686.ins,i686.reg,null.ins,sparc.h,sparc.ins,sparc.reg [amd64] type=plugin @@ -10,7 +10,7 @@ sources=amd64.c install=$(LIBDIR)/asm/arch [amd64.c] -depends=amd64.reg,common.ins,null.ins,i386.h,i386.ins,i386.reg,i486.ins,i686.ins,i686.reg +depends=amd64.ins,amd64.reg,common.ins,null.ins,i386.h,i386.ins,i386.reg,i486.ins,i686.ins,i686.reg [dalvik] type=plugin