From: <cap...@us...> - 2007-04-23 22:13:20
|
Revision: 89 http://svn.sourceforge.net/pearcolator/?rev=89&view=rev Author: captain5050 Date: 2007-04-23 15:12:34 -0700 (Mon, 23 Apr 2007) Log Message: ----------- Support for move to/from segments, fix for open system call, try to run past unimplemented system calls, fake out x86 set_thread_area syscall with a null system call, try to initialize references as static finals. Modified Paths: -------------- src/org/binarytranslator/DBT_Options.java 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/decoder/X86_ModRM_Decoder.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/DBT_Options.java =================================================================== --- src/org/binarytranslator/DBT_Options.java 2007-04-23 21:57:27 UTC (rev 88) +++ src/org/binarytranslator/DBT_Options.java 2007-04-23 22:12:34 UTC (rev 89) @@ -27,7 +27,7 @@ /** * Are unimplemented system calls are fatal? */ - public final static boolean unimplementedSystemCallsFatal = true; + public final static boolean unimplementedSystemCallsFatal = false; // -oO Translation settings Oo- Modified: src/org/binarytranslator/arch/x86/decoder/X862IR.java =================================================================== --- src/org/binarytranslator/arch/x86/decoder/X862IR.java 2007-04-23 21:57:27 UTC (rev 88) +++ src/org/binarytranslator/arch/x86/decoder/X862IR.java 2007-04-23 22:12:34 UTC (rev 89) @@ -27,6 +27,67 @@ public class X862IR extends DecoderUtils implements OPT_HIRGenerator, OPT_Operators, OPT_Constants { + private static final VM_TypeReference psTref; + private static final VM_FieldReference registersFref; + private static final VM_TypeReference registersTref; + private static final VM_FieldReference segRegFref; + private static final VM_TypeReference segRegTref; + private static final VM_FieldReference gp32Fref; + private static final VM_TypeReference gp32Tref; + private static final VM_FieldReference flagCFref; + private static final VM_FieldReference flagSFref; + private static final VM_FieldReference flagZFref; + private static final VM_FieldReference flagOFref; + private static final VM_FieldReference flagDFref; + + static { + psTref = VM_TypeReference.findOrCreate( + VM_BootstrapClassLoader.getBootstrapClassLoader(), + VM_Atom + .findOrCreateAsciiAtom("Lorg/binarytranslator/arch/x86/os/process/X86_ProcessSpace;")); + + registersFref = VM_MemberReference + .findOrCreate( + psTref, + VM_Atom.findOrCreateAsciiAtom("registers"), + VM_Atom.findOrCreateAsciiAtom("Lorg/binarytranslator/arch/x86/os/process/X86_Registers;")) + .asFieldReference(); + + registersTref = registersFref.getFieldContentsType(); + + segRegFref = VM_MemberReference.findOrCreate( + registersTref, VM_Atom.findOrCreateAsciiAtom("segmentRegister"), + VM_Atom.findOrCreateAsciiAtom("[C")).asFieldReference(); + + segRegTref = segRegFref.getFieldContentsType(); + + gp32Fref = VM_MemberReference.findOrCreate( + registersTref, VM_Atom.findOrCreateAsciiAtom("gp32"), + VM_Atom.findOrCreateAsciiAtom("[I")).asFieldReference(); + + gp32Tref = gp32Fref.getFieldContentsType(); + + flagCFref = VM_MemberReference.findOrCreate( + registersTref, VM_Atom.findOrCreateAsciiAtom("flag_CF"), + VM_Atom.findOrCreateAsciiAtom("Z")).asFieldReference(); + + flagSFref = VM_MemberReference.findOrCreate( + registersTref, VM_Atom.findOrCreateAsciiAtom("flag_SF"), + VM_Atom.findOrCreateAsciiAtom("Z")).asFieldReference(); + + flagZFref = VM_MemberReference.findOrCreate( + registersTref, VM_Atom.findOrCreateAsciiAtom("flag_ZF"), + VM_Atom.findOrCreateAsciiAtom("Z")).asFieldReference(); + + flagOFref = VM_MemberReference.findOrCreate( + registersTref, VM_Atom.findOrCreateAsciiAtom("flag_OF"), + VM_Atom.findOrCreateAsciiAtom("Z")).asFieldReference(); + + flagDFref = VM_MemberReference.findOrCreate( + registersTref, VM_Atom.findOrCreateAsciiAtom("flag_DF"), + VM_Atom.findOrCreateAsciiAtom("Z")).asFieldReference(); + } + /** * Constructor */ @@ -34,6 +95,9 @@ super(context); // Create the registers + SegReg = new OPT_Register[6]; + SegRegInUse = new boolean[6]; + GP32 = new OPT_Register[8]; GP32InUse = new boolean[8]; @@ -94,6 +158,17 @@ // -oO Register Manipulation Oo- /** + * Registers holding 16bit segment values during the trace + */ + private OPT_Register[] SegReg; + + /** + * Which 16bit segment registers have been used during the trace - unused + * registers can be eliminated + */ + private boolean[] SegRegInUse; + + /** * Registers holding 32bit values during the trace */ private OPT_Register[] GP32; @@ -181,6 +256,19 @@ * @param r * the register to read */ + public OPT_RegisterOperand getSegRegister(X86_Laziness laziness, int r) { + SegRegInUse[r] = true; + return new OPT_RegisterOperand(SegReg[r], VM_TypeReference.Int); + } + + /** + * Read a 32bit register + * + * @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; resolveGPRegister32(laziness, r); @@ -439,9 +527,9 @@ private OPT_Register ps_registers; /** - * The type of ps.registers + * A register holding a reference to ps.registers.segmentRegister */ - private VM_TypeReference registersTref; + private OPT_Register ps_registers_segReg; /** * A register holding a reference to ps.registers.gp32 @@ -449,11 +537,6 @@ private OPT_Register ps_registers_gp32; /** - * The type of ps.registers.gp32 - */ - private VM_TypeReference gp32Tref; - - /** * Fill all the registers from the ProcessSpace, that is take the register * values from the process space and place them in the traces registers. */ @@ -462,19 +545,6 @@ // Get the registers if (ps_registers == null) { // Set up the reference to memory - VM_TypeReference psTref = VM_TypeReference - .findOrCreate( - VM_BootstrapClassLoader.getBootstrapClassLoader(), - VM_Atom - .findOrCreateAsciiAtom("Lorg/binarytranslator/arch/x86/os/process/X86_ProcessSpace;")); - VM_FieldReference registersFref = VM_MemberReference - .findOrCreate( - psTref, - VM_Atom.findOrCreateAsciiAtom("registers"), - VM_Atom - .findOrCreateAsciiAtom("Lorg/binarytranslator/arch/x86/os/process/X86_Registers;")) - .asFieldReference(); - registersTref = registersFref.getFieldContentsType(); ps_registersOp = gc.temps.makeTemp(registersTref); ps_registers = ps_registersOp.register; appendInstructionToCurrentBlock(GetField.create(GETFIELD, ps_registersOp, @@ -484,13 +554,22 @@ } else { ps_registersOp = new OPT_RegisterOperand(ps_registers, registersTref); } + // Get the array of segment registers + OPT_RegisterOperand ps_registers_segRegOp; + if (ps_registers_segReg == null) { + ps_registers_segRegOp = gc.temps.makeTemp(segRegTref); + appendInstructionToCurrentBlock(GetField.create(GETFIELD, + ps_registers_segRegOp, ps_registersOp.copyRO(), + new OPT_AddressConstantOperand(segRegFref.peekResolvedField() + .getOffset()), new OPT_LocationOperand(segRegFref), + new OPT_TrueGuardOperand())); + ps_registers_segReg = ps_registers_segRegOp.register; + } else { + ps_registers_segRegOp = new OPT_RegisterOperand(ps_registers_segReg, segRegTref); + } // Get the array of general purpose registers OPT_RegisterOperand ps_registers_gp32Op; if (ps_registers_gp32 == null) { - VM_FieldReference gp32Fref = VM_MemberReference.findOrCreate( - registersTref, VM_Atom.findOrCreateAsciiAtom("gp32"), - VM_Atom.findOrCreateAsciiAtom("[I")).asFieldReference(); - gp32Tref = gp32Fref.getFieldContentsType(); ps_registers_gp32Op = gc.temps.makeTemp(gp32Tref); appendInstructionToCurrentBlock(GetField.create(GETFIELD, ps_registers_gp32Op, ps_registersOp.copyRO(), @@ -501,6 +580,20 @@ } else { ps_registers_gp32Op = new OPT_RegisterOperand(ps_registers_gp32, gp32Tref); } + // Fill segment registers + for (int i = 0; i < SegReg.length; i++) { + OPT_RegisterOperand segRegOp; + if (GP32[i] == null) { + segRegOp = makeTemp(VM_TypeReference.Char); + SegReg[i] = segRegOp.register; + } else { + segRegOp = new OPT_RegisterOperand(SegReg[i], VM_TypeReference.Char); + } + appendInstructionToCurrentBlock(ALoad.create(USHORT_ALOAD, segRegOp, + ps_registers_segRegOp.copyRO(), new OPT_IntConstantOperand(i), + new OPT_LocationOperand(VM_TypeReference.Char), + new OPT_TrueGuardOperand())); + } // Fill general purpose registers for (int i = 0; i < GP32.length; i++) { OPT_RegisterOperand gp32op; @@ -524,14 +617,11 @@ } else { flag_CF_Op = new OPT_RegisterOperand(flag_CF, VM_TypeReference.Boolean); } - VM_FieldReference flagFref = VM_MemberReference.findOrCreate( - registersTref, VM_Atom.findOrCreateAsciiAtom("flag_CF"), - VM_Atom.findOrCreateAsciiAtom("Z")).asFieldReference(); - VM_TypeReference flagTref = flagFref.getFieldContentsType(); appendInstructionToCurrentBlock(GetField.create(GETFIELD, flag_CF_Op, - ps_registersOp.copyRO(), new OPT_AddressConstantOperand(flagFref - .peekResolvedField().getOffset()), new OPT_LocationOperand( - flagFref), new OPT_TrueGuardOperand())); + ps_registersOp.copyRO(), + new OPT_AddressConstantOperand(flagCFref.peekResolvedField().getOffset()), + new OPT_LocationOperand(flagCFref), + new OPT_TrueGuardOperand())); } { OPT_RegisterOperand flag_SF_Op; @@ -541,14 +631,11 @@ } else { flag_SF_Op = new OPT_RegisterOperand(flag_SF, VM_TypeReference.Boolean); } - VM_FieldReference flagFref = VM_MemberReference.findOrCreate( - registersTref, VM_Atom.findOrCreateAsciiAtom("flag_SF"), - VM_Atom.findOrCreateAsciiAtom("Z")).asFieldReference(); - VM_TypeReference flagTref = flagFref.getFieldContentsType(); appendInstructionToCurrentBlock(GetField.create(GETFIELD, flag_SF_Op, - ps_registersOp.copyRO(), new OPT_AddressConstantOperand(flagFref - .peekResolvedField().getOffset()), new OPT_LocationOperand( - flagFref), new OPT_TrueGuardOperand())); + ps_registersOp.copyRO(), + new OPT_AddressConstantOperand(flagSFref.peekResolvedField().getOffset()), + new OPT_LocationOperand(flagSFref), + new OPT_TrueGuardOperand())); } { OPT_RegisterOperand flag_ZF_Op; @@ -558,14 +645,11 @@ } else { flag_ZF_Op = new OPT_RegisterOperand(flag_ZF, VM_TypeReference.Boolean); } - VM_FieldReference flagFref = VM_MemberReference.findOrCreate( - registersTref, VM_Atom.findOrCreateAsciiAtom("flag_ZF"), - VM_Atom.findOrCreateAsciiAtom("Z")).asFieldReference(); - VM_TypeReference flagTref = flagFref.getFieldContentsType(); appendInstructionToCurrentBlock(GetField.create(GETFIELD, flag_ZF_Op, - ps_registersOp.copyRO(), new OPT_AddressConstantOperand(flagFref - .peekResolvedField().getOffset()), new OPT_LocationOperand( - flagFref), new OPT_TrueGuardOperand())); + ps_registersOp.copyRO(), + new OPT_AddressConstantOperand(flagZFref.peekResolvedField().getOffset()), + new OPT_LocationOperand(flagZFref), + new OPT_TrueGuardOperand())); } { OPT_RegisterOperand flag_OF_Op; @@ -575,14 +659,11 @@ } else { flag_OF_Op = new OPT_RegisterOperand(flag_OF, VM_TypeReference.Boolean); } - VM_FieldReference flagFref = VM_MemberReference.findOrCreate( - registersTref, VM_Atom.findOrCreateAsciiAtom("flag_OF"), - VM_Atom.findOrCreateAsciiAtom("Z")).asFieldReference(); - VM_TypeReference flagTref = flagFref.getFieldContentsType(); appendInstructionToCurrentBlock(GetField.create(GETFIELD, flag_OF_Op, - ps_registersOp.copyRO(), new OPT_AddressConstantOperand(flagFref - .peekResolvedField().getOffset()), new OPT_LocationOperand( - flagFref), new OPT_TrueGuardOperand())); + ps_registersOp.copyRO(), + new OPT_AddressConstantOperand(flagOFref.peekResolvedField().getOffset()), + new OPT_LocationOperand(flagOFref), + new OPT_TrueGuardOperand())); } { OPT_RegisterOperand flag_DF_Op; @@ -592,14 +673,11 @@ } else { flag_DF_Op = new OPT_RegisterOperand(flag_DF, VM_TypeReference.Boolean); } - VM_FieldReference flagFref = VM_MemberReference.findOrCreate( - registersTref, VM_Atom.findOrCreateAsciiAtom("flag_DF"), - VM_Atom.findOrCreateAsciiAtom("Z")).asFieldReference(); - VM_TypeReference flagTref = flagFref.getFieldContentsType(); appendInstructionToCurrentBlock(GetField.create(GETFIELD, flag_DF_Op, - ps_registersOp.copyRO(), new OPT_AddressConstantOperand(flagFref - .peekResolvedField().getOffset()), new OPT_LocationOperand( - flagFref), new OPT_TrueGuardOperand())); + ps_registersOp.copyRO(), + new OPT_AddressConstantOperand(flagDFref.peekResolvedField().getOffset()), + new OPT_LocationOperand(flagDFref), + new OPT_TrueGuardOperand())); } } @@ -608,9 +686,24 @@ * into the process space */ protected void spillAllRegisters() { + // spill segment registers + OPT_RegisterOperand ps_registers_segRegOp = + new OPT_RegisterOperand(ps_registers_segReg, segRegTref); + for (int i = 0; i < SegReg.length; i++) { + // We can save spills if the trace has no syscalls and the register was + // never used + if ((DBT_Options.singleInstrTranslation == false) + || (SegRegInUse[i] == true)) { + appendInstructionToCurrentBlock(AStore.create(SHORT_ASTORE, + new OPT_RegisterOperand(GP32[i], VM_TypeReference.Int), + ps_registers_segRegOp.copyRO(), new OPT_IntConstantOperand(i), + new OPT_LocationOperand(VM_TypeReference.Char), + new OPT_TrueGuardOperand())); + } + } // spill general purpose registers - OPT_RegisterOperand ps_registers_gp32Op = new OPT_RegisterOperand( - ps_registers_gp32, gp32Tref); + OPT_RegisterOperand ps_registers_gp32Op = + new OPT_RegisterOperand(ps_registers_gp32, gp32Tref); for (int i = 0; i < GP32.length; i++) { // We can save spills if the trace has no syscalls and the register was // never used @@ -624,67 +717,52 @@ } } // Spill flags - OPT_RegisterOperand ps_registersOp = new OPT_RegisterOperand(ps_registers, - registersTref); + OPT_RegisterOperand ps_registersOp = + new OPT_RegisterOperand(ps_registers, registersTref); { - OPT_RegisterOperand flag_CF_Op = new OPT_RegisterOperand(flag_CF, - VM_TypeReference.Boolean); - VM_FieldReference flagFref = VM_MemberReference.findOrCreate( - registersTref, VM_Atom.findOrCreateAsciiAtom("flag_CF"), - VM_Atom.findOrCreateAsciiAtom("Z")).asFieldReference(); - VM_TypeReference flagTref = flagFref.getFieldContentsType(); - appendInstructionToCurrentBlock(GetField.create(PUTFIELD, flag_CF_Op, - ps_registersOp, new OPT_AddressConstantOperand(flagFref - .peekResolvedField().getOffset()), new OPT_LocationOperand( - flagFref), new OPT_TrueGuardOperand())); + OPT_RegisterOperand flag_CF_Op = + new OPT_RegisterOperand(flag_CF, VM_TypeReference.Boolean); + appendInstructionToCurrentBlock(GetField.create(PUTFIELD, + flag_CF_Op, ps_registersOp, + new OPT_AddressConstantOperand(flagCFref.peekResolvedField().getOffset()), + new OPT_LocationOperand(flagCFref), + new OPT_TrueGuardOperand())); } { OPT_RegisterOperand flag_SF_Op = new OPT_RegisterOperand(flag_SF, VM_TypeReference.Boolean); - VM_FieldReference flagFref = VM_MemberReference.findOrCreate( - registersTref, VM_Atom.findOrCreateAsciiAtom("flag_SF"), - VM_Atom.findOrCreateAsciiAtom("Z")).asFieldReference(); - VM_TypeReference flagTref = flagFref.getFieldContentsType(); - appendInstructionToCurrentBlock(GetField.create(PUTFIELD, flag_SF_Op, - ps_registersOp.copyRO(), new OPT_AddressConstantOperand(flagFref - .peekResolvedField().getOffset()), new OPT_LocationOperand( - flagFref), new OPT_TrueGuardOperand())); + appendInstructionToCurrentBlock(GetField.create(PUTFIELD, + flag_SF_Op, ps_registersOp.copyRO(), + new OPT_AddressConstantOperand(flagSFref.peekResolvedField().getOffset()), + new OPT_LocationOperand(flagSFref), + new OPT_TrueGuardOperand())); } { - OPT_RegisterOperand flag_ZF_Op = new OPT_RegisterOperand(flag_ZF, - VM_TypeReference.Boolean); - VM_FieldReference flagFref = VM_MemberReference.findOrCreate( - registersTref, VM_Atom.findOrCreateAsciiAtom("flag_ZF"), - VM_Atom.findOrCreateAsciiAtom("Z")).asFieldReference(); - VM_TypeReference flagTref = flagFref.getFieldContentsType(); - appendInstructionToCurrentBlock(GetField.create(PUTFIELD, flag_ZF_Op, - ps_registersOp.copyRO(), new OPT_AddressConstantOperand(flagFref - .peekResolvedField().getOffset()), new OPT_LocationOperand( - flagFref), new OPT_TrueGuardOperand())); + OPT_RegisterOperand flag_ZF_Op = + new OPT_RegisterOperand(flag_ZF, VM_TypeReference.Boolean); + appendInstructionToCurrentBlock(GetField.create(PUTFIELD, + flag_ZF_Op, ps_registersOp.copyRO(), + new OPT_AddressConstantOperand(flagZFref.peekResolvedField().getOffset()), + new OPT_LocationOperand(flagZFref), + new OPT_TrueGuardOperand())); } { - OPT_RegisterOperand flag_OF_Op = new OPT_RegisterOperand(flag_OF, - VM_TypeReference.Boolean); - VM_FieldReference flagFref = VM_MemberReference.findOrCreate( - registersTref, VM_Atom.findOrCreateAsciiAtom("flag_OF"), - VM_Atom.findOrCreateAsciiAtom("Z")).asFieldReference(); - VM_TypeReference flagTref = flagFref.getFieldContentsType(); - appendInstructionToCurrentBlock(GetField.create(PUTFIELD, flag_OF_Op, - ps_registersOp, new OPT_AddressConstantOperand(flagFref - .peekResolvedField().getOffset()), new OPT_LocationOperand( - flagFref), new OPT_TrueGuardOperand())); + OPT_RegisterOperand flag_OF_Op = + new OPT_RegisterOperand(flag_OF, VM_TypeReference.Boolean); + appendInstructionToCurrentBlock(GetField.create(PUTFIELD, + flag_OF_Op, ps_registersOp.copyRO(), + new OPT_AddressConstantOperand(flagOFref.peekResolvedField().getOffset()), + new OPT_LocationOperand(flagOFref), + new OPT_TrueGuardOperand())); } { - OPT_RegisterOperand flag_DF_Op = new OPT_RegisterOperand(flag_DF, - VM_TypeReference.Boolean); - VM_FieldReference flagFref = VM_MemberReference.findOrCreate( - registersTref, VM_Atom.findOrCreateAsciiAtom("flag_DF"), - VM_Atom.findOrCreateAsciiAtom("Z")).asFieldReference(); - VM_TypeReference flagTref = flagFref.getFieldContentsType(); - appendInstructionToCurrentBlock(GetField.create(PUTFIELD, flag_DF_Op, - ps_registersOp, new OPT_AddressConstantOperand(flagFref - .peekResolvedField().getOffset()), new OPT_LocationOperand( - flagFref), new OPT_TrueGuardOperand())); + OPT_RegisterOperand flag_DF_Op = + new OPT_RegisterOperand(flag_DF, VM_TypeReference.Boolean); + appendInstructionToCurrentBlock(GetField.create(PUTFIELD, + flag_DF_Op, ps_registersOp.copyRO(), + new OPT_AddressConstantOperand(flagDFref.peekResolvedField().getOffset()), + new OPT_LocationOperand(flagDFref), + new OPT_TrueGuardOperand())); } } @@ -713,8 +791,14 @@ * Return an array of unused registers */ protected OPT_Register[] getUnusedRegisters() { - ArrayList unusedRegisterList = new ArrayList(); + ArrayList<OPT_Register> unusedRegisterList = new ArrayList<OPT_Register>(); // Add general purpose registers + for (int i = 0; i < SegRegInUse.length; i++) { + if (SegRegInUse[i] == false) { + unusedRegisterList.add(SegReg[i]); + } + } + // Add general purpose registers for (int i = 0; i < GP32InUse.length; i++) { if (GP32InUse[i] == false) { unusedRegisterList.add(GP32[i]); @@ -736,7 +820,7 @@ if (flag_OF_InUse == false) { unusedRegisterList.add(flag_OF); } - return (OPT_Register[]) unusedRegisterList - .toArray(new OPT_Register[unusedRegisterList.size()]); + return unusedRegisterList.toArray( + new OPT_Register[unusedRegisterList.size()]); } } Modified: src/org/binarytranslator/arch/x86/decoder/X86_DecodedOperand.java =================================================================== --- src/org/binarytranslator/arch/x86/decoder/X86_DecodedOperand.java 2007-04-23 21:57:27 UTC (rev 88) +++ src/org/binarytranslator/arch/x86/decoder/X86_DecodedOperand.java 2007-04-23 22:12:34 UTC (rev 89) @@ -49,6 +49,13 @@ } /** + * Get a decoded operand for a segment register + */ + static X86_DecodedOperand getSegmentRegister(int reg) { + return new X86_SegRegDecodedOperand(reg); + } + + /** * Get a memory reference to the stack */ static X86_DecodedOperand getStack(int addressSize, int operandSize) { @@ -160,6 +167,50 @@ } /** + * Segment Registers + */ +final class X86_SegRegDecodedOperand extends X86_DecodedOperand { + /** + * The register in question + */ + final int reg; + + /** + * Constructor + */ + X86_SegRegDecodedOperand(int reg) { + this.reg = reg; + } + + /** + * Read the value into a register + */ + void readToRegister(X862IR translationHelper, X86_Laziness lazy, + OPT_RegisterOperand op) { + translationHelper.appendInstructionToCurrentBlock(Move.create(INT_MOVE, op, + translationHelper.getSegRegister(lazy, reg))); + } + + /** + * Write the given operand to this + */ + void writeValue(X862IR translationHelper, X86_Laziness lazy, + OPT_RegisterOperand op) { + OPT_RegisterOperand result = translationHelper.getSegRegister(lazy, reg); + translationHelper.appendInstructionToCurrentBlock(Move.create(INT_MOVE, + result, op)); + } + + /** + * Read the value as giving an address + */ + void readEffectiveAddress(X862IR translationHelper, X86_Laziness lazy, + OPT_RegisterOperand op) { + throw new Error("Trying to read the address of a register!"); + } +} + +/** * Memory */ final class X86_MemDecodedOperand extends X86_DecodedOperand { Modified: src/org/binarytranslator/arch/x86/decoder/X86_InstructionDecoder.java =================================================================== --- src/org/binarytranslator/arch/x86/decoder/X86_InstructionDecoder.java 2007-04-23 21:57:27 UTC (rev 88) +++ src/org/binarytranslator/arch/x86/decoder/X86_InstructionDecoder.java 2007-04-23 22:12:34 UTC (rev 89) @@ -328,22 +328,17 @@ /* 0x7E */new X86_Jcc_OpcodeDecoder(LESS_EQUAL, 8), /* 0x7F */new X86_Jcc_OpcodeDecoder(GREATER, 8), - /* 0x80 */new X86_OpcodeInModRMReg_Decoder(new X86_OpcodeDecoder[] {// 8bit, - // ModRM, - // 8bit - // imm, - // rm - // is - // dest - new X86_Add_OpcodeDecoder(8, true, 8, true),// 0 - new X86_Or_OpcodeDecoder(8, true, 8, true),// 1 - new X86_Adc_OpcodeDecoder(8, true, 8, true),// 2 - new X86_Sbb_OpcodeDecoder(8, true, 8, true),// 3 - new X86_And_OpcodeDecoder(8, true, 8, true),// 4 - new X86_Sub_OpcodeDecoder(8, true, 8, true),// 5 - new X86_Xor_OpcodeDecoder(8, true, 8, true),// 6 - new X86_Cmp_OpcodeDecoder(8, true, 8, true) // 7 - }), + /* 0x80 */new X86_OpcodeInModRMReg_Decoder(new X86_OpcodeDecoder[] { + // 8bit, ModRM, 8bit imm, rm is dest + new X86_Add_OpcodeDecoder(8, true, 8, true),// 0 + new X86_Or_OpcodeDecoder(8, true, 8, true),// 1 + new X86_Adc_OpcodeDecoder(8, true, 8, true),// 2 + new X86_Sbb_OpcodeDecoder(8, true, 8, true),// 3 + new X86_And_OpcodeDecoder(8, true, 8, true),// 4 + new X86_Sub_OpcodeDecoder(8, true, 8, true),// 5 + new X86_Xor_OpcodeDecoder(8, true, 8, true),// 6 + new X86_Cmp_OpcodeDecoder(8, true, 8, true) // 7 + }), /* 0x81 */new X86_OpcodeInModRMReg_Decoder(new X86_OpcodeDecoder[] { // 16/32bit, ModRM, 16/32bit imm, rm is dest new X86_Add_OpcodeDecoder(_16BIT?16:32, true, _16BIT?16:32, true),// 0 @@ -358,46 +353,34 @@ /* 0x82 */null, /* 0x83 */new X86_OpcodeInModRMReg_Decoder(new X86_OpcodeDecoder[] { // 16/32bit, ModRM, 8bit imm, rm is dest - new X86_Add_OpcodeDecoder(_16BIT ? 16 : 32, true, 8, true),// 0 - new X86_Or_OpcodeDecoder(_16BIT ? 16 : 32, true, 8, true),// 1 - new X86_Adc_OpcodeDecoder(_16BIT ? 16 : 32, true, 8, true),// 2 - new X86_Sbb_OpcodeDecoder(_16BIT ? 16 : 32, true, 8, true),// 3 - new X86_And_OpcodeDecoder(_16BIT ? 16 : 32, true, 8, true),// 4 - new X86_Sub_OpcodeDecoder(_16BIT ? 16 : 32, true, 8, true),// 5 - new X86_Xor_OpcodeDecoder(_16BIT ? 16 : 32, true, 8, true),// 6 - new X86_Cmp_OpcodeDecoder(_16BIT ? 16 : 32, true, 8, true) // 7 - }), - /* 0x84 */new X86_Test_OpcodeDecoder(8, true, 0), // 8bit, has ModRM, no - // imm - /* 0x85 */new X86_Test_OpcodeDecoder(_16BIT ? 16 : 32, true, 0), // 16/32bit,has - // ModRM, - // no - // imm + new X86_Add_OpcodeDecoder(_16BIT ? 16 : 32, true, 8, true),// 0 + new X86_Or_OpcodeDecoder(_16BIT ? 16 : 32, true, 8, true),// 1 + new X86_Adc_OpcodeDecoder(_16BIT ? 16 : 32, true, 8, true),// 2 + new X86_Sbb_OpcodeDecoder(_16BIT ? 16 : 32, true, 8, true),// 3 + new X86_And_OpcodeDecoder(_16BIT ? 16 : 32, true, 8, true),// 4 + new X86_Sub_OpcodeDecoder(_16BIT ? 16 : 32, true, 8, true),// 5 + new X86_Xor_OpcodeDecoder(_16BIT ? 16 : 32, true, 8, true),// 6 + new X86_Cmp_OpcodeDecoder(_16BIT ? 16 : 32, true, 8, true) // 7 + }), + /* 0x84 */new X86_Test_OpcodeDecoder(8, true, 0), + // 8bit, has ModRM, no imm + /* 0x85 */new X86_Test_OpcodeDecoder(_16BIT ? 16 : 32, true, 0), + // 16/32bit,has ModRM, no imm /* 0x86 */null, /* 0x87 */null, - /* 0x88 */new X86_Mov_OpcodeDecoder(8, true, 0, true), // 8bit, has - // ModRM, no imm, - // rm is dest - /* 0x89 */new X86_Mov_OpcodeDecoder(_16BIT ? 16 : 32, true, 0, true), // 16/32bit,has - // ModRM, - // no - // imm, - // rm - // is - // dest - /* 0x8A */new X86_Mov_OpcodeDecoder(8, true, 0, false),// 8bit, has - // ModRM, no imm, - // rm is src - /* 0x8B */new X86_Mov_OpcodeDecoder(_16BIT ? 16 : 32, true, 0, false),// 16/32bit,has - // ModRM, - // no - // imm, - // rm - // is - // src - /* 0x8C */null, + /* 0x88 */new X86_Mov_OpcodeDecoder(8, true, 0, true), + // 8bit, has ModRM, no imm, rm is dest + /* 0x89 */new X86_Mov_OpcodeDecoder(_16BIT ? 16 : 32, true, 0, true), + // 16/32bit,has ModRM, no imm, rm is dest + /* 0x8A */new X86_Mov_OpcodeDecoder(8, true, 0, false), + // 8bit, has ModRM, no imm, rm is src + /* 0x8B */new X86_Mov_OpcodeDecoder(_16BIT ? 16 : 32, true, 0, false), + // 16/32bit,has ModRM, no imm, rm is src + /* 0x8C */new X86_MovSeg_OpcodeDecoder(true), + // move Sreg to r/m /* 0x8D */new X86_Lea_OpcodeDecoder(), - /* 0x8E */null, + /* 0x8E */new X86_MovSeg_OpcodeDecoder(false), + // move r/m to Sreg /* 0x8F */new X86_OpcodeInModRMReg_Decoder(new X86_OpcodeDecoder[] { new X86_Pop_OpcodeDecoder(-1), // 0 - Pop of memory operand null, // 1 @@ -447,30 +430,24 @@ /* 0xAE */null, /* 0xAF */null, - /* 0xB0 */new X86_Mov_OpcodeDecoder(0, 8), // reg, 8bit immediate - /* 0xB1 */new X86_Mov_OpcodeDecoder(1, 8), // reg, 8bit immediate - /* 0xB2 */new X86_Mov_OpcodeDecoder(2, 8), // reg, 8bit immediate - /* 0xB3 */new X86_Mov_OpcodeDecoder(3, 8), // reg, 8bit immediate - /* 0xB4 */new X86_Mov_OpcodeDecoder(4, 8), // reg, 8bit immediate - /* 0xB5 */new X86_Mov_OpcodeDecoder(5, 8), // reg, 8bit immediate - /* 0xB6 */new X86_Mov_OpcodeDecoder(6, 8), // reg, 8bit immediate - /* 0xB7 */new X86_Mov_OpcodeDecoder(7, 8), // reg, 8bit immediate - /* 0xB8 */new X86_Mov_OpcodeDecoder(0, _16BIT ? 16 : 32), // reg, 16/32bit - // immediate - /* 0xB9 */new X86_Mov_OpcodeDecoder(1, _16BIT ? 16 : 32), // reg, 16/32bit - // immediate - /* 0xBA */new X86_Mov_OpcodeDecoder(2, _16BIT ? 16 : 32), // reg, 16/32bit - // immediate - /* 0xBB */new X86_Mov_OpcodeDecoder(3, _16BIT ? 16 : 32), // reg, 16/32bit - // immediate - /* 0xBC */new X86_Mov_OpcodeDecoder(4, _16BIT ? 16 : 32), // reg, 16/32bit - // immediate - /* 0xBD */new X86_Mov_OpcodeDecoder(5, _16BIT ? 16 : 32), // reg, 16/32bit - // immediate - /* 0xBE */new X86_Mov_OpcodeDecoder(6, _16BIT ? 16 : 32), // reg, 16/32bit - // immediate - /* 0xBF */new X86_Mov_OpcodeDecoder(7, _16BIT ? 16 : 32), // reg, 16/32bit - // immediate + // reg, 8bit immediate + /* 0xB0 */new X86_Mov_OpcodeDecoder(0, 8), + /* 0xB1 */new X86_Mov_OpcodeDecoder(1, 8), + /* 0xB2 */new X86_Mov_OpcodeDecoder(2, 8), + /* 0xB3 */new X86_Mov_OpcodeDecoder(3, 8), + /* 0xB4 */new X86_Mov_OpcodeDecoder(4, 8), + /* 0xB5 */new X86_Mov_OpcodeDecoder(5, 8), + /* 0xB6 */new X86_Mov_OpcodeDecoder(6, 8), + /* 0xB7 */new X86_Mov_OpcodeDecoder(7, 8), + // reg, 16/32bit immediate + /* 0xB8 */new X86_Mov_OpcodeDecoder(0, _16BIT ? 16 : 32), + /* 0xB9 */new X86_Mov_OpcodeDecoder(1, _16BIT ? 16 : 32), + /* 0xBA */new X86_Mov_OpcodeDecoder(2, _16BIT ? 16 : 32), + /* 0xBB */new X86_Mov_OpcodeDecoder(3, _16BIT ? 16 : 32), + /* 0xBC */new X86_Mov_OpcodeDecoder(4, _16BIT ? 16 : 32), + /* 0xBD */new X86_Mov_OpcodeDecoder(5, _16BIT ? 16 : 32), + /* 0xBE */new X86_Mov_OpcodeDecoder(6, _16BIT ? 16 : 32), + /* 0xBF */new X86_Mov_OpcodeDecoder(7, _16BIT ? 16 : 32), /* 0xC0 */null, /* 0xC1 */new X86_OpcodeInModRMReg_Decoder(new X86_OpcodeDecoder[] { @@ -478,45 +455,30 @@ null, // 1 null, // 2 null, // 3 - new X86_Shl_OpcodeDecoder(_16BIT ? 16 : 32, true, 8, true), // 4 - - // 16/32bit, - // has - // ModRM, - // 8bit - // imm, rm - // is dest - new X86_Ushr_OpcodeDecoder(_16BIT ? 16 : 32, true, 8, true),// 5 - - // 16/32bit, - // has - // ModRM, - // 8bit - // imm, rm - // is dest + new X86_Shl_OpcodeDecoder(_16BIT ? 16 : 32, true, 8, true), + // 4 - 16/32bit, has ModRM, 8bit imm, rm is dest + new X86_Ushr_OpcodeDecoder(_16BIT ? 16 : 32, true, 8, true), + // 5 - 16/32bit, has ModRM, 8bit imm, rm is dest null, // 6 - new X86_Shr_OpcodeDecoder(_16BIT ? 16 : 32, true, 8, true) // 7 - - // 16/32bit, - // has - // ModRM, - // 8bit - // imm, rm - // is dest + new X86_Shr_OpcodeDecoder(_16BIT ? 16 : 32, true, 8, true) + // 7 - 16/32bit, has ModRM, 8bit imm, rm is dest }), - /* 0xC2 */new X86_Ret_OpcodeDecoder(false, 16), // near return, 16bit - // immediate - /* 0xC3 */new X86_Ret_OpcodeDecoder(false, 0), // near return, no - // immediate + /* 0xC2 */new X86_Ret_OpcodeDecoder(false, 16), + // near return, 16bit immediate + /* 0xC3 */new X86_Ret_OpcodeDecoder(false, 0), + // near return, no immediate /* 0xC4 */null, /* 0xC5 */null, - /* 0xC6 */new X86_Mov_OpcodeDecoder(8, true, 8, true), // 8bit, has - // ModRM, 8bit - // imm, rm is dest + /* 0xC6 */new X86_Mov_OpcodeDecoder(8, true, 8, true), + // 8bit, has ModRM, 8bit imm, rm is dest /* 0xC7 */new X86_Mov_OpcodeDecoder(_16BIT ? 16 : 32, true, _16BIT ? 16 : 32, true), // 16/32bit, has ModRM, 16/32bit imm, rm is dest /* 0xC8 */null, /* 0xC9 */new X86_Leave_OpcodeDecoder(), - /* 0xCA */new X86_Ret_OpcodeDecoder(true, 16), // far return, 16bit - // immediate - /* 0xCB */new X86_Ret_OpcodeDecoder(true, 0), // far return, no immediate + /* 0xCA */new X86_Ret_OpcodeDecoder(true, 16), + // far return, 16bit immediate + /* 0xCB */new X86_Ret_OpcodeDecoder(true, 0), + // far return, no immediate /* 0xCC */null, /* 0xCD */new X86_Int_OpcodeDecoder(), /* 0xCE */null, @@ -2483,7 +2445,118 @@ return "mov"; } } +/** + * The decoder for the Mov opcode + */ +class X86_MovSeg_OpcodeDecoder extends X86_OpcodeDecoder { + /** + * Constructor, {@see X86_OpcodeDecoder} + */ + X86_MovSeg_OpcodeDecoder(boolean isMemoryOperandDestination) { + super(X86_64 ? 64 : 16, true, 0, 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 operandSize = this.operandSize; + int addressSize; + if (prefix4 == null) { + addressSize = _16BIT ? 16 : 32; + } else { + addressSize = _16BIT ? 32 : 16; + } + X86_DecodedOperand destination; + X86_DecodedOperand source = null; + if (isMemoryOperandDestination) { + destination = modrm.getRM(translationHelper, lazy, sib, displacement, + operandSize, addressSize, (prefix2 != null) ? prefix2.getSegment() + : X86_Registers.DS); + source = modrm.getSReg(); + } else { + destination = modrm.getSReg(); + source = modrm.getRM(translationHelper, lazy, sib, displacement, + operandSize, addressSize, (prefix2 != null) ? prefix2.getSegment() + : X86_Registers.DS); + } + + OPT_RegisterOperand temp = translationHelper.getTempInt(0); + OPT_RegisterOperand sourceOp1 = translationHelper.getTempInt(1); + source.readToRegister(translationHelper, lazy, sourceOp1); + translationHelper.appendInstructionToCurrentBlock(Move.create(INT_MOVE, + temp, sourceOp1.copyRO())); + destination.writeValue(translationHelper, lazy, 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 operandSize; + if (prefix3 == null) { + operandSize = this.operandSize; + } else if (this.operandSize == 32) { + operandSize = 16; + } else { + operandSize = 32; + } + char addressPrefix; + if (prefix4 == null) { + addressPrefix = _16BIT ? ' ' : 'e'; + } else { + addressPrefix = _16BIT ? 'e' : ' '; + } + // TODO: apply segment override + switch (operandSize) { + case 8: + return "movsb es:" + addressPrefix + "di, ds:" + addressPrefix + "si"; + case 16: + return "movsw es:" + addressPrefix + "di, ds:" + addressPrefix + "si"; + case 32: + return "movsd es:" + addressPrefix + "di, ds:" + addressPrefix + "si"; + default: + DBT_OptimizingCompilerException.UNREACHABLE(); + return "error"; + } + } +} + /** * The decoder for the Movs opcode */ Modified: src/org/binarytranslator/arch/x86/decoder/X86_ModRM_Decoder.java =================================================================== --- src/org/binarytranslator/arch/x86/decoder/X86_ModRM_Decoder.java 2007-04-23 21:57:27 UTC (rev 88) +++ src/org/binarytranslator/arch/x86/decoder/X86_ModRM_Decoder.java 2007-04-23 22:12:34 UTC (rev 89) @@ -466,6 +466,13 @@ } /** + * Get the segment reg field as a decoded operand + */ + X86_DecodedOperand getSReg() { + return X86_DecodedOperand.getSegmentRegister(reg); + } + + /** * Get the reg/opcode field as an integer */ int getOpcode() { 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-23 21:57:27 UTC (rev 88) +++ src/org/binarytranslator/arch/x86/os/abi/linux/X86_LinuxSystemCalls.java 2007-04-23 22:12:34 UTC (rev 89) @@ -40,6 +40,7 @@ systemCallTable[202] = new LinuxSystemCalls.SysGetEGID(); systemCallTable[221] = new LinuxSystemCalls.SysFcntl64(); systemCallTable[252] = new LinuxSystemCalls.SysExitGroup(); + systemCallTable[243] = new LinuxSystemCalls.NullSystemCall(); } /** * The machine for this system given by uname Modified: src/org/binarytranslator/arch/x86/os/process/X86_Registers.java =================================================================== --- src/org/binarytranslator/arch/x86/os/process/X86_Registers.java 2007-04-23 21:57:27 UTC (rev 88) +++ src/org/binarytranslator/arch/x86/os/process/X86_Registers.java 2007-04-23 22:12:34 UTC (rev 89) @@ -56,24 +56,24 @@ /** * Translate a register number into its 32bit string variant */ - private static final String name64[] = {"rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}; + private static final String[] name64 = {"rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}; /** * Translate a register number into its 32bit string variant */ - private static final String name32[] = {"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"}; + private static final String[] name32 = {"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"}; /** * Translate a register number into its 16bit string variant */ - private static final String name16[] = {"ax", "cx", "dx", "bx", "sp", "bp", "si", "di"}; + private static final String[] name16 = {"ax", "cx", "dx", "bx", "sp", "bp", "si", "di"}; /** * Translate a register number into its 32bit string variant */ - private static final String name8[] = {"al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"}; + private static final String[] name8 = {"al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"}; /** * Array holding the 8 32bit versions of the registers */ - private int gp32[] = new int[8]; + private int[] gp32 = new int[8]; /** * The instruction pointer register @@ -83,7 +83,7 @@ /** * Array holding the 6 segment registers */ - private short segmentRegister[] = new short[6]; + private char[] segmentRegister = new char[6]; /* * Flags @@ -405,13 +405,13 @@ /** * Read 16 bit segment */ - public short readSeg(int reg) { + public char readSeg(int reg) { return segmentRegister[reg]; } /** * Write a segment register value */ - public void writeSeg(int reg, short val) { + public void writeSeg(int reg, char val) { segmentRegister[reg] = val; } /** Modified: src/org/binarytranslator/generic/os/abi/linux/LinuxSystemCalls.java =================================================================== --- src/org/binarytranslator/generic/os/abi/linux/LinuxSystemCalls.java 2007-04-23 21:57:27 UTC (rev 88) +++ src/org/binarytranslator/generic/os/abi/linux/LinuxSystemCalls.java 2007-04-23 22:12:34 UTC (rev 89) @@ -457,13 +457,15 @@ * Class capturing file control (fcntl) constants */ private final static class fcntl { - public final static int O_RDONLY=0x0; - public final static int O_WRONLY=0x1; - public final static int O_RDWR =0x2; - public final static int O_CREAT =0x40; - public final static int O_EXCL =0x80; - public final static int O_TRUNC =0x200; - public final static int O_APPEND=0x400; + public final static int O_RDONLY = 0; + public final static int O_WRONLY = 1; + public final static int O_RDWR = 2; + public final static int O_CREAT = 0100; + public final static int O_EXCL = 0200; + public final static int O_NOCTTY = 0400; + public final static int O_TRUNC = 01000; + public final static int O_APPEND = 02000; + public final static int O_NONBLOCK = 04000; } /** @@ -512,6 +514,18 @@ } /** + * 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 { @@ -635,6 +649,7 @@ Memory mem = src.getProcessSpace().memory; if((fd == 1)||(fd == 2)) { // stdout || stderr + PrintStream out = (fd == 1) ? System.out : System.err; int base = mem.load32(vector); int len = mem.load32(vector+4); int currentVector = 0; @@ -646,12 +661,31 @@ len = mem.load32(vector+(currentVector*8)+4); curVectorPos = 0; } - System.out.print((char) mem.loadUnsigned8(base + curVectorPos)); + out.print((char) mem.loadUnsigned8(base + curVectorPos)); curVectorPos++; } src.setSysCallReturn(count); } else { - throw new Error("TODO: "+ fd); + try { + RandomAccessFile out = getRAFile(fd); + int base = mem.load32(vector); + int len = mem.load32(vector+4); + int currentVector = 0; + int curVectorPos = 0; + for(int c = 0 ; c < count; c++) { + if(curVectorPos == len) { + currentVector++; + base = mem.load32(vector+(currentVector*8)); + len = mem.load32(vector+(currentVector*8)+4); + curVectorPos = 0; + } + out.write((int)mem.loadUnsigned8(base + curVectorPos)); + curVectorPos++; + } + src.setSysCallReturn(count); + } catch(IOException e) { + throw new Error("TODO - set error correctly", e); + } } } } @@ -699,8 +733,12 @@ } // NOT YET HANDLING ALL THE flags OPTIONS (IW have included // TRUNC & APPEND but not properly!) - if((flags & ~(fcntl.O_WRONLY | fcntl.O_RDWR | fcntl.O_CREAT | fcntl.O_EXCL | fcntl.O_TRUNC | fcntl.O_APPEND)) != 0) - throw new Error("Not yet implemented option to sys_open. " + Integer.toString(flags,8)); + if((flags & ~(fcntl.O_WRONLY | fcntl.O_RDWR | fcntl.O_CREAT | fcntl.O_EXCL | fcntl.O_TRUNC | + fcntl.O_APPEND | fcntl.O_NOCTTY | fcntl.O_NONBLOCK)) != 0) { + throw new Error("Not yet implemented option to sys_open. 0" + Integer.toString(flags,8) + + " flag 0" + Integer.toString(flags & ~(fcntl.O_WRONLY | fcntl.O_RDWR | fcntl.O_CREAT | + fcntl.O_EXCL | fcntl.O_TRUNC | fcntl.O_APPEND | fcntl.O_NOCTTY | fcntl.O_NONBLOCK),8)); + } } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |