From: <cap...@us...> - 2007-04-24 23:01:36
|
Revision: 91 http://svn.sourceforge.net/pearcolator/?rev=91&view=rev Author: captain5050 Date: 2007-04-24 16:01:32 -0700 (Tue, 24 Apr 2007) Log Message: ----------- IA32 implementation of set_thread_area, support for ld/st mxcsr, various other improvements. Running crashes as IA32 interpreter controller not yet implemented. Modified Paths: -------------- src/org/binarytranslator/arch/x86/decoder/X862IR.java src/org/binarytranslator/arch/x86/decoder/X86_DecodedOperand.java src/org/binarytranslator/arch/x86/decoder/X86_InstructionDecoder.java src/org/binarytranslator/arch/x86/os/abi/linux/X86_LinuxSystemCalls.java src/org/binarytranslator/arch/x86/os/process/X86_Registers.java src/org/binarytranslator/generic/os/abi/linux/LinuxSystemCalls.java Modified: src/org/binarytranslator/arch/x86/decoder/X862IR.java =================================================================== --- src/org/binarytranslator/arch/x86/decoder/X862IR.java 2007-04-24 18:16:44 UTC (rev 90) +++ src/org/binarytranslator/arch/x86/decoder/X862IR.java 2007-04-24 23:01:32 UTC (rev 91) @@ -39,7 +39,8 @@ private static final VM_FieldReference flagZFref; private static final VM_FieldReference flagOFref; private static final VM_FieldReference flagDFref; - + private static final VM_FieldReference gsBaseAddrFref; + private static final VM_FieldReference mxcsrFref; static { psTref = VM_TypeReference.findOrCreate( VM_BootstrapClassLoader.getBootstrapClassLoader(), @@ -86,8 +87,16 @@ flagDFref = VM_MemberReference.findOrCreate( registersTref, VM_Atom.findOrCreateAsciiAtom("flag_DF"), VM_Atom.findOrCreateAsciiAtom("Z")).asFieldReference(); - } + gsBaseAddrFref = VM_MemberReference.findOrCreate( + registersTref, VM_Atom.findOrCreateAsciiAtom("gsBaseAddr"), + VM_Atom.findOrCreateAsciiAtom("I")).asFieldReference(); + + mxcsrFref = VM_MemberReference.findOrCreate( + registersTref, VM_Atom.findOrCreateAsciiAtom("mxcsr"), + VM_Atom.findOrCreateAsciiAtom("I")).asFieldReference(); + } + /** * Constructor */ @@ -110,11 +119,8 @@ /** * Translate the instruction at the given pc - * - * @param lazy - * the status of the lazy evaluation - * @param pc - * the program counter for the instruction + * @param lazy the status of the lazy evaluation + * @param pc the program counter for the instruction * @return the next instruction address or -1 */ protected int translateInstruction(Laziness lazy, int pc) { @@ -203,11 +209,8 @@ /** * Resolve a 32bit register - * - * @param laziness - * the lazy state, used to determine register mangling - * @param r - * the register to resolve + * @param laziness the lazy state, used to determine register mangling + * @param r the register to resolve */ private void resolveGPRegister32(X86_Laziness laziness, int r) { if (laziness.is32bitRegisterValid(r) == false) { @@ -250,11 +253,8 @@ /** * Read a 32bit register - * - * @param laziness - * the lazy state, used to determine register mangling - * @param r - * the register to read + * @param laziness the lazy state, used to determine register mangling + * @param r the register to read */ public OPT_RegisterOperand getSegRegister(X86_Laziness laziness, int r) { SegRegInUse[r] = true; @@ -262,12 +262,34 @@ } /** + * Add a segment base address to the given address + * @param segment segment to get base address for + * @param address the address to add the value onto + */ + public void addSegmentBaseAddress(int segment, OPT_RegisterOperand address) { + switch(segment) { + case X86_Registers.GS: { + OPT_RegisterOperand temp = getTempInt(9); + appendInstructionToCurrentBlock(GetField.create(GETFIELD, + temp, new OPT_RegisterOperand(ps_registers, registersTref), + new OPT_AddressConstantOperand(gsBaseAddrFref.peekResolvedField().getOffset()), + new OPT_LocationOperand(gsBaseAddrFref), + new OPT_TrueGuardOperand())); + appendInstructionToCurrentBlock(Binary.create(INT_ADD, + address.copyRO(), address.copyRO(), temp.copyRO())); + break; + } + case X86_Registers.FS: + throw new Error("Unhandled segment override FS"); + default: + break; + } + } + + /** * Read a 32bit register - * - * @param laziness - * the lazy state, used to determine register mangling - * @param r - * the register to read + * @param laziness the lazy state, used to determine register mangling + * @param r the register to read */ public OPT_RegisterOperand getGPRegister32(X86_Laziness laziness, int r) { GP32InUse[r] = true; @@ -277,11 +299,8 @@ /** * Read a 16bit register - * - * @param laziness - * the lazy state, used to determine register mangling - * @param r - * the register to read + * @param laziness the lazy state, used to determine register mangling + * @param r the register to read */ public OPT_RegisterOperand getGPRegister16(X86_Laziness laziness, int r) { GP32InUse[r] = true; @@ -324,11 +343,8 @@ /** * Read a 8bit register - * - * @param laziness - * the lazy state, used to determine register mangling - * @param r - * the register to read + * @param laziness the lazy state, used to determine register mangling + * @param r the register to read */ public OPT_RegisterOperand getGPRegister8(X86_Laziness laziness, int r) { int rl, rh; // low and high 8bit registers @@ -375,11 +391,8 @@ /** * Read a 8bit register - * - * @param laziness - * the lazy state, used to determine register mangling - * @param r - * the register to read + * @param laziness the lazy state, used to determine register mangling + * @param r the register to read */ public OPT_RegisterOperand getGPRegister(X86_Laziness laziness, int r, int size) { @@ -396,6 +409,14 @@ } } + /** + * Read the MXCSR register + */ + public OPT_RegisterOperand getMXCSR() { + ps_registers_mxcsr_InUse = true; + return new OPT_RegisterOperand(ps_registers_mxcsr, VM_TypeReference.Int); + } + // -- status flags /** * X86 flag register constituants - bit 0 - CF or carry flag @@ -537,6 +558,16 @@ private OPT_Register ps_registers_gp32; /** + * X87 mxcsr register + */ + private OPT_Register ps_registers_mxcsr; + + /** + * Was the register used during the trace? + */ + private boolean ps_registers_mxcsr_InUse; + + /** * Fill all the registers from the ProcessSpace, that is take the register * values from the process space and place them in the traces registers. */ @@ -608,6 +639,21 @@ new OPT_LocationOperand(VM_TypeReference.Int), new OPT_TrueGuardOperand())); } + // Fill MXCSR + { + OPT_RegisterOperand ps_registers_mxcsr_Op; + if (ps_registers_mxcsr == null) { + ps_registers_mxcsr_Op = makeTemp(VM_TypeReference.Int); + ps_registers_mxcsr = ps_registers_mxcsr_Op.register; + } else { + ps_registers_mxcsr_Op = new OPT_RegisterOperand(flag_CF, VM_TypeReference.Boolean); + } + appendInstructionToCurrentBlock(GetField.create(GETFIELD, ps_registers_mxcsr_Op, + ps_registersOp.copyRO(), + new OPT_AddressConstantOperand(mxcsrFref.peekResolvedField().getOffset()), + new OPT_LocationOperand(mxcsrFref), + new OPT_TrueGuardOperand())); + } // Fill flags { OPT_RegisterOperand flag_CF_Op; @@ -716,14 +762,25 @@ new OPT_TrueGuardOperand())); } } - // Spill flags OPT_RegisterOperand ps_registersOp = new OPT_RegisterOperand(ps_registers, registersTref); + // Spill mxcsr { + OPT_RegisterOperand ps_registers_mxcsr_Op = + new OPT_RegisterOperand(ps_registers_mxcsr, VM_TypeReference.Int); + appendInstructionToCurrentBlock(GetField.create(PUTFIELD, + ps_registers_mxcsr_Op, ps_registersOp, + new OPT_AddressConstantOperand(mxcsrFref.peekResolvedField().getOffset()), + new OPT_LocationOperand(mxcsrFref), + new OPT_TrueGuardOperand())); + } + + // Spill flags + { OPT_RegisterOperand flag_CF_Op = new OPT_RegisterOperand(flag_CF, VM_TypeReference.Boolean); appendInstructionToCurrentBlock(GetField.create(PUTFIELD, - flag_CF_Op, ps_registersOp, + flag_CF_Op, ps_registersOp.copyRO(), new OPT_AddressConstantOperand(flagCFref.peekResolvedField().getOffset()), new OPT_LocationOperand(flagCFref), new OPT_TrueGuardOperand())); @@ -777,9 +834,7 @@ /** * Plant instructions modifying a lazy state into one with no laziness - * - * @param laziness - * the laziness to modify + * @param laziness the laziness to modify */ public void resolveLaziness(Laziness laziness) { for (int i = 0; i < GP32.length; i++) { @@ -807,6 +862,10 @@ // ignore GP16 and GP8 registers as they are only created lazily, // and so must be in use + // Add MXCSR + if (ps_registers_mxcsr_InUse == false) { + unusedRegisterList.add(ps_registers_mxcsr); + } // Add flags if (flag_CF_InUse == false) { unusedRegisterList.add(flag_CF); Modified: src/org/binarytranslator/arch/x86/decoder/X86_DecodedOperand.java =================================================================== --- src/org/binarytranslator/arch/x86/decoder/X86_DecodedOperand.java 2007-04-24 18:16:44 UTC (rev 90) +++ src/org/binarytranslator/arch/x86/decoder/X86_DecodedOperand.java 2007-04-24 23:01:32 UTC (rev 91) @@ -248,7 +248,7 @@ * The size of the operand */ final int operandSize; - + /** * Constructor */ @@ -271,11 +271,7 @@ this.base = base; this.scale = scale; this.index = index; - if (segment == X86_Registers.GS){ - this.displacement = displacement + 0xffffe000; - } else { - this.displacement = displacement; - } + this.displacement = displacement; this.addressSize = addressSize; this.operandSize = operandSize; } @@ -285,7 +281,7 @@ */ void readToRegister(X862IR translationHelper, X86_Laziness lazy, OPT_RegisterOperand op) { - OPT_RegisterOperand address = translationHelper.getTempInt(9); + OPT_RegisterOperand address = translationHelper.getTempInt(8); readEffectiveAddress(translationHelper, lazy, address); // Perform the load switch (operandSize) { @@ -308,7 +304,7 @@ */ void writeValue(X862IR translationHelper, X86_Laziness lazy, OPT_RegisterOperand op) { - OPT_RegisterOperand address = translationHelper.getTempInt(9); + OPT_RegisterOperand address = translationHelper.getTempInt(8); readEffectiveAddress(translationHelper, lazy, address); // Perform the store switch (operandSize) { @@ -356,5 +352,7 @@ address.copyRO(), address.copyRO(), new OPT_IntConstantOperand( displacement))); } + // Add on any base address from a segment override + translationHelper.addSegmentBaseAddress(segment, address); } } Modified: src/org/binarytranslator/arch/x86/decoder/X86_InstructionDecoder.java =================================================================== --- src/org/binarytranslator/arch/x86/decoder/X86_InstructionDecoder.java 2007-04-24 18:16:44 UTC (rev 90) +++ src/org/binarytranslator/arch/x86/decoder/X86_InstructionDecoder.java 2007-04-24 23:01:32 UTC (rev 91) @@ -127,8 +127,10 @@ /* 0x15 */null, /* 0x16 */null, /* 0x17 */null, - /* 0x18 */null, - /* 0x19 */null, + /* 0x18 */new X86_Sbb_OpcodeDecoder(8, true, 0, true), + // 8bit, has ModRM, no imm, rm is dest + /* 0x19 */new X86_Sbb_OpcodeDecoder(_16BIT ? 16 : 32, true, 0, true), + // 16/32bit, has ModRM, no imm, rm is dest /* 0x1A */null, /* 0x1B */null, /* 0x1C */null, @@ -136,28 +138,16 @@ /* 0x1E */null, /* 0x1F */null, - /* 0x20 */new X86_And_OpcodeDecoder(8, true, 0, true), // 8bit, has - // ModRM, no imm, - // rm is dest - /* 0x21 */new X86_And_OpcodeDecoder(_16BIT ? 16 : 32, true, 0, true), // 16/32bit,has - // ModRM, - // no - // imm, - // rm - // is - // dest - /* 0x22 */new X86_And_OpcodeDecoder(8, true, 0, false),// 8bit, has - // ModRM, no imm, - // rm is src - /* 0x23 */new X86_And_OpcodeDecoder(_16BIT ? 16 : 32, true, 0, false),// 16/32bit,has - // ModRM, - // no - // imm, - // rm - // is - // src - /* 0x24 */new X86_And_OpcodeDecoder(8, false, 8, false),// 8bit, no ModRM, - // 8bit imm + /* 0x20 */new X86_And_OpcodeDecoder(8, true, 0, true), + // 8bit, has ModRM, no imm, rm is dest + /* 0x21 */new X86_And_OpcodeDecoder(_16BIT ? 16 : 32, true, 0, true), + // 16/32bit, has ModRM, no imm, rm is dest + /* 0x22 */new X86_And_OpcodeDecoder(8, true, 0, false), + // 8bit, has ModRM, no imm, rm is src + /* 0x23 */new X86_And_OpcodeDecoder(_16BIT ? 16 : 32, true, 0, false), + // 16/32bit, has ModRM, no imm, rm is src + /* 0x24 */new X86_And_OpcodeDecoder(8, false, 8, false), + // 8bit, no ModRM, 8bit imm /* 0x25 */new X86_And_OpcodeDecoder(_16BIT ? 16 : 32, false, _16BIT ? 16 : 32, false),// 16/32bit, no ModRM, 16/32bit imm /* 0x26 */new X86_ES_SegmentOverride_PrefixDecoder(), @@ -303,9 +293,9 @@ /* 0x67 */new X86_AddressSizeOverride_PrefixDecoder(), /* 0x68 */new X86_Push_OpcodeDecoder(_16BIT ? -16 : -32), // Push 16/32bit // immediate - /* 0x69 */null, + /* 0x69 */new X86_Imul_OpcodeDecoder(_16BIT ? 16 : 32, _16BIT ? 16 : 32, false), /* 0x6A */new X86_Push_OpcodeDecoder(-8), // Push 8bit immediate - /* 0x6B */null, + /* 0x6B */new X86_Imul_OpcodeDecoder(_16BIT ? 16 : 32, 8, false), /* 0x6C */null, /* 0x6D */null, /* 0x6E */null, @@ -1919,7 +1909,7 @@ /** * Look up table to find secondary opcode translator */ - private static final X86_OpcodeDecoder[] secondaryOpcodes = { + private static final X86_InstructionDecoder[] secondaryOpcodes = { /* 0x00 */null, /* 0x01 */null, /* 0x02 */null, @@ -2104,12 +2094,21 @@ /* 0xAB */null, /* 0xAC */null, /* 0xAD */null, - /* 0xAE */null, + /* 0xAE */new X86_OpcodeInModRMReg_Decoder(new X86_OpcodeDecoder[] { + null,// 0 + null,// 1 + new X86_LdMXCSR_OpcodeDecoder(),// 2 + new X86_StMXCSR_OpcodeDecoder(),// 3 + null,// 4 + null,// 5 + null,// 6 + null // 7 + }), /* 0xAF */new X86_Imul_OpcodeDecoder(_16BIT ? 16 : 32, 0, false), // 16/32bit, no imm, not edx:eax - /* 0xB0 */null, - /* 0xB1 */null, + /* 0xB0 */new X86_CmpXChg_OpcodeDecoder(8), + /* 0xB1 */new X86_CmpXChg_OpcodeDecoder(_16BIT ? 16 : 32), /* 0xB2 */null, /* 0xB3 */null, /* 0xB4 */null, @@ -2406,6 +2405,93 @@ } /** + * The decoder for the Cmp opcode + */ +class X86_CmpXChg_OpcodeDecoder extends X86_OpcodeDecoder { + /** + * Constructor, {@see X86_OpcodeDecoder} + */ + X86_CmpXChg_OpcodeDecoder(int size) { + super(size, true, 0, true); + } + + /** + * Perform the actual translation + * @param translationHelper + * @param ps + * @param lazy + * @param pc the address of the instruction being translated + * @param modrm the decoder for any modrm part of the instruction + * @param sib the sib decoder for any sib part of the instruction + * @param displacement any displacement to be added to the modrm + * @param immediateSize what size is the immediate value + * @param immediate if immediateSize > 0 then this is the immediate value + * @param length the length of the instruction + * @param prefix2 a group2 prefix decoder or null + * @param prefix3 a group3 prefix decoder or null + * @param prefix4 a group4 prefix decoder or null + * @param prefix5 a group5 prefix decoder or null + */ + protected int translate(X862IR translationHelper, ProcessSpace ps, + X86_Laziness lazy, int pc, X86_ModRM_Decoder modrm, X86_SIB_Decoder sib, + int displacement, int immediateSize, int immediate, int length, + X86_Group2PrefixDecoder prefix2, X86_Group3PrefixDecoder prefix3, + X86_Group4PrefixDecoder prefix4, X86_Group5PrefixDecoder prefix5) { + int operandSize; + if (prefix3 == null) { + operandSize = this.operandSize; + } else { + switch (this.operandSize) { + case 32: + operandSize = 16; + break; + case 16: + operandSize = 32; + break; + default: + operandSize = -1; + DBT_OptimizingCompilerException.UNREACHABLE(); + } + } + int addressSize; + if (prefix4 == null) { + addressSize = _16BIT ? 16 : 32; + } else { + addressSize = _16BIT ? 32 : 16; + } + + X86_DecodedOperand destination = modrm.getRM(translationHelper, lazy, sib, displacement, + operandSize, addressSize, (prefix2 != null) ? prefix2.getSegment() + : X86_Registers.DS); + X86_DecodedOperand source = modrm.getReg(operandSize); + + + OPT_RegisterOperand newValue = translationHelper.getTempInt(0); + OPT_RegisterOperand oldValue = translationHelper.getTempInt(1); + + source.readToRegister(translationHelper, lazy, newValue); + destination.readToRegister(translationHelper, lazy, oldValue); + OPT_RegisterOperand expected = translationHelper.getGPRegister(lazy, X86_Registers.EAX, operandSize); + + translationHelper.appendInstructionToCurrentBlock(CondMove.create(INT_COND_MOVE, + newValue.copyRO(), + expected, oldValue.copyRO(), OPT_ConditionOperand.EQUAL(), + newValue.copyRO(), oldValue.copyRO() + )); + + destination.writeValue(translationHelper, lazy, newValue.copyRO()); + return pc + length; + } + + /** + * Return "cmpxchg" + */ + String getOperatorString() { + return "cmpxchg"; + } +} + +/** * The decoder for the Mov opcode */ class X86_Mov_OpcodeDecoder extends X86_OpcodeDecoder { @@ -2949,7 +3035,6 @@ * Return the SBB operator */ OPT_Operator getOperator() { - TODO(); return INT_SUB; } @@ -4207,7 +4292,88 @@ } } } +/** + * The decoder for the STMXCSR opcode + */ +class X86_StMXCSR_OpcodeDecoder extends X86_OpcodeDecoder { + /** + * Constructor, {@see X86_OpcodeDecoder} + */ + X86_StMXCSR_OpcodeDecoder() { + super(32, // operandSize + true, // hasModRM, + 0, // immediateSize + true // isMemoryOperandDestination + ); + } + /** + * Perform the actual translation + * @param translationHelper + * @param ps + * @param lazy + * @param pc the address of the instruction being translated + * @param modrm the decoder for any modrm part of the instruction + * @param sib the sib decoder for any sib part of the instruction + * @param displacement any displacement to be added to the modrm + * @param immediateSize what size is the immediate value + * @param immediate if immediateSize > 0 then this is the immediate value + * @param length the length of the instruction + * @param prefix2 a group2 prefix decoder or null + * @param prefix3 a group3 prefix decoder or null + * @param prefix4 a group4 prefix decoder or null + * @param prefix5 a group5 prefix decoder or null + */ + protected int translate(X862IR translationHelper, ProcessSpace ps, + X86_Laziness lazy, int pc, X86_ModRM_Decoder modrm, X86_SIB_Decoder sib, + int displacement, int immediateSize, int immediate, int length, + X86_Group2PrefixDecoder prefix2, X86_Group3PrefixDecoder prefix3, + X86_Group4PrefixDecoder prefix4, X86_Group5PrefixDecoder prefix5) { + int addressSize; + if (prefix4 == null) { + addressSize = _16BIT ? 16 : 32; + } else { + addressSize = _16BIT ? 32 : 16; + } + + X86_DecodedOperand destination = modrm.getRM(translationHelper, lazy, sib, displacement, + 32, addressSize, (prefix2 != null) ? prefix2.getSegment() : X86_Registers.DS); + + OPT_RegisterOperand mxcsr = translationHelper.getMXCSR(); + destination.writeValue(translationHelper, lazy, mxcsr); + return pc + length; + } + + /** + * Disassemble the opcode + * @param ps + * @param pc the address of the instruction being translated + * @param modrm the decoder for any modrm part of the instruction + * @param sib the sib decoder for any sib part of the instruction + * @param displacement any displacement to be added to the modrm + * @param immediateSize what size is the immediate value + * @param immedate if immediateSize > 0 then this is the immediate value + * @param length the length of the instruction + * @param prefix2 a group2 prefix decoder or null + * @param prefix3 a group3 prefix decoder or null + * @param prefix4 a group4 prefix decoder or null + * @param prefix5 a group5 prefix decoder or null + */ + protected String disassemble(ProcessSpace ps, int pc, + X86_ModRM_Decoder modrm, X86_SIB_Decoder sib, int displacement, + int immediateSize, int immediate, int length, + X86_Group2PrefixDecoder prefix2, X86_Group3PrefixDecoder prefix3, + X86_Group4PrefixDecoder prefix4, X86_Group5PrefixDecoder prefix5) { + int addressSize; + if (prefix4 == null) { + addressSize = _16BIT ? 16 : 32; + } else { + addressSize = _16BIT ? 32 : 16; + } + return "stmxcsr " + modrm.disassembleRM(sib, displacement, 32, addressSize, (prefix2 != null) ? prefix2.getSegment() : X86_Registers.DS); + } +} + /** * The decoder for the Set opcode */ @@ -4571,6 +4737,91 @@ } /** + * The decoder for the LDMXCSR opcode + */ +class X86_LdMXCSR_OpcodeDecoder extends X86_OpcodeDecoder { + /** + * Constructor, {@see X86_OpcodeDecoder} + */ + X86_LdMXCSR_OpcodeDecoder() { + super(32, // operandSize + true, // hasModRM, + 0, // immediateSize + false // isMemoryOperandDestination + ); + } + + /** + * Perform the actual translation + * @param translationHelper + * @param ps + * @param lazy + * @param pc the address of the instruction being translated + * @param modrm the decoder for any modrm part of the instruction + * @param sib the sib decoder for any sib part of the instruction + * @param displacement any displacement to be added to the modrm + * @param immediateSize what size is the immediate value + * @param immediate if immediateSize > 0 then this is the immediate value + * @param length the length of the instruction + * @param prefix2 a group2 prefix decoder or null + * @param prefix3 a group3 prefix decoder or null + * @param prefix4 a group4 prefix decoder or null + * @param prefix5 a group5 prefix decoder or null + */ + protected int translate(X862IR translationHelper, ProcessSpace ps, + X86_Laziness lazy, int pc, X86_ModRM_Decoder modrm, X86_SIB_Decoder sib, + int displacement, int immediateSize, int immediate, int length, + X86_Group2PrefixDecoder prefix2, X86_Group3PrefixDecoder prefix3, + X86_Group4PrefixDecoder prefix4, X86_Group5PrefixDecoder prefix5) { + int addressSize; + if (prefix4 == null) { + addressSize = _16BIT ? 16 : 32; + } else { + addressSize = _16BIT ? 32 : 16; + } + + X86_DecodedOperand source = modrm.getRM(translationHelper, lazy, sib, displacement, + 32, addressSize, (prefix2 != null) ? prefix2.getSegment() : X86_Registers.DS); + + OPT_RegisterOperand temp = translationHelper.getTempInt(0); + source.readToRegister(translationHelper, lazy, temp); + + OPT_RegisterOperand mxcsr = translationHelper.getMXCSR(); + translationHelper.appendInstructionToCurrentBlock(Move.create(INT_MOVE, mxcsr, temp.copyRO())); + return pc + length; + } + + /** + * Disassemble the opcode + * @param ps + * @param pc the address of the instruction being translated + * @param modrm the decoder for any modrm part of the instruction + * @param sib the sib decoder for any sib part of the instruction + * @param displacement any displacement to be added to the modrm + * @param immediateSize what size is the immediate value + * @param immedate if immediateSize > 0 then this is the immediate value + * @param length the length of the instruction + * @param prefix2 a group2 prefix decoder or null + * @param prefix3 a group3 prefix decoder or null + * @param prefix4 a group4 prefix decoder or null + * @param prefix5 a group5 prefix decoder or null + */ + protected String disassemble(ProcessSpace ps, int pc, + X86_ModRM_Decoder modrm, X86_SIB_Decoder sib, int displacement, + int immediateSize, int immediate, int length, + X86_Group2PrefixDecoder prefix2, X86_Group3PrefixDecoder prefix3, + X86_Group4PrefixDecoder prefix4, X86_Group5PrefixDecoder prefix5) { + int addressSize; + if (prefix4 == null) { + addressSize = _16BIT ? 16 : 32; + } else { + addressSize = _16BIT ? 32 : 16; + } + return "ldmxcsr " + modrm.disassembleRM(sib, displacement, 32, addressSize, (prefix2 != null) ? prefix2.getSegment() : X86_Registers.DS); + } +} + +/** * The decoder for the Lea opcode */ class X86_Lea_OpcodeDecoder extends X86_OpcodeDecoder { Modified: src/org/binarytranslator/arch/x86/os/abi/linux/X86_LinuxSystemCalls.java =================================================================== --- src/org/binarytranslator/arch/x86/os/abi/linux/X86_LinuxSystemCalls.java 2007-04-24 18:16:44 UTC (rev 90) +++ src/org/binarytranslator/arch/x86/os/abi/linux/X86_LinuxSystemCalls.java 2007-04-24 23:01:32 UTC (rev 91) @@ -8,8 +8,11 @@ */ package org.binarytranslator.arch.x86.os.abi.linux; +import org.binarytranslator.arch.x86.os.process.X86_ProcessSpace; +import org.binarytranslator.generic.memory.Memory; import org.binarytranslator.generic.os.abi.linux.LinuxSystemCallGenerator; import org.binarytranslator.generic.os.abi.linux.LinuxSystemCalls; +import org.binarytranslator.generic.os.abi.linux.LinuxSystemCalls.SystemCall; /** * Linux system call handling class @@ -40,7 +43,7 @@ systemCallTable[202] = new LinuxSystemCalls.SysGetEGID(); systemCallTable[221] = new LinuxSystemCalls.SysFcntl64(); systemCallTable[252] = new LinuxSystemCalls.SysExitGroup(); - systemCallTable[243] = new LinuxSystemCalls.NullSystemCall(); + systemCallTable[243] = new SetThreadAreaSystemCall(); } /** * The machine for this system given by uname @@ -356,4 +359,45 @@ } } } + /** + * Set the thread area - Set a Thread Local Storage (TLS) area + */ + public class SetThreadAreaSystemCall extends LinuxSystemCalls.SystemCall { + /** + * Handle a system call + */ + public void doSysCall() { + // Ok, we're faking this call at the moment. It's called by glibc to set + // up a TLS area that GS will address. The call will provide -1 asking us + // for a GS segment number and to record the base_addr,... for GS. + Memory mem = src.getProcessSpace().memory; + int user_desc_ptr = arguments.nextInt(); + + int user_desc_entry_number = mem.load32(user_desc_ptr); + System.err.println("entry number="+user_desc_entry_number); + int user_desc_base_addr = mem.load32(user_desc_ptr+4); + System.err.println("base addr="+user_desc_base_addr); + int user_desc_limit = mem.load32(user_desc_ptr+8); + System.err.println("limit="+user_desc_limit); + int packed = mem.load32(user_desc_ptr+12); + System.err.println("packed="+packed); + + boolean user_desc_seg_32bit = (packed & 1) != 0; + int user_desc_contents = (packed >> 1) & 0x3; + boolean user_desc_read_exec_only = ((packed >> 3) & 0x1) != 0; + boolean user_desc_limit_in_pages = ((packed >> 4) & 0x1) != 0; + boolean user_desc_seg_not_present= ((packed >> 4) & 0x1) != 0; + boolean user_desc_useable = ((packed >> 4) & 0x1) != 0; + + if (user_desc_entry_number == -1) { + user_desc_entry_number = 7; + mem.store32(user_desc_ptr, user_desc_entry_number); + ((X86_ProcessSpace)src.getProcessSpace()).registers.writeGS_BaseAddr(user_desc_base_addr); + src.setSysCallReturn(0); + } else { + throw new Error("Unexpected use of set_thread_area"); + } + } + } + } Modified: src/org/binarytranslator/arch/x86/os/process/X86_Registers.java =================================================================== --- src/org/binarytranslator/arch/x86/os/process/X86_Registers.java 2007-04-24 18:16:44 UTC (rev 90) +++ src/org/binarytranslator/arch/x86/os/process/X86_Registers.java 2007-04-24 23:01:32 UTC (rev 91) @@ -85,6 +85,11 @@ */ private char[] segmentRegister = new char[6]; + /** + * Base address to be added onto gs segment overrides + */ + private int gsBaseAddr; + /* * Flags */ @@ -414,7 +419,15 @@ public void writeSeg(int reg, char val) { segmentRegister[reg] = val; } + /** + * Write a segment register value + */ + public void writeGS_BaseAddr(int baseAddr) { + gsBaseAddr = baseAddr; + } + + /** * Read flags */ public int readFlags() { Modified: src/org/binarytranslator/generic/os/abi/linux/LinuxSystemCalls.java =================================================================== --- src/org/binarytranslator/generic/os/abi/linux/LinuxSystemCalls.java 2007-04-24 18:16:44 UTC (rev 90) +++ src/org/binarytranslator/generic/os/abi/linux/LinuxSystemCalls.java 2007-04-24 23:01:32 UTC (rev 91) @@ -157,8 +157,6 @@ files.add(System.in); files.add(System.out); files.add(System.err); - - structures = new LinuxStructureFactory(); } /** @@ -489,7 +487,7 @@ /** * Define the system call interface */ - abstract class SystemCall { + public abstract class SystemCall { /** * Handle a system call */ @@ -514,18 +512,6 @@ } /** - * Null System Call - do nothing just return 0 - */ - public class NullSystemCall extends SystemCall { - /** - * Handle a system call - */ - public void doSysCall() { - src.setSysCallReturn(0); - } - } - - /** * Exit system call */ public class SysExit extends SystemCall { @@ -853,7 +839,6 @@ domainName = localhostString.substring(index + 1); hostName = localhostString.substring(0,index); } - // Fill in utsname struct - see /usr/include/sys/utsname.h memoryWriteString (addr, getSysName()); // sysname memoryWriteString (addr+65, hostName); // nodename This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |