Esempio n. 1
0
        private Instruction[] ParseInstructions(XmlNode opList, ILProcessor proc)
        {
            List <Instruction>     ret = new List <Instruction>();
            List <QueuedGenerator> queuedGenerators = new List <QueuedGenerator>();

            foreach (XmlNode opNode in opList.ChildNodes)
            {
                if (opNode is XmlComment)
                {
                    continue;
                }
                //if (opNode.Attributes["name"] == null)
                //	continue;
                IInstructionGenerator instGen = ParseOpcode(opNode);
                Instruction           inst    = instGen.Generate(proc, ret);
                if (inst == null)
                {
                    inst = proc.Create(OpCodes.Nop);
                    queuedGenerators.Add(new QueuedGenerator(instGen, ret.Count));
                }
                ret.Add(inst);
            }
            foreach (QueuedGenerator curGen in queuedGenerators)
            {
                Instruction newInstr = curGen.generator.Generate(proc, ret);
                if (newInstr == null)
                {
                    throw new ArgumentOutOfRangeException("xmlpatchers.xml : Instruction reference out of range!");
                }
                Instruction prevInstr = ret[curGen.index];
                prevInstr.OpCode  = newInstr.OpCode;
                prevInstr.Operand = newInstr.Operand;
            }
            return(ret.ToArray());
        }
Esempio n. 2
0
        public OpCodeInfo(byte opCode, string assemblerKeyword, byte instructionSize, byte numberOfArguments, IInstructionGenerator instructionGenerator = null)
        {
            this.OpCode = opCode;
            this.AssemblerKeyword = assemblerKeyword;
            this.InstructionSize = instructionSize;
            this.NumberOfArguments = numberOfArguments;

            if (instructionSize > 1 && instructionGenerator == null)
                throw new ArgumentNullException("instructionGenerator", string.Format("[{0}]: instructionGenerator is required when the instruction size is greater than 1.", assemblerKeyword));

            this.InstructionGenerator = instructionGenerator;
        }
Esempio n. 3
0
        /// <summary>
        /// Generates code for a .text instruction in the file.
        /// </summary>
        /// <param name="fileName">The source file name.</param>
        /// <param name="asmLine">The line to parse.</param>
        /// <param name="objFile">The object file that will be written to.</param>
        /// <param name="currAlignment">The current specified alignment of the file. Unused for .text parsers.</param>
        public void GenerateCodeForSegment(string fileName, LineData asmLine, BasicObjectFile objFile, int currAlignment)
        {
            // scan to the first instruction.
            // this could share the same line as a label, so split on ':' and ','
            string[] tokenizedStr     = asmLine.Text.Split(new char[] { ',', ':', ' ' }, StringSplitOptions.RemoveEmptyEntries);
            bool     foundInstruction = false;

            string instructionToken = string.Empty;

            for (int i = 0; i < tokenizedStr.Length && !foundInstruction; ++i)
            {
                string token = tokenizedStr[i].Trim();
                // we found our instruction. build a string from this token
                // to the end of the array.
                if (m_ParserFac.IsInstruction(token))
                {
                    foundInstruction = true;
                    instructionToken = token;
                }
            }

            if (foundInstruction)
            {
                // first, validate that the instruction is not the last token in the string.
                // try to parse the instruction parameters
                // get the substring starting at the index of the next character after the instruction
                string instSubstring = asmLine.Text.Substring(asmLine.Text.IndexOf(instructionToken) + instructionToken.Length);

                //split the substring at the comma to get the instruction parameters.
                string[] argTokens = instSubstring.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

                // trim whitespace from the beginning and end of each token.
                argTokens = argTokens.Apply((str) => str.Trim()).ToArray();

                // find the parser for the instruction.
                IInstructionGenerator parser = m_ParserFac.GetProcessorForInstruction(instructionToken);

                // beq instructions should (hopefully) not generate multiple instructions..
                IEnumerable <int> generatedInstructions = parser.GenerateCodeForInstruction(m_CurrTextAddress, argTokens);

                var srcInfo = new SourceLineInformation(fileName, asmLine.LineNum, m_CurrTextAddress, asmLine.Text);
                objFile.AddSourceInformation(srcInfo);

                foreach (int generatedInstruction in generatedInstructions)
                {
                    objFile.AddInstruction(generatedInstruction);
                    m_CurrTextAddress += CommonConstants.BASE_INSTRUCTION_SIZE_BYTES;
                }
            }
            else
            {
                // if not an instruction (may be a symbol)
                // preprocesor instruction shouldn't bring us here.
                // make sure the user is not typing garbage.
                string symStr = tokenizedStr[0];
                if (!m_SymTbl.ContainsSymbol(symStr))
                {
                    throw new AssemblyException(asmLine.LineNum, "Unknown instruction \"" + asmLine.Text + "\" found.");
                }
            }
        }
Esempio n. 4
0
        private bool Matches(MethodDefinition method, XmlNode opList)
        {
            ILProcessor        proc   = method.Body.GetILProcessor();
            List <Instruction> instrs = new List <Instruction>(method.Body.Instructions);
            int i = 0;

            foreach (XmlNode opNode in opList.ChildNodes)
            {
                if (opNode is XmlComment)
                {
                    continue;
                }
                int          index;
                XmlAttribute indexAttribute = opNode.Attributes["index"];
                if (indexAttribute == null)
                {
                    index = i++;
                }
                else
                {
                    index = Int32.Parse(indexAttribute.Value);
                    if (index < 0)
                    {
                        index += instrs.Count;
                    }
                    i = index + 1;
                }
                if (index >= instrs.Count || index < 0)
                {
                    return(false);
                }
                //if (opNode.Attributes["name"] == null)
                //	continue;
                IInstructionGenerator instGen = ParseOpcode(opNode);
                if (instGen.GetOpCode() != instrs[index].OpCode)
                {
                    return(false);
                }
                if (instGen.HasOperand() != (instrs[index].Operand != null))
                {
                    continue;
                }
                Instruction inst = instGen.Generate(proc, instrs);
                if (inst == null)
                {
                    return(false);
                }

                object methodOp     = instrs[index].Operand;
                object compareOp    = inst.Operand;
                Type   methodOpType = instrs[index].Operand.GetType();
                if (methodOpType != inst.Operand.GetType())
                {
                    return(false);
                }
                switch (methodOpType.Name)
                {
                case "Byte":
                    if ((Byte)methodOp != (Byte)compareOp)
                    {
                        return(false);
                    }
                    break;

                case "SByte":
                    if ((SByte)methodOp != (SByte)compareOp)
                    {
                        return(false);
                    }
                    break;

                case "Int32":
                    if ((Int32)methodOp != (Int32)compareOp)
                    {
                        return(false);
                    }
                    break;

                case "Int64":
                    if ((Int64)methodOp != (Int64)compareOp)
                    {
                        return(false);
                    }
                    break;

                case "Single":
                    if ((Single)methodOp != (Single)compareOp)
                    {
                        return(false);
                    }
                    break;

                case "Double":
                    if ((Double)methodOp != (Double)compareOp)
                    {
                        return(false);
                    }
                    break;

                case "String":
                    if (!methodOp.Equals(compareOp))
                    {
                        return(false);
                    }
                    break;

                case "Instruction":
                    if (methodOp != compareOp)
                    {
                        return(false);
                    }
                    break;

                case "TypeReference":
                    if (!((TypeReference)methodOp).FullName.Equals(((TypeReference)compareOp).FullName))
                    {
                        return(false);
                    }
                    break;

                case "FieldReference":
                    if (!((FieldReference)methodOp).FullName.Equals(((FieldReference)compareOp).FullName))
                    {
                        return(false);
                    }
                    break;

                case "MethodReference":
                    if (!((MethodReference)methodOp).ToString().Equals(((MethodReference)compareOp).ToString()))                             //ToString includes the method
                    {
                        return(false);
                    }
                    break;

                default:
                    logger.Warning("XmlPatches : Nobody told me how to compare two " + methodOpType.Name + "s!");
                    break;
                }
            }
            return(true);
        }
Esempio n. 5
0
 public QueuedGenerator(IInstructionGenerator generator, int index)
 {
     this.generator = generator;
     this.index     = index;
 }