public void LoadElfIdentification(EndianImageReader rdr) { var elfMagic = rdr.ReadBeInt32(); if (elfMagic != ELF_MAGIC) { throw new BadImageFormatException("File is not in ELF format."); } this.fileClass = rdr.ReadByte(); this.endianness = rdr.ReadByte(); this.fileVersion = rdr.ReadByte(); this.osAbi = rdr.ReadByte(); }
/// <summary> /// Attempts to decode an operand. /// </summary> /// <param name="rdr"></param> /// <param name="args"></param> /// <param name="dataWidth"></param> /// <param name="op"></param> /// <returns>If true, either no more operands are needed, or an /// operand was fetched sucessfully. If false, the operand was /// invalid, either due to a bad encoding or because the reader read /// off the end of the memory area. /// </returns> public bool TryGetOperand(EndianImageReader rdr, string args, PrimitiveType dataWidth, out MachineOperand op) { if (i >= args.Length) { op = null; return(true); } for (; ;) { if (args[i] == ',') { ++i; } Address addr; switch (args[i++]) { case 'A': // Address register A0-A7 encoded in in instrution op = new RegisterOperand(AddressRegister(opcode, GetOpcodeOffset(args[i++]))); return(true); case 'c': // CCR register op = new RegisterOperand(Registers.ccr); return(true); case 'D': // Data register D0-D7 encoded in instruction op = DataRegisterOperand(opcode, GetOpcodeOffset(args[i++])); return(true); case 'E': // Effective address (EA) return(TryParseOperand(opcode, GetOpcodeOffset(args[i++]), dataWidth, rdr, out op)); case 'e': // Effective address with 3-bit halves swapped return(TryParseSwappedOperand(opcode, GetOpcodeOffset(args[i++]), dataWidth, rdr, out op)); case 'I': // Immediate operand return(TryGetImmediate(rdr, GetSizeType(0, args[i++], dataWidth), out op)); case 'J': // PC Relative jump return(TryPcRelative(rdr, opcode, out op)); case 'M': // Register bitset var size = GetSizeType(0, args[i++], dataWidth); op = new RegisterSetOperand(rdr.ReadBeUInt16(), size); return(true); case 'n': // cache bitset bitSet = rdr.ReadBeUInt16(); break; case 'm': // Register bitset reversed size = GetSizeType(0, args[i++], dataWidth); op = RegisterSetOperand.CreateReversed(bitSet, size); return(true); case 'q': // "Small" quick constant (3-bit part of the opcode) op = GetQuickImmediate(GetOpcodeOffset(args[i++]), 0x07, 8, PrimitiveType.Byte); return(true); case 'Q': // "Large" quick constant (8-bit part of the opcode) op = GetQuickImmediate(GetOpcodeOffset(args[i++]), 0xFF, 0, PrimitiveType.SByte); return(true); case 'R': // relative addr = rdr.Address; int relative = 0; switch (args[i++]) { case 'w': relative = rdr.ReadBeInt16(); break; case 'l': relative = rdr.ReadBeInt32(); break; default: throw new NotImplementedException(); } op = new M68kAddressOperand(addr + relative); return(true); case 's': // SR register op = new RegisterOperand(Registers.sr); return(true); case '+': // Postincrement operator; following character specifies bit offset of the address register code. op = new PostIncrementMemoryOperand(dataWidth, AddressRegister(opcode, GetOpcodeOffset(args[i++]))); return(true); case '-': // Predecrement operator; following character specifies bit offset of the address register code. op = new PredecrementMemoryOperand(dataWidth, AddressRegister(opcode, GetOpcodeOffset(args[i++]))); return(true); default: throw new FormatException(string.Format("Unknown argument type {0}.", args[--i])); } } }