Merge remote-tracking branch 'origin/GP-2480_ghidra1_Sleigh_inst_next2'

Conflicts:
	Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/pcode/exec/trace/TracePcodeEmulatorTest.java
This commit is contained in:
Ryan Kurtz 2022-08-25 01:19:02 -04:00
commit ca80be44ff
121 changed files with 4074 additions and 4553 deletions

View file

@ -349,9 +349,10 @@ specific_symbol[String purpose] returns [SpecificSymbol symbol]
: ^(OP_IDENTIFIER s=.) {
SleighSymbol sym = pcode.findSymbol($s.getText());
if (sym == null) {
unknownSymbolError($s.getText(), find($s), "start, end, operand, epsilon, or varnode", purpose);
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.end_symbol
&& sym.getType() != symbol_type.next2_symbol
&& sym.getType() != symbol_type.operand_symbol
&& sym.getType() != symbol_type.epsilon_symbol
&& sym.getType() != symbol_type.varnode_symbol) {
@ -839,7 +840,7 @@ pattern_symbol[String purpose] returns [PatternExpression expr]
: ^(OP_IDENTIFIER s=.) {
SleighSymbol sym = sc.findSymbol($s.getText());
if (sym == null) {
unknownSymbolError($s.getText(), find($s), "start, end, operand, epsilon, or varnode", purpose);
unknownSymbolError($s.getText(), find($s), "start, end, next2, operand, epsilon, or varnode", purpose);
} else if(sym.getType() == symbol_type.operand_symbol) {
OperandSymbol os = (OperandSymbol) sym;
if (os.getDefiningSymbol() != null && os.getDefiningSymbol().getType() == symbol_type.subtable_symbol) {
@ -848,6 +849,7 @@ pattern_symbol[String purpose] returns [PatternExpression expr]
$expr = os.getPatternExpression();
} else if(sym.getType() == symbol_type.start_symbol
|| sym.getType() == symbol_type.end_symbol
|| sym.getType() == symbol_type.next2_symbol
|| sym.getType() == symbol_type.epsilon_symbol
|| sym.getType() == symbol_type.varnode_symbol) {
SpecificSymbol ss = (SpecificSymbol) sym;
@ -864,7 +866,7 @@ pattern_symbol[String purpose] returns [PatternExpression expr]
reportError(find($s), "Global symbol '" + sym.getName() + "' is not allowed in action expression");
}
} else {
wrongSymbolTypeError(sym, find($s), "start, end, operand, epsilon, or varnode", purpose);
wrongSymbolTypeError(sym, find($s), "start, end, next2, operand, epsilon, or varnode", purpose);
}
}
| t=OP_WILDCARD {
@ -877,9 +879,10 @@ pattern_symbol2[String purpose] returns [PatternExpression expr]
: ^(OP_IDENTIFIER s=.) {
SleighSymbol sym = sc.findSymbol($s.getText());
if (sym == null) {
unknownSymbolError($s.getText(), find($s), "start, end, operand, epsilon, or varnode", purpose);
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.end_symbol
|| sym.getType() == symbol_type.next2_symbol
|| sym.getType() == symbol_type.operand_symbol
|| sym.getType() == symbol_type.epsilon_symbol
|| sym.getType() == symbol_type.varnode_symbol) {
@ -893,7 +896,7 @@ pattern_symbol2[String purpose] returns [PatternExpression expr]
FamilySymbol z = (FamilySymbol) sym;
$expr = z.getPatternValue();
} else {
wrongSymbolTypeError(sym, find($s), "start, end, operand, epsilon, or varnode", purpose);
wrongSymbolTypeError(sym, find($s), "start, end, next2, operand, epsilon, or varnode", purpose);
}
}
| t=OP_WILDCARD {
@ -922,7 +925,7 @@ cstatement[VectorSTL<ContextChange> r]
} else if(sym.getType() == symbol_type.context_symbol) {
ContextSymbol t = (ContextSymbol) sym;
if (!sc.contextMod(r, t, e)) {
reportError(find($id), "Cannot use 'inst_next' to set context variable: '" + t.getName() + "'");
reportError(find($id), "Cannot use 'inst_next' or 'inst_next2' to set context variable: '" + t.getName() + "'");
}
} else if(sym.getType() == symbol_type.operand_symbol) {
OperandSymbol t = (OperandSymbol) sym;
@ -950,6 +953,7 @@ cstatement[VectorSTL<ContextChange> r]
|| sym.getType() == symbol_type.varnodelist_symbol
|| sym.getType() == symbol_type.start_symbol
|| sym.getType() == symbol_type.end_symbol
|| sym.getType() == symbol_type.next2_symbol
|| sym.getType() == symbol_type.operand_symbol
|| sym.getType() == symbol_type.epsilon_symbol
|| sym.getType() == symbol_type.varnode_symbol) {
@ -1176,10 +1180,11 @@ assignment returns [VectorSTL<OpTpl> value]
$value = pcode.newOutput(find(id), false, e, $id.getText());
} else if(sym.getType() != symbol_type.start_symbol
&& sym.getType() != symbol_type.end_symbol
&& sym.getType() != symbol_type.next2_symbol
&& sym.getType() != symbol_type.operand_symbol
&& sym.getType() != symbol_type.epsilon_symbol
&& sym.getType() != symbol_type.varnode_symbol) {
wrongSymbolTypeError(sym, find(id), "start, end, operand, epsilon, or varnode", "assignment");
wrongSymbolTypeError(sym, find(id), "start, end, next2, operand, epsilon, or varnode", "assignment");
} else {
VarnodeTpl v = ((SpecificSymbol) sym).getVarnode();
e.setOutput(find(t), v);
@ -1309,7 +1314,9 @@ jump_symbol[String purpose] returns [VarnodeTpl value]
SleighSymbol sym = pcode.findSymbol($s.getText());
if (sym == null) {
unknownSymbolError($s.getText(), find($s), "start, end, or operand", purpose);
} else if(sym.getType() == symbol_type.start_symbol || sym.getType() == symbol_type.end_symbol) {
} else if (sym.getType() == symbol_type.start_symbol ||
sym.getType() == symbol_type.end_symbol ||
sym.getType() == symbol_type.next2_symbol) {
SpecificSymbol ss = (SpecificSymbol) sym;
$value = new VarnodeTpl(find($s), new ConstTpl(ConstTpl.const_type.j_curspace),
ss.getVarnode().getOffset(),
@ -1489,6 +1496,7 @@ expr_apply returns [Object value]
}
} else if(sym.getType() == symbol_type.start_symbol
|| sym.getType() == symbol_type.end_symbol
|| sym.getType() == symbol_type.next2_symbol
|| sym.getType() == symbol_type.operand_symbol
|| sym.getType() == symbol_type.epsilon_symbol
|| sym.getType() == symbol_type.varnode_symbol) {

View file

@ -573,6 +573,10 @@ public class SleighAssemblerBuilder implements AssemblerBuilder {
else if (sym instanceof EndSymbol) {
// Ignore. We handle inst_next in semantic processing
}
else if (sym instanceof Next2Symbol) {
// Ignore. We handle inst_next2 in semantic processing
}
else if (sym instanceof UseropSymbol) {
// Ignore. We don't do pcode.
}

View file

@ -0,0 +1,77 @@
/* ###
* 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.
*/
package ghidra.app.plugin.assembler.sleigh.expr;
import java.util.Map;
import java.util.Set;
import ghidra.app.plugin.assembler.sleigh.sem.*;
import ghidra.app.plugin.processors.sleigh.expression.EndInstructionValue;
/**
* "Solves" expressions of {@code inst_next2}
*
* <p>
* Works like the constant solver, but takes the value of {@code inst_next}, which is given by the
* assembly address and the resulting instruction length.
*
* <p>
* <b>NOTE:</b> This solver requires backfill, since the value of {@code inst_next2} is not known
* until possible prefixes have been considered.
*/
public class Next2InstructionValueSolver extends AbstractExpressionSolver<EndInstructionValue> {
public Next2InstructionValueSolver() {
super(EndInstructionValue.class);
}
@Override
public AssemblyResolution solve(EndInstructionValue iv, MaskedLong goal, Map<String, Long> vals,
AssemblyResolvedPatterns cur, Set<SolverHint> hints, String description) {
throw new AssertionError(
"INTERNAL: Should never be asked to solve for " + AssemblyTreeResolver.INST_NEXT2);
}
@Override
public MaskedLong getValue(EndInstructionValue iv, Map<String, Long> vals,
AssemblyResolvedPatterns cur) throws NeedsBackfillException {
Long instNext = vals.get(AssemblyTreeResolver.INST_NEXT2);
if (instNext == null) {
throw new NeedsBackfillException(AssemblyTreeResolver.INST_NEXT2);
}
return MaskedLong.fromLong(instNext);
}
@Override
public int getInstructionLength(EndInstructionValue iv) {
return 0;
}
@Override
public MaskedLong valueForResolution(EndInstructionValue exp, Map<String, Long> vals,
AssemblyResolvedPatterns rc) {
Long instNext = vals.get(AssemblyTreeResolver.INST_NEXT2);
if (instNext == null) {
/**
* This method is used in forward state construction, so just leave unknown. This may
* cause unresolvable trees to get generated, but we can't know that until we try to
* resolve them.
*/
return MaskedLong.UNKS;
}
return MaskedLong.fromLong(instNext);
}
}

View file

@ -53,6 +53,7 @@ public class RecursiveDescentSolver {
new ContextFieldSolver().register(this);
new DivExpressionSolver().register(this);
new EndInstructionValueSolver().register(this);
new Next2InstructionValueSolver().register(this);
new LeftShiftExpressionSolver().register(this);
new MinusExpressionSolver().register(this);
new MultExpressionSolver().register(this);

View file

@ -78,6 +78,9 @@ public abstract class AbstractExpressionMatcher<T extends PatternExpression>
if (a instanceof EndInstructionValue) {
return true;
}
if (a instanceof Next2InstructionValue) {
return true;
}
if (a instanceof StartInstructionValue) {
return true;
}

View file

@ -54,6 +54,7 @@ public class AssemblyTreeResolver {
public static final String INST_START = "inst_start";
public static final String INST_NEXT = "inst_next";
public static final String INST_NEXT2 = "inst_next2";
protected final SleighLanguage lang;
protected final Address at;
@ -195,6 +196,8 @@ public class AssemblyTreeResolver {
return rc;
}
vals.put(INST_NEXT, at.add(rc.getInstructionLength()).getAddressableWordOffset());
// inst_next2 use not really supported
vals.put(INST_NEXT2, at.add(rc.getInstructionLength()).getAddressableWordOffset());
DBG.println("Backfilling: " + rc);
AssemblyResolution ar = rc.backfill(SOLVER, vals);
DBG.println("Backfilled final: " + ar);

View file

@ -210,6 +210,12 @@ public class ParserWalker {
return context.getNaddr();
}
public Address getN2addr() {
if (cross_context != null)
return cross_context.getN2addr();
return context.getN2addr();
}
public AddressSpace getCurSpace() {
return context.getCurSpace();
}

View file

@ -246,7 +246,7 @@ public abstract class PcodeEmit {
if (opcode == PcodeOp.BRANCH) {
int offsetType = inputs[0].getOffset().getType();
if (offsetType == ConstTpl.J_RELATIVE || offsetType == ConstTpl.J_START ||
offsetType == ConstTpl.J_NEXT) {
offsetType == ConstTpl.J_NEXT || offsetType == ConstTpl.J_NEXT2) {
return false;
}
OpTpl callopt = new OpTpl(PcodeOp.CALL, null, inputs);
@ -269,7 +269,7 @@ public abstract class PcodeEmit {
else if (opcode == PcodeOp.CBRANCH) {
int offsetType = inputs[0].getOffset().getType();
if (offsetType == ConstTpl.J_RELATIVE || offsetType == ConstTpl.J_START ||
offsetType == ConstTpl.J_NEXT) {
offsetType == ConstTpl.J_NEXT || offsetType == ConstTpl.J_NEXT2) {
return false;
}
@ -326,7 +326,7 @@ public abstract class PcodeEmit {
if (opcode == PcodeOp.BRANCH || opcode == PcodeOp.CALL) {
int offsetType = inputs[0].getOffset().getType();
if (offsetType == ConstTpl.J_RELATIVE || offsetType == ConstTpl.J_START ||
offsetType == ConstTpl.J_NEXT) {
offsetType == ConstTpl.J_NEXT || offsetType == ConstTpl.J_NEXT2) {
return false;
}

View file

@ -89,7 +89,6 @@ public class SleighInstructionPrototype implements InstructionPrototype {
private final static Address[] emptyFlow = new Address[0];
private ContextCache contextCache;
// private InstructionContext instructionContextCache;
private int length;
private ConstructState rootState;
private ConstructState mnemonicState; // state for print mnemonic
@ -236,6 +235,9 @@ public class SleighInstructionPrototype implements InstructionPrototype {
if (destType == ConstTpl.J_NEXT) {
flags = BRANCH_TO_END;
}
else if (destType == ConstTpl.J_NEXT2) {
flags = JUMPOUT;
}
else if ((destType != ConstTpl.J_START) && (destType != ConstTpl.J_RELATIVE)) {
flags = JUMPOUT;
}
@ -674,6 +676,9 @@ public class SleighInstructionPrototype implements InstructionPrototype {
Address addr = getHandleAddr(hand, parsecontext.getAddr().getAddressSpace());
res.add(addr);
}
else if (rec.op.getInput()[0].getOffset().getType() == ConstTpl.J_NEXT2) {
res.add(parsecontext.getN2addr());
}
}
}
}

View file

@ -21,8 +21,7 @@ import ghidra.app.plugin.processors.sleigh.symbol.OperandSymbol;
import ghidra.app.plugin.processors.sleigh.symbol.TripleSymbol;
import ghidra.program.model.address.*;
import ghidra.program.model.lang.*;
import ghidra.program.model.mem.MemBuffer;
import ghidra.program.model.mem.MemoryAccessException;
import ghidra.program.model.mem.*;
/**
*
@ -33,8 +32,9 @@ import ghidra.program.model.mem.MemoryAccessException;
public class SleighParserContext implements ParserContext {
private MemBuffer memBuffer;
private Address addr; // Address of start of instruction
private Address nextInstrAddr; // Address of next instruction
private Address addr; // Address of start of instruction (inst_start)
private Address nextInstrAddr; // Address of next instruction (inst_next)
private Address next2InstAddr; // Address of instruction after next instruction (inst_next2)
private Address refAddr; // corresponds to inst_ref for call-fixup use
private Address destAddr; // corresponds to inst_dest for call-fixup use
private SleighInstructionPrototype prototype;
@ -71,7 +71,8 @@ public class SleighParserContext implements ParserContext {
}
/**
* Constructor for building precompiled templates
* Constructor for building precompiled templates.
* NOTE: This form does not support use of <code>inst_next2</next>.
* @param aAddr = address to which 'inst_start' resolves
* @param nAddr = address to which 'inst_next' resolves
* @param rAddr = special address associated with original call
@ -172,22 +173,99 @@ public class SleighParserContext implements ParserContext {
return handle;
}
/**
* get address of current instruction
* @return address of current instruction
*/
public Address getAddr() {
return addr;
}
/**
* Get address of instruction after current instruction. This may return null if this context
* instance does not support use of {@code inst_next} or next address falls beyond end of
* address space.
* @return address of next instruction or null
*/
public Address getNaddr() {
return nextInstrAddr;
}
/**
* Get address of instruction after the next instruction. This may return {@link #getNaddr()}
* if this context instance does not support use of {@code inst_next2} or parse of next
* instruction fails.
* @return address of instruction after the next instruction or null
*/
public Address getN2addr() {
if (next2InstAddr != null) {
return next2InstAddr;
}
next2InstAddr = computeNext2Address();
if (next2InstAddr == null) {
// unsupported use of inst_next2 or parse failure on next instruction
// returns same as inst_next
next2InstAddr = nextInstrAddr;
}
return next2InstAddr;
}
/**
* Return the address after the next instruction (inst_next2). The length of next instruction
* based on attempted parse of next instruction and does not consider any delayslot use.
* The current instructions context is used during the parse.
* @return address after the next instruction or null if unable/failed to determine
*/
private Address computeNext2Address() {
if (memBuffer == null || nextInstrAddr == null) {
return null; // not supported without memBuffer for parse
}
try {
Address nextAddr = nextInstrAddr;
Language language = prototype.getLanguage();
// limitation: assumes same context as current instruction
ProcessorContextImpl ctx = new ProcessorContextImpl(language);
RegisterValue ctxVal = getContextRegisterValue();
if (ctxVal != null) {
ctx.setRegisterValue(ctxVal);
}
int offset = (int) nextAddr.subtract(addr);
MemBuffer nearbymem = new WrappedMemBuffer(memBuffer, offset);
SleighInstructionPrototype proto =
(SleighInstructionPrototype) language.parse(nearbymem, ctx, true);
return nextAddr.addNoWrap(proto.getLength());
}
catch (Exception e) {
// ignore
}
return null;
}
/**
* Get address space containing current instruction
* @return address space containing current instruction
*/
public AddressSpace getCurSpace() {
return addr.getAddressSpace();
}
/**
* Get constant address space
* @return constant address space
*/
public AddressSpace getConstSpace() {
return constantSpace;
}
/**
* Get memory buffer for current instruction which may also be used to parse next instruction
* or delay slot instructions.
* @return memory buffer for current instruction
*/
public MemBuffer getMemBuffer() {
return memBuffer;
}
@ -251,6 +329,44 @@ public class SleighParserContext implements ParserContext {
return res;
}
/**
* Get the processor context value as a RegisterValue
* @return processor context value
*/
public RegisterValue getContextRegisterValue() {
Register baseContextRegister = prototype.getLanguage().getContextBaseRegister();
if (baseContextRegister == null) {
return null;
}
// convert context int words to byte array for RegisterValue use
int ctxByteLen = baseContextRegister.getMinimumByteSize();
byte[] ctxValueBytes = new byte[ctxByteLen];
for (int i = 0; i < context.length; i++) {
int word = context[i];
for (int n = 3; n >= 0; --n) {
int byteIndex = (i * 4) + n;
setByte(ctxValueBytes, byteIndex, (byte) word);
word >>= 8;
}
}
// append mask to value array for RegisterValue use
byte[] ctxValueMaskBytes = new byte[2 * ctxByteLen];
Arrays.fill(ctxValueMaskBytes, 0, ctxByteLen, (byte) 0xff);
System.arraycopy(ctxValueBytes, 0, ctxValueMaskBytes, ctxByteLen, ctxByteLen);
return new RegisterValue(baseContextRegister, ctxValueMaskBytes);
}
private void setByte(byte[] bytes, int index, byte b) {
if (index < bytes.length) {
bytes[index] = b;
}
}
/**
* Get bytes from context into an int
* @param bytestart is the index of the first byte to fetch

View file

@ -0,0 +1,68 @@
/* ###
* 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.
*/
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 integer offset of the address following the current instruction
*/
public class Next2InstructionValue extends PatternValue {
private static final int HASH = "[inst_next2]".hashCode();
@Override
public int hashCode() {
return HASH;
}
@Override
public boolean equals(Object obj) {
return obj instanceof Next2InstructionValue;
}
@Override
public long minValue() {
return 0;
}
@Override
public long maxValue() {
return 0;
}
@Override
public long getValue(ParserWalker walker) throws MemoryAccessException {
Address addr = walker.getN2addr();
return addr.getAddressableWordOffset();
}
@Override
public void restoreXml(XmlPullParser parser, SleighLanguage lang) {
parser.discardSubTree("next2_exp");
// Nothing to do
}
@Override
public String toString() {
return "[inst_next2]";
}
}

View file

@ -51,6 +51,8 @@ public abstract class PatternExpression {
res = new StartInstructionValue();
else if (nm.equals("end_exp"))
res = new EndInstructionValue();
else if (nm.equals("next2_exp"))
res = new Next2InstructionValue();
else if (nm.equals("plus_exp"))
res = new PlusExpression();
else if (nm.equals("sub_exp"))

View file

@ -0,0 +1,68 @@
/* ###
* 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.
*/
package ghidra.app.plugin.processors.sleigh.symbol;
import java.util.ArrayList;
import ghidra.app.plugin.processors.sleigh.*;
import ghidra.app.plugin.processors.sleigh.expression.Next2InstructionValue;
import ghidra.app.plugin.processors.sleigh.expression.PatternExpression;
import ghidra.program.model.mem.MemoryAccessException;
import ghidra.xml.XmlElement;
import ghidra.xml.XmlPullParser;
/**
*
*
* Symbol with semantic value equal to offset of address immediately
* after the next instruction (inst_next2)
*/
public class Next2Symbol 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.getN2addr().getOffset();
hand.size = hand.space.getPointerSize();
}
@Override
public String print(ParserWalker walker) throws MemoryAccessException {
long val = walker.getN2addr().getOffset();
return "0x"+Long.toHexString(val);
}
@Override
public void printList(ParserWalker walker, ArrayList<Object> list) {
list.add(walker.getParentHandle());
}
@Override
public void restoreXml(XmlPullParser parser, SleighLanguage sleigh) {
XmlElement element = parser.start("next2_sym");
patexp = new Next2InstructionValue();
parser.end(element);
}
}

View file

@ -19,6 +19,8 @@
*/
package ghidra.app.plugin.processors.sleigh.symbol;
import java.util.ArrayList;
import ghidra.app.plugin.processors.sleigh.SleighException;
import ghidra.app.plugin.processors.sleigh.SleighLanguage;
import ghidra.program.model.lang.UnknownInstructionException;
@ -26,8 +28,6 @@ import ghidra.util.xml.SpecXmlUtils;
import ghidra.xml.XmlElement;
import ghidra.xml.XmlPullParser;
import java.util.ArrayList;
/**
*
*
@ -152,6 +152,8 @@ public class SymbolTable {
sym = new StartSymbol();
else if (el.getName().equals("end_sym_head"))
sym = new EndSymbol();
else if (el.getName().equals("next2_sym_head"))
sym = new Next2Symbol();
else if (el.getName().equals("subtable_sym_head"))
sym = new SubtableSymbol();
else

View file

@ -39,14 +39,15 @@ public class ConstTpl {
public static final int HANDLE = 1;
public static final int J_START = 2;
public static final int J_NEXT = 3;
public static final int J_CURSPACE = 4;
public static final int J_CURSPACE_SIZE = 5;
public static final int SPACEID = 6;
public static final int J_RELATIVE = 7;
public static final int J_FLOWREF = 8;
public static final int J_FLOWREF_SIZE = 9;
public static final int J_FLOWDEST = 10;
public static final int J_FLOWDEST_SIZE = 11;
public static final int J_NEXT2 = 4;
public static final int J_CURSPACE = 5;
public static final int J_CURSPACE_SIZE = 6;
public static final int SPACEID = 7;
public static final int J_RELATIVE = 8;
public static final int J_FLOWREF = 9;
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 V_SPACE = 0;
public static final int V_OFFSET = 1;
@ -143,6 +144,8 @@ public class ConstTpl {
return walker.getAddr().getOffset();
case J_NEXT:
return walker.getNaddr().getOffset();
case J_NEXT2:
return walker.getN2addr().getOffset();
case J_FLOWREF:
return walker.getFlowRefAddr().getOffset();
case J_FLOWREF_SIZE:
@ -315,6 +318,9 @@ public class ConstTpl {
else if (typestr.equals("next")) {
type = J_NEXT;
}
else if (typestr.equals("next2")) {
type = J_NEXT2;
}
else if (typestr.equals("curspace")) {
type = J_CURSPACE;
}
@ -379,6 +385,8 @@ public class ConstTpl {
return "[flowref_size]";
case J_NEXT:
return "[next]";
case J_NEXT2:
return "[next2]";
case J_START:
return "[start]";
case J_RELATIVE:

View file

@ -1,302 +0,0 @@
/* ###
* 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.
*/
package ghidra.pcodeCPort.context;
import generic.stl.IteratorSTL;
import generic.stl.VectorSTL;
import ghidra.app.plugin.processors.sleigh.SleighException;
import ghidra.pcodeCPort.address.Address;
import ghidra.pcodeCPort.globalcontext.ContextCache;
import ghidra.pcodeCPort.slghsymbol.*;
import ghidra.pcodeCPort.space.AddrSpace;
import ghidra.pcodeCPort.translate.BadDataError;
public class ParserContext {
public enum ContextState {
uninitialized, disassembly, pcode;
}
private ContextState parsestate;
private AddrSpace const_space;
private byte[] buf = new byte[16]; // Pointer to instruction bit stream
private int[] context; // Pointer to local context
private int contextsize; // Number of entries in context array
private ContextCache contcache; // Interface for getting/setting context
private VectorSTL<ContextSet> contextcommit = new VectorSTL<ContextSet>();
private Address addr; // Address of start of instruction
private Address naddr; // Address of next instruction
private VectorSTL<ConstructState> state = new VectorSTL<ConstructState>(); // Current resolved
// instruction
ConstructState base_state;
private ConstructState point; // Current substate
private boolean outofband;
private int oob_offset;
private int alloc; // Number of ConstructState's allocated
private int delayslot; // delayslot depth
public void dispose() {
if (context != null) {
context = null;
}
}
private ConstructState getState(int index) {
ConstructState constructState = state.get(index);
if (constructState == null) {
constructState = new ConstructState();
state.set(index, constructState);
}
return constructState;
}
public void setAddr(Address ad) {
addr = ad;
}
public void setNaddr(Address ad) {
naddr = ad;
}
public void clearCommits() {
contextcommit.clear();
}
public Address getAddr() {
return addr;
}
public Address getNaddr() {
return naddr;
}
public AddrSpace getCurSpace() {
return addr.getSpace();
}
public AddrSpace getConstSpace() {
return const_space;
}
public void setContextWord(int i, int val, int mask) {
context[i] = (context[i] & (~mask)) | (mask & val);
}
public void loadContext() {
contcache.getContext(addr, context);
}
public int getLength() {
return base_state.length;
}
public void setDelaySlot(int val) {
delayslot = val;
}
public int getDelaySlot() {
return delayslot;
}
public ParserContext(ContextCache ccache) {
parsestate = ContextState.uninitialized;
contcache = ccache;
if (ccache != null) {
contextsize = ccache.getDatabase().getContextSize();
context = new int[contextsize];
}
else {
contextsize = 0;
context = null;
}
}
private void resize(VectorSTL<ConstructState> list, int newsize) {
while (list.size() < newsize) {
list.push_back(new ConstructState());
}
while (list.size() > newsize) {
list.pop_back();
}
}
public byte[] getBuffer() {
return buf;
}
public void initialize(int maxstate, int maxparam, AddrSpace spc) {
const_space = spc;
resize(state, maxstate);
getState(0).parent = null;
for (int i = 0; i < maxstate; ++i) {
resize(getState(i).resolve, maxparam);
}
base_state = getState(0);
}
public ContextState getParserState() {
return parsestate;
}
public void setParserState(ContextState st) {
parsestate = st;
}
public void deallocateState(ParserWalkerChange walker) {
alloc = 1;
walker.context = this;
walker.baseState();
}
public void allocateOperand(int i, ParserWalkerChange walker) {
ConstructState opstate = state.get(alloc++);
opstate.parent = walker.point;
opstate.ct = null;
walker.point.resolve.set(i, opstate);
walker.breadcrumb[walker.depth++] += 1;
walker.point = opstate;
walker.breadcrumb[walker.depth] = 0;
}
public int getInstructionBytes(int bytestart, int size, int off) {
// Get bytes from the instruction stream into an int
// (assuming big endian format)
off += bytestart;
if (off >= 16) {
throw new BadDataError("Instruction is using more than 16 bytes");
}
int res = 0;
for (int i = 0; i < size; ++i) {
res <<= 8;
res |= buf[i + off];
}
return res;
}
public int getInstructionBits(int startbit, int size, int off) {
off += (startbit / 8);
if (off >= 16) {
throw new BadDataError("Instruction is using more than 16 bytes");
}
startbit = startbit % 8;
int bytesize = (startbit + size - 1) / 8 + 1;
int res = 0;
for (int i = 0; i < bytesize; ++i) {
res <<= 8;
res |= buf[i + off];
}
res <<= 8 * (4 - bytesize) + startbit; // Move starting bit to highest position
res >>= 8 * 4 - size; // Shift to bottom of intm
return res;
}
// Get bytes from context into a intm
// Assume request is within a intm
public int getContextBytes(int bytestart, int size) {
int res = context[bytestart / 4];
res <<= (bytestart % 4) * 8;
res >>>= (4 - size) * 8;
return res;
}
public int getContextBits(int startbit, int size) {
int res = context[startbit / (8 * 4)]; // Get intm containing highest bit
res <<= (startbit % (8 * 4)); // Shift startbit to highest position
res >>>= (8 * 4 - size);
return res;
}
// set the offset into instruction bytes (for
// future calls into getInstructionBytes) without
// disturbing the tree walk
public void setOffsetOutOfBand(Constructor c, int index) {
outofband = true;
ConstructState pt = point;
while (pt.ct != c) {
if (pt == getState(0)) {
return;
}
pt = pt.parent;
}
OperandSymbol sym = c.getOperand(index);
int i = sym.getOffsetBase();
// if i<0, i.e. the offset of the operand is constructor relative
// its possible that the branch corresponding to the operand
// has not been constructed yet. Context expressions are
// evaluated BEFORE the constructors branches are created.
// So we have to construct the offset explicitly.
if (i < 0) {
oob_offset = pt.offset + sym.getRelativeOffset();
}
else {
oob_offset = pt.resolve.get(index).offset;
}
}
public void addCommit(TripleSymbol sym, int num, int mask, boolean flow, ConstructState point) {
contextcommit.push_back(new ContextSet());
ContextSet set = contextcommit.back();
set.sym = sym;
set.point = point; // This is the current state
set.num = num;
set.mask = mask;
set.value = context[num] & mask;
set.flow = flow;
}
public void applyCommits() {
if (contextcommit.empty()) {
return;
}
ParserWalker walker = new ParserWalker(this);
walker.baseState();
IteratorSTL<ContextSet> iter;
for (iter = contextcommit.begin(); !iter.isEnd(); iter.increment()) {
TripleSymbol sym = iter.get().sym;
Address addr = null;
if (sym.getType() == symbol_type.operand_symbol) {
// The value for an OperandSymbol is probabably already
// calculated, we just need to find the right
// tree node of the state
int i = ((OperandSymbol) sym).getIndex();
FixedHandle h = (iter.get().point.resolve.get(i).hand);
addr = new Address(h.space, h.offset_offset);
}
else {
FixedHandle hand = new FixedHandle();
sym.getFixedHandle(hand, walker);
addr = new Address(hand.space, hand.offset_offset);
}
// Commit context change
contcache.setContext(addr, iter.get().num, iter.get().mask, iter.get().value);
}
}
/**
* Returns primary flow reference destination address for instruction or null
*/
public Address getFlowRefAddr() {
throw new SleighException("Flow reference (inst_ref) is undefined at " + getAddr());
}
/**
* Returns original flow destination address for instruction or null
*/
public Address getFlowDestAddr() {
throw new SleighException("Flow destination (inst_dest) is undefined at " + getAddr());
}
}

View file

@ -1,160 +0,0 @@
/* ###
* 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.
*/
package ghidra.pcodeCPort.context;
import ghidra.pcodeCPort.address.Address;
import ghidra.pcodeCPort.slghsymbol.Constructor;
import ghidra.pcodeCPort.slghsymbol.OperandSymbol;
import ghidra.pcodeCPort.space.AddrSpace;
public class ParserWalker {
// A class for walking the ParserContext
private ParserContext const_context;
protected ConstructState point; // The current node being visited
protected int depth; // Depth of the current node
protected int[] breadcrumb; // Path of operands from root
public ParserWalker(ParserContext c) {
const_context = c;
breadcrumb = new int[32];
}
public ParserContext getParserContext() {
return const_context;
}
public void baseState() {
point = const_context.base_state;
depth = 0;
breadcrumb[0] = 0;
}
public void setOutOfBandState(Constructor ct, int index, ConstructState tempstate,
ParserWalker otherwalker) {
// Initialize walker for future calls into getInstructionBytes assuming -ct- is the current position in the walk
ConstructState pt = otherwalker.point;
int curdepth = otherwalker.depth;
while (pt.ct != ct) {
if (curdepth <= 0) {
return;
}
curdepth -= 1;
pt = pt.parent;
}
OperandSymbol sym = ct.getOperand(index);
int i = sym.getOffsetBase();
// if i<0, i.e. the offset of the operand is constructor relative
// its possible that the branch corresponding to the operand
// has not been constructed yet. Context expressions are
// evaluated BEFORE the constructors branches are created.
// So we have to construct the offset explicitly.
if (i < 0) {
tempstate.offset = pt.offset + sym.getRelativeOffset();
}
else {
tempstate.offset = pt.resolve.get(index).offset;
}
tempstate.ct = ct;
tempstate.length = pt.length;
point = tempstate;
depth = 0;
breadcrumb[0] = 0;
}
public boolean isState() {
return (point != null);
}
public void pushOperand(int i) {
breadcrumb[depth++] = i + 1;
point = point.resolve.get(i);
breadcrumb[depth] = 0;
}
public void popOperand() {
point = point.parent;
depth -= 1;
}
public int getOffset(int i) {
if (i < 0) {
return point.offset;
}
ConstructState op = point.resolve.get(i);
return op.offset + op.length;
}
public Constructor getConstructor() {
return point.ct;
}
public int getOperand() {
return breadcrumb[depth];
}
public FixedHandle getParentHandle() {
return point.hand;
}
public FixedHandle getFixedHandle(int i) {
return point.resolve.get(i).hand;
}
public AddrSpace getCurSpace() {
return const_context.getCurSpace();
}
public AddrSpace getConstSpace() {
return const_context.getConstSpace();
}
public Address getAddr() {
return const_context.getAddr();
}
public Address getNaddr() {
return const_context.getNaddr();
}
public Address getFlowRefAddr() {
return const_context.getFlowRefAddr();
}
public Address getFlowDestAddr() {
return const_context.getFlowDestAddr();
}
public int getLength() {
return const_context.getLength();
}
public int getInstructionBytes(int byteoff, int numbytes) {
return const_context.getInstructionBytes(byteoff, numbytes, point.offset);
}
public int getContextBytes(int byteoff, int numbytes) {
return const_context.getContextBytes(byteoff, numbytes);
}
public int getInstructionBits(int startbit, int size) {
return const_context.getInstructionBits(startbit, size, point.offset);
}
public int getContextBits(int startbit, int size) {
return const_context.getContextBits(startbit, size);
}
}

View file

@ -1,66 +0,0 @@
/* ###
* 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.context;
import ghidra.pcodeCPort.slghsymbol.Constructor;
public class ParserWalkerChange extends ParserWalker {
// Extension to walker that allows for on the fly modifications to tree
ParserContext context;
public ParserWalkerChange(ParserContext c) {
super(c);
context = c;
}
@Override
public ParserContext getParserContext() {
return context;
}
public ConstructState getPoint() {
return point;
}
public void setOffset(int off) {
point.offset = off;
}
public void setConstructor(Constructor c) {
point.ct = c;
}
public void setCurrentLength(int len) {
point.length = len;
}
public void calcCurrentLength(int length, int numopers) {
// Calculate the length of the current constructor
// state assuming all its operands are constructed
length += point.offset; // Convert relative length to absolute length
for (int i = 0; i < numopers; ++i) {
ConstructState subpoint = point.resolve.get(i);
int sublength = subpoint.length + subpoint.offset;
// Since subpoint->offset is an absolute offset
// (relative to beginning of instruction) sublength
if (sublength > length) {
length = sublength;
}
}
point.length = length - point.offset; // Convert back to relative length
}
}

View file

@ -20,13 +20,10 @@ import java.io.PrintStream;
import org.jdom.Element;
import generic.stl.VectorSTL;
import ghidra.pcodeCPort.context.FixedHandle;
import ghidra.pcodeCPort.context.ParserWalker;
import ghidra.pcodeCPort.error.LowlevelError;
import ghidra.pcodeCPort.space.AddrSpace;
import ghidra.pcodeCPort.space.spacetype;
import ghidra.pcodeCPort.translate.Translate;
import ghidra.pcodeCPort.utils.AddrSpaceToIdSymmetryMap;
import ghidra.pcodeCPort.utils.XmlUtils;
public class ConstTpl {
@ -41,6 +38,7 @@ public class ConstTpl {
handle,
j_start,
j_next,
j_next2,
j_curspace,
j_curspace_size,
spaceid,
@ -198,138 +196,6 @@ public class ConstTpl {
return 0;
}
public long fix(ParserWalker walker) {
// Get the value of the ConstTpl in context
// NOTE: if the property is dynamic this returns the property
// of the temporary storage
switch (type) {
case j_start:
return walker.getAddr().getOffset(); // Fill in starting address placeholder with real address
case j_next:
return walker.getNaddr().getOffset(); // Fill in next address placeholder with real address
case j_curspace_size:
return walker.getCurSpace().getAddrSize();
case j_curspace:
return AddrSpaceToIdSymmetryMap.getID(walker.getCurSpace());
case handle: {
FixedHandle hand = walker.getFixedHandle(handle_index);
switch (select) {
case v_space:
if (hand.offset_space == null) {
return AddrSpaceToIdSymmetryMap.getID(hand.space);
}
return AddrSpaceToIdSymmetryMap.getID(hand.temp_space);
case v_offset:
if (hand.offset_space == null) {
return hand.offset_offset;
}
return hand.temp_offset;
case v_size:
return hand.size;
case v_offset_plus:
if (hand.space != walker.getConstSpace()) { // If we are not a constant
if (hand.offset_space == null) {
return hand.offset_offset + (value_real&0xffff);
}
return hand.temp_offset + (value_real&0xffff);
}
// If we are a constant, return a shifted value
long val;
if (hand.offset_space == null)
val = hand.offset_offset;
else
val = hand.temp_offset;
val >>= 8 * (value_real >> 16);
return val;
}
break;
}
case j_relative:
case real:
return value_real;
case spaceid:
return AddrSpaceToIdSymmetryMap.getID(spaceid);
default:
break;
}
return 0; // Should never reach here
}
// Get the value of the ConstTpl in context
// when we know it is a space
public AddrSpace fixSpace(ParserWalker walker) {
// Get the value of the ConstTpl in context
// when we know it is a space
switch (type) {
case j_curspace:
return walker.getCurSpace();
case handle: {
FixedHandle hand = walker.getFixedHandle(handle_index);
switch (select) {
case v_space:
if (hand.offset_space == null) {
return hand.space;
}
return hand.temp_space;
default:
break;
}
break;
}
case spaceid:
return spaceid;
default:
break;
}
throw new LowlevelError("ConstTpl is not a spaceid as expected");
}
// Fill in the space portion of a FixedHandle, base on this ConstTpl
public void fillinSpace(FixedHandle hand, ParserWalker walker) {
switch (type) {
case j_curspace:
hand.space = walker.getCurSpace();
return;
case handle: {
FixedHandle otherhand = walker.getFixedHandle(handle_index);
switch (select) {
case v_space:
hand.space = otherhand.space;
return;
default:
break;
}
break;
}
case spaceid:
hand.space = spaceid;
return;
default:
break;
}
throw new LowlevelError("ConstTpl is not a spaceid as expected");
}
// Fillin the offset portion of a FixedHandle, based on this ConstTpl
// If the offset value is dynamic, indicate this in the handle
// we don't just fill in the temporary variable offset
// we assume hand.space is already filled in
public void fillinOffset(FixedHandle hand, ParserWalker walker) {
if (type == const_type.handle) {
FixedHandle otherhand = walker.getFixedHandle(handle_index);
hand.offset_space = otherhand.offset_space;
hand.offset_offset = otherhand.offset_offset;
hand.offset_size = otherhand.offset_size;
hand.temp_space = otherhand.temp_space;
hand.temp_offset = otherhand.temp_offset;
}
else {
hand.offset_space = null;
hand.offset_offset = fix(walker);
hand.offset_offset &= hand.space.getMask();
}
}
private void copyIntoMe(ConstTpl other) {
type = other.type;
spaceid = other.spaceid;
@ -434,6 +300,9 @@ public class ConstTpl {
case j_next:
s.append("next\"/>");
break;
case j_next2:
s.append("next2\"/>");
break;
case j_curspace:
s.append("curspace\"/>");
break;
@ -485,6 +354,9 @@ public class ConstTpl {
else if (typestring.equals("next")) {
type = const_type.j_next;
}
else if (typestring.equals("next2")) {
type = const_type.j_next2;
}
else if (typestring.equals("curspace")) {
type = const_type.j_curspace;
}

View file

@ -1,6 +1,5 @@
/* ###
* 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.
@ -16,18 +15,15 @@
*/
package ghidra.pcodeCPort.semantics;
import generic.stl.VectorSTL;
import ghidra.pcodeCPort.context.FixedHandle;
import ghidra.pcodeCPort.context.ParserWalker;
import ghidra.pcodeCPort.space.AddrSpace;
import ghidra.pcodeCPort.space.spacetype;
import ghidra.pcodeCPort.translate.Translate;
import java.io.PrintStream;
import java.util.List;
import org.jdom.Element;
import generic.stl.VectorSTL;
import ghidra.pcodeCPort.space.AddrSpace;
import ghidra.pcodeCPort.translate.Translate;
public class HandleTpl {
private ConstTpl space;
@ -114,33 +110,6 @@ public class HandleTpl {
// Build handle to thing being pointed at by -vn-
}
public void fix(FixedHandle hand, ParserWalker walker) {
if (ptrspace.getType() == ConstTpl.const_type.real) {
// The export is unstarred, but this doesn't mean the varnode
// being exported isn't dynamic
space.fillinSpace(hand, walker);
hand.size = (int) size.fix(walker);
ptroffset.fillinOffset(hand, walker);
}
else {
hand.space = space.fixSpace(walker);
hand.size = (int) size.fix(walker);
hand.offset_offset = ptroffset.fix(walker);
hand.offset_space = ptrspace.fixSpace(walker);
if (hand.offset_space.getType() == spacetype.IPTR_CONSTANT) {
// Handle could have been dynamic but wasn't
hand.offset_space = null;
hand.offset_offset <<= hand.space.getScale();
hand.offset_offset &= hand.space.getMask();
}
else {
hand.offset_size = (int) ptrsize.fix(walker);
hand.temp_space = temp_space.fixSpace(walker);
hand.temp_offset = temp_offset.fix(walker);
}
}
}
public void changeHandleIndex(VectorSTL<Integer> handmap) {
space.changeHandleIndex(handmap);
size.changeHandleIndex(handmap);

View file

@ -1,6 +1,5 @@
/* ###
* 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.
@ -18,7 +17,6 @@ package ghidra.pcodeCPort.semantics;
import generic.stl.IteratorSTL;
import generic.stl.VectorSTL;
import ghidra.pcodeCPort.context.ParserWalker;
import ghidra.pcodeCPort.translate.UnimplError;
// SLEIGH specific pcode generator
@ -27,8 +25,6 @@ public abstract class PcodeBuilder {
private int labelbase;
private int labelcount;
protected ParserWalker walker;
protected abstract void dump(OpTpl op);
public PcodeBuilder(int lbcnt) {
@ -42,10 +38,6 @@ public abstract class PcodeBuilder {
return labelbase;
}
public ParserWalker getCurrentWalker() {
return walker;
}
public abstract void appendBuild(OpTpl bld, int secnum);
public abstract void appendCrossBuild(OpTpl bld, int secnum);

View file

@ -21,8 +21,6 @@ import java.util.List;
import org.jdom.Element;
import generic.stl.VectorSTL;
import ghidra.pcodeCPort.context.FixedHandle;
import ghidra.pcodeCPort.context.ParserWalker;
import ghidra.pcodeCPort.semantics.ConstTpl.const_type;
import ghidra.pcodeCPort.semantics.ConstTpl.v_field;
import ghidra.pcodeCPort.space.spacetype;
@ -129,17 +127,6 @@ public class VarnodeTpl {
return true;
}
public boolean isDynamic(ParserWalker walker) {
if (offset.getType() != ConstTpl.const_type.handle) {
return false;
}
// Technically we should probably check all three
// ConstTpls for dynamic handles, but in all cases
// if there is any dynamic piece then the offset is
FixedHandle hand = walker.getFixedHandle(offset.getHandleIndex());
return (hand.offset_space != null);
}
public int transfer(VectorSTL<HandleTpl> params) {
boolean doesOffsetPlus = false;
int handleIndex=0;

View file

@ -289,6 +289,8 @@ public class SleighCompile extends SleighBase {
symtab.addSymbol(startsym);
EndSymbol endsym = new EndSymbol(location, "inst_next", getConstantSpace());
symtab.addSymbol(endsym);
Next2Symbol next2sym = new Next2Symbol(location, "inst_next2", getConstantSpace());
symtab.addSymbol(next2sym);
EpsilonSymbol epsilon = new EpsilonSymbol(location, "epsilon", getConstantSpace());
symtab.addSymbol(epsilon);
}
@ -1280,7 +1282,8 @@ public class SleighCompile extends SleighBase {
VectorSTL<PatternValue> vallist = new VectorSTL<>();
pe.listValues(vallist);
for (int i = 0; i < vallist.size(); ++i) {
if (vallist.get(i) instanceof EndInstructionValue) {
PatternValue v = vallist.get(i);
if (v instanceof EndInstructionValue || v instanceof Next2InstructionValue) {
return false;
}
}

View file

@ -1,6 +1,5 @@
/* ###
* 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.
@ -32,6 +31,7 @@ class Yylval {
OperandSymbol operandsym;
StartSymbol startsym;
EndSymbol endsym;
Next2Symbol next2sym;
SubtableSymbol subtablesym;
MacroSymbol macrosym;
LabelSymbol labelsym;

View file

@ -1,6 +1,5 @@
/* ###
* 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.
@ -16,13 +15,12 @@
*/
package ghidra.pcodeCPort.slghpatexpress;
import java.io.PrintStream;
import generic.stl.VectorSTL;
import ghidra.pcodeCPort.context.ParserWalker;
import ghidra.pcodeCPort.utils.MutableInt;
import ghidra.sleigh.grammar.Location;
import java.io.PrintStream;
public class AndExpression extends BinaryExpression {
public AndExpression(Location location) {
@ -33,13 +31,6 @@ public class AndExpression extends BinaryExpression {
super(location, l, r);
}
@Override
public long getValue(ParserWalker pos) {
long leftval = getLeft().getValue(pos);
long rightval = getRight().getValue(pos);
return leftval & rightval;
}
@Override
public long getSubValue(VectorSTL<Long> replace, MutableInt listpos) {
long leftval = getLeft().getSubValue(replace, listpos); // Must be left first

View file

@ -1,6 +1,5 @@
/* ###
* 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.
@ -16,16 +15,15 @@
*/
package ghidra.pcodeCPort.slghpatexpress;
import generic.stl.VectorSTL;
import ghidra.pcodeCPort.context.ParserWalker;
import ghidra.pcodeCPort.translate.Translate;
import ghidra.pcodeCPort.utils.XmlUtils;
import ghidra.sleigh.grammar.Location;
import java.io.PrintStream;
import org.jdom.Element;
import generic.stl.VectorSTL;
import ghidra.pcodeCPort.translate.Translate;
import ghidra.pcodeCPort.utils.XmlUtils;
import ghidra.sleigh.grammar.Location;
public class ConstantValue extends PatternValue {
long val;
@ -39,11 +37,6 @@ public class ConstantValue extends PatternValue {
val = v;
}
@Override
public long getValue(ParserWalker pos) {
return val;
}
@Override
public TokenPattern genMinPattern(VectorSTL<TokenPattern> ops) {
return new TokenPattern(location);

View file

@ -1,6 +1,5 @@
/* ###
* 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.
@ -16,17 +15,16 @@
*/
package ghidra.pcodeCPort.slghpatexpress;
import java.io.PrintStream;
import org.jdom.Element;
import generic.stl.VectorSTL;
import ghidra.pcodeCPort.context.ParserWalker;
import ghidra.pcodeCPort.translate.Translate;
import ghidra.pcodeCPort.utils.Utils;
import ghidra.pcodeCPort.utils.XmlUtils;
import ghidra.sleigh.grammar.Location;
import java.io.PrintStream;
import org.jdom.Element;
public class ContextField extends PatternValue {
private int startbit, endbit;
@ -80,19 +78,6 @@ public class ContextField extends PatternValue {
shift = 7 - (endbit % 8);
}
@Override
public long getValue(ParserWalker pos) {
long res = ExpressUtils.getContextBytes(pos, startbyte, endbyte);
res >>>= shift;
if (signbit) {
res = Utils.zzz_sign_extend(res, endbit - startbit);
}
else {
res = Utils.zzz_zero_extend(res, endbit - startbit);
}
return res;
}
@Override
public String toString() {
return "cf:{" + startbit + "," + endbit + "," + startbyte + "," + endbyte + "," + shift +

View file

@ -1,6 +1,5 @@
/* ###
* 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.
@ -16,13 +15,12 @@
*/
package ghidra.pcodeCPort.slghpatexpress;
import java.io.PrintStream;
import generic.stl.VectorSTL;
import ghidra.pcodeCPort.context.ParserWalker;
import ghidra.pcodeCPort.utils.MutableInt;
import ghidra.sleigh.grammar.Location;
import java.io.PrintStream;
public class DivExpression extends BinaryExpression {
public DivExpression(Location location) {
@ -33,13 +31,6 @@ public class DivExpression extends BinaryExpression {
super(location, l, r);
}
@Override
public long getValue(ParserWalker pos) {
long leftval = getLeft().getValue(pos);
long rightval = getRight().getValue(pos);
return leftval / rightval;
}
@Override
public long getSubValue(VectorSTL<Long> replace, MutableInt listpos) {
long leftval = getLeft().getSubValue(replace, listpos); // Must be left first

View file

@ -1,6 +1,5 @@
/* ###
* 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.
@ -16,26 +15,20 @@
*/
package ghidra.pcodeCPort.slghpatexpress;
import generic.stl.VectorSTL;
import ghidra.pcodeCPort.context.ParserWalker;
import ghidra.pcodeCPort.translate.Translate;
import ghidra.sleigh.grammar.Location;
import java.io.PrintStream;
import org.jdom.Element;
import generic.stl.VectorSTL;
import ghidra.pcodeCPort.translate.Translate;
import ghidra.sleigh.grammar.Location;
public class EndInstructionValue extends PatternValue {
public EndInstructionValue(Location location) {
super(location);
}
@Override
public long getValue(ParserWalker pos) {
return (pos.getNaddr().getOffset() >>> pos.getNaddr().getSpace().getScale());
}
@Override
public TokenPattern genMinPattern(VectorSTL<TokenPattern> ops) {
return new TokenPattern(location);

View file

@ -1,6 +1,5 @@
/* ###
* 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.
@ -17,55 +16,9 @@
package ghidra.pcodeCPort.slghpatexpress;
import generic.stl.VectorSTL;
import ghidra.pcodeCPort.context.ParserWalker;
import ghidra.pcodeCPort.utils.Utils;
public class ExpressUtils {
// Build a long from the instruction bytes
static long getInstructionBytes(ParserWalker pos, int bytestart, int byteend, boolean bigendian) {
long res = 0;
int size = byteend - bytestart + 1;
int tmpsize = size;
while (tmpsize >= 4) {
int tmp = pos.getInstructionBytes(bytestart, 4);
res <<= 32;
res |= tmp;
bytestart += 4;
tmpsize -= 4;
}
if (tmpsize > 0) {
int tmp = pos.getInstructionBytes(bytestart, tmpsize);
res <<= 8 * tmpsize;
res |= tmp;
}
if (!bigendian) {
res = Utils.byte_swap(res, size);
}
return res;
}
// Build a intb from the context bytes
static long getContextBytes(ParserWalker pos, int bytestart, int byteend) {
long res = 0;
int size = byteend - bytestart + 1;
while (size >= 4) {
int tmp = pos.getContextBytes(bytestart, 4);
res <<= 32;
res |= tmp;
bytestart += 4;
size = byteend - bytestart + 1;
}
if (size > 0) {
int tmp = pos.getContextBytes(bytestart, size);
res <<= 8 * size;
res |= tmp;
}
return res;
}
static boolean advance_combo(VectorSTL<Long> val, VectorSTL<Long> min, VectorSTL<Long> max) {
int i = 0;
while (i < val.size()) {

View file

@ -1,6 +1,5 @@
/* ###
* 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.
@ -16,13 +15,12 @@
*/
package ghidra.pcodeCPort.slghpatexpress;
import java.io.PrintStream;
import generic.stl.VectorSTL;
import ghidra.pcodeCPort.context.ParserWalker;
import ghidra.pcodeCPort.utils.MutableInt;
import ghidra.sleigh.grammar.Location;
import java.io.PrintStream;
public class LeftShiftExpression extends BinaryExpression {
public LeftShiftExpression(Location location) {
@ -33,13 +31,6 @@ public class LeftShiftExpression extends BinaryExpression {
super(location, l, r);
}
@Override
public long getValue(ParserWalker pos) {
long leftval = getLeft().getValue(pos);
long rightval = getRight().getValue(pos);
return leftval << rightval;
}
@Override
public long getSubValue(VectorSTL<Long> replace, MutableInt listpos) {
long leftval = getLeft().getSubValue(replace, listpos); // Must be left first

View file

@ -1,6 +1,5 @@
/* ###
* 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.
@ -16,13 +15,12 @@
*/
package ghidra.pcodeCPort.slghpatexpress;
import java.io.PrintStream;
import generic.stl.VectorSTL;
import ghidra.pcodeCPort.context.ParserWalker;
import ghidra.pcodeCPort.utils.MutableInt;
import ghidra.sleigh.grammar.Location;
import java.io.PrintStream;
public class MinusExpression extends UnaryExpression {
public MinusExpression(Location location) {
@ -33,12 +31,6 @@ public class MinusExpression extends UnaryExpression {
super(location, u);
}
@Override
public long getValue(ParserWalker pos) {
long val = getUnary().getValue(pos);
return -val;
}
@Override
public long getSubValue(VectorSTL<Long> replace, MutableInt listpos) {
long val = getUnary().getSubValue(replace, listpos);

View file

@ -1,6 +1,5 @@
/* ###
* 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.
@ -16,13 +15,12 @@
*/
package ghidra.pcodeCPort.slghpatexpress;
import java.io.PrintStream;
import generic.stl.VectorSTL;
import ghidra.pcodeCPort.context.ParserWalker;
import ghidra.pcodeCPort.utils.MutableInt;
import ghidra.sleigh.grammar.Location;
import java.io.PrintStream;
public class MultExpression extends BinaryExpression {
public MultExpression(Location location) {
@ -33,13 +31,6 @@ public class MultExpression extends BinaryExpression {
super(location, l, r);
}
@Override
public long getValue(ParserWalker pos) {
long leftval = getLeft().getValue(pos);
long rightval = getRight().getValue(pos);
return leftval * rightval;
}
@Override
public long getSubValue(VectorSTL<Long> replace, MutableInt listpos) {
long leftval = getLeft().getSubValue(replace, listpos); // Must be left first

View file

@ -0,0 +1,61 @@
/* ###
* 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.
*/
package ghidra.pcodeCPort.slghpatexpress;
import java.io.PrintStream;
import org.jdom.Element;
import generic.stl.VectorSTL;
import ghidra.pcodeCPort.translate.Translate;
import ghidra.sleigh.grammar.Location;
public class Next2InstructionValue extends PatternValue {
public Next2InstructionValue(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 saveXml(PrintStream s) {
s.append("<next2_exp/>");
}
@Override
public void restoreXml(Element el, Translate trans) {
}
}

View file

@ -1,6 +1,5 @@
/* ###
* 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.
@ -16,13 +15,12 @@
*/
package ghidra.pcodeCPort.slghpatexpress;
import java.io.PrintStream;
import generic.stl.VectorSTL;
import ghidra.pcodeCPort.context.ParserWalker;
import ghidra.pcodeCPort.utils.MutableInt;
import ghidra.sleigh.grammar.Location;
import java.io.PrintStream;
public class NotExpression extends UnaryExpression {
public NotExpression(Location location) {
@ -33,12 +31,6 @@ public class NotExpression extends UnaryExpression {
super(location, u);
}
@Override
public long getValue(ParserWalker pos) {
long val = getUnary().getValue(pos);
return ~val;
}
@Override
public long getSubValue(VectorSTL<Long> replace, MutableInt listpos) {
long val = getUnary().getSubValue(replace, listpos);

View file

@ -20,7 +20,7 @@ import java.io.PrintStream;
import org.jdom.Element;
import generic.stl.VectorSTL;
import ghidra.pcodeCPort.context.*;
import ghidra.pcodeCPort.context.SleighError;
import ghidra.pcodeCPort.sleighbase.SleighBase;
import ghidra.pcodeCPort.slghsymbol.*;
import ghidra.pcodeCPort.translate.Translate;
@ -79,28 +79,6 @@ public class OperandValue extends PatternValue {
throw new SleighError("Operand used in pattern expression", ct.location);
}
// Get the value of an operand when it is used in
// an expression.
@Override
public long getValue(ParserWalker pos) {
OperandSymbol sym = ct.getOperand(index);
PatternExpression patexp = sym.getDefiningExpression();
if (patexp == null) {
TripleSymbol defsym = sym.getDefiningSymbol();
if (defsym != null) {
patexp = defsym.getPatternExpression();
}
if (patexp == null) {
return 0;
}
}
ConstructState tempstate = new ConstructState();
ParserWalker newwalker = new ParserWalker(pos.getParserContext());
newwalker.setOutOfBandState(ct, index, tempstate, pos);
long res = patexp.getValue(newwalker);
return res;
}
@Override
public long getSubValue(VectorSTL<Long> replace, MutableInt listpos) {
OperandSymbol sym = ct.getOperand(index);

View file

@ -1,6 +1,5 @@
/* ###
* 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.
@ -16,13 +15,12 @@
*/
package ghidra.pcodeCPort.slghpatexpress;
import java.io.PrintStream;
import generic.stl.VectorSTL;
import ghidra.pcodeCPort.context.ParserWalker;
import ghidra.pcodeCPort.utils.MutableInt;
import ghidra.sleigh.grammar.Location;
import java.io.PrintStream;
public class OrExpression extends BinaryExpression {
public OrExpression(Location location) {
@ -33,13 +31,6 @@ public class OrExpression extends BinaryExpression {
super(location, l, r);
}
@Override
public long getValue(ParserWalker pos) {
long leftval = getLeft().getValue(pos);
long rightval = getRight().getValue(pos);
return leftval | rightval;
}
@Override
public long getSubValue(VectorSTL<Long> replace, MutableInt listpos) {
long leftval = getLeft().getSubValue(replace, listpos); // Must be left first

View file

@ -1,6 +1,5 @@
/* ###
* 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.
@ -16,16 +15,15 @@
*/
package ghidra.pcodeCPort.slghpatexpress;
import generic.stl.VectorSTL;
import ghidra.pcodeCPort.context.ParserWalker;
import ghidra.pcodeCPort.translate.Translate;
import ghidra.pcodeCPort.utils.MutableInt;
import ghidra.sleigh.grammar.Location;
import java.io.PrintStream;
import org.jdom.Element;
import generic.stl.VectorSTL;
import ghidra.pcodeCPort.translate.Translate;
import ghidra.pcodeCPort.utils.MutableInt;
import ghidra.sleigh.grammar.Location;
public abstract class PatternExpression {
public final Location location;
@ -39,8 +37,6 @@ public abstract class PatternExpression {
refcount = 0;
}
public abstract long getValue(ParserWalker pos);
public abstract TokenPattern genMinPattern(VectorSTL<TokenPattern> ops);
public abstract void listValues(VectorSTL<PatternValue> list);
@ -91,6 +87,9 @@ public abstract class PatternExpression {
else if (nm.equals("end_exp")) {
res = new EndInstructionValue(null);
}
else if (nm.equals("next2_exp")) {
res = new Next2InstructionValue(null);
}
else if (nm.equals("plus_exp")) {
res = new PlusExpression(null);
}

View file

@ -1,6 +1,5 @@
/* ###
* 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.
@ -16,13 +15,12 @@
*/
package ghidra.pcodeCPort.slghpatexpress;
import java.io.PrintStream;
import generic.stl.VectorSTL;
import ghidra.pcodeCPort.context.ParserWalker;
import ghidra.pcodeCPort.utils.MutableInt;
import ghidra.sleigh.grammar.Location;
import java.io.PrintStream;
public class PlusExpression extends BinaryExpression {
public PlusExpression(Location location) {
@ -33,13 +31,6 @@ public class PlusExpression extends BinaryExpression {
super(location, l, r);
}
@Override
public long getValue(ParserWalker pos) {
long leftval = getLeft().getValue(pos);
long rightval = getRight().getValue(pos);
return leftval + rightval;
}
@Override
public long getSubValue(VectorSTL<Long> replace, MutableInt listpos) {
long leftval = getLeft().getSubValue(replace, listpos); // Must be left first

View file

@ -1,6 +1,5 @@
/* ###
* 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.
@ -16,13 +15,12 @@
*/
package ghidra.pcodeCPort.slghpatexpress;
import java.io.PrintStream;
import generic.stl.VectorSTL;
import ghidra.pcodeCPort.context.ParserWalker;
import ghidra.pcodeCPort.utils.MutableInt;
import ghidra.sleigh.grammar.Location;
import java.io.PrintStream;
public class RightShiftExpression extends BinaryExpression {
public RightShiftExpression(Location location) {
@ -33,13 +31,6 @@ public class RightShiftExpression extends BinaryExpression {
super(location, l, r);
}
@Override
public long getValue(ParserWalker pos) {
long leftval = getLeft().getValue(pos);
long rightval = getRight().getValue(pos);
return leftval >>> rightval;
}
@Override
public long getSubValue(VectorSTL<Long> replace, MutableInt listpos) {
long leftval = getLeft().getSubValue(replace, listpos); // Must be left first

View file

@ -1,6 +1,5 @@
/* ###
* 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.
@ -16,26 +15,20 @@
*/
package ghidra.pcodeCPort.slghpatexpress;
import generic.stl.VectorSTL;
import ghidra.pcodeCPort.context.ParserWalker;
import ghidra.pcodeCPort.translate.Translate;
import ghidra.sleigh.grammar.Location;
import java.io.PrintStream;
import org.jdom.Element;
import generic.stl.VectorSTL;
import ghidra.pcodeCPort.translate.Translate;
import ghidra.sleigh.grammar.Location;
public class StartInstructionValue extends PatternValue {
public StartInstructionValue(Location location) {
super(location);
}
@Override
public long getValue(ParserWalker pos) {
return (pos.getAddr().getOffset() >> pos.getAddr().getSpace().getScale());
}
@Override
public TokenPattern genMinPattern(VectorSTL<TokenPattern> ops) {
return new TokenPattern(location);

View file

@ -1,6 +1,5 @@
/* ###
* 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.
@ -16,13 +15,12 @@
*/
package ghidra.pcodeCPort.slghpatexpress;
import java.io.PrintStream;
import generic.stl.VectorSTL;
import ghidra.pcodeCPort.context.ParserWalker;
import ghidra.pcodeCPort.utils.MutableInt;
import ghidra.sleigh.grammar.Location;
import java.io.PrintStream;
public class SubExpression extends BinaryExpression {
public SubExpression(Location location) {
@ -33,13 +31,6 @@ public class SubExpression extends BinaryExpression {
super(location, l, r);
}
@Override
public long getValue(ParserWalker pos) {
long leftval = getLeft().getValue(pos);
long rightval = getRight().getValue(pos);
return leftval - rightval;
}
@Override
public long getSubValue(VectorSTL<Long> replace, MutableInt listpos) {
long leftval = getLeft().getSubValue(replace, listpos); // Must be left first

View file

@ -1,6 +1,5 @@
/* ###
* 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.
@ -16,18 +15,17 @@
*/
package ghidra.pcodeCPort.slghpatexpress;
import java.io.PrintStream;
import org.jdom.Element;
import generic.stl.VectorSTL;
import ghidra.pcodeCPort.context.ParserWalker;
import ghidra.pcodeCPort.context.Token;
import ghidra.pcodeCPort.translate.Translate;
import ghidra.pcodeCPort.utils.Utils;
import ghidra.pcodeCPort.utils.XmlUtils;
import ghidra.sleigh.grammar.Location;
import java.io.PrintStream;
import org.jdom.Element;
public class TokenField extends PatternValue {
private Token tok;
@ -77,21 +75,6 @@ public class TokenField extends PatternValue {
shift = bitstart % 8;
}
@Override
public long getValue(ParserWalker pos) { // Construct value given specific
// instruction stream
long res = ExpressUtils.getInstructionBytes(pos, bytestart, byteend, bigendian);
res >>>= shift;
if (signbit) {
res = Utils.zzz_sign_extend(res, bitend - bitstart);
}
else {
res = Utils.zzz_zero_extend(res, bitend - bitstart);
}
return res;
}
@Override
public TokenPattern genPattern(long val) { // Generate corresponding pattern if the
// value is forced to be val

View file

@ -1,6 +1,5 @@
/* ###
* 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.
@ -16,13 +15,12 @@
*/
package ghidra.pcodeCPort.slghpatexpress;
import java.io.PrintStream;
import generic.stl.VectorSTL;
import ghidra.pcodeCPort.context.ParserWalker;
import ghidra.pcodeCPort.utils.MutableInt;
import ghidra.sleigh.grammar.Location;
import java.io.PrintStream;
public class XorExpression extends BinaryExpression {
public XorExpression(Location location) {
@ -33,13 +31,6 @@ public class XorExpression extends BinaryExpression {
super(location, l, r);
}
@Override
public long getValue(ParserWalker pos) {
long leftval = getLeft().getValue(pos);
long rightval = getRight().getValue(pos);
return leftval ^ rightval;
}
@Override
public long getSubValue(VectorSTL<Long> replace, MutableInt listpos) {
long leftval = getLeft().getSubValue(replace, listpos); // Must be left first

View file

@ -1,6 +1,5 @@
/* ###
* 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.
@ -16,8 +15,6 @@
*/
package ghidra.pcodeCPort.slghpattern;
import ghidra.pcodeCPort.context.ParserWalker;
import java.io.PrintStream;
import java.util.List;
@ -63,17 +60,6 @@ public class CombinePattern extends DisjointPattern {
}
}
@Override
public boolean isMatch(ParserWalker pos) {
if (!instr.isMatch(pos)) {
return false;
}
if (!context.isMatch(pos)) {
return false;
}
return true;
}
@Override
public boolean alwaysTrue() {
return (context.alwaysTrue() && instr.alwaysTrue());

View file

@ -1,6 +1,5 @@
/* ###
* 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.
@ -16,8 +15,6 @@
*/
package ghidra.pcodeCPort.slghpattern;
import ghidra.pcodeCPort.context.ParserWalker;
import java.io.PrintStream;
import java.util.List;
@ -60,11 +57,6 @@ public class ContextPattern extends DisjointPattern {
public void shiftInstruction(int sa) {
} // do nothing
@Override
public boolean isMatch(ParserWalker pos) {
return maskvalue.isContextMatch(pos, 0);
}
@Override
public boolean alwaysTrue() {
return maskvalue.alwaysTrue();

View file

@ -1,6 +1,5 @@
/* ###
* 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.
@ -16,8 +15,6 @@
*/
package ghidra.pcodeCPort.slghpattern;
import ghidra.pcodeCPort.context.ParserWalker;
import java.io.PrintStream;
import java.util.List;
@ -70,11 +67,6 @@ public class InstructionPattern extends DisjointPattern {
maskvalue.shift(sa);
}
@Override
public boolean isMatch(ParserWalker pos) {
return maskvalue.isInstructionMatch(pos, 0);
}
@Override
public boolean alwaysTrue() {
return maskvalue.alwaysTrue();

View file

@ -1,6 +1,5 @@
/* ###
* 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.
@ -16,16 +15,15 @@
*/
package ghidra.pcodeCPort.slghpattern;
import generic.stl.IteratorSTL;
import generic.stl.VectorSTL;
import ghidra.pcodeCPort.context.ParserWalker;
import java.io.PrintStream;
import java.util.Iterator;
import java.util.List;
import org.jdom.Element;
import generic.stl.IteratorSTL;
import generic.stl.VectorSTL;
public class OrPattern extends Pattern {
private VectorSTL<DisjointPattern> orlist = new VectorSTL<DisjointPattern>();
@ -71,16 +69,6 @@ public class OrPattern extends Pattern {
}
}
@Override
public boolean isMatch(ParserWalker pos) {
for (int i = 0; i < orlist.size(); ++i) {
if (orlist.get(i).isMatch(pos)) {
return true;
}
}
return false;
}
// This isn't quite right because different branches
// may cover the entire gamut
@Override

View file

@ -1,6 +1,5 @@
/* ###
* 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.
@ -16,8 +15,6 @@
*/
package ghidra.pcodeCPort.slghpattern;
import ghidra.pcodeCPort.context.ParserWalker;
import java.io.PrintStream;
import org.jdom.Element;
@ -37,8 +34,6 @@ public abstract class Pattern {
public abstract Pattern commonSubPattern(Pattern b, int sa);
public abstract boolean isMatch(ParserWalker pos); // Does this pattern match context
public abstract int numDisjoint();
public abstract DisjointPattern getDisjoint(int i);

View file

@ -23,7 +23,6 @@ import org.jdom.Element;
import generic.stl.IteratorSTL;
import generic.stl.VectorSTL;
import ghidra.pcodeCPort.context.ParserWalker;
import ghidra.pcodeCPort.utils.Utils;
import ghidra.pcodeCPort.utils.XmlUtils;
@ -364,36 +363,6 @@ public class PatternBlock {
return res;
}
public boolean isInstructionMatch(ParserWalker pos, int off) {
if (nonzerosize <= 0) {
return (nonzerosize == 0);
}
off += offset;
for (int i = 0; i < maskvec.size(); ++i) {
int data = pos.getInstructionBytes(off, 4);
if ((maskvec.get(i) & data) != valvec.get(i)) {
return false;
}
off += 4;
}
return true;
}
public boolean isContextMatch(ParserWalker pos, int off) {
if (nonzerosize <= 0) {
return (nonzerosize == 0);
}
off += offset;
for (int i = 0; i < maskvec.size(); ++i) {
int data = pos.getContextBytes(off, 4);
if ((maskvec.get(i) & data) != valvec.get(i)) {
return false;
}
off += 4;
}
return true;
}
public void saveXml(PrintStream s) {
s.append("<pat_block ");
s.append("offset=\"");

View file

@ -22,7 +22,7 @@ import org.jdom.Element;
import generic.stl.IteratorSTL;
import generic.stl.VectorSTL;
import ghidra.pcodeCPort.context.*;
import ghidra.pcodeCPort.context.SleighError;
import ghidra.pcodeCPort.semantics.ConstTpl.const_type;
import ghidra.pcodeCPort.semantics.ConstructTpl;
import ghidra.pcodeCPort.semantics.HandleTpl;
@ -129,13 +129,6 @@ public class Constructor {
return namedtempl.size();
}
public void applyContext(ParserWalkerChange pos) {
IteratorSTL<ContextChange> iter = context.begin();
for (; !iter.isEnd(); iter.increment()) {
iter.get().apply(pos);
}
}
public void markSubtableOperands(VectorSTL<Integer> check) {
// Adjust -check- so it has one entry for every operand, a 0 if it is a subtable, a 2 if it is not
check.resize(operands.size(), 0);
@ -296,65 +289,6 @@ public class Constructor {
namedtempl.set(id, tpl);
}
public void print(PrintStream s, ParserWalker pos) {
IteratorSTL<String> piter;
for (piter = printpiece.begin(); !piter.isEnd(); piter.increment()) {
if (piter.get().charAt(0) == '\n') {
int index = piter.get().charAt(1) - 'A';
operands.get(index).print(s, pos);
}
else {
s.append(piter.get());
}
}
}
public void printMnemonic(PrintStream s, ParserWalker pos) {
if (flowthruindex != -1) {
TripleSymbol definingSymbol = operands.get(flowthruindex).getDefiningSymbol();
if (definingSymbol instanceof SubtableSymbol) {
pos.pushOperand(flowthruindex);
pos.getConstructor().printMnemonic(s, pos);
pos.popOperand();
return;
}
}
int endind = (firstwhitespace == -1) ? printpiece.size() : firstwhitespace;
for (int i = 0; i < endind; ++i) {
if (printpiece.get(i).charAt(0) == '\n') {
int index = printpiece.get(i).charAt(1) - 'A';
operands.get(index).print(s, pos);
}
else {
s.append(printpiece.get(i));
}
}
}
public void printBody(PrintStream s, ParserWalker pos) {
if (flowthruindex != -1) {
TripleSymbol sym = operands.get(flowthruindex).getDefiningSymbol();
if (sym instanceof SubtableSymbol) {
pos.pushOperand(flowthruindex);
pos.getConstructor().printBody(s, pos);
pos.popOperand();
return;
}
}
if (firstwhitespace == -1) {
return; // Nothing to print after firstwhitespace
}
for (int i = firstwhitespace + 1; i < printpiece.size(); ++i) {
if (printpiece.get(i).charAt(0) == '\n') {
int index = printpiece.get(i).charAt(1) - 'A';
operands.get(index).print(s, pos);
}
else {
s.append(printpiece.get(i));
}
}
}
// Allow for user to force extra space at end of printing
public void removeTrailingSpace() {
if ((!printpiece.empty()) && (printpiece.back().equals(" "))) {

View file

@ -1,6 +1,5 @@
/* ###
* 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.
@ -16,13 +15,12 @@
*/
package ghidra.pcodeCPort.slghsymbol;
import ghidra.pcodeCPort.context.ParserWalkerChange;
import ghidra.pcodeCPort.sleighbase.SleighBase;
import java.io.PrintStream;
import org.jdom.Element;
import ghidra.pcodeCPort.sleighbase.SleighBase;
// Change to context command
public abstract class ContextChange {
@ -35,8 +33,6 @@ public abstract class ContextChange {
public abstract void restoreXml(Element el, SleighBase trans);
public abstract void apply(ParserWalkerChange pos);
public void dispose() {
}
}

View file

@ -1,6 +1,5 @@
/* ###
* 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.
@ -16,14 +15,13 @@
*/
package ghidra.pcodeCPort.slghsymbol;
import ghidra.pcodeCPort.context.ParserWalkerChange;
import ghidra.pcodeCPort.sleighbase.SleighBase;
import ghidra.pcodeCPort.utils.*;
import java.io.PrintStream;
import org.jdom.Element;
import ghidra.pcodeCPort.sleighbase.SleighBase;
import ghidra.pcodeCPort.utils.*;
public class ContextCommit extends ContextChange {
private TripleSymbol sym;
@ -49,12 +47,6 @@ public class ContextCommit extends ContextChange {
mask = m.get();
}
@Override
public void apply(ParserWalkerChange pos) {
pos.getParserContext().addCommit(sym, num, mask, flow, pos.getPoint());
}
@Override
public void saveXml(PrintStream s) {
s.append("<commit");

View file

@ -1,6 +1,5 @@
/* ###
* 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.
@ -16,18 +15,17 @@
*/
package ghidra.pcodeCPort.slghsymbol;
import java.io.PrintStream;
import org.jdom.Element;
import generic.stl.VectorSTL;
import ghidra.pcodeCPort.context.ParserWalkerChange;
import ghidra.pcodeCPort.context.SleighError;
import ghidra.pcodeCPort.sleighbase.SleighBase;
import ghidra.pcodeCPort.slghpatexpress.*;
import ghidra.pcodeCPort.utils.*;
import ghidra.sleigh.grammar.Location;
import java.io.PrintStream;
import org.jdom.Element;
public class ContextOp extends ContextChange {
public final Location location;
@ -58,13 +56,6 @@ public class ContextOp extends ContextChange {
patexp.layClaim();
}
@Override
public void apply(ParserWalkerChange pos) {
int val = (int) patexp.getValue(pos); // Get our value based on context
val <<= shift;
pos.getParserContext().setContextWord(num, val, mask);
}
// Throw an exception if the PatternExpression is not valid
@Override
public void validate() {

View file

@ -22,10 +22,8 @@ import java.util.List;
import org.jdom.Element;
import generic.stl.*;
import ghidra.pcodeCPort.context.ParserWalker;
import ghidra.pcodeCPort.error.LowlevelError;
import ghidra.pcodeCPort.slghpattern.DisjointPattern;
import ghidra.pcodeCPort.translate.BadDataError;
import ghidra.pcodeCPort.utils.XmlUtils;
public class DecisionNode {
@ -356,27 +354,6 @@ public class DecisionNode {
}
}
Constructor resolve(ParserWalker pos) {
if (bitsize == 0) { // The node is terminal
IteratorSTL<Pair<DisjointPattern, Constructor>> iter;
for (iter = list.begin(); !iter.isEnd(); iter.increment()) {
if (iter.get().first.isMatch(pos)) {
return iter.get().second;
}
}
throw new BadDataError(pos.getAddr().getShortcut() + pos.getAddr().toString() +
": Unable to resolve constructor");
}
int val;
if (contextdecision) {
val = pos.getContextBits(startbit, bitsize);
}
else {
val = pos.getInstructionBits(startbit, bitsize);
}
return children.get(val).resolve(pos);
}
void saveXml(PrintStream s) {
s.append("<decision");
s.append(" number=\"");

View file

@ -1,6 +1,5 @@
/* ###
* 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.
@ -16,8 +15,10 @@
*/
package ghidra.pcodeCPort.slghsymbol;
import ghidra.pcodeCPort.context.FixedHandle;
import ghidra.pcodeCPort.context.ParserWalker;
import java.io.PrintStream;
import org.jdom.Element;
import ghidra.pcodeCPort.semantics.ConstTpl;
import ghidra.pcodeCPort.semantics.VarnodeTpl;
import ghidra.pcodeCPort.sleighbase.SleighBase;
@ -26,10 +27,6 @@ import ghidra.pcodeCPort.slghpatexpress.PatternExpression;
import ghidra.pcodeCPort.space.AddrSpace;
import ghidra.sleigh.grammar.Location;
import java.io.PrintStream;
import org.jdom.Element;
public class EndSymbol extends SpecificSymbol {
private AddrSpace const_space;
private PatternExpression patexp;
@ -72,21 +69,6 @@ public class EndSymbol extends SpecificSymbol {
return new VarnodeTpl(location, spc, off, sz_zero);
}
@Override
public void getFixedHandle(FixedHandle hand, ParserWalker pos) {
hand.space = pos.getCurSpace();
hand.offset_space = null;
hand.offset_offset = pos.getNaddr().getOffset(); // Get starting address of next instruction
hand.size = hand.space.getAddrSize();
}
@Override
public void print(PrintStream s, ParserWalker pos) {
long val = pos.getNaddr().getOffset();
s.append("0x");
s.append(Long.toHexString(val));
}
@Override
public void saveXml(PrintStream s) {
s.append("<end_sym");

View file

@ -1,6 +1,5 @@
/* ###
* 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.
@ -16,18 +15,16 @@
*/
package ghidra.pcodeCPort.slghsymbol;
import ghidra.pcodeCPort.context.FixedHandle;
import ghidra.pcodeCPort.context.ParserWalker;
import java.io.PrintStream;
import org.jdom.Element;
import ghidra.pcodeCPort.semantics.ConstTpl;
import ghidra.pcodeCPort.semantics.VarnodeTpl;
import ghidra.pcodeCPort.sleighbase.SleighBase;
import ghidra.pcodeCPort.space.AddrSpace;
import ghidra.sleigh.grammar.Location;
import java.io.PrintStream;
import org.jdom.Element;
// Another name for zero pattern/value
public class EpsilonSymbol extends PatternlessSymbol {
@ -47,19 +44,6 @@ public class EpsilonSymbol extends PatternlessSymbol {
return symbol_type.epsilon_symbol;
}
@Override
public void getFixedHandle(FixedHandle hand, ParserWalker pos) {
hand.space = const_space;
hand.offset_space = null; // Not a dynamic value
hand.offset_offset = 0;
hand.size = 0; // Cannot provide size
}
@Override
public void print(PrintStream s, ParserWalker pos) {
s.append('0');
}
@Override
public VarnodeTpl getVarnode() {
return new VarnodeTpl(location, new ConstTpl(const_space), new ConstTpl(

View file

@ -15,11 +15,6 @@
*/
package ghidra.pcodeCPort.slghsymbol;
import java.io.PrintStream;
import ghidra.pcodeCPort.address.Address;
import ghidra.pcodeCPort.context.FixedHandle;
import ghidra.pcodeCPort.context.ParserWalker;
import ghidra.pcodeCPort.semantics.ConstTpl;
import ghidra.pcodeCPort.semantics.VarnodeTpl;
import ghidra.pcodeCPort.slghpatexpress.PatternExpression;
@ -49,15 +44,6 @@ public class FlowDestSymbol extends SpecificSymbol {
return symbol_type.start_symbol;
}
@Override
public void getFixedHandle(FixedHandle hand, ParserWalker walker) {
Address refAddr = walker.getFlowDestAddr();
hand.space = const_space;
hand.offset_space = null;
hand.offset_offset = refAddr.getOffset();
hand.size = refAddr.getAddrSize();
}
@Override
public VarnodeTpl getVarnode() {
ConstTpl spc = new ConstTpl(const_space);
@ -66,10 +52,4 @@ public class FlowDestSymbol extends SpecificSymbol {
return new VarnodeTpl(location, spc, off, sz_zero);
}
@Override
public void print(PrintStream s, ParserWalker pos) {
long val = pos.getFlowDestAddr().getOffset();
s.append("0x");
s.print(Long.toHexString(val));
}
}

View file

@ -15,11 +15,6 @@
*/
package ghidra.pcodeCPort.slghsymbol;
import java.io.PrintStream;
import ghidra.pcodeCPort.address.Address;
import ghidra.pcodeCPort.context.FixedHandle;
import ghidra.pcodeCPort.context.ParserWalker;
import ghidra.pcodeCPort.semantics.ConstTpl;
import ghidra.pcodeCPort.semantics.VarnodeTpl;
import ghidra.pcodeCPort.slghpatexpress.PatternExpression;
@ -50,15 +45,6 @@ public class FlowRefSymbol extends SpecificSymbol {
return symbol_type.start_symbol;
}
@Override
public void getFixedHandle(FixedHandle hand, ParserWalker walker) {
Address refAddr = walker.getFlowRefAddr();
hand.space = const_space;
hand.offset_space = null;
hand.offset_offset = refAddr.getOffset();
hand.size = refAddr.getAddrSize();
}
@Override
public VarnodeTpl getVarnode() {
ConstTpl spc = new ConstTpl(const_space);
@ -67,10 +53,4 @@ public class FlowRefSymbol extends SpecificSymbol {
return new VarnodeTpl(location, spc, off, sz_zero);
}
@Override
public void print(PrintStream s, ParserWalker pos) {
long val = pos.getFlowRefAddr().getOffset();
s.append("0x");
s.print(Long.toHexString(val));
}
}

View file

@ -22,11 +22,9 @@ import java.util.List;
import org.jdom.Element;
import generic.stl.VectorSTL;
import ghidra.pcodeCPort.context.ParserWalker;
import ghidra.pcodeCPort.sleighbase.SleighBase;
import ghidra.pcodeCPort.slghpatexpress.PatternExpression;
import ghidra.pcodeCPort.slghpatexpress.PatternValue;
import ghidra.pcodeCPort.translate.BadDataError;
import ghidra.sleigh.grammar.Location;
public class NameSymbol extends ValueSymbol {
@ -56,32 +54,11 @@ public class NameSymbol extends ValueSymbol {
}
}
@Override
public Constructor resolve(ParserWalker pos) {
if (!tableisfilled) {
int ind = (int) patval.getValue(pos);
if ((ind >= nametable.size()) || (ind < 0) || (nametable.get(ind).length() == 0)) {
throw new BadDataError(
"No corresponding entry in nametable <" + getName() + ">, index=" + ind);
}
}
return null;
}
@Override
public symbol_type getType() {
return symbol_type.name_symbol;
}
@Override
public void print(PrintStream s, ParserWalker pos)
{
int ind = (int) patval.getValue(pos);
// ind is already checked to be in range by the resolve routine
s.print(nametable.get(ind));
}
@Override
public void saveXml(PrintStream s) {
s.append("<name_sym");

View file

@ -0,0 +1,93 @@
/* ###
* 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.
*/
package ghidra.pcodeCPort.slghsymbol;
import java.io.PrintStream;
import org.jdom.Element;
import ghidra.pcodeCPort.semantics.ConstTpl;
import ghidra.pcodeCPort.semantics.VarnodeTpl;
import ghidra.pcodeCPort.sleighbase.SleighBase;
import ghidra.pcodeCPort.slghpatexpress.Next2InstructionValue;
import ghidra.pcodeCPort.slghpatexpress.PatternExpression;
import ghidra.pcodeCPort.space.AddrSpace;
import ghidra.sleigh.grammar.Location;
public class Next2Symbol extends SpecificSymbol {
private AddrSpace const_space;
private PatternExpression patexp;
public Next2Symbol(Location location) {
super(location);
patexp = null;
} // For use with restoreXml
@Override
public PatternExpression getPatternExpression() {
return patexp;
}
@Override
public symbol_type getType() {
return symbol_type.next2_symbol;
}
public Next2Symbol(Location location, String nm, AddrSpace cspc) {
super(location, nm);
const_space = cspc;
patexp = new Next2InstructionValue(location);
patexp.layClaim();
}
@Override
public void dispose() {
if (patexp != null) {
PatternExpression.release(patexp);
}
}
// Return next instruction offset as a constant
@Override
public VarnodeTpl getVarnode() {
ConstTpl spc = new ConstTpl(const_space);
ConstTpl off = new ConstTpl(ConstTpl.const_type.j_next2);
ConstTpl sz_zero = new ConstTpl();
return new VarnodeTpl(location, spc, off, sz_zero);
}
@Override
public void saveXml(PrintStream s) {
s.append("<next2_sym");
saveSleighSymbolXmlHeader(s);
s.println("/>");
}
@Override
public void saveXmlHeader(PrintStream s) {
s.append("<next2_sym_head");
saveSleighSymbolXmlHeader(s);
s.println("/>");
}
@Override
public void restoreXml(Element el, SleighBase trans) {
const_space = trans.getConstantSpace();
patexp = new Next2InstructionValue(null);
patexp.layClaim();
}
}

View file

@ -21,7 +21,7 @@ import java.util.List;
import org.jdom.Element;
import ghidra.pcodeCPort.context.*;
import ghidra.pcodeCPort.context.SleighError;
import ghidra.pcodeCPort.semantics.VarnodeTpl;
import ghidra.pcodeCPort.sleighbase.SleighBase;
import ghidra.pcodeCPort.slghpatexpress.OperandValue;
@ -168,11 +168,6 @@ public class OperandSymbol extends SpecificSymbol {
return new VarnodeTpl(location, hand, false); // Possible dynamic handle
}
@Override
public void getFixedHandle(FixedHandle hnd, ParserWalker pos) {
hnd = pos.getFixedHandle(hand);
}
@Override
public int getSize() {
if (triple != null) {
@ -181,31 +176,6 @@ public class OperandSymbol extends SpecificSymbol {
return 0;
}
@Override
public void print(PrintStream s, ParserWalker pos) {
pos.pushOperand(getIndex());
if (triple != null) {
if (triple.getType() == symbol_type.subtable_symbol) {
pos.getConstructor().print(s, pos);
}
else {
triple.print(s, pos);
}
}
else {
long val = defexp.getValue(pos);
if (val >= 0) {
s.append("0x");
s.append(Long.toHexString(val));
}
else {
s.append("-0x");
s.append(Long.toHexString(-val));
}
}
pos.popOperand();
}
@Override
public void collectLocalValues(ArrayList<Long> results) {
if (triple != null) {

View file

@ -1,6 +1,5 @@
/* ###
* 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.
@ -16,8 +15,10 @@
*/
package ghidra.pcodeCPort.slghsymbol;
import ghidra.pcodeCPort.context.FixedHandle;
import ghidra.pcodeCPort.context.ParserWalker;
import java.io.PrintStream;
import org.jdom.Element;
import ghidra.pcodeCPort.semantics.ConstTpl;
import ghidra.pcodeCPort.semantics.VarnodeTpl;
import ghidra.pcodeCPort.sleighbase.SleighBase;
@ -26,10 +27,6 @@ import ghidra.pcodeCPort.slghpatexpress.StartInstructionValue;
import ghidra.pcodeCPort.space.AddrSpace;
import ghidra.sleigh.grammar.Location;
import java.io.PrintStream;
import org.jdom.Element;
public class StartSymbol extends SpecificSymbol {
private AddrSpace const_space;
private PatternExpression patexp;
@ -72,21 +69,6 @@ public class StartSymbol extends SpecificSymbol {
return new VarnodeTpl(location, spc, off, sz_zero);
}
@Override
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.getAddrSize();
}
@Override
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");

View file

@ -22,7 +22,7 @@ import org.jdom.Element;
import generic.stl.IteratorSTL;
import generic.stl.VectorSTL;
import ghidra.pcodeCPort.context.*;
import ghidra.pcodeCPort.context.SleighError;
import ghidra.pcodeCPort.sleighbase.SleighBase;
import ghidra.pcodeCPort.slghpatexpress.PatternExpression;
import ghidra.pcodeCPort.slghpatexpress.TokenPattern;
@ -58,11 +58,6 @@ public class SubtableSymbol extends TripleSymbol {
construct.push_back(ct);
}
@Override
public Constructor resolve(ParserWalker pos) {
return decisiontree.resolve(pos);
}
public TokenPattern getPattern() {
return pattern;
}
@ -80,21 +75,11 @@ public class SubtableSymbol extends TripleSymbol {
throw new SleighError("Cannot use subtable in expression", null);
}
@Override
public void getFixedHandle(FixedHandle hand, ParserWalker pos) {
throw new SleighError("Cannot use subtable in expression", null);
}
@Override
public int getSize() {
return -1;
}
@Override
public void print(PrintStream s, ParserWalker pos) {
throw new SleighError("Cannot use subtable in expression", null);
}
@Override
public void collectLocalValues(ArrayList<Long> results) {
for (Constructor curConstruct : construct) {

View file

@ -15,6 +15,12 @@
*/
package ghidra.pcodeCPort.slghsymbol;
import java.io.PrintStream;
import java.util.Iterator;
import java.util.List;
import org.jdom.Element;
import generic.stl.IteratorSTL;
import generic.stl.VectorSTL;
import ghidra.pcodeCPort.context.SleighError;
@ -22,12 +28,6 @@ import ghidra.pcodeCPort.sleighbase.SleighBase;
import ghidra.pcodeCPort.utils.XmlUtils;
import ghidra.sleigh.grammar.Location;
import java.io.PrintStream;
import java.util.Iterator;
import java.util.List;
import org.jdom.Element;
public class SymbolTable {
private VectorSTL<SleighSymbol> symbollist = new VectorSTL<SleighSymbol>();
@ -300,6 +300,9 @@ public class SymbolTable {
else if (el.getName().equals("end_sym_head")) {
sym = new EndSymbol(location);
}
else if (el.getName().equals("next2_sym_head")) {
sym = new Next2Symbol(location);
}
else if (el.getName().equals("subtable_sym_head")) {
sym = new SubtableSymbol(location);
}

View file

@ -15,11 +15,8 @@
*/
package ghidra.pcodeCPort.slghsymbol;
import java.io.PrintStream;
import java.util.ArrayList;
import ghidra.pcodeCPort.context.FixedHandle;
import ghidra.pcodeCPort.context.ParserWalker;
import ghidra.pcodeCPort.slghpatexpress.PatternExpression;
import ghidra.sleigh.grammar.Location;
@ -36,20 +33,12 @@ public abstract class TripleSymbol extends SleighSymbol {
public abstract PatternExpression getPatternExpression();
public abstract void getFixedHandle(FixedHandle hand, ParserWalker pos);
public int getSize() {
return 0;
} // Size out of context
public abstract void print(PrintStream s, ParserWalker pos);
public void collectLocalValues(ArrayList<Long> results) {
// By default, assume symbol has no local exports
}
public Constructor resolve(ParserWalker pos) {
return null;
}
}

View file

@ -1,6 +1,5 @@
/* ###
* 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.
@ -16,22 +15,19 @@
*/
package ghidra.pcodeCPort.slghsymbol;
import generic.stl.VectorSTL;
import ghidra.pcodeCPort.context.FixedHandle;
import ghidra.pcodeCPort.context.ParserWalker;
import ghidra.pcodeCPort.sleighbase.SleighBase;
import ghidra.pcodeCPort.slghpatexpress.PatternExpression;
import ghidra.pcodeCPort.slghpatexpress.PatternValue;
import ghidra.pcodeCPort.translate.BadDataError;
import ghidra.pcodeCPort.utils.XmlUtils;
import ghidra.sleigh.grammar.Location;
import java.io.PrintStream;
import java.util.Iterator;
import java.util.List;
import org.jdom.Element;
import generic.stl.VectorSTL;
import ghidra.pcodeCPort.sleighbase.SleighBase;
import ghidra.pcodeCPort.slghpatexpress.PatternExpression;
import ghidra.pcodeCPort.slghpatexpress.PatternValue;
import ghidra.pcodeCPort.utils.XmlUtils;
import ghidra.sleigh.grammar.Location;
public class ValueMapSymbol extends ValueSymbol {
private VectorSTL<Long> valuetable = new VectorSTL<Long>();
private boolean tableisfilled;
@ -63,41 +59,6 @@ public class ValueMapSymbol extends ValueSymbol {
}
}
@Override
public Constructor resolve(ParserWalker pos) {
if (!tableisfilled) {
int ind = (int) patval.getValue(pos);
if ((ind >= valuetable.size()) || (ind < 0) || (valuetable.get(ind) == 0xBADBEEF)) {
throw new BadDataError("No corresponding entry in nametable <" + getName() +
">, index=" + ind);
}
}
return null;
}
@Override
public void getFixedHandle(FixedHandle hand, ParserWalker pos) {
int ind = (int) patval.getValue(pos);
// The resolve routine has checked that -ind- must be a valid index
hand.space = pos.getConstSpace();
hand.offset_space = null; // Not a dynamic value
hand.offset_offset = valuetable.get(ind);
hand.size = 0; // Cannot provide size
}
@Override
public void print(PrintStream s, ParserWalker pos) {
int ind = (int) patval.getValue(pos);
// ind is already checked to be in range by the resolve routine
Long val = valuetable.get(ind);
if (val >= 0) {
s.append("0x").append(Long.toHexString(val));
}
else {
s.append("-0x").append(Long.toHexString(-val));
}
}
@Override
public void saveXml(PrintStream s) {
s.append("<valuemap_sym");

View file

@ -1,6 +1,5 @@
/* ###
* 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.
@ -16,18 +15,16 @@
*/
package ghidra.pcodeCPort.slghsymbol;
import ghidra.pcodeCPort.context.FixedHandle;
import ghidra.pcodeCPort.context.ParserWalker;
import ghidra.pcodeCPort.sleighbase.SleighBase;
import ghidra.pcodeCPort.slghpatexpress.PatternExpression;
import ghidra.pcodeCPort.slghpatexpress.PatternValue;
import ghidra.sleigh.grammar.Location;
import java.io.PrintStream;
import java.util.List;
import org.jdom.Element;
import ghidra.pcodeCPort.sleighbase.SleighBase;
import ghidra.pcodeCPort.slghpatexpress.PatternExpression;
import ghidra.pcodeCPort.slghpatexpress.PatternValue;
import ghidra.sleigh.grammar.Location;
public class ValueSymbol extends FamilySymbol {
protected PatternValue patval;
@ -65,27 +62,6 @@ public class ValueSymbol extends FamilySymbol {
}
}
@Override
public void getFixedHandle(FixedHandle hand, ParserWalker pos) {
hand.space = pos.getConstSpace();
hand.offset_space = null;
hand.offset_offset = patval.getValue(pos);
hand.size = 0; // Cannot provide size
}
@Override
public void print(PrintStream s, ParserWalker pos) {
long val = patval.getValue(pos);
if (val >= 0) {
s.append("0x");
s.append(Long.toHexString(val));
}
else {
s.append("-0x");
s.append(Long.toHexString(-val));
}
}
@Override
public void saveXml(PrintStream s) {
s.append("<value_sym");

View file

@ -1,6 +1,5 @@
/* ###
* 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.
@ -16,23 +15,20 @@
*/
package ghidra.pcodeCPort.slghsymbol;
import generic.stl.VectorSTL;
import ghidra.pcodeCPort.context.*;
import ghidra.pcodeCPort.pcoderaw.VarnodeData;
import ghidra.pcodeCPort.sleighbase.SleighBase;
import ghidra.pcodeCPort.slghpatexpress.PatternExpression;
import ghidra.pcodeCPort.slghpatexpress.PatternValue;
import ghidra.pcodeCPort.translate.BadDataError;
import ghidra.pcodeCPort.utils.XmlUtils;
import ghidra.sleigh.grammar.Location;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.Iterator;
import java.util.List;
import org.jdom.Element;
import generic.stl.VectorSTL;
import ghidra.pcodeCPort.context.SleighError;
import ghidra.pcodeCPort.sleighbase.SleighBase;
import ghidra.pcodeCPort.slghpatexpress.PatternExpression;
import ghidra.pcodeCPort.slghpatexpress.PatternValue;
import ghidra.pcodeCPort.utils.XmlUtils;
import ghidra.sleigh.grammar.Location;
public class VarnodeListSymbol extends ValueSymbol {
private VectorSTL<VarnodeSymbol> varnode_table = new VectorSTL<VarnodeSymbol>();
@ -67,32 +63,6 @@ public class VarnodeListSymbol extends ValueSymbol {
}
}
@Override
public Constructor resolve(ParserWalker walker) {
if (!tableisfilled) {
int ind = (int) patval.getValue(walker);
if ((ind < 0) || (ind >= varnode_table.size()) || (varnode_table.get(ind) == null)) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream s = new PrintStream(baos);
walker.getAddr().printRaw(s);
throw new BadDataError(walker.getAddr().getShortcut() + baos.toString() +
": No corresponding entry in varnode list");
}
}
return null;
}
@Override
public void getFixedHandle(FixedHandle hand, ParserWalker pos) {
int ind = (int) patval.getValue(pos);
// The resolve routine has checked that -ind- must be a valid index
VarnodeData fix = varnode_table.get(ind).getFixedVarnode();
hand.space = fix.space;
hand.offset_space = null; // Not a dynamic value
hand.offset_offset = fix.offset;
hand.size = fix.size;
}
@Override
public int getSize() {
for (int i = 0; i < varnode_table.size(); ++i) {
@ -104,15 +74,6 @@ public class VarnodeListSymbol extends ValueSymbol {
throw new SleighError("No register attached to: " + getName(), getLocation());
}
@Override
public void print(PrintStream s, ParserWalker pos) {
int ind = (int) patval.getValue(pos);
if (ind >= varnode_table.size()) {
throw new SleighError("Value out of range for varnode table", getLocation());
}
s.append(varnode_table.get(ind).getName());
}
@Override
public void saveXml(PrintStream s) {
s.append("<varlist_sym");

View file

@ -22,7 +22,7 @@ import org.jdom.Element;
import generic.util.UnsignedDataUtils;
// A global varnode
import ghidra.pcodeCPort.context.*;
import ghidra.pcodeCPort.context.SleighError;
import ghidra.pcodeCPort.pcoderaw.VarnodeData;
import ghidra.pcodeCPort.semantics.ConstTpl;
import ghidra.pcodeCPort.semantics.VarnodeTpl;
@ -54,11 +54,6 @@ public class VarnodeSymbol extends PatternlessSymbol {
return fix.size;
}
@Override
public void print(PrintStream s, ParserWalker pos) {
s.append(getName());
}
@Override
public void collectLocalValues(ArrayList<Long> results) {
if (fix.space.getType() == spacetype.IPTR_INTERNAL) {
@ -98,14 +93,6 @@ public class VarnodeSymbol extends PatternlessSymbol {
new ConstTpl(ConstTpl.const_type.real, fix.size));
}
@Override
public void getFixedHandle(FixedHandle hand, ParserWalker pos) {
hand.space = fix.space;
hand.offset_space = null; // Not a dynamic symbol
hand.offset_offset = fix.offset;
hand.size = fix.size;
}
@Override
public void saveXml(PrintStream s) {
s.append("<varnode_sym");

View file

@ -27,6 +27,7 @@ public enum symbol_type {
operand_symbol,
start_symbol, // inst_start, inst_ref, inst_def
end_symbol, // inst_next
next2_symbol, // inst_next2
subtable_symbol,
macro_symbol,
section_symbol,

View file

@ -63,6 +63,7 @@ public interface InstructionContext {
* at the specified address. The returned ParserContext may be cast to the prototype's
* implementation without checking. This method will throw an UnknownContextException
* if a compatible ParserContext is not found at the specified address.
* @param instructionAddress instruction address of requested context
* @return the instruction parser context at the specified instruction address
* @throws UnknownContextException if the instruction at the specified address
* was not previously parsed or attempting to instantiate context resulted in an

View file

@ -85,6 +85,7 @@ public class PcodeParser extends PcodeCompile {
Location internalLoc = Location.INTERNALLY_DEFINED;
symbolMap.put("inst_start", new StartSymbol(internalLoc, "inst_start", 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()));
symbolMap.put("inst_dest",
new FlowDestSymbol(internalLoc, "inst_dest", getConstantSpace()));