File 0004-Add-offset-to-sleigh-Java.patch of Package ghidra
From a04b8dc5840d7aa2353204fc2daa64fc32e22f11 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 4/8] Add offset to sleigh Java
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This provides Sleigh access to the offset property of the ParserWalker,
giving the offset of the currently parsed byte from inst_start.
Signed-off-by: Klaus Kämpf <kkaempf@gmail.com>
---
.../Decompiler/src/main/doc/sleigh.xml | 7 ++
.../ghidra/sleigh/grammar/SleighCompiler.g | 6 ++
.../expression/OffsetInstructionValue.java | 73 ++++++++++++++++
.../sleigh/expression/PatternExpression.java | 3 +
.../sleigh/symbol/OffsetSymbol.java | 73 ++++++++++++++++
.../processors/sleigh/symbol/SymbolTable.java | 3 +
.../processors/sleigh/template/ConstTpl.java | 8 ++
.../util/pcode/AbstractPcodeFormatter.java | 3 +
.../java/ghidra/pcode/utils/SlaFormat.java | 4 +
.../ghidra/pcodeCPort/semantics/ConstTpl.java | 8 +-
.../slgh_compile/SleighCompile.java | 2 +
.../pcodeCPort/slgh_compile/Yylval.java | 1 +
.../OffsetInstructionValue.java | 59 +++++++++++++
.../slghpatexpress/PatternExpression.java | 1 -
.../pcodeCPort/slghsymbol/OffsetSymbol.java | 87 +++++++++++++++++++
.../pcodeCPort/slghsymbol/symbol_type.java | 1 +
.../program/model/lang/PcodeParser.java | 1 +
17 files changed, 337 insertions(+), 3 deletions(-)
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/Features/Decompiler/src/main/doc/sleigh.xml b/Ghidra/Features/Decompiler/src/main/doc/sleigh.xml
index d4af0e8599..a36cf1f308 100644
--- a/Ghidra/Features/Decompiler/src/main/doc/sleigh.xml
+++ b/Ghidra/Features/Decompiler/src/main/doc/sleigh.xml
@@ -1097,6 +1097,10 @@ We list all of the symbols that are predefined by SLEIGH.
<td><code>epsilon</code></td>
<td>A special identifier indicating an empty bit pattern.</td>
</tr>
+<tr>
+ <td><code>operand_offset</code></td>
+ <td>Offset of the address of the current operand. Useful for variable-length instructions.</td>
+</tr>
</tbody>
</table>
</informalexample>
@@ -1113,6 +1117,9 @@ identifiers are address spaces. The <emphasis>epsilon</emphasis>
identifier is inherited from SLED and is a specific symbol equivalent
to the constant zero. The <emphasis>instruction</emphasis> identifier
is the root instruction table.
+<emphasis>operand_offset</emphasis> was introduced to support VAX
+variable-length, multi-operand instructions. PC-relative addressing in
+VAX is relative to the operand address, not the instruction address.
</para>
</sect2>
</sect1>
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 d254d2bd92..46d32ef429 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.flowdest_symbol
@@ -841,6 +842,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.flowdest_symbol
@@ -876,6 +878,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.flowdest_symbol
@@ -949,6 +952,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.flowdest_symbol
@@ -1184,6 +1188,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.flowdest_symbol
@@ -1528,6 +1533,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.flowdest_symbol
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 0000000000..c04bd7412a
--- /dev/null
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/expression/OffsetInstructionValue.java
@@ -0,0 +1,73 @@
+/* ###
+ * 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 static ghidra.pcode.utils.SlaFormat.*;
+
+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.program.model.pcode.Decoder;
+import ghidra.program.model.pcode.DecoderException;
+
+/**
+ * The offset value of the current instructions address
+ */
+public class OffsetInstructionValue extends PatternValue {
+ private static final int HASH = "[inst_offset]".hashCode();
+
+ @Override
+ public int hashCode() {
+ return HASH;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj instanceof OffsetInstructionValue;
+ }
+
+ @Override
+ public long minValue() {
+ return 0;
+ }
+
+ @Override
+ public long maxValue() {
+ return 0;
+ }
+
+ @Override
+ public long getValue(ParserWalker walker) throws MemoryAccessException {
+ return walker.getOffset(-1);
+ }
+
+ @Override
+ public void decode(Decoder decoder, SleighLanguage lang) throws DecoderException {
+ int el = decoder.openElement(ELEM_OFFSET_EXP);
+ decoder.closeElement(el);
+ // Nothing to do
+ }
+
+ @Override
+ public String toString() {
+ return "[inst_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 3818f96ee1..f91fe4122d 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
@@ -54,6 +54,9 @@ public abstract class PatternExpression {
else if (el == ELEM_START_EXP.id()) {
res = new StartInstructionValue();
}
+ else if (el == ELEM_OFFSET_EXP.id()) {
+ res = new OffsetInstructionValue();
+ }
else if (el == ELEM_END_EXP.id()) {
res = new EndInstructionValue();
}
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 0000000000..042e7277db
--- /dev/null
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/symbol/OffsetSymbol.java
@@ -0,0 +1,73 @@
+/* ###
+ * 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 static ghidra.pcode.utils.SlaFormat.*;
+
+import java.util.ArrayList;
+
+import ghidra.app.plugin.processors.sleigh.*;
+import ghidra.app.plugin.processors.sleigh.expression.PatternExpression;
+import ghidra.app.plugin.processors.sleigh.expression.OffsetInstructionValue;
+import ghidra.program.model.mem.MemoryAccessException;
+import ghidra.program.model.pcode.Decoder;
+import ghidra.program.model.pcode.DecoderException;
+
+/**
+ * TripleSymbol with semantic value equal to offset of instruction's
+ * operand current address
+ */
+public class OffsetSymbol extends SpecificSymbol {
+
+ private PatternExpression patexp;
+
+ @Override
+ public PatternExpression getPatternExpression() {
+ return patexp;
+ }
+
+ @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();
+ }
+
+ @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());
+ }
+
+ @Override
+ public void decode(Decoder decoder, SleighLanguage sleigh) throws DecoderException {
+// int element = decoder.openElement(ELEM_OFFSET_SYM);
+ patexp = new OffsetInstructionValue();
+ decoder.closeElement(ELEM_OFFSET_SYM.id());
+ }
+
+}
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 1b3f1ae1be..d77f1b5021 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
@@ -174,6 +174,9 @@ public class SymbolTable {
else if (el == ELEM_START_SYM_HEAD.id()) {
sym = new StartSymbol();
}
+ else if (el == ELEM_OFFSET_SYM_HEAD.id()) {
+ sym = new OffsetSymbol();
+ }
else if (el == ELEM_END_SYM_HEAD.id()) {
sym = new EndSymbol();
}
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/template/ConstTpl.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/template/ConstTpl.java
index 75cc37f1e2..73e90e92fb 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/template/ConstTpl.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/template/ConstTpl.java
@@ -46,6 +46,7 @@ public class ConstTpl {
public static final int J_FLOWREF_SIZE = 10;
public static final int J_FLOWDEST = 11;
public static final int J_FLOWDEST_SIZE = 12;
+ public static final int J_OFFSET = 13;
public static final int V_SPACE = 0;
public static final int V_OFFSET = 1;
@@ -140,6 +141,8 @@ public class ConstTpl {
switch (type) {
case J_START:
return walker.getAddr().getOffset();
+ case J_OFFSET:
+ return walker.getAddr().getOffset();
case J_NEXT:
return walker.getNaddr().getOffset();
case J_NEXT2:
@@ -302,6 +305,9 @@ public class ConstTpl {
else if (el == ELEM_CONST_START.id()) {
type = J_START;
}
+ else if (el == ELEM_CONST_OFFSET.id()) {
+ type = J_OFFSET;
+ }
else if (el == ELEM_CONST_NEXT.id()) {
type = J_NEXT;
}
@@ -376,6 +382,8 @@ public class ConstTpl {
return "[next2]";
case J_START:
return "[start]";
+ case J_OFFSET:
+ return "[offset]";
case J_RELATIVE:
return "[rel:" + Long.toHexString(value_real) + "]";
}
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/util/pcode/AbstractPcodeFormatter.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/util/pcode/AbstractPcodeFormatter.java
index e0a52013d6..808dd4596b 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/util/pcode/AbstractPcodeFormatter.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/util/pcode/AbstractPcodeFormatter.java
@@ -173,6 +173,9 @@ public abstract class AbstractPcodeFormatter<T, A extends Appender<T>>
if (offset.getType() == ConstTpl.J_START) {
appender.appendLabel("inst_start");
}
+ else if (offset.getType() == ConstTpl.J_OFFSET) {
+ appender.appendLabel("operand_offset");
+ }
else if (offset.getType() == ConstTpl.J_NEXT) {
appender.appendLabel("inst_next");
}
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcode/utils/SlaFormat.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcode/utils/SlaFormat.java
index 742341daa6..7209f25a61 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcode/utils/SlaFormat.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcode/utils/SlaFormat.java
@@ -191,6 +191,10 @@ public class SlaFormat {
public static final ElementId ELEM_CONST_FLOWDEST = new ElementId("const_flowdest", 87);
public static final ElementId ELEM_CONST_FLOWDEST_SIZE =
new ElementId("const_flowdest_size", 88);
+ public static final ElementId ELEM_OFFSET_EXP = new ElementId("offset_exp", 89);
+ public static final ElementId ELEM_OFFSET_SYM = new ElementId("offset_sym", 90);
+ public static final ElementId ELEM_OFFSET_SYM_HEAD = new ElementId("offset_sym_head",91);
+ public static final ElementId ELEM_CONST_OFFSET = new ElementId("const_offset",92);
/**
* Try to read the header bytes of the .sla format from the given stream. If the header bytes
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 4c84b4d94e..88b28eff01 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
@@ -45,7 +45,8 @@ public class ConstTpl {
j_flowref,
j_flowref_size,
j_flowdest,
- j_flowdest_size
+ j_flowdest_size,
+ j_offset
}
public enum v_field {
@@ -263,6 +264,10 @@ public class ConstTpl {
encoder.openElement(ELEM_CONST_START);
encoder.closeElement(ELEM_CONST_START);
break;
+ case j_offset:
+ encoder.openElement(ELEM_CONST_OFFSET);
+ encoder.closeElement(ELEM_CONST_OFFSET);
+ break;
case j_next:
encoder.openElement(ELEM_CONST_NEXT);
encoder.closeElement(ELEM_CONST_NEXT);
@@ -307,5 +312,4 @@ public class ConstTpl {
break;
}
}
-
}
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 a953e401ff..1fb0b64069 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
@@ -290,6 +290,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 f165ca6b8b..dc57400015 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 0000000000..8684da3830
--- /dev/null
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slghpatexpress/OffsetInstructionValue.java
@@ -0,0 +1,59 @@
+/* ###
+ * 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 static ghidra.pcode.utils.SlaFormat.*;
+
+import java.io.IOException;
+
+import generic.stl.VectorSTL;
+import ghidra.program.model.pcode.Encoder;
+import ghidra.sleigh.grammar.Location;
+
+public class OffsetInstructionValue extends PatternValue {
+
+ public OffsetInstructionValue(Location location) {
+ super(location);
+ }
+
+ @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 encode(Encoder encoder) throws IOException {
+ encoder.openElement(ELEM_OFFSET_EXP);
+ encoder.closeElement(ELEM_OFFSET_EXP);
+ }
+
+}
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 12955493dd..38651b908a 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
@@ -60,5 +60,4 @@ public abstract class PatternExpression {
p.dispose();
}
}
-
}
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 0000000000..9b753b8d66
--- /dev/null
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slghsymbol/OffsetSymbol.java
@@ -0,0 +1,87 @@
+/* ###
+ * 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 static ghidra.pcode.utils.SlaFormat.*;
+
+import java.io.IOException;
+
+import ghidra.pcodeCPort.semantics.ConstTpl;
+import ghidra.pcodeCPort.semantics.VarnodeTpl;
+import ghidra.pcodeCPort.slghpatexpress.PatternExpression;
+import ghidra.pcodeCPort.slghpatexpress.OffsetInstructionValue;
+import ghidra.pcodeCPort.space.AddrSpace;
+import ghidra.program.model.pcode.Encoder;
+import ghidra.sleigh.grammar.Location;
+
+public class OffsetSymbol extends SpecificSymbol {
+ private AddrSpace const_space;
+ private PatternExpression patexp;
+
+ OffsetSymbol(Location location) {
+ super(location);
+ patexp = null;
+ }
+
+ @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 operand 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);
+ }
+
+ @Override
+ public void encode(Encoder encoder) throws IOException {
+ encoder.openElement(ELEM_OFFSET_SYM);
+ encoder.writeUnsignedInteger(ATTRIB_ID, id);
+ encoder.closeElement(ELEM_OFFSET_SYM);
+ }
+
+ @Override
+ public void encodeHeader(Encoder encoder) throws IOException {
+ encoder.openElement(ELEM_OFFSET_SYM_HEAD);
+ encodeSleighSymbolHeader(encoder);
+ encoder.closeElement(ELEM_OFFSET_SYM_HEAD);
+ }
+
+}
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 b29cc3f238..1c14a38090 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 8166b87ef8..eee777c613 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.49.0