From: <mic...@us...> - 2007-04-20 22:55:51
|
Revision: 78 http://svn.sourceforge.net/pearcolator/?rev=78&view=rev Author: michael_baer Date: 2007-04-20 15:55:52 -0700 (Fri, 20 Apr 2007) Log Message: ----------- Fixed various bugs in ARM disassembler and interpreter Modified Paths: -------------- src/org/binarytranslator/arch/arm/decoder/ARM_Disassembler.java src/org/binarytranslator/arch/arm/decoder/ARM_InstructionDecoder.java src/org/binarytranslator/arch/arm/decoder/ARM_InstructionVisitor.java src/org/binarytranslator/arch/arm/decoder/ARM_Instructions.java src/org/binarytranslator/arch/arm/decoder/ARM_Interpreter.java src/org/binarytranslator/arch/arm/os/process/linux/ARM_LinuxProcessSpace.java Modified: src/org/binarytranslator/arch/arm/decoder/ARM_Disassembler.java =================================================================== --- src/org/binarytranslator/arch/arm/decoder/ARM_Disassembler.java 2007-04-20 22:15:52 UTC (rev 77) +++ src/org/binarytranslator/arch/arm/decoder/ARM_Disassembler.java 2007-04-20 22:55:52 UTC (rev 78) @@ -1,7 +1,7 @@ package org.binarytranslator.arch.arm.decoder; import org.binarytranslator.arch.arm.decoder.ARM_Instructions.Instruction; -import org.binarytranslator.arch.arm.decoder.ARM_Instructions.BlockDataTransfer; +import org.binarytranslator.arch.arm.decoder.ARM_Instructions.MultipleDataTransfer; import org.binarytranslator.arch.arm.decoder.ARM_Instructions.Branch; import org.binarytranslator.arch.arm.decoder.ARM_Instructions.BranchExchange; import org.binarytranslator.arch.arm.decoder.ARM_Instructions.CoprocessorDataProcessing; @@ -188,11 +188,18 @@ String mnemonic = instr.getOpcode().name(); mnemonic += cond(instr); + String parameters; + + if (instr.getOpcode() == DataProcessing.Opcode.CMN || + instr.getOpcode() == DataProcessing.Opcode.CMP) { + //these functions don't use the destination register and always set the condition codes + setResult(String.format("%s r%s, %s", mnemonic, instr.getRn(), operand(instr.getOperand2()))); + return; + } + if (instr.updateConditionCodes()) mnemonic += 'S'; - String parameters; - // Filter instructions that only take one parameter if (instr.getOpcode() == DataProcessing.Opcode.MOV || instr.getOpcode() == DataProcessing.Opcode.MVN @@ -212,12 +219,22 @@ String address = "[r" + instr.getRn(); if (instr.preIndexing()) { - address += ", " + operand(instr.getOffset()) + "]"; + address += ", "; + + if (!instr.positiveOffset()) + address += '-'; + + address += operand(instr.getOffset()) + ']'; if (instr.writeBack()) address += '!'; } else { - address += "], " + operand(instr.getOffset()); + address += "], "; + + if (!instr.positiveOffset()) + address += '-'; + + address += operand(instr.getOffset()); } mnemonic += cond(instr); @@ -287,7 +304,7 @@ instr.getRd(), instr.getRm(), instr.getRn())); } - public void visit(BlockDataTransfer instr) { + public void visit(MultipleDataTransfer instr) { String mnemonic = instr.isLoad() ? "LDM" : "STM"; String baseRegister = "r" + instr.getBaseRegister(); Modified: src/org/binarytranslator/arch/arm/decoder/ARM_InstructionDecoder.java =================================================================== --- src/org/binarytranslator/arch/arm/decoder/ARM_InstructionDecoder.java 2007-04-20 22:15:52 UTC (rev 77) +++ src/org/binarytranslator/arch/arm/decoder/ARM_InstructionDecoder.java 2007-04-20 22:55:52 UTC (rev 78) @@ -61,8 +61,8 @@ byte bits_7_4 = (byte)Utils.getBits(instr, 4, 7); - if (bits_7_4 == 0 && ((instr & 0x01900000) == 0x01100000)) { - //Utils.getBit(instr, 24) == true && Utils.getBit(instr, 23) == false && Utils.getBit(instr, 20) == true + if (bits_7_4 == 0 && ((instr & 0x01900000) == 0x01000000)) { + //Utils.getBit(instr, 24) == true && Utils.getBit(instr, 23) == false && Utils.getBit(instr, 20) == false if (Utils.getBit(instr, 21)) return factory.createMoveToStatusRegister(instr); else @@ -276,7 +276,7 @@ static class DefaultFactory implements ARM_InstructionFactory<ARM_Instructions.Instruction> { public Instruction createBlockDataTransfer(int instr) { - return new BlockDataTransfer(instr); + return new MultipleDataTransfer(instr); } public Instruction createBranch(int instr) { Modified: src/org/binarytranslator/arch/arm/decoder/ARM_InstructionVisitor.java =================================================================== --- src/org/binarytranslator/arch/arm/decoder/ARM_InstructionVisitor.java 2007-04-20 22:15:52 UTC (rev 77) +++ src/org/binarytranslator/arch/arm/decoder/ARM_InstructionVisitor.java 2007-04-20 22:55:52 UTC (rev 78) @@ -10,7 +10,7 @@ void visit(IntMultiply instr); void visit(LongMultiply instr); void visit(Swap instr); - void visit(BlockDataTransfer instr); + void visit(MultipleDataTransfer instr); void visit(SoftwareInterrupt instr); void visit(Branch instr); void visit(BranchExchange instr); Modified: src/org/binarytranslator/arch/arm/decoder/ARM_Instructions.java =================================================================== --- src/org/binarytranslator/arch/arm/decoder/ARM_Instructions.java 2007-04-20 22:15:52 UTC (rev 77) +++ src/org/binarytranslator/arch/arm/decoder/ARM_Instructions.java 2007-04-20 22:55:52 UTC (rev 78) @@ -193,7 +193,7 @@ public static OperandWrapper decodeDataProcessingOperand(int instr) { if (Utils.getBit(instr, 25)) { //this is a right-rotated immediate value - byte shiftAmount = (byte)(Utils.getBits(instr, 8, 11) << 2); + byte shiftAmount = (byte)(Utils.getBits(instr, 8, 11) * 2); int value = instr & 0xFF; if (shiftAmount == 0) @@ -707,7 +707,7 @@ } /** Represents a LDM/STM instruction. */ - public static class BlockDataTransfer extends Instruction { + public static class MultipleDataTransfer extends Instruction { /** @see #postIndexing() */ protected final boolean postIndexing; @@ -730,10 +730,10 @@ /** Contains a set bit at position N if rN should be transferred using this instruction.*/ protected final int registerList; - public BlockDataTransfer(int instr) { + public MultipleDataTransfer(int instr) { super(instr); - postIndexing = Utils.getBit(instr, 24); + postIndexing = !Utils.getBit(instr, 24); incrementBase = Utils.getBit(instr, 23); forceUser = Utils.getBit(instr, 22); writeBack = Utils.getBit(instr, 21); @@ -820,7 +820,7 @@ public Branch(int instr) { super(instr); link = Utils.getBit(instr, 24); - offset = Utils.signExtend((instr & 0xFFF) << 2, 14); + offset = Utils.signExtend((instr & 0xFFFFFF) << 2, 26); } /** Should the current PC be put into the lr? */ Modified: src/org/binarytranslator/arch/arm/decoder/ARM_Interpreter.java =================================================================== --- src/org/binarytranslator/arch/arm/decoder/ARM_Interpreter.java 2007-04-20 22:15:52 UTC (rev 77) +++ src/org/binarytranslator/arch/arm/decoder/ARM_Interpreter.java 2007-04-20 22:55:52 UTC (rev 78) @@ -68,8 +68,16 @@ } public void execute() { - if (isConditionTrue()) + if (isConditionTrue()) { conditionalInstruction.execute(); + + int nextInstruction = conditionalInstruction.getSuccessor(ps.getCurrentInstructionAddress()); + + if (nextInstruction != -1) + ps.setCurrentInstructionAddress(nextInstruction); + } + else + ps.setCurrentInstructionAddress(ps.getCurrentInstructionAddress()+4); } public int getSuccessor(int pc) { @@ -135,6 +143,11 @@ throw new RuntimeException("Unexpected condition code: " + conditionalInstruction.getCondition()); } } + + @Override + public String toString() { + return conditionalInstruction.toString(); + } } /** A base class for all data processing interpreter instructions, including CLZ.*/ @@ -658,11 +671,11 @@ } /** Transfer multiple registers at once between the register bank and the memory. */ - private class BlockDataTransfer extends ARM_Instructions.BlockDataTransfer + private class BlockDataTransfer extends ARM_Instructions.MultipleDataTransfer implements ARM_Instruction { /** the lowest address that we're reading a register from / writing a register to */ - private final int startAddress; + private final int registerCount; /** An array that contains the registers to be transferd in ascending order. * The list is delimited by setting the entry after the last register index to -1. @@ -676,38 +689,40 @@ super(instr); transferPC = transferRegister(15); - int registerCount = 0; + int regCount = 0; for (int i = 0; i < 14; i++) if (transferRegister(i)) { - registersToTransfer[registerCount++] = i; + registersToTransfer[regCount++] = i; } - registersToTransfer[registerCount] = -1; + registersToTransfer[regCount] = -1; + + registerCount = regCount; + } + public void execute() { //build the address, which generally ignores the last two bits + int startAddress = regs.get(baseRegister) & 0xFFFFFFFC; + if (!incrementBase) { if (postIndexing) { //post-indexing, backward reading - startAddress = regs.get(baseRegister) & 0xFFFFFFFC - - (registerCount + (transferPC ? -1 : 0)) * 4; + startAddress -= (registerCount + (transferPC ? 1 : 0)) * 4; } else { //pre-indexing, backward-reading - startAddress = regs.get(baseRegister) & 0xFFFFFFFC - - (registerCount + (transferPC ? 1 : 0)) * 4; + startAddress -= (registerCount + (transferPC ? 2 : 1)) * 4; } } else { if (postIndexing) { //post-indexing, forward reading - startAddress = regs.get(baseRegister) & 0xFFFFFFFC - 4; + startAddress -= 4; } else { //pre-indexing, forward reading - startAddress = regs.get(baseRegister) & 0xFFFFFFFC; + //no need to adjust the start address + } } - } - - public void execute() { int nextAddress = startAddress; //are we supposed to load or store multiple registers? @@ -747,9 +762,22 @@ if (writeBack) { //write the last address we read from back to a register - //TODO: Check if we have to consider the different cases? - if (!incrementBase) - nextAddress = startAddress; + if (!incrementBase) { + //backward reading + if (postIndexing) { + //backward reading, post-indexing + nextAddress = startAddress; + } + else { + //backward reading, pre-indexing + nextAddress = startAddress + 4; + } + } + else { + //forward reading + if (postIndexing) + nextAddress += 4; + } regs.set(baseRegister, nextAddress); } @@ -954,32 +982,27 @@ //if we are not pre-indexing, then just use the base register for the memory access if (!preIndexing) return base; + + int addrOffset; switch (offset.getType()) { case Immediate: - if (positiveOffset) - return base + offset.getImmediate(); - else - return base - offset.getImmediate(); + addrOffset = offset.getImmediate(); + break; case Register: - int offsetRegister = regs.get(offset.getRegister()); + addrOffset = regs.get(offset.getRegister()); if (offset.getRegister() == ARM_Registers.PC) { - offsetRegister += 8; + addrOffset += 8; } + break; - if (positiveOffset) - return base + offsetRegister; - else - return base - offsetRegister; - case ImmediateShiftedRegister: + addrOffset = regs.get(offset.getRegister()); + if (offset.getRegister() == 15) - throw new RuntimeException( - "PC-relative memory accesses are not yet supported."); + addrOffset += 8; - int addrOffset = regs.get(offset.getRegister()); - switch (offset.getShiftType()) { case ASR: addrOffset = addrOffset >>> offset.getShiftAmount(); @@ -1008,6 +1031,7 @@ throw new RuntimeException("Unexpected shift type: " + offset.getShiftType()); } + break; case PcRelative: case RegisterShiftedRegister: @@ -1015,7 +1039,11 @@ throw new RuntimeException("Unexpected operand type: " + offset.getType()); } - + + if (positiveOffset) + return base + addrOffset; + else + return base - addrOffset; } public void execute() { Modified: src/org/binarytranslator/arch/arm/os/process/linux/ARM_LinuxProcessSpace.java =================================================================== --- src/org/binarytranslator/arch/arm/os/process/linux/ARM_LinuxProcessSpace.java 2007-04-20 22:15:52 UTC (rev 77) +++ src/org/binarytranslator/arch/arm/os/process/linux/ARM_LinuxProcessSpace.java 2007-04-20 22:55:52 UTC (rev 78) @@ -9,6 +9,7 @@ import org.binarytranslator.generic.os.abi.linux.LinuxSystemCallGenerator; import org.binarytranslator.generic.os.abi.linux.LinuxSystemCalls; import org.binarytranslator.generic.os.loader.Loader; +import org.binarytranslator.generic.os.loader.elf.ELF_Loader; import org.binarytranslator.generic.os.process.ProcessSpace; public class ARM_LinuxProcessSpace extends ARM_ProcessSpace implements @@ -51,13 +52,13 @@ this.brk = brk; // initialize the stack - int[] auxVector = { LinuxStackInitializer.AuxiliaryVectorType.AT_SYSINFO, - 0xffffe400, LinuxStackInitializer.AuxiliaryVectorType.AT_SYSINFO_EHDR, - 0xffffe000, LinuxStackInitializer.AuxiliaryVectorType.AT_HWCAP, - 0x78bfbff, LinuxStackInitializer.AuxiliaryVectorType.AT_PAGESZ, 0x1000, + int[] auxVector = {//LinuxStackInitializer.AuxiliaryVectorType.AT_SYSINFO, 0xffffe400, + //LinuxStackInitializer.AuxiliaryVectorType.AT_SYSINFO_EHDR, 0xffffe000, + LinuxStackInitializer.AuxiliaryVectorType.AT_HWCAP, 0x78bfbff, + LinuxStackInitializer.AuxiliaryVectorType.AT_PAGESZ, 0x1000, LinuxStackInitializer.AuxiliaryVectorType.AT_CLKTCK, 0x64, - LinuxStackInitializer.AuxiliaryVectorType.AT_PHDR, 0xBADADD8E, - LinuxStackInitializer.AuxiliaryVectorType.AT_PHNUM, 0xBAD2BAD2, + LinuxStackInitializer.AuxiliaryVectorType.AT_PHDR, ((ELF_Loader)loader).getProgramHeaderAddress(), + LinuxStackInitializer.AuxiliaryVectorType.AT_PHNUM, ((ELF_Loader)loader).elfHeader.getNumberOfProgramSegmentHeaders(), LinuxStackInitializer.AuxiliaryVectorType.AT_BASE, 0x0, LinuxStackInitializer.AuxiliaryVectorType.AT_FLAGS, 0x0, LinuxStackInitializer.AuxiliaryVectorType.AT_ENTRY, pc, @@ -68,9 +69,10 @@ LinuxStackInitializer.AuxiliaryVectorType.AT_EGID, DBT_Options.GID, LinuxStackInitializer.AuxiliaryVectorType.AT_SECURE, 0, - LinuxStackInitializer.AuxiliaryVectorType.AT_NULL, 0x0 }; + //LinuxStackInitializer.AuxiliaryVectorType.AT_PLATFORM, LinuxStackInitializer.AuxiliaryVectorType.STACK_TOP - getPlatformString().length, + LinuxStackInitializer.AuxiliaryVectorType.AT_NULL, 0x0}; - LinuxStackInitializer.stackInit(memory, STACK_TOP, getEnvironmentVariables(), auxVector); + registers.set(ARM_Registers.SP, LinuxStackInitializer.stackInit(memory, STACK_TOP, getEnvironmentVariables(), auxVector)); } public int getBrk() { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |