예제 #1
0
 bool retf(List <OutputBlock> ret, AsmParser.ParseOutput op, List <AsmParser.ParseOutput> prefixes,
           List <AsmParser.ParseOutput> parameters, AssemblerState state)
 {
     ret.Add(new CodeBlock {
         Code = new byte[] { 0xcb }
     });
     return(true);
 }
예제 #2
0
        private OpcodeImplementation.OpcodeDelegate FindOperation(AsmParser.ParseOutput op, List <AsmParser.ParseOutput> prefixes, List <AsmParser.ParseOutput> parameters, AssemblerState state)
        {
            if (!opcodes.ContainsKey(op.Name))
            {
                return(null);
            }
            List <OpcodeImplementation> ops = opcodes[op.Name];

            if (ops == null)
            {
                return(null);
            }
            foreach (OpcodeImplementation oi in ops)
            {
                // Match prefixes
                bool allowed = true;
                foreach (AsmParser.ParseOutput prefix in prefixes)
                {
                    if (!oi.AllowedPrefixes.Contains(prefix.Name.ToLower()))
                    {
                        allowed = false;
                        break;
                    }
                }
                if (!allowed)
                {
                    continue;
                }

                // Match parameters
                if (parameters.Count != oi.ParamConstraints.Count)
                {
                    continue;
                }

                for (int i = 0; i < parameters.Count; i++)
                {
                    Location l = ParseLocation(parameters[i]);
                    if (!MatchConstraint(oi.ParamConstraints[i], l))
                    {
                        allowed = false;
                        break;
                    }
                }
                if (!allowed)
                {
                    continue;
                }

                return(oi.emitter);
            }
            return(null);
        }
예제 #3
0
        bool mov_r3264_creg(List <OutputBlock> ret, AsmParser.ParseOutput op, List <AsmParser.ParseOutput> prefixes,
                            List <AsmParser.ParseOutput> parameters, AssemblerState state)
        {
            Reg r  = regs[parameters[1].Name];
            Reg rm = regs[parameters[0].Name];

            AppendRex(ret, GenerateRex(false, r, rm));
            ret.Add(new CodeBlock {
                Code = new byte[] { 0x0f, 0x20 }
            });
            AppendModRM(ret, r, rm, state);
            return(true);
        }
예제 #4
0
        private void AssembleLabel(AsmParser.ParseOutput line_entry, AssemblerState state)
        {
            Label l = new Label {
                Name = line_entry.Name, ObjectType = binary_library.SymbolObjectType.Unknown, Type = binary_library.SymbolType.Local
            };

            if (state.sym_types.ContainsKey(line_entry.Name))
            {
                l.Type = state.sym_types[line_entry.Name];
            }
            if (state.sym_obj_types.ContainsKey(line_entry.Name))
            {
                l.ObjectType = state.sym_obj_types[line_entry.Name];
            }
            state.OutputBlocks.Add(l);
        }
예제 #5
0
        private void AssembleOperation(AsmParser.ParseOutput line_entry, AssemblerState state)
        {
            // Interpret the operation
            List <AsmParser.ParseOutput> prefixes = new List <AsmParser.ParseOutput>();

            AsmParser.ParseOutput        op         = null;
            List <AsmParser.ParseOutput> parameters = new List <AsmParser.ParseOutput>();

            foreach (AsmParser.ParseOutput p in line_entry.Children)
            {
                switch (p.Type)
                {
                case AsmParser.ParseOutput.OutputType.Operation:
                    if (op != null)
                    {
                        throw new Exception("More than one operation per line");
                    }
                    op = p;
                    break;

                case AsmParser.ParseOutput.OutputType.Prefix:
                    prefixes.Add(p);
                    break;

                case AsmParser.ParseOutput.OutputType.Parameter:
                    if (p.Children.Count > 1)
                    {
                        throw new Exception("Only one parameter child allowed");
                    }
                    parameters.Add(p.Children[0]);
                    break;

                default:
                    throw new Exception("Unsupported operation argument type: " + p.ToString());
                }
            }

            // Now get the appropriate operations
            OpcodeImplementation.OpcodeDelegate del = FindOperation(op, prefixes, parameters, state);
            if ((del == null) || (!del(state.OutputBlocks, op, prefixes, parameters, state)))
            {
                throw new Exception("Unable to assemble: " + line_entry.ToString());
            }
        }
예제 #6
0
        static void Main(string[] args)
        {
            // Load a test file
            string       test_file = "..\\..\\..\\libsupcs\\x86_64_cpu.asm";
            FileStream   fs        = new FileStream(test_file, FileMode.Open, FileAccess.Read);
            StreamReader sr        = new StreamReader(fs);
            string       file      = sr.ReadToEnd();

            // Tokenize and parse
            List <Tokenizer.TokenDefinition> tokens = Tokenizer.Tokenize(file, Tokenizer.CAsmTokenGrammar, Tokenizer.NasmPreprocessorOptions);

            AsmParser.ParseOutput parsed = AsmParser.Parse(tokens);

            // Create an output file
            binary_library.IBinaryFile output_file = binary_library.BinaryFile.CreateBinaryFile("elf");

            // Assemble to the output file
            Assembler ass = new x86_Assembler();

            ass.Assemble(parsed, output_file);
        }
예제 #7
0
        public void Assemble(AsmParser.ParseOutput input, binary_library.IBinaryFile output)
        {
            AssemblerState state = CreateAssemblerState(output);

            if (input.Type != AsmParser.ParseOutput.OutputType.Block)
            {
                throw new Exception("Expected Block");
            }

            foreach (AsmParser.ParseOutput line in input.Children)
            {
                if (line.Type != AsmParser.ParseOutput.OutputType.Line)
                {
                    throw new Exception("Expected Line");
                }

                foreach (AsmParser.ParseOutput line_entry in line.Children)
                {
                    switch (line_entry.Type)
                    {
                    case AsmParser.ParseOutput.OutputType.DirectiveCommand:
                        AssembleDirective(line_entry, state);
                        break;

                    case AsmParser.ParseOutput.OutputType.OpCommand:
                        AssembleOperation(line_entry, state);
                        break;

                    case AsmParser.ParseOutput.OutputType.Label:
                        AssembleLabel(line_entry, state);
                        break;

                    default:
                        throw new NotSupportedException();
                    }
                }
            }
        }
예제 #8
0
        private void AssembleDirective(AsmParser.ParseOutput line_entry, AssemblerState state)
        {
            AsmParser.ParseOutput dir = line_entry.Children[0];

            // Interpret directives
            if ((dir.Name == "weak") || (dir.Name == "global"))
            {
                // these are of the form <weak | global> <label> [:function | :data]
                string t_name = line_entry.Children[1].Children[0].Name;
                binary_library.SymbolType       st  = binary_library.SymbolType.Undefined;
                binary_library.SymbolObjectType sot = binary_library.SymbolObjectType.Unknown;

                if (dir.Name == "weak")
                {
                    st = binary_library.SymbolType.Weak;
                }
                else if (dir.Name == "global")
                {
                    st = binary_library.SymbolType.Global;
                }

                if (line_entry.Children.Count >= 3)
                {
                    string ot_name = line_entry.Children[2].Children[0].Name;
                    if (ot_name == "function")
                    {
                        sot = binary_library.SymbolObjectType.Function;
                    }
                    else if (ot_name == "data")
                    {
                        sot = binary_library.SymbolObjectType.Object;
                    }
                }

                if (st != binary_library.SymbolType.Undefined)
                {
                    state.sym_types[t_name] = st;
                }
                if (sot != binary_library.SymbolObjectType.Unknown)
                {
                    state.sym_obj_types[t_name] = sot;
                }
            }
            else if (dir.Name == "extern")
            {
                string t_name = line_entry.Children[1].Name;
                if (!state.extern_labels.Contains(t_name))
                {
                    state.extern_labels.Add(t_name);
                }
            }
            else if (dir.Name == "bits16")
            {
                state.cur_bitness = binary_library.Bitness.Bits16;
            }
            else if (dir.Name == "bits32")
            {
                state.cur_bitness = binary_library.Bitness.Bits32;
            }
            else if (dir.Name == "bits64")
            {
                state.cur_bitness = binary_library.Bitness.Bits64;
            }
            else
            {
                throw new NotImplementedException();
            }
        }
예제 #9
0
        protected virtual Location ParseLocation(AsmParser.ParseOutput param)
        {
            switch (param.Type)
            {
            case AsmParser.ParseOutput.OutputType.Label:
                return(new Location {
                    AType = Location.LocationType.Label, A = param.Name
                });

            case AsmParser.ParseOutput.OutputType.Number:
                return(new Location {
                    AType = Location.LocationType.Number, A = param.Name
                });

            case AsmParser.ParseOutput.OutputType.Register:
                return(new Location {
                    AType = Location.LocationType.Register, A = param.Name
                });

            case AsmParser.ParseOutput.OutputType.ContentsOf:
                AsmParser.ParseOutput p = param.Children[0];
                if (p.Type != AsmParser.ParseOutput.OutputType.Parameter)
                {
                    throw new NotSupportedException();
                }
                AsmParser.ParseOutput e = p.Children[0];
                if (e.Type != AsmParser.ParseOutput.OutputType.Expression)
                {
                    throw new NotSupportedException();
                }
                Location l = ParseLocation(e.Children[0]);
                l.ModifierType = Location.LocationModifierType.ContentsOf;
                if (e.Children.Count > 1)
                {
                    if (e.Children[1].Type != AsmParser.ParseOutput.OutputType.NumOp)
                    {
                        throw new NotSupportedException();
                    }
                    AsmParser.ParseOutput nop = e.Children[1];
                    if (nop.Name == "+")
                    {
                        l.NumOp = Location.NumOpType.Plus;
                    }
                    else if (nop.Name == "-")
                    {
                        l.NumOp = Location.NumOpType.Minus;
                    }
                    else
                    {
                        throw new NotSupportedException();
                    }
                    Location b = ParseLocation(e.Children[2]);
                    l.BType = b.AType;
                    l.B     = b.A;
                }
                return(l);

            default:
                throw new NotSupportedException();
            }
        }
예제 #10
0
 bool mov_creg_r3264(List <OutputBlock> ret, AsmParser.ParseOutput op, List <AsmParser.ParseOutput> prefixes,
                     List <AsmParser.ParseOutput> parameters, AssemblerState state)
 {
     return(true);
 }