Ejemplo n.º 1
0
        private bool createLines()
        {
            if (linesCreated.HasValue)
            {
                return((bool)linesCreated);
            }
            linesCreated = false; // temporary result until work completed

            ArmAssembly.AssembledProgram ap = JM.AssembledProgram;
            if (ap == null)
            {
                return(false);             // added by NH: 10-04-2015
            }
            _codeViewList.SuspendLayout();
            _codeViewList.Items.Clear();
            Errors = false;

            // it is an object code or executable file

            ArmAssembly.ObjFromAsmFileInfo pi = _PI as ArmAssembly.ObjFromAsmFileInfo;
            if (pi != null)
            {
                ArmAssembly.SectionType sect = ArmAssembly.SectionType.Text;
                for (int i = 0; i < pi.SourceLines.Length; i++)
                {
                    ListLine newLine = analyzeLine(pi, i, ref sect);
                    _codeViewList.Items.Add(newLine);
                }
            }
            else
            {
                uint textAddress = (uint)(_PI.SectionAddress[(int)(ArmAssembly.SectionType.Text)]);
                uint dataAddress = (uint)(_PI.SectionAddress[(int)(ArmAssembly.SectionType.Data)]);
                uint bssAddress  = (uint)(_PI.SectionAddress[(int)(ArmAssembly.SectionType.Bss)]);

                // get sorted list of code labels to intersperse in the code listing
                AddressLabelPair[] cl;
                int clLen;
                if (JM.CodeLabels == null)
                {
                    cl    = null;
                    clLen = 0;
                }
                else
                {
                    cl    = JM.CodeLabels.CodeLabelList();
                    clLen = cl.Length;
                }
                ArmAssembly.DisassembleARM.CurrentLabels = cl;
                int clix = 0;
                while (clix < clLen && cl[clix].Address < textAddress)
                {
                    clix++;
                }
                uint addrss     = textAddress;
                uint endAddress = (uint)(textAddress + _PI.SectionSize[(int)(ArmAssembly.SectionType.Text)]);
                while (addrss < endAddress)
                {
                    while (clix < clLen && cl[clix].Address <= addrss)
                    {
                        _codeViewList.Items.Add(
                            new ListLine(_drawParameters, cl[clix].Label + ":", cl[clix].Address, this));
                        clix++;
                    }
                    string contents;
                    uint   opcode;
                    if (ap != null)
                    {
                        opcode   = ap.LoadWord((int)addrss);
                        contents = "    " + ArmAssembly.DisassembleARM.DisassembleARMInstruction(opcode, addrss);
                    }
                    else
                    {
                        opcode   = 0;
                        contents = "     <<disassembly not available>>";
                    }
                    _codeViewList.Items.Add(new ObjectCodeLine(_drawParameters, addrss, opcode, contents, this));
                    addrss += 4;
                }
                while (clix < clLen && cl[clix].Address < dataAddress)
                {
                    clix++;
                }
                addrss     = dataAddress;
                endAddress = (uint)(dataAddress + _PI.SectionSize[(int)(ArmAssembly.SectionType.Data)]);
                // Generate labels for the defined data area.  We display up to 16 bytes per line.
                while (addrss < endAddress)
                {
                    string hex;
                    uint   nextLabel      = clix < clLen ? cl[clix].Address : (uint)ap.BssStart;
                    int    bytesToDisplay = (int)nextLabel - (int)addrss;
                    if ((addrss & 0x3) != 0)
                    {
                        int oddBytes = 4 - (int)(addrss & 0x3);
                        if (oddBytes > bytesToDisplay)
                        {
                            oddBytes = bytesToDisplay;
                        }
                        hex = convertBytes(oddBytes, addrss);
                        _codeViewList.Items.Add(
                            new ObjectCodeLine(_drawParameters, addrss, ".byte", hex, this));
                        bytesToDisplay -= oddBytes;
                        addrss         += (uint)oddBytes;
                    }
                    while (bytesToDisplay >= 16)
                    {
                        hex = String.Format(
                            "0x{0,8:X8}, 0x{1,8:X8}, 0x{2,8:X8}, 0x{3,8:X8}",
                            ap.LoadWord((int)addrss), ap.LoadWord((int)addrss + 4),
                            ap.LoadWord((int)addrss + 8), ap.LoadWord((int)addrss + 12));
                        _codeViewList.Items.Add(
                            new ObjectCodeLine(_drawParameters, addrss, ".word", hex, this));
                        addrss         += 16;
                        bytesToDisplay -= 16;
                    }
                    if (bytesToDisplay > 0)
                    {
                        if (bytesToDisplay >= 4)
                        {
                            hex = "";
                            string sep  = "";
                            uint   addr = addrss;
                            while (bytesToDisplay >= 4)
                            {
                                hex            += String.Format("{0} 0x{1,8:X8}", sep, ap.LoadWord((int)addrss));
                                sep             = ",";
                                addrss         += 4;
                                bytesToDisplay -= 4;
                            }
                            _codeViewList.Items.Add(
                                new ObjectCodeLine(_drawParameters, addr, ".word", hex, this));
                        }
                        if (bytesToDisplay > 0)
                        {
                            hex = convertBytes(bytesToDisplay, addrss);
                            _codeViewList.Items.Add(
                                new ObjectCodeLine(_drawParameters, addrss, ".byte", hex, this));
                            addrss += (uint)bytesToDisplay;
                        }
                    }
                    if (clix < clLen)
                    {
                        _codeViewList.Items.Add(
                            new ListLine(_drawParameters, cl[clix].Label + ":", cl[clix].Address, this));
                        clix++;
                    }
                }
                while (clix < clLen && cl[clix].Address < bssAddress)
                {
                    clix++;
                }
                addrss     = bssAddress;
                endAddress = (uint)(bssAddress + _PI.SectionSize[(int)(ArmAssembly.SectionType.Bss)]);
                // Generate labels in the BSS region
                while (addrss < endAddress)
                {
                    uint nextLabel      = clix < clLen ? cl[clix].Address : (uint)ap.EndAddress;
                    int  bytesToDisplay = (int)nextLabel - (int)addrss;
                    if (bytesToDisplay > 0)
                    {
                        _codeViewList.Items.Add(
                            new ObjectCodeLine(_drawParameters, addrss, ".space", bytesToDisplay.ToString(), this));
                        addrss = nextLabel;
                    }
                    if (clix < clLen)
                    {
                        _codeViewList.Items.Add(
                            new ListLine(_drawParameters, cl[clix].Label + ":", cl[clix].Address, this));
                        clix++;
                    }
                }
            }

            computeMaxWidth();
            _codeViewList.ResumeLayout();
            linesCreated = true;
            return(true);
        }//init
Ejemplo n.º 2
0
        /// <summary>
        /// Load a new program into the simulator. This function will compile it, load it and set up the
        /// simulator for a run.
        /// </summary>
        /// <param name="fileNames">list of filenames to load</param>
        /// <param name="preferences">ARMSim preferences</param>
        /// <returns>true if sucessful</returns>
        public bool Load(IList <string> fileNames)
        {
            this.ValidLoadedProgram = false;

            foreach (string str in fileNames)
            {
                if (str.EndsWith(".o") || str.EndsWith(".O"))
                {
                    OutputConsoleString("Loading object code file {0}\n", str);
                }
                else if (str.EndsWith(".a") || str.EndsWith(".A"))
                {
                    OutputConsoleString("Searching library archive {0}\n", str);
                }
                else
                {
                    OutputConsoleString("Loading assembly language file {0}\n", str);
                }
            }//foreach

            mArmAssembler = new ArmAssembly.ArmAssembler(fileNames);

            try
            {
                //perform pass 1 on all the files
                mArmAssembler.PerformPass();
                //ar.DumpInfo();
                if (ArmAssembly.AssemblerErrors.ErrorReports.Count <= 0)
                {
                    // now determine where everything will go in memory
                    mArmAssembler.PlaceCode((int)this.ARMPreferences.SimulatorPreferences.MemoryStart);
                    //ar.DumpInfo();

                    // allocate a block of memory for the assembled
                    // and linked program
                    mAssembledProgram = new ArmAssembly.AssembledProgram(mArmAssembler);

                    // perform pass 2 on all the files
                    mArmAssembler.PerformPass(mAssembledProgram);
                    //ar.DumpInfo();
                    //ap.Hexdump();	// display all code
                }
            }
            catch (Exception ex)
            {
                OutputConsoleString("A fatal error occurred while assembling the program, Reason:{0}\n", ex.Message);
                OutputConsoleString("Please keep a copy of the ARM source code and report this ARMSim bug!\n");
                return(false);
            }//catch

            if (ArmAssembly.AssemblerErrors.ErrorReports.Count > 0)
            {
                OutputConsoleString("The following assembler/loader errors occurred ...\n");
                IDictionary <string, IList <ArmAssembly.ErrorReport> > xxx = ArmAssembly.AssemblerErrors.ErrorReports.ErrorLists;

                //display each reported error in the outputview
                foreach (string fileName in xxx.Keys)
                {
                    OutputConsoleString("** File: {0}\n", fileName);
                    IList <ArmAssembly.ErrorReport> ht = ArmAssembly.AssemblerErrors.ErrorReports.GetErrorsList(fileName);
                    foreach (ArmAssembly.ErrorReport ce in ht)
                    {
                        string fmt;
                        if (ce.Col == 0)
                        {
                            if (ce.Line == 0)
                            {
                                fmt = "   Message = {0}\n";
                            }
                            else
                            {
                                fmt = "   Line {1}: Message = {0}\n";
                            }
                        }
                        else
                        {
                            fmt = "   Line {1}, col {2}: Message = {0}\n";
                        }
                        OutputConsoleString(fmt, ce.ErrorMsg, ce.Line, ce.Col);
                    }
                }
                OutputConsoleString("End of assembler errors\n");

                //all done for error case
                return(false);
            }

            //Construct the code labels data structure from the assembled program.
            mCodeLabels = new CodeLabels(mArmAssembler);

            //tell the simulator which directory to try for user files
            this.UserDirectory = System.IO.Path.GetDirectoryName(fileNames[0]);

            // set the program entry point to be the _start label if it exists;
            //   otherwise set it to the address of main if it exists;
            //   otherwise set it to the start of memory
            //save the entry point in case the user does a "Restart" but the preferences may have changed - dale
            if (!mCodeLabels.LabelToAddress("_start", ref mEntryPoint))
            {
                if (!mCodeLabels.LabelToAddress("main", ref mEntryPoint))
                {
                    mEntryPoint = (uint)mAssembledProgram.StartAddress;
                }
            }

            //define the simulation memory
            //save the stack pointer in case the user does a "Restart" but the preferences may have changed - dale
            mStackPointer = this.DefineMemory(this.ARMPreferences.SimulatorPreferences, mAssembledProgram.Memory.Length);

            //create the caches based on the user preferences
            this.DefineCache(this.ARMPreferences.CachePreferences);

            //perform a restart - loads code into memory, zeros cpu registers, sets pc and sp
            //note sets the ValidLoadedProgram flag to true
            this.Restart();

            return(true);
        }//Load