protected ListLine makeResult(string s, uint offsetInFile, string hexcontents, ArmAssembly.SectionType sect, ArmAssembly.ArmFileInfo pi) { // attempt to eliminate a bug in the mono implementation where tabs do not // always seem to be honoured when displaying the line of text if (!ARMSim.ARMSimUtil.RunningOnWindows && !String.IsNullOrEmpty(s) && s[0] == '\t') { s = " " + s.Substring(1); } if (offsetInFile == 0xFFFFFFFF) { if (hexcontents != null) { return(new ListLine(_drawParameters, s, hexcontents, this)); } return(new ListLine(_drawParameters, s, this)); } if (hexcontents != null) { return(new ListLine(_drawParameters, s, (uint)(offsetInFile + pi.SectionAddress[(int)sect]), hexcontents, this)); } return(new ListLine(_drawParameters, s, (uint)(offsetInFile + pi.SectionAddress[(int)sect]), this)); }
protected ListLine analyzeLine(ArmAssembly.ObjFromAsmFileInfo pi, int x, ref ArmAssembly.SectionType sect) { string s = pi.SourceLines[x]; if (s == null) { s = ""; } uint offsetInFile = pi.Offsets[x]; string hexcontents = pi.HexContent[x]; ListLine result = null; int i = 0; while (i < s.Length && Char.IsWhiteSpace(s[i])) { i++; } if (i >= s.Length || s[i] == '@' || (!Char.IsLetterOrDigit(s[i]) && s[i] != '.')) { return(makeResult(s, offsetInFile, hexcontents, sect, pi)); } // it's a label, or opcode, or directive int start = i; while (i < s.Length && (Char.IsLetterOrDigit(s[i]) || s[i] == '.')) { i++; } int length = i - start; // skip any white space while (i < s.Length && Char.IsWhiteSpace(s[i])) { i++; } // if it was a label, or not a directive, nothing to do if (i < s.Length && s[i] == ':' || s[start] != '.') { return(makeResult(s, offsetInFile, hexcontents, sect, pi)); } string directive = s.Substring(start, length).ToLower(); switch (directive) { case ".text": case ".data": case ".rodata": case ".rodata.str1.4": case ".bss": sect = handleSect(directive); break; case ".section": while (i < s.Length && Char.IsWhiteSpace(s[i])) { i++; } if (i >= s.Length) { return(result); } start = i; while (i < s.Length && (Char.IsLetterOrDigit(s[i]) || s[i] == '.')) { i++; } length = i - start; sect = handleSect(s.Substring(start, length)); break; default: break; } return(makeResult(s, offsetInFile, hexcontents, sect, pi)); }
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