Ejemplo n.º 1
0
        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();
        }
Ejemplo n.º 2
0
        /// <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]));
                }
            }
        }