mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 10:49:34 +02:00
GP-2480 Add sleigh compiler support for inst_next2
This commit is contained in:
parent
39baf3a691
commit
8d4a6c213e
84 changed files with 3623 additions and 2807 deletions
|
@ -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) {
|
||||
|
|
|
@ -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.
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]";
|
||||
}
|
||||
}
|
|
@ -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"))
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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) {
|
||||
}
|
||||
|
||||
}
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue