Пример #1
0
        private ushort GetOperand(ParsedInstruction currentLine, out Error error)
        {
            if (currentLine.operandExpression == null)
            {
                error = Error.None;
                return(currentLine.operandValue.Value);
            }
            if (currentLine.operandExpression != null)
            {
                StringSection expression = currentLine.operandExpression;

                var result = Assembler.Evaluator.EvaluateExpression(ref expression, currentLine.sourceLine, out error).Value;

                if (error.Code != ErrorCode.None)
                {
                    error = new Error(error, currentLine.sourceLine);
                    return(0);
                }
                else if (!expression.IsNullOrEmpty)
                {
                    error = new Error(ErrorCode.Invalid_Expression, Error.Msg_InvalidExpression, currentLine.sourceLine);
                    return(0);
                }
                return(result);
            }

            error = new Error(ErrorCode.Engine_Error, "Instruction required an operand, but none was present. Instruction may have been mis-parsed.", currentLine.sourceLine);
            return(0);
        }
Пример #2
0
        public Script(Resource res, bool translated)
        {
            Resource    = res;
            _translated = translated;

            SourceData = res.GetContent(translated);

            ushort i = 0;

            while (i < SourceData.Length)
            {
                SectionType type = (SectionType)Helpers.GetUShortBE(SourceData, i);
                if (type == SectionType.None)
                {
                    break;
                }

                ushort size = (ushort)(Helpers.GetUShortBE(SourceData, i + 2) - 4);
                i += 4;

                Section sec = Section.Create(this, type, SourceData, i, size);
                Sections.Add(sec);
                i += size;

                if (sec is StringSection)
                {
                    _strings = (StringSection)sec;
                }
            }

            foreach (var sec in Sections)
            {
                sec.SetupByOffset();
            }
        }
        public IList <StringSection> ProcessString(string rawText)
        {
            const string spanPattern = @"(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+";

            MatchCollection collection = Regex.Matches(rawText, spanPattern, RegexOptions.None);
            var             sections   = new List <StringSection>();

            foreach (Match item in collection)
            {
                var lastIndex = 0;
                var foundText = item.Value;
                var tt        = rawText.Substring(lastIndex);
                var index     = tt.IndexOf(foundText);
                if (lastIndex != index)
                {
                    var tmpSS = new StringSection()
                    {
                        Text = rawText.Substring(lastIndex, index - lastIndex)
                    };
                    sections.Add(tmpSS);
                    lastIndex = lastIndex + item.Length + index;
                }
                var ss = new StringSection()
                {
                    Text = rawText.Substring(index, item.Length), Link = item.Value
                };

                sections.Add(ss);
                rawText = rawText.Substring(lastIndex);
            }

            return(sections);
        }
Пример #4
0
        public override void Process(Pass pass, out Error error)
        {
            error = Error.None;

            LiteralValue value;

            if (Address.IsExpression)
            {
                StringSection exp = Address.Expression;

                value = pass.Assembler.Evaluator.EvaluateExpression(ref exp, SourceLine, out error);

                if (error.Code == ErrorCode.None)
                {
                    if (exp.Length != 0)
                    {
                        error = new Error(ErrorCode.Unexpected_Text, Error.Msg_InvalidExpression, SourceLine);
                        return;
                    }
                }
                else
                {
                    return;
                }
            }
            else
            {
                value = Address.Literal;
            }

            pass.SetAddress(value.Value);
        }
Пример #5
0
        /// <summary>
        /// Returns a symbol name, or a zero-length string of no symbol was found.
        /// </summary>
        /// <param name="exp"></param>
        /// <returns></returns>
        private StringSection GetSymbol(StringSection exp)
        {
            // Check for special '$' variable
            if (exp.Length > 0 && exp[0] == '$' && !char.IsLetter(exp[0]) && !char.IsDigit(exp[0]))
            {
                return("$");
            }

            if (exp.Length == 0)
            {
                return(StringSection.Empty);
            }
            if (!char.IsLetter(exp[0]) && exp[0] != '@')
            {
                return(StringSection.Empty);
            }

            int i = 1;

            while (i < exp.Length)
            {
                char c = exp[i];
                if (char.IsLetter(c) | char.IsDigit(c) | c == '_')
                {
                    i++;
                }
                else
                {
                    var result = exp.Substring(0, i);
                    return(result);
                }
            }
            return(exp);
        }
Пример #6
0
        private Span CreateSpan(StringSection section)
        {
            var text = section.Text.StripHtml()?.Trim();

            if (string.IsNullOrEmpty(text))
            {
                return(null);
            }

            text = Regex.Replace(section.Text, "<br.*?>|<.?p>", "\n")
                   .StripHtml();

            var span = new Span
            {
                Text = text
            };

            if (!string.IsNullOrEmpty(section.Link))
            {
                span.GestureRecognizers.Add(new TapGestureRecognizer()
                {
                    Command          = new Command <string>(OpenLink),
                    CommandParameter = section.Link
                });
                span.TextColor       = Color.FromHex("#0072bc");
                span.TextDecorations = TextDecorations.Underline;
            }

            return(span);
        }
        private Span CreateSpan(StringSection section)
        {
            var span = new Span()
            {
                Text = section.Text
            };

            switch (section.CommandType)
            {
            case CommandType.Url:
                span.GestureRecognizers.Add(new TapGestureRecognizer()
                {
                    Command          = openUrlCommand,
                    CommandParameter = section.Parameter
                });
                span.TextColor = (Color)App.Current.Resources["LinkTextColor"];
                break;

            case CommandType.Group:
                span.GestureRecognizers.Add(new TapGestureRecognizer()
                {
                    Command          = openGroupCommand,
                    CommandParameter = section.Parameter
                });
                span.TextColor = (Color)App.Current.Resources["LinkTextColor"];
                break;
            }

            return(span);
        }
Пример #8
0
        private bool IsDirective(StringSection directiveName)
        {
            int listStart = 0;
            int listEnd   = directiveNames.Length / 2; // Exclusive

            int listCount = listEnd - listStart;

            while (listCount > 1)
            {
                // first item of second half
                int split = listStart + listCount / 2;

                var splitText = directiveNames[split];
                var compare   = StringSection.Compare(directiveName, splitText, true);
                if (compare == 0)
                {
                    return(true);
                }
                if (compare > 0)   // directiveName > splitText
                {
                    listStart = split;
                }
                else
                {
                    listEnd = split;
                }

                listCount = listEnd - listStart;
            }
            return(StringSection.Compare(directiveName, directiveNames[listStart], true) == 0);
        }
Пример #9
0
        private void ParsePlusOrMinusLabel(ref StringSection line, char labelChar, int iInstruction, int iSourceLine)
        {
            int charCount = 1; // Number of times the label char (+ or -) appears

            while (charCount < line.Length && line[charCount] == labelChar)
            {
                charCount++;
            }


            if (labelChar == '+')
            {
                assembly.AnonymousLabels.AddPlusLabel(charCount, iSourceLine);
            }
            else if (labelChar == '-')
            {
                assembly.AnonymousLabels.AddMinusLabel(charCount, iSourceLine);
            }
            else
            {
                throw new ArgumentException("Invalid label character for +/- label.", "labelChar");
            }
            assembly.TagAnonLabel(iInstruction, iSourceLine);

            line = line.Substring(charCount).Trim();
            // Remove colon if present
            if (line.Length > 0 && line[0] == ':')
            {
                line = line.Substring(1).TrimLeft();
            }
        }
Пример #10
0
 public Assignment(int instructionIndex, int sourceLine, StringSection variable, bool isLabel, AsmValue value)
     : base(instructionIndex, sourceLine)
 {
     this.Variable = variable;
     this.Value    = value;
     this.IsLabel  = isLabel;
 }
Пример #11
0
        private void RemoveComments(ref StringSection line)
        {
            // ; denotes a comment, except within a string
            bool inString = false;

            for (int i = 0; i < line.Length; i++)
            {
                if (inString)
                {
                    if (line[i] == '\"')   // End of string
                    // unless it is preceeded by a backslash (then it's as escaped quote)
                    {
                        if (i == 0 || line[i - 1] != '\\')
                        {
                            inString = false;
                        }
                    }
                }
                else
                {
                    if (line[i] == ';')   // Comment
                    {
                        line = line.Substring(0, i);
                        return;
                    }
                    else if (line[i] == '\"')     // Start of string
                    {
                        inString = true;
                    }
                }
            }
        }
Пример #12
0
 private void StoreEditList()
 {
     if (treeSections.SelectedNode != null && _targetStrings != null && _modifiedSection)
     {
         if (_targetSection >= 0)
         {
             StringSection section = _targetStrings._sections[_targetSection];
             section._localizedStrings = new List <StringLocalized>();
             foreach (StringLocalized newString in _editList.Values)
             {
                 section.LocalizedStrings.Add(newString);
             }
         }
         else
         {
             StringSection section = new StringSection();
             section._name             = _defaultStrings._sections[_currentSection].SectionName;
             section._localizedStrings = new List <StringLocalized>();
             foreach (StringLocalized newString in _editList.Values)
             {
                 section.LocalizedStrings.Add(newString);
             }
             _targetStrings.Sections.Add(section);
         }
         _modifiedSection = false;
     }
 }
Пример #13
0
 private void Write(StringSection ss)
 {
     sb.AppendLine($"[String section]");
     foreach (var s in ss.Strings)
     {
         sb.AppendLine($"{s.Address:x4} = '{s.GetStringEscape()}'");
     }
 }
Пример #14
0
        private static void StripComments(ref StringSection line)
        {
            int iComment = line.IndexOf(';');

            if (iComment >= 0)
            {
                line = line.Substring(0, iComment);
            }
            line = line.Trim();
        }
Пример #15
0
        private StringSection ParseDirectiveName(StringSection text)
        {
            int i = 0;

            while (i < text.Length && Char.IsLetter(text[i]))
            {
                i++;
            }
            return(text.Substring(0, i));
        }
Пример #16
0
        public IncBinDirective(int instructionIndex, int sourceLine, StringSection file)
            : base(instructionIndex, sourceLine)
        {
            file = file.Trim();
            if (file.Length > 1 && file[0] == '\"' && file[file.Length - 1] == '\"')
            {
                file = file.Substring(1, file.Length - 2);
            }

            this.Filename = file.ToString();
        }
Пример #17
0
        private bool ParseNamedLabels(ref StringSection line, int iParsedLine, int iSourceLine)
        {
            int iColon = line.IndexOf(':');

            if (iColon < 0)
            {
                return(false);
            }

            if ((line.Length - 1 > iColon) && (line[iColon + 1] == '='))
            {
                // := is not a label
                return(false);
            }

            var labelName = line.Substring(0, iColon).Trim();

            // Todo: should be able to validate via a 'parse symbol' func

            // Check for nonzero length and that label starts with letter or @
            if (labelName.Length == 0)
            {
                return(false);
            }
            if (!char.IsLetter(labelName[0]) && labelName[0] != '@')
            {
                return(false);
            }

            for (int i = 1; i < labelName.Length; i++)   // i = 1 because we've already checked zero
            {
                if (!char.IsLetter(labelName[i]) && !char.IsDigit(labelName[i]) && labelName[i] != '_')
                {
                    return(false);
                }
            }

            if (labelName[0] == '@')                                                 // Local label
            {
                labelName = labelName.Substring(1);                                  // Remove @
                string fullName = mostRecentNamedLabel + "." + labelName.ToString(); // example: SomeFunction.LoopTop
                assembly.Labels.Add(new Label(fullName, iParsedLine, iSourceLine, true));
            }
            else     // Normal label
            {
                var sLabelName = labelName.ToString();
                mostRecentNamedLabel = sLabelName;
                assembly.Labels.Add(new Label(sLabelName, iParsedLine, iSourceLine, false));
            }
            line = line.Substring(iColon + 1).TrimLeft();

            return(true);
        }
Пример #18
0
        private void ProcessDirective(StringSection directiveName, StringSection directiveText)
        {
            string directive = directiveName.ToString().ToUpper();

            switch (directive)
            {
            case "ORG":

            default:
                break;
            }
        }
Пример #19
0
        public void Process(StringSection source, List <StringSection> output, IFileSystem files)
        {
            bool moreLines = !source.IsNullOrEmpty;

            while (moreLines)
            {
                int           iLineBreak = source.IndexOfAny(lineBreaks);
                StringSection line;

                if (iLineBreak == -1)
                {
                    // Last line
                    line      = source;
                    source    = StringSection.Empty;
                    moreLines = false;
                }
                else
                {
                    line = source.Substring(0, iLineBreak);
                    bool isCRLF = (source[iLineBreak] == '\r') && (source.Length > iLineBreak + 1) && (source[iLineBreak + 1] == '\n');
                    if (isCRLF)
                    {
                        source = source.Substring(iLineBreak + 2);
                    }
                    else
                    {
                        source = source.Substring(iLineBreak + 1);
                    }
                }

                if (IsIncludeLine(line))
                {
                    string includeFile = line.Substring(includeDirective.Length).Trim().ToString();
                    // Need to remove optional quotes
                    if (includeFile.Length >= 2 && includeFile[0] == '\"' && includeFile[includeFile.Length - 1] == '\"')
                    {
                        includeFile = includeFile.Substring(1, includeFile.Length - 2).Trim();
                    }
                    if (assembler.FileSystem.FileExists(includeFile))
                    {
                        ProcessInclude(output, files, includeFile);
                    }
                    else
                    {
                        assembler.AddError(new Error(ErrorCode.File_Error, string.Format(Error.Msg_FileNotFound_name, includeFile), output.Count));
                    }
                }
                else
                {
                    output.Add(line);
                }
            }
        }
Пример #20
0
        /// <summary>
        /// Returns a value between 0 and 255, or -1 if no opcode was found, or -2 if the addressing mode is not available for the instruction..
        /// </summary>
        /// <param name="instruction"></param>
        /// <param name="addressing"></param>
        /// <returns></returns>
        private int FindOpcode(StringSection instruction, Opcode.addressing addressing)
        {
            var  ops = Opcode.allOps;
            bool instructionFound        = false;
            bool foundInstructionInvalid = false;

            for (int i = 0; i < Opcode.allOps.Length; i++)
            {
                if (StringEquals(ops[i].name, instruction, true))
                {
                    // Note that the instruction exists. We need to tell the user whether
                    // an instruction does not exist or the desired addressing mode is not available.
                    instructionFound = true;

                    var addrMode = ops[i].addressing;

                    // Branch instructions will be treated as absolute until they are actually encoded.
                    if (addrMode == Opcode.addressing.relative)
                    {
                        addrMode = Opcode.addressing.absolute;
                    }

                    if (addressing == addrMode)
                    {
                        if (ops[i].valid | Assembler.AllowInvalidOpcodes)
                        {
                            return(i);
                        }
                        else
                        {
                            foundInstructionInvalid = true;
                        }
                    }
                }
            }

            if (instructionFound)
            {
                if (foundInstructionInvalid)
                {
                    return((int)OpcodeError.InvalidOpcode);
                }
                else
                {
                    return((int)OpcodeError.InvalidAddressing);
                }
            }
            else
            {
                return((int)OpcodeError.UnknownInstruction);
            }
        }
Пример #21
0
 private void WriteStrings(StringSection section)
 {
     sb.AppendLine("(string");
     if (section != null)
     {
         foreach (var str in section.Strings)
         {
             sb.AppendFormat("    string_{0:x4} \"{1}\"", str.Address, str.Value).AppendLine();
         }
     }
     sb.AppendLine(")");
     sb.AppendLine();
 }
Пример #22
0
        private void tvSections_AfterSelect(object sender, TreeViewEventArgs e)
        {
            _currentSection = tvSections.SelectedNode.Index;
            StringSection section = _defaultStrings._sections[_currentSection];

            lvStrings.Items.Clear();
            foreach (StringLocalized defaultString in section.LocalizedStrings)
            {
                ListViewItem stringItem = new ListViewItem(defaultString.StringName);
                stringItem.SubItems.Add(defaultString.Text);
                lvStrings.Items.Add(stringItem);
            }
        }
Пример #23
0
        private bool IsIncludeLine(StringSection line)
        {
            if (line.Length < includeDirective.Length)
            {
                return(false);
            }
            var lineStart = line.Substring(0, includeDirective.Length);

            if (StringSection.Compare(lineStart, includeDirective, true) == 0)
            {
                return(true);
            }
            return(false);
        }
Пример #24
0
        /// <summary>
        /// Returns a char array containing all the characters from a string. Escapes are processed. The specified string
        /// should not include the opening quote. The parsed string will be removed from the string passed in. The closing
        /// quote will not be removed, so that the caller can examine it and verify that there was a closing quote.
        /// </summary>
        /// <param name="section"></param>
        /// <returns></returns>
        public static char[] ParseString(ref StringSection str, out ErrorCode error)
        {
            error = ErrorCode.None;

            // Only one thread can run this method at a time
            lock (ParseLock) {
                charBuilder.Clear();

                while (str.Length > 0)
                {
                    char c = str[0];
                    if (c == '\"')
                    {
                        return(charBuilder.ToArray());
                    }
                    else if (c == '\\')
                    {
                        str = str.Substring(1);
                        if (str.Length > 0)
                        {
                            c = str[0];

                            int escapeIndex = Array.IndexOf(escapeCodes, c);
                            if (escapeIndex < 0)
                            {
                                error = ErrorCode.Invalid_Escape;
                                return(null);
                            }
                            else
                            {
                                charBuilder.Add(escapeValues[escapeIndex]);
                            }
                        }
                        else
                        {
                            error = ErrorCode.Invalid_Escape;
                            return(null);
                        }
                    }
                    else
                    {
                        charBuilder.Add(c);
                    }
                    str = str.Substring(1);
                }

                return(charBuilder.ToArray());
            }
        }
Пример #25
0
        bool EndsWith(StringSection text, string ending)
        {
            int diff = text.Length - ending.Length;

            if (diff < 0)
            {
                return(false);
            }
            for (int i = 0; i < ending.Length; i++)
            {
                if (text[i + diff] != ending[i])
                {
                    return(false);
                }
            }
            return(true);
        }
Пример #26
0
        private void lvCreateStrings_AfterLabelEdit(object sender, LabelEditEventArgs e)
        {
            if (e.Label == null)
            {
                return;
            }
            StringSection stringSection = (StringSection)tvCreateSections.SelectedNode.Tag;

            foreach (StringLocalized str in stringSection.LocalizedStrings)
            {
                if (str.StringName == lvCreateStrings.Items[e.Item].SubItems[1].Text)
                {
                    str._text = e.Label;
                }
            }
            btnSaveNewStrings.Enabled = true;
        }
Пример #27
0
        public override void Process(Pass pass, out Error error)
        {
            error = Error.None;

            if (Value.IsLiteral)
            {
                pass.Assembler.Values.SetValue(Variable, Value.Literal, IsLabel, out error);
                if (error.IsError)   // Add source line
                {
                    error = new Error(error, SourceLine);
                }
                if (IsLabel)
                {
                    int bank = pass.Bank;
                    pass.Assembler.AddDebugLabel(bank, Value.Literal.Value, Variable.ToString());
                }
            }
            else
            {
                StringSection exp             = Value.Expression;
                var           expressionValue = pass.Assembler.Evaluator.EvaluateExpression(ref exp, int.MinValue, out error);
                if (!error.IsError)
                {
                    pass.Assembler.Values.SetValue(Variable, expressionValue, IsLabel, out error);
                }
                if (error.IsError)   // Add source line
                {
                    error = new Error(error, SourceLine);
                }
                else if (IsLabel)
                {
                    int bank = pass.Bank;
                    if (bank < 0)
                    {
                        bank = 0;
                    }
                    pass.Assembler.AddDebugLabel(bank, expressionValue.Value, Variable.ToString());
                }

                if (!exp.IsNullOrEmpty)
                {
                    error = new Error(ErrorCode.Invalid_Expression, Error.Msg_InvalidExpression, SourceLine);
                }
            }
        }
Пример #28
0
        private void btnAddSection_Click(object sender, EventArgs e)
        {
            if (!_defaultStrings.IsSection(_textBoxNewSection.Text) && _textBoxNewSection.Text != String.Empty)
            {
                StringSection section = new StringSection();
                section._localizedStrings = new List <StringLocalized>();
                section._name             = _textBoxNewSection.Text;
//        section.isNew = true;
                _defaultStrings.Sections.Add(section);
                _textBoxNewSection.Text   = string.Empty;
                btnSaveNewStrings.Enabled = true;
                DrawCreateSectionsTreeView();
            }
            else
            {
                MessageBox.Show("A Section with the same name already exists", "Section Name", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
        }
Пример #29
0
        protected override void ProcessCurrentInstruction()
        {
            var currentLine = Assembly.ParsedInstructions[iCurrentInstruction];
            var opcode      = Opcode.allOps[currentLine.opcode];

            bool SingleByteOperand = false;

            if (currentLine.operandExpression != null)
            {
                // If an AsmValue has not been resolved to a literal value yet, it is because it references a label, and thus must be 16-bit

                Error error;

                StringSection expression = currentLine.operandExpression;
                SingleByteOperand = Assembler.Evaluator.EvaluateExpression(ref expression, currentLine.sourceLine, out error).IsByte;
                if (error.Code != ErrorCode.None)
                {
                    AddError(new Error(error, currentLine.sourceLine));
                }
                else if (!expression.IsNullOrEmpty)
                {
                    AddError(new Error(ErrorCode.Invalid_Expression, Error.Msg_InvalidExpression, currentLine.sourceLine));
                }
            }
            else if (currentLine.operandValue.IsByte)
            {
                SingleByteOperand = true;
            }

            if (SingleByteOperand)
            {
                // Todo: Consider moving TryToConvertToZeroPage to more appropriate class
                if (Assembler.Parser.TryToConvertToZeroPage(ref currentLine))
                {
                    // If the instruction can be coded as zero-page, update it
                    Assembly.ParsedInstructions[iCurrentInstruction] = currentLine; // Todo: consider method such as UpdateParsedInstruction
                }
            }

            var instructionLen = Opcode.GetParamBytes(currentLine.opcode) + 1;

            CurrentOutputOffset += instructionLen;
            CurrentAddress      += instructionLen;
        }
Пример #30
0
        protected override void Render(ConsoleRenderContext context, StringSection text)
        {
            switch (text.SectionType)
            {
            case StringSectionType.Normal:
                Console.ForegroundColor = ConsoleColor.White;
                Console.BackgroundColor = ConsoleColor.Black;
                break;

            case StringSectionType.Error:
                Console.ForegroundColor = ConsoleColor.Red;
                Console.BackgroundColor = ConsoleColor.Black;
                break;

            case StringSectionType.Fatal:
                Console.ForegroundColor = ConsoleColor.White;
                Console.BackgroundColor = ConsoleColor.Red;
                break;

            case StringSectionType.Highlighted:
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.BackgroundColor = ConsoleColor.Black;
                break;
            }

            if (text.IsMultiLine)
            {
                Console.WriteLine();
                foreach (var item in text.Lines)
                {
                    Console.Write("\t");
                    Console.WriteLine(item);
                }
                Console.WriteLine();
            }
            else
            {
                Console.Write(text.Text);
            }


            Console.ForegroundColor = ConsoleColor.White;
            Console.BackgroundColor = ConsoleColor.Black;
        }
Пример #31
0
 private void StoreEditList()
 {
   if (treeSections.SelectedNode != null && _targetStrings != null && _modifiedSection)
   {
     if (_targetSection >= 0)
     {
       StringSection section = _targetStrings._sections[_targetSection];
       section._localizedStrings = new List<StringLocalized>();
       foreach (StringLocalized newString in _editList.Values)
       {
         section.LocalizedStrings.Add(newString);
       }
     }
     else
     {
       StringSection section = new StringSection();
       section._name = _defaultStrings._sections[_currentSection].SectionName;
       section._localizedStrings = new List<StringLocalized>();
       foreach (StringLocalized newString in _editList.Values)
       {
         section.LocalizedStrings.Add(newString);
       }
       _targetStrings.Sections.Add(section);
     }
     _modifiedSection = false;
   }
 }
Пример #32
0
    private void btnAddSection_Click(object sender, EventArgs e)
    {
      if (!_defaultStrings.IsSection(_textBoxNewSection.Text) && _textBoxNewSection.Text!=String.Empty)
      {
        StringSection section = new StringSection();
        section._localizedStrings = new List<StringLocalized>();
        section._name = _textBoxNewSection.Text;
//        section.isNew = true;
        _defaultStrings.Sections.Add(section);
        _textBoxNewSection.Text = string.Empty;
        btnSaveNewStrings.Enabled = true;
        DrawCreateSectionsTreeView();
      }
      else
      {
        MessageBox.Show("A Section with the same name already exists", "Section Name", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
      }
    }
Пример #33
0
        private void AddSymbol(ISymbol sym, StringSection strtab,
            List<ElfSymbol> osyms, Dictionary<ISymbol, int> sym_map,
            Dictionary<ISection, int> sect_map)
        {
            ElfSymbol esym = new ElfSymbol();
            esym.Name = sym.Name;
            esym.st_name = AllocateString(sym.Name, strtab);
            esym.st_value = sym.Offset;

            if (IsExecutable && sym.DefinedIn != null)
                esym.st_value += sym.DefinedIn.LoadAddress;

            esym.st_size = sym.Size;
            esym.st_bind = 0;
            switch(sym.Type)
            {
                case SymbolType.Global:
                    esym.st_bind = 1;
                    break;
                case SymbolType.Weak:
                    esym.st_bind = 2;
                    break;                        
            }
            esym.st_type = 0;
            switch (sym.ObjectType)
            {
                case SymbolObjectType.Object:
                    esym.st_type = 1;
                    break;
                case SymbolObjectType.Function:
                    esym.st_type = 2;
                    break;
            }
            esym.st_shndx = sect_map[sym.DefinedIn];

            sym_map[sym] = osyms.Count;
            osyms.Add(esym);
        }
Пример #34
0
        private static int AllocateString(string name, StringSection strtab)
        {
            if (strtab.StringCache == null)
                strtab.StringCache = new Dictionary<string, int>();
            else if (strtab.StringCache.ContainsKey(name))
                return strtab.StringCache[name];

            if (strtab.cur_offset == 0)
            {
                strtab.oput.Add(0);
                strtab.cur_offset++;
            }

            int ret = strtab.cur_offset;
            foreach (char c in name)
            {
                strtab.oput.Add((byte)c);
                strtab.cur_offset++;
            }
            strtab.oput.Add(0);
            strtab.cur_offset++;

            strtab.StringCache[name] = ret;
            return ret;
        }
Пример #35
0
        protected override void Write(System.IO.BinaryWriter w)
        {
            Init();

            // First, build a list of output sections
            List<SectionHeader> osects = new List<SectionHeader>();
            Dictionary<ISection, int> osect_map = new Dictionary<ISection, int>();
            osects.Add(new NullSection());

            StringSection strtab = new StringSection();
            StringSection shstrtab = new StringSection();

            foreach(var sect in sections)
            {
                SectionHeader sh = new SectionHeader();
                sh.sh_name = AllocateString(sect.Name, shstrtab);
                if (sect.HasData)
                    sh.sh_type = 1;
                else
                    sh.sh_type = 8;
                sh.sh_flags = 0;
                if (sect.IsWriteable)
                    sh.sh_flags |= 0x1;
                if (sect.IsAlloc)
                    sh.sh_flags |= 0x2;
                if (sect.IsExecutable)
                    sh.sh_flags |= 0x4;
                sh.sh_addr = sect.LoadAddress;
                sh.sh_size = sect.Length;

                sh.sh_link = 0;
                sh.sh_info = 0;
                sh.sh_addralign = sect.AddrAlign;
                sh.sh_entsize = 0;

                osect_map[sect] = osects.Count;
                osects.Add(sh);                
            }

            strtab.sh_name = AllocateString(".strtab", shstrtab);
            int strtab_idx = osects.Count;
            osects.Add(strtab);

            shstrtab.sh_name = AllocateString(".shstrtab", shstrtab);
            int shstrtab_idx = osects.Count;
            e_shstrndx = shstrtab_idx;
            osects.Add(shstrtab);

            SectionHeader symtab = new SectionHeader();
            symtab.sh_name = AllocateString(".symtab", shstrtab);
            symtab.sh_link = strtab_idx;
            symtab.sh_type = 2;
            int symtab_idx = osects.Count;
            osects.Add(symtab);

            // Build symbol table
            List<ElfSymbol> osyms = new List<ElfSymbol>();
            osyms.Add(new ElfSymbol());
            Dictionary<ISymbol, int> sym_map = new Dictionary<ISymbol, int>();

            // Add local symbols first
            foreach(var sym in symbols)
            {
                if (sym.Type == SymbolType.Local)
                    AddSymbol(sym, strtab, osyms, sym_map, osect_map);
            }
            int last_local = osyms.Count;
            foreach(var sym in symbols)
            {
                if (sym.Type != SymbolType.Local)
                    AddSymbol(sym, strtab, osyms, sym_map, osect_map);
            }
            symtab.sh_info = last_local;

            // Write out file header
            // e_ident
            w.Write((byte)0x7f);
            w.Write((byte)'E');
            w.Write((byte)'L');
            w.Write((byte)'F');
            w.Write((byte)ec);
            w.Write((byte)ed);
            w.Write((byte)1);
            for (int i = 0; i < 9; i++)
                w.Write((byte)0);
            // store fh_start because we will re-write the header later
            int fh_start = (int)w.BaseStream.Position;
            switch(ec)
            {
                case ElfClass.ELFCLASS32:
                    WriteElf32FileHeader(w);
                    break;
                case ElfClass.ELFCLASS64:
                    WriteElf64FileHeader(w);
                    break;
                default:
                    throw new Exception("Invalid ELF class");
            }

            // Now write out the section data
            foreach(var s in sections)
            {
                // align up to addralign
                var sh = osects[osect_map[s]];
                if (sh.sh_addralign != 0)
                {
                    while ((w.BaseStream.Position % sh.sh_addralign) != 0)
                        w.Write((byte)0);
                }

                sh.sh_offset = w.BaseStream.Position;

                if (s.HasData == false)
                    continue;

                // write out data
                foreach (byte b in s.Data)
                    w.Write(b);
            }

            // Write out string tables
            while ((w.BaseStream.Position % 16) != 0)
                w.Write((byte)0);
            strtab.sh_offset = w.BaseStream.Position;
            foreach (byte b in strtab.oput)
                w.Write(b);
            strtab.sh_size = strtab.oput.Count;

            while ((w.BaseStream.Position % 16) != 0)
                w.Write((byte)0);
            shstrtab.sh_offset = w.BaseStream.Position;
            foreach (byte b in shstrtab.oput)
                w.Write(b);
            shstrtab.sh_size = shstrtab.oput.Count;

            // Write out symbol table
            while ((w.BaseStream.Position % 16) != 0)
                w.Write((byte)0);
            symtab.sh_offset = w.BaseStream.Position;
            foreach (var sym in osyms)
            {
                switch (ec)
                {
                    case ElfClass.ELFCLASS32:
                        WriteElf32Symbol(sym, w);
                        break;
                    case ElfClass.ELFCLASS64:
                        WriteElf64Symbol(sym, w);
                        break;
                }
            }

            // Fill in file type specific details in various structures
            switch(ec)
            {
                case ElfClass.ELFCLASS32:
                    symtab.sh_entsize = 16;
                    symtab.sh_size = osyms.Count * symtab.sh_entsize;
                    e_shentsize = 40;
                    e_phentsize = 32;
                    break;
                case ElfClass.ELFCLASS64:
                    throw new NotImplementedException();
            }

            // Write out section header table
            while ((w.BaseStream.Position % 16) != 0)
                w.Write((byte)0);

            e_shoff = w.BaseStream.Position;
            foreach(var sect in osects)
            {
                switch(ec)
                {
                    case ElfClass.ELFCLASS32:
                        WriteElf32Section(sect, w);
                        break;
                    case ElfClass.ELFCLASS64:
                        WriteElf64Section(sect, w);
                        break;
                }
            }

            // Write program headers
            e_phnum = 0;
            if (IsExecutable)
            {
                while ((w.BaseStream.Position % 16) != 0)
                    w.Write((byte)0);

                e_phoff = w.BaseStream.Position;
                foreach (var sect in sections)
                {
                    ElfProgramHeader ph = new ElfProgramHeader();
                    ph.p_type = ElfProgramHeader.PT_LOAD;
                    ph.p_offset = (ulong)osects[osect_map[sect]].sh_offset;
                    ph.p_vaddr = sect.LoadAddress;
                    ph.p_paddr = 0;
                    ph.p_filesz = sect.HasData ? (ulong)sect.Data.Count : 0UL;
                    ph.p_memsz = (ulong)sect.Length;
                    ph.p_flags = 0;
                    if (sect.IsExecutable)
                        ph.p_flags |= ElfProgramHeader.PF_X;
                    if (sect.IsWriteable)
                        ph.p_flags |= ElfProgramHeader.PF_W;
                    ph.p_flags |= ElfProgramHeader.PF_R;
                    ph.p_align = (ulong)sect.AddrAlign;

                    if (ph.p_memsz != 0)
                    {
                        switch (ec)
                        {
                            case ElfClass.ELFCLASS32:
                                WriteElf32Segment(ph, w);
                                break;
                            case ElfClass.ELFCLASS64:
                                WriteElf64Segment(ph, w);
                                break;
                        }
                        e_phnum++;
                    }
                }
            }
            if (e_phnum == 0)
                e_phoff = 0;

            // Rewrite file header
            e_shnum = osects.Count;
            if (is_exec)
                e_type = 2;
            else
                e_type = 1;

            if(EntryPoint != null && IsExecutable)
            {
                var s = FindSymbol(EntryPoint);
                if (s != null && s.DefinedIn != null)
                    e_entry = s.Offset + s.DefinedIn.LoadAddress;
                else
                {
                    // default to offset 0x0 in text
                    var sect = FindSection(".text");
                    if(sect == null)
                    {
                        // default to 0x0
                        Console.WriteLine("Entry point " + EntryPoint +
                            " not found, defaulting to 0x0");
                        e_entry = 0;
                    }
                    else
                    {
                        Console.WriteLine("Entry point " + EntryPoint +
                            " not found, defaulting to 0x" +
                            sect.LoadAddress.ToString("X"));
                        e_entry = sect.LoadAddress;
                    }
                }
            }

            int cur_pos = (int)w.BaseStream.Position;
            w.Seek(fh_start, System.IO.SeekOrigin.Begin);
            switch(ec)
            {
                case ElfClass.ELFCLASS32:
                    WriteElf32FileHeader(w);
                    break;
                case ElfClass.ELFCLASS64:
                    WriteElf64FileHeader(w);
                    break;
            }
            w.Seek(cur_pos, System.IO.SeekOrigin.Begin);
        }