Skip to content

Commit

Permalink
Merge pull request #2 from Pear0/speculative-execution
Browse files Browse the repository at this point in the history
Add description and analysis write-up
  • Loading branch information
Pear0 authored Mar 5, 2019
2 parents 34a0356 + 8a632d3 commit e0c92e1
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 22 deletions.
36 changes: 36 additions & 0 deletions Flow Analysis.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Flow Analysis

This page describes at a high level how this
plugin analyzes code to symbolically trace execution.


## Setup

First, the full assembly file is analyzed to find all jump targets. This flow analysis
does not currently support indirect jumps. Each jump target is used to split the assembly
into basic blocks. Basic blocks are a commonly used in compilers, and they represent a
block of code that always runs together.

An important concept is that these basic blocks combined with jumps/branches form
a directed graph. This fact is used in the next section.

## Function Analysis

For every function labeled with a `; pragma function prologue`, a virtual LC-3 is created
and initialized with symbolic values for the registers and stack. The basic blocks for
this function are traversed in a depth first search until a basic block that ends with a
`RET` is found.

Because this a directed graph and not a tree, sometimes a basic block will have multiple
parents. When this happens, the virtual LC-3 states are merged and the graph is traversed
again. This is done in a way that reaches a steady state after a few iterations because
LC-3 is a fairly simple ISA.

Because the code is not actually executed, it is guaranteed to converge at
the cost of knowing exactly what the state of the LC-3 is. This is usually fine because
the most important registers are R5 and R6 because they are used to keep track of the
stack. R5 and R6 are usually not modified very much in hand-written assembly and are
not branch dependent.

Finally, at each `RET`, the LC-3 state is compared to the expected result following the
LC-3 calling convention.
6 changes: 3 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ apply plugin: 'org.jetbrains.grammarkit'


group 'cn.codetector.lc3'
version '1.0.1-SNAPSHOT'
version '1.1.1'

sourceCompatibility = 1.8

Expand Down Expand Up @@ -81,6 +81,6 @@ intellij {
}
patchPluginXml {
changeNotes """
Add change notes here.<br>
<em>most HTML tags may be used</em>"""
<p>1.1.1 - Fix some invalid instruction issues</p>
<p>1.1.0 - Add Symbolic execution engine</p>"""
}
42 changes: 36 additions & 6 deletions src/main/kotlin/cn/codetector/lc3/asm/VirtualLC3.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package cn.codetector.lc3.asm

import org.fest.swing.util.Arrays
import java.lang.IllegalArgumentException

class VirtualLC3 {
companion object {
Expand Down Expand Up @@ -204,7 +202,26 @@ class VirtualLC3 {

true
}
Instruction.LDI -> false // TODO
Instruction.LDI -> {
arg0 as Register
arg1 as Value

val pc = registers[Register.PC.ordinal]
if (pc.magic) {
registers[arg0.ordinal] = UNKNOWN
} else {
val address = pc.value + 1 + arg1.value

val indirectAddress = mem.resolveValue(address)
if (indirectAddress.magic) {
registers[arg0.ordinal] = UNKNOWN
} else {
registers[arg0.ordinal] = mem.resolveValue(indirectAddress.value)
}
}

true
}
Instruction.LDR -> {
arg0 as Register
arg1 as Register
Expand All @@ -218,7 +235,20 @@ class VirtualLC3 {
true
}
}
Instruction.LEA -> false // TODO
Instruction.LEA -> {
arg0 as Register
arg1 as Value

val pc = registers[Register.PC.ordinal]
if (pc.magic) {
registers[arg0.ordinal] = UNKNOWN
} else {
val address = pc.value + 1 + arg1.value
registers[arg0.ordinal] = InternalValue(address, false)
}

true
}
Instruction.NOT -> {
arg0 as Register
arg1 as Register
Expand All @@ -235,8 +265,8 @@ class VirtualLC3 {
}
Instruction.RET -> false // handled externally
Instruction.RTI -> false // handled externally
Instruction.ST -> false // TODO
Instruction.STI -> false // TODO
Instruction.ST -> true // TODO
Instruction.STI -> true // TODO
Instruction.STR -> {
arg0 as Register
arg1 as Register
Expand Down
6 changes: 6 additions & 0 deletions src/main/kotlin/cn/codetector/lc3/lc3intellij/LC3Annotator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ class LC3Annotator : Annotator {
}
}

if (element is PsiLabel || element is PsiLabelReference) {
if (element.text.toUpperCase() == "NOP") {
holder.createWarningAnnotation(element, "NOP is currently not handled properly. BR 0 is equivalent and supported.")
}
}

if (element is LC3PsiImmediate) {
val value = element.getIntegerValue()
if (value != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,30 @@ import cn.codetector.lc3.lc3intellij.filetype.LC3ASMFileType
import cn.codetector.lc3.lc3intellij.psi.SimpleLC3Tracer
import com.intellij.openapi.Disposable
import com.intellij.openapi.components.AbstractProjectComponent
import com.intellij.openapi.components.ProjectComponent
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.editor.EditorFactory
import com.intellij.openapi.editor.LogicalPosition
import com.intellij.openapi.editor.event.CaretEvent
import com.intellij.openapi.editor.event.CaretListener
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.openapi.editor.event.EditorFactoryEvent
import com.intellij.openapi.editor.event.EditorFactoryListener
import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.util.TextRange
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.ui.SeparatorComponent
import com.intellij.ui.SeparatorOrientation
import com.intellij.ui.table.JBTable
import java.awt.BorderLayout
import java.awt.GridBagConstraints
import java.awt.GridBagLayout
import java.awt.Insets
import java.util.*
import javax.swing.*
import javax.swing.table.*
import kotlin.collections.HashMap
import javax.swing.text.StyleConstants
import javax.swing.JPanel
import javax.swing.JTextPane
import javax.swing.table.AbstractTableModel
import javax.swing.text.SimpleAttributeSet
import javax.swing.text.StyledDocument
import javax.swing.text.StyleConstants
import kotlin.collections.HashMap


class EditorSidebar(val editor: Editor) : CaretListener {
Expand Down
36 changes: 33 additions & 3 deletions src/main/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
@@ -1,13 +1,43 @@
<idea-plugin>
<id>cn.codetector.lc3.lc3intellij</id>
<name>LC-3 Assembly Support For IntelliJ Platform</name>
<version>1.0.1</version>
<version>1.1.1</version>
<idea-version since-build="181.0"/>
<depends>com.intellij.modules.lang</depends>
<vendor email="[email protected]" url="https://blog.codetector.cn">Codetector</vendor>
<vendor email="[email protected]" url="https://github.com/Pear0">Will Gulian</vendor>

<description><![CDATA[
<p>Language support for LC-3 Assembly. Mainly targeting Georgia Tech CS-2110</p>
<h2>Language support for LC-3 Assembly.</p>
<ul>
<li>Syntax Highlighting</li>
<li>Code Completion on labels</li>
<li>Track memory addresses in the sidebar</li>
<li>Navigate labels to their declarations</li>
<li>Verify instruction immediates are in range</li>
<li><b>Symbolic Execution</b> of assembly to track stack and frame pointers and verify functions
correctly implement the standard calling convention.</li>
</ul>
<h2>How do I use the symbolic execution checker?</h2>
Place a comment after your label like so:
<pre>
FOO ; pragma function prologue
ADD R6, R6, -4
...
RET
</pre>
<p>After adding the pragma comment, whenever the cursor is in the function, the sidebar will
show the current stack and the registers to the best of the symbolic execution engine's knowledge.</p>
<p>Any calling convention issues will be listed as warnings on the <pre>RET</pre> instruction.</p>
<h2>Notes</h2>
<p>Mainly targeting Georgia Tech CS-2110</p>
<p>The idea and original version of this plugin were made by <a href="https://blog.codetector.cn">Codetector</a>.
]]></description>

<!-- please see http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/plugin_compatibility.html
Expand Down

0 comments on commit e0c92e1

Please sign in to comment.