File 0004-Add-operand_offset-to-sleigh-Java.patch of Package ghidra

From d54704aec188ff05580e5daa8f5aad58a6b35c8a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Klaus=20K=C3=A4mpf?= <kkaempf@gmail.com>
Date: Sun, 30 Oct 2022 22:18:33 +0100
Subject: [PATCH 04/12] Add operand_offset to sleigh Java
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Klaus Kämpf <kkaempf@gmail.com>
---
 .../ghidra/sleigh/grammar/SleighCompiler.g    |   6 +
 .../sleigh/SleighAssemblerBuilder.java        |   3 +
 .../expression/OffsetInstructionValue.java    |  83 +++++++++++++
 .../sleigh/expression/PatternExpression.java  |   2 +
 .../sleigh/symbol/OffsetSymbol.java           |  82 +++++++++++++
 .../processors/sleigh/symbol/SymbolTable.java |   2 +
 .../ghidra/pcodeCPort/semantics/ConstTpl.java |   9 +-
 .../slgh_compile/SleighCompile.java           |   2 +
 .../pcodeCPort/slgh_compile/Yylval.java       |   1 +
 .../OffsetInstructionValue.java               |  67 +++++++++++
 .../slghpatexpress/PatternExpression.java     |   3 +
 .../pcodeCPort/slghsymbol/OffsetSymbol.java   | 109 ++++++++++++++++++
 .../pcodeCPort/slghsymbol/SymbolTable.java    |   3 +
 .../pcodeCPort/slghsymbol/symbol_type.java    |   1 +
 .../program/model/lang/PcodeParser.java       |   1 +
 15 files changed, 373 insertions(+), 1 deletion(-)
 create mode 100644 Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/expression/OffsetInstructionValue.java
 create mode 100644 Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/symbol/OffsetSymbol.java
 create mode 100644 Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slghpatexpress/OffsetInstructionValue.java
 create mode 100644 Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slghsymbol/OffsetSymbol.java

diff --git a/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/SleighCompiler.g b/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/SleighCompiler.g
index 4ff7d5066..607d2171e 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/SleighCompiler.g
+++ b/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/SleighCompiler.g
@@ -342,6 +342,7 @@ specific_symbol[String purpose] returns [SpecificSymbol symbol]
 			if (sym == null) {
 				unknownSymbolError($s.getText(), find($s), "start, end, next2, operand, epsilon, or varnode", purpose);
 			} else if(sym.getType() != symbol_type.start_symbol
+					&& sym.getType() != symbol_type.offset_symbol
 					&& sym.getType() != symbol_type.end_symbol
 					&& sym.getType() != symbol_type.next2_symbol
 					&& sym.getType() != symbol_type.operand_symbol
@@ -839,6 +840,7 @@ pattern_symbol[String purpose] returns [PatternExpression expr]
                 }
                 $expr = os.getPatternExpression();
 			} else if(sym.getType() == symbol_type.start_symbol
+					|| sym.getType() == symbol_type.offset_symbol
 					|| sym.getType() == symbol_type.end_symbol
 					|| sym.getType() == symbol_type.next2_symbol
 					|| sym.getType() == symbol_type.epsilon_symbol
@@ -872,6 +874,7 @@ pattern_symbol2[String purpose] returns [PatternExpression expr]
 			if (sym == null) {
 				unknownSymbolError($s.getText(), find($s), "start, end, next2, operand, epsilon, or varnode", purpose);
 			} else if(sym.getType() == symbol_type.start_symbol
+					|| sym.getType() == symbol_type.offset_symbol
 					|| sym.getType() == symbol_type.end_symbol
 					|| sym.getType() == symbol_type.next2_symbol
 					|| sym.getType() == symbol_type.operand_symbol
@@ -943,6 +946,7 @@ cstatement[VectorSTL<ContextChange> r]
 							|| sym.getType() == symbol_type.name_symbol
 							|| sym.getType() == symbol_type.varnodelist_symbol
 							|| sym.getType() == symbol_type.start_symbol
+							|| sym.getType() == symbol_type.offset_symbol
 							|| sym.getType() == symbol_type.end_symbol
 							|| sym.getType() == symbol_type.next2_symbol
 							|| sym.getType() == symbol_type.operand_symbol
@@ -1176,6 +1180,7 @@ assignment returns [VectorSTL<OpTpl> value]
                                               bitSym.getBitOffset(),
                                               bitSym.numBits(),e);
 			} else if(sym.getType() != symbol_type.start_symbol
+					&& sym.getType() != symbol_type.offset_symbol
 					&& sym.getType() != symbol_type.end_symbol
 					&& sym.getType() != symbol_type.next2_symbol
 					&& sym.getType() != symbol_type.operand_symbol
@@ -1516,6 +1521,7 @@ expr_apply returns [Object value]
 						pcode.reportError(find($t), "macro invocation not allowed as expression");
 					}
 				} else if(sym.getType() == symbol_type.start_symbol
+					|| sym.getType() == symbol_type.offset_symbol
 					|| sym.getType() == symbol_type.end_symbol
 					|| sym.getType() == symbol_type.next2_symbol
 					|| sym.getType() == symbol_type.operand_symbol
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/SleighAssemblerBuilder.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/SleighAssemblerBuilder.java
index 1a6f544b1..282731ef3 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/SleighAssemblerBuilder.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/SleighAssemblerBuilder.java
@@ -570,6 +570,9 @@ public class SleighAssemblerBuilder implements AssemblerBuilder {
 				else if (sym instanceof StartSymbol) {
 					// Ignore. We handle inst_start in semantic processing
 				}
+				else if (sym instanceof OffsetSymbol) {
+					// Ignore. We handle inst_start in semantic processing
+				}
 				else if (sym instanceof EndSymbol) {
 					// Ignore. We handle inst_next in semantic processing
 				}
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/expression/OffsetInstructionValue.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/expression/OffsetInstructionValue.java
new file mode 100644
index 000000000..db872ec16
--- /dev/null
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/expression/OffsetInstructionValue.java
@@ -0,0 +1,83 @@
+/* ###
+ * IP: GHIDRA
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * Created on Feb 8, 2005
+ *
+ */
+package ghidra.app.plugin.processors.sleigh.expression;
+
+import ghidra.app.plugin.processors.sleigh.ParserWalker;
+import ghidra.app.plugin.processors.sleigh.SleighLanguage;
+import ghidra.program.model.address.Address;
+import ghidra.program.model.mem.MemoryAccessException;
+import ghidra.xml.XmlPullParser;
+
+/**
+ * 
+ *
+ * The offset value of the current instructions address
+ */
+public class OffsetInstructionValue extends PatternValue {
+	private static final int HASH = "[operand_offset]".hashCode();
+
+	@Override
+	public int hashCode() {
+		return HASH;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		return obj instanceof OffsetInstructionValue;
+	}
+
+	/* (non-Javadoc)
+	 * @see ghidra.app.plugin.processors.sleigh.expression.PatternValue#minValue()
+	 */
+	@Override
+	public long minValue() {
+		return 0;
+	}
+
+	/* (non-Javadoc)
+	 * @see ghidra.app.plugin.processors.sleigh.expression.PatternValue#maxValue()
+	 */
+	@Override
+	public long maxValue() {
+		return 0;
+	}
+
+	/* (non-Javadoc)
+	 * @see ghidra.app.plugin.processors.sleigh.expression.PatternExpression#getValue(ghidra.app.plugin.processors.sleigh.ParserWalker)
+	 */
+	@Override
+	public long getValue(ParserWalker walker) throws MemoryAccessException {
+		return walker.getOffset(-1);
+	}
+
+	/* (non-Javadoc)
+	 * @see ghidra.app.plugin.processors.sleigh.PatternExpression#restoreXml(org.jdom.Element)
+	 */
+	@Override
+	public void restoreXml(XmlPullParser parser, SleighLanguage lang) {
+		parser.discardSubTree("offset_exp");
+		// Nothing to do
+	}
+
+	@Override
+	public String toString() {
+		return "[operand_offset]";
+	}
+}
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/expression/PatternExpression.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/expression/PatternExpression.java
index 69b6f9c3c..920ea9238 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/expression/PatternExpression.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/expression/PatternExpression.java
@@ -49,6 +49,8 @@ public abstract class PatternExpression {
 			res = new OperandValue();
 		else if (nm.equals("start_exp"))
 			res = new StartInstructionValue();
+		else if (nm.equals("offset_exp"))
+			res = new OffsetInstructionValue();
 		else if (nm.equals("end_exp"))
 			res = new EndInstructionValue();
 		else if (nm.equals("next2_exp"))
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/symbol/OffsetSymbol.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/symbol/OffsetSymbol.java
new file mode 100644
index 000000000..86f096fbe
--- /dev/null
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/symbol/OffsetSymbol.java
@@ -0,0 +1,82 @@
+/* ###
+ * IP: GHIDRA
+ * REVIEWED: YES
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * Created on Feb 8, 2005
+ *
+ */
+package ghidra.app.plugin.processors.sleigh.symbol;
+
+import ghidra.app.plugin.processors.sleigh.*;
+import ghidra.app.plugin.processors.sleigh.expression.*;
+import ghidra.program.model.mem.*;
+import ghidra.xml.*;
+
+import java.util.*;
+
+/**
+ * 
+ *
+ * TripleSymbol with semantic value equal to offset of instruction's
+ * current address
+ */
+public class OffsetSymbol extends SpecificSymbol {
+
+	private PatternExpression patexp;
+	
+	/* (non-Javadoc)
+	 * @see ghidra.app.plugin.processors.sleigh.symbol.TripleSymbol#getPatternExpression()
+	 */
+	@Override
+    public PatternExpression getPatternExpression() {
+		return patexp;
+	}
+
+	/* (non-Javadoc)
+	 * @see ghidra.app.plugin.processors.sleigh.symbol.TripleSymbol#getFixedHandle(ghidra.app.plugin.processors.sleigh.FixedHandle, ghidra.app.plugin.processors.sleigh.ParserWalker)
+	 */
+	@Override
+    public void getFixedHandle(FixedHandle hand, ParserWalker walker) {
+		hand.space = walker.getCurSpace();
+		hand.offset_space = null;
+		hand.offset_offset = walker.getAddr().getOffset();
+		hand.size = hand.space.getPointerSize();
+	}
+
+	/* (non-Javadoc)
+	 * @see ghidra.app.plugin.processors.sleigh.symbol.TripleSymbol#print(ghidra.app.plugin.processors.sleigh.ParserWalker)
+	 */
+	@Override
+    public String print(ParserWalker walker) throws MemoryAccessException {
+		long val = walker.getAddr().getOffset();
+		return "0x" + Long.toHexString(val);
+	}
+
+	@Override
+    public void printList(ParserWalker walker, ArrayList<Object> list) {
+		list.add(walker.getParentHandle());
+	}
+	/* (non-Javadoc)
+	 * @see ghidra.app.plugin.processors.sleigh.symbol.Symbol#restoreXml(org.jdom.Element, ghidra.app.plugin.processors.sleigh.SleighLanguage)
+	 */
+	@Override
+    public void restoreXml(XmlPullParser parser, SleighLanguage sleigh) {
+	    XmlElement element = parser.start("offset_sym");
+		patexp = new OffsetInstructionValue();
+		parser.end(element);
+	}
+
+}
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/symbol/SymbolTable.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/symbol/SymbolTable.java
index dd9cec532..0cc6a2a81 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/symbol/SymbolTable.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/symbol/SymbolTable.java
@@ -150,6 +150,8 @@ public class SymbolTable {
 			sym = new OperandSymbol();
 		else if (el.getName().equals("start_sym_head"))
 			sym = new StartSymbol();
+		else if (el.getName().equals("offset_sym_head"))
+			sym = new OffsetSymbol();
 		else if (el.getName().equals("end_sym_head"))
 			sym = new EndSymbol();
 		else if (el.getName().equals("next2_sym_head"))
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/semantics/ConstTpl.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/semantics/ConstTpl.java
index 341877dae..5c14e3bbc 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/semantics/ConstTpl.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/semantics/ConstTpl.java
@@ -46,7 +46,8 @@ public class ConstTpl {
 		j_flowref,
 		j_flowref_size,
 		j_flowdest,
-		j_flowdest_size
+		j_flowdest_size,
+		j_offset
 	}
 
 	public enum v_field {
@@ -297,6 +298,9 @@ public class ConstTpl {
 			case j_start:
 				s.append("start\"/>");
 				break;
+			case j_offset:
+				s.append("offset\"/>");
+				break;
 			case j_next:
 				s.append("next\"/>");
 				break;
@@ -351,6 +355,9 @@ public class ConstTpl {
 		else if (typestring.equals("start")) {
 			type = const_type.j_start;
 		}
+		else if (typestring.equals("offset")) {
+			type = const_type.j_offset;
+		}
 		else if (typestring.equals("next")) {
 			type = const_type.j_next;
 		}
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slgh_compile/SleighCompile.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slgh_compile/SleighCompile.java
index 4a8e710b3..aa1b3686e 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slgh_compile/SleighCompile.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slgh_compile/SleighCompile.java
@@ -287,6 +287,8 @@ public class SleighCompile extends SleighBase {
 		symtab.addSymbol(spacesym);
 		StartSymbol startsym = new StartSymbol(location, "inst_start", getConstantSpace());
 		symtab.addSymbol(startsym);
+		OffsetSymbol offsetsym = new OffsetSymbol(location, "operand_offset", getConstantSpace());
+		symtab.addSymbol(offsetsym);
 		EndSymbol endsym = new EndSymbol(location, "inst_next", getConstantSpace());
 		symtab.addSymbol(endsym);
 		Next2Symbol next2sym = new Next2Symbol(location, "inst_next2", getConstantSpace());
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slgh_compile/Yylval.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slgh_compile/Yylval.java
index f165ca6b8..dc5740001 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slgh_compile/Yylval.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slgh_compile/Yylval.java
@@ -30,6 +30,7 @@ class Yylval {
     VarnodeListSymbol varlistsym;
     OperandSymbol operandsym;
     StartSymbol startsym;
+    OffsetSymbol offsetsym;
     EndSymbol endsym;
 	Next2Symbol next2sym;
     SubtableSymbol subtablesym;
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slghpatexpress/OffsetInstructionValue.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slghpatexpress/OffsetInstructionValue.java
new file mode 100644
index 000000000..e5bb4b893
--- /dev/null
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slghpatexpress/OffsetInstructionValue.java
@@ -0,0 +1,67 @@
+/* ###
+ * IP: GHIDRA
+ * REVIEWED: YES
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package ghidra.pcodeCPort.slghpatexpress;
+
+import generic.stl.VectorSTL;
+import ghidra.app.plugin.processors.sleigh.ParserWalker;
+import ghidra.pcodeCPort.translate.Translate;
+import ghidra.sleigh.grammar.Location;
+
+import java.io.PrintStream;
+
+import org.jdom.Element;
+
+public class OffsetInstructionValue extends PatternValue {
+
+	public OffsetInstructionValue(Location location) {
+		super(location);
+	}
+
+	public long getValue(ParserWalker pos) {
+		return pos.getOffset(-1);
+	}
+
+	@Override
+	public TokenPattern genMinPattern(VectorSTL<TokenPattern> ops) {
+		return new TokenPattern(location);
+	}
+
+	@Override
+	public TokenPattern genPattern(long val) {
+		return new TokenPattern(location);
+	}
+
+	@Override
+	public long minValue() {
+		return 0;
+	}
+
+	@Override
+	public long maxValue() {
+		return 0;
+	}
+
+	@Override
+	public void saveXml(PrintStream s) {
+		s.append("<offset_exp/>");
+	}
+
+	@Override
+	public void restoreXml(Element el, Translate trans) {
+	}
+
+}
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slghpatexpress/PatternExpression.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slghpatexpress/PatternExpression.java
index 2842fa83a..315450dd8 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slghpatexpress/PatternExpression.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slghpatexpress/PatternExpression.java
@@ -84,6 +84,9 @@ public abstract class PatternExpression {
 		else if (nm.equals("start_exp")) {
 			res = new StartInstructionValue(null);
 		}
+		else if (nm.equals("offset_exp")) {
+			res = new OffsetInstructionValue(null);
+		}
 		else if (nm.equals("end_exp")) {
 			res = new EndInstructionValue(null);
 		}
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slghsymbol/OffsetSymbol.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slghsymbol/OffsetSymbol.java
new file mode 100644
index 000000000..95214daba
--- /dev/null
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slghsymbol/OffsetSymbol.java
@@ -0,0 +1,109 @@
+/* ###
+ * IP: GHIDRA
+ * REVIEWED: YES
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package ghidra.pcodeCPort.slghsymbol;
+
+import ghidra.app.plugin.processors.sleigh.ParserWalker;
+import ghidra.app.plugin.processors.sleigh.FixedHandle;
+import ghidra.pcodeCPort.semantics.ConstTpl;
+import ghidra.pcodeCPort.semantics.VarnodeTpl;
+import ghidra.pcodeCPort.sleighbase.SleighBase;
+import ghidra.pcodeCPort.slghpatexpress.PatternExpression;
+import ghidra.pcodeCPort.slghpatexpress.OffsetInstructionValue;
+import ghidra.pcodeCPort.space.AddrSpace;
+import ghidra.sleigh.grammar.Location;
+
+import java.io.PrintStream;
+
+import org.jdom.Element;
+
+public class OffsetSymbol extends SpecificSymbol {
+	private AddrSpace const_space;
+	private PatternExpression patexp;
+
+	OffsetSymbol(Location location) {
+		super(location);
+		patexp = null;
+	} // For use with restoreXml
+
+	@Override
+	public PatternExpression getPatternExpression() {
+		return patexp;
+	}
+
+	@Override
+	public symbol_type getType() {
+		return symbol_type.offset_symbol;
+	}
+
+	public OffsetSymbol(Location location, String nm, AddrSpace cspc) {
+		super(location, nm);
+		const_space = cspc;
+		patexp = new OffsetInstructionValue(location);
+		patexp.layClaim();
+	}
+
+	@Override
+	public void dispose() {
+		if (patexp != null) {
+			PatternExpression.release(patexp);
+		}
+	}
+
+// Returns current instruction offset as a constant
+	@Override
+	public VarnodeTpl getVarnode() {
+		ConstTpl spc = new ConstTpl(const_space);
+		ConstTpl off = new ConstTpl(ConstTpl.const_type.j_offset);
+		ConstTpl sz_zero = new ConstTpl();
+		return new VarnodeTpl(location, spc, off, sz_zero);
+	}
+
+	public void getFixedHandle(FixedHandle hand, ParserWalker pos) {
+		hand.space = pos.getCurSpace();
+		hand.offset_space = null;
+		hand.offset_offset = pos.getAddr().getOffset(); // Get starting address of instruction
+		hand.size = hand.space.getPointerSize();
+	}
+
+	public void print(PrintStream s, ParserWalker pos) {
+		long val = pos.getAddr().getOffset();
+		s.append("0x");
+		s.print(Long.toHexString(val));
+	}
+
+	@Override
+	public void saveXml(PrintStream s) {
+		s.append("<start_sym");
+		saveSleighSymbolXmlHeader(s);
+		s.println("/>");
+	}
+
+	@Override
+	public void saveXmlHeader(PrintStream s) {
+		s.append("<start_sym_head");
+		saveSleighSymbolXmlHeader(s);
+		s.append("/>\n");
+	}
+
+	@Override
+	public void restoreXml(Element el, SleighBase trans) {
+		const_space = trans.getConstantSpace();
+		patexp = new OffsetInstructionValue(null);
+		patexp.layClaim();
+	}
+
+}
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slghsymbol/SymbolTable.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slghsymbol/SymbolTable.java
index 33fbb65e9..8cdd4cddd 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slghsymbol/SymbolTable.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slghsymbol/SymbolTable.java
@@ -297,6 +297,9 @@ public class SymbolTable {
 		else if (el.getName().equals("start_sym_head")) {
 			sym = new StartSymbol(location);
 		}
+		else if (el.getName().equals("offset_sym_head")) {
+			sym = new OffsetSymbol(location);
+		}
 		else if (el.getName().equals("end_sym_head")) {
 			sym = new EndSymbol(location);
 		}
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slghsymbol/symbol_type.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slghsymbol/symbol_type.java
index 272b5fe64..cc3b29f27 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slghsymbol/symbol_type.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slghsymbol/symbol_type.java
@@ -26,6 +26,7 @@ public enum symbol_type {
 	varnodelist_symbol,
 	operand_symbol,
 	start_symbol,  // inst_start, inst_ref, inst_def
+        offset_symbol,
 	end_symbol,    // inst_next
 	next2_symbol,    // inst_next2
 	subtable_symbol,
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/PcodeParser.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/PcodeParser.java
index 19d8622dd..7dc039226 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/PcodeParser.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/PcodeParser.java
@@ -84,6 +84,7 @@ public class PcodeParser extends PcodeCompile {
 
 		Location internalLoc = Location.INTERNALLY_DEFINED;
 		symbolMap.put("inst_start", new StartSymbol(internalLoc, "inst_start", getConstantSpace()));
+		symbolMap.put("operand_offset", new OffsetSymbol(internalLoc, "operand_offset", getConstantSpace()));
 		symbolMap.put("inst_next", new EndSymbol(internalLoc, "inst_next", getConstantSpace()));
 		symbolMap.put("inst_next2", new Next2Symbol(internalLoc, "inst_next2", getConstantSpace()));
 		symbolMap.put("inst_ref", new FlowRefSymbol(internalLoc, "inst_ref", getConstantSpace()));
-- 
2.43.0

openSUSE Build Service is sponsored by