GP-8 Additional support for BitrangeSymbol

This commit is contained in:
caheckman 2023-03-21 16:12:18 -04:00
parent 1bac23c59c
commit 35f20dd20d
3 changed files with 52 additions and 13 deletions

View file

@ -287,6 +287,7 @@ void SymbolTable::purge(void)
case SleighSymbol::token_symbol: case SleighSymbol::token_symbol:
case SleighSymbol::epsilon_symbol: case SleighSymbol::epsilon_symbol:
case SleighSymbol::section_symbol: case SleighSymbol::section_symbol:
case SleighSymbol::bitrange_symbol:
break; break;
case SleighSymbol::macro_symbol: case SleighSymbol::macro_symbol:
{ // Delete macro's local symbols { // Delete macro's local symbols

View file

@ -1169,6 +1169,12 @@ assignment returns [VectorSTL<OpTpl> value]
SleighSymbol sym = pcode.findSymbol($id.getText()); SleighSymbol sym = pcode.findSymbol($id.getText());
if (sym == null) { if (sym == null) {
$value = pcode.newOutput(find(id), false, e, $id.getText()); $value = pcode.newOutput(find(id), false, e, $id.getText());
} else if (sym instanceof BitrangeSymbol) {
BitrangeSymbol bitSym = (BitrangeSymbol)sym;
VarnodeSymbol parent = bitSym.getParentSymbol();
$value = pcode.assignBitRange(find(t), parent.getVarnode(),
bitSym.getBitOffset(),
bitSym.numBits(),e);
} else if(sym.getType() != symbol_type.start_symbol } else if(sym.getType() != symbol_type.start_symbol
&& sym.getType() != symbol_type.end_symbol && sym.getType() != symbol_type.end_symbol
&& sym.getType() != symbol_type.next2_symbol && sym.getType() != symbol_type.next2_symbol
@ -1450,7 +1456,7 @@ expr returns [ExprTree value]
| s=sizedstar { $value = pcode.createLoad(s.first.location, s.first, s.second); } | s=sizedstar { $value = pcode.createLoad(s.first.location, s.first, s.second); }
| a=expr_apply { $value = (ExprTree) $a.value; } | a=expr_apply { $value = (ExprTree) $a.value; }
| v=varnode { $value = new ExprTree(v.location, v); } | v=varnode_or_bitsym["expression"] { $value = $v.value; }
| b=bitrange { $value = $b.value; } | b=bitrange { $value = $b.value; }
| i=integer { $value = new ExprTree(i.location, new VarnodeTpl(i.location, new ConstTpl(pcode.getConstantSpace()), | i=integer { $value = new ExprTree(i.location, new VarnodeTpl(i.location, new ConstTpl(pcode.getConstantSpace()),
new ConstTpl(ConstTpl.const_type.real, $i.value.longValue()), new ConstTpl(ConstTpl.const_type.real, $i.value.longValue()),
@ -1463,6 +1469,30 @@ expr returns [ExprTree value]
} }
; ;
varnode_or_bitsym[String purpose] returns [ExprTree value]
: ^(t=OP_IDENTIFIER s=.) {
SleighSymbol sym = pcode.findSymbol($s.getText());
if (sym == null) {
unknownSymbolError($s.getText(), find($s), "varnode or bitrange symbol", purpose);
} else if (sym instanceof BitrangeSymbol) {
BitrangeSymbol bitSym = (BitrangeSymbol)sym;
$value = pcode.createBitRange(find(t), bitSym.getParentSymbol(),
bitSym.getBitOffset(),
bitSym.numBits());
} else if (sym instanceof SpecificSymbol) {
VarnodeTpl vTemp = ((SpecificSymbol)sym).getVarnode();
$value = new ExprTree(vTemp.location, vTemp);
} else {
undeclaredSymbolError(sym, find($s), purpose);
}
}
| v=varnode_adorned { $value = new ExprTree($v.value.location,$v.value); }
| t=OP_WILDCARD {
wildcardError($t, purpose);
$value = null;
}
;
expr_apply returns [Object value] expr_apply returns [Object value]
@after { @after {
$code_block::stmtLocation = find(x); $code_block::stmtLocation = find(x);
@ -1517,9 +1547,8 @@ expr_operands returns [VectorSTL<ExprTree> value]
: (e=expr { value.push_back(e); })* : (e=expr { value.push_back(e); })*
; ;
varnode returns [VarnodeTpl value] varnode_adorned returns [VarnodeTpl value]
: ss=specific_symbol["varnode reference"] { $value = ss.getVarnode(); } : ^(t=OP_TRUNCATION_SIZE n=integer m=integer) {
| ^(t=OP_TRUNCATION_SIZE n=integer m=integer) {
if ($m.value.longValue() > 8) { if ($m.value.longValue() > 8) {
reportError(find(t), "Constant varnode size must not exceed 8 (" + reportError(find(t), "Constant varnode size must not exceed 8 (" +
$n.value.longValue() + ":" + $m.value.longValue() + ")"); $n.value.longValue() + ":" + $m.value.longValue() + ")");
@ -1532,6 +1561,11 @@ varnode returns [VarnodeTpl value]
| ^(OP_ADDRESS_OF v=varnode) { $value = pcode.addressOf(v, 0); } | ^(OP_ADDRESS_OF v=varnode) { $value = pcode.addressOf(v, 0); }
; ;
varnode returns [VarnodeTpl value]
: ss=specific_symbol["varnode reference"] { $value = ss.getVarnode(); }
| v=varnode_adorned { $value = $v.value; }
;
qstring returns [String value] qstring returns [String value]
: ^(OP_QSTRING s=.) { $value = $s.getText(); } : ^(OP_QSTRING s=.) { $value = $s.getText(); }
; ;

View file

@ -30,8 +30,8 @@ import ghidra.sleigh.grammar.Location;
public class SymbolTable { public class SymbolTable {
private VectorSTL<SleighSymbol> symbollist = new VectorSTL<SleighSymbol>(); private VectorSTL<SleighSymbol> symbollist = new VectorSTL<>();
private VectorSTL<SymbolScope> table = new VectorSTL<SymbolScope>(); private VectorSTL<SymbolScope> table = new VectorSTL<>();
private SymbolScope curscope; private SymbolScope curscope;
public SymbolTable() { public SymbolTable() {
@ -51,7 +51,7 @@ public class SymbolTable {
} }
public VectorSTL<SleighSymbol> getUnsoughtSymbols() { public VectorSTL<SleighSymbol> getUnsoughtSymbols() {
VectorSTL<SleighSymbol> result = new VectorSTL<SleighSymbol>(); VectorSTL<SleighSymbol> result = new VectorSTL<>();
IteratorSTL<SleighSymbol> siter; IteratorSTL<SleighSymbol> siter;
for (siter = symbollist.begin(); !siter.isEnd(); siter.increment()) { for (siter = symbollist.begin(); !siter.isEnd(); siter.increment()) {
SleighSymbol sleighSymbol = siter.get(); SleighSymbol sleighSymbol = siter.get();
@ -333,10 +333,12 @@ public class SymbolTable {
case token_symbol: case token_symbol:
case epsilon_symbol: case epsilon_symbol:
case section_symbol: case section_symbol:
case bitrange_symbol:
break; break;
case macro_symbol: { // Delete macro's local symbols case macro_symbol: { // Delete macro's local symbols
MacroSymbol macro = (MacroSymbol) sym; MacroSymbol macro = (MacroSymbol) sym;
for (int macroIndex = 0; macroIndex < macro.getNumOperands(); ++macroIndex) { for (int macroIndex = 0; macroIndex < macro
.getNumOperands(); ++macroIndex) {
SleighSymbol opersym = macro.getOperand(macroIndex); SleighSymbol opersym = macro.getOperand(macroIndex);
table.get(opersym.scopeid).removeSymbol(opersym); table.get(opersym.scopeid).removeSymbol(opersym);
symbollist.set(opersym.id, null); symbollist.set(opersym.id, null);
@ -349,11 +351,13 @@ public class SymbolTable {
if (subsym.getPattern() != null) { if (subsym.getPattern() != null) {
continue; continue;
} }
for (int subtableIndex = 0; subtableIndex < subsym.getNumConstructors(); ++subtableIndex) { // Go thru for (int subtableIndex = 0; subtableIndex < subsym
.getNumConstructors(); ++subtableIndex) { // Go thru
// each // each
// constructor // constructor
Constructor con = subsym.getConstructor(subtableIndex); Constructor con = subsym.getConstructor(subtableIndex);
for (int operandIndex = 0; operandIndex < con.getNumOperands(); ++operandIndex) { // Go thru each operand for (int operandIndex = 0; operandIndex < con
.getNumOperands(); ++operandIndex) { // Go thru each operand
OperandSymbol oper = con.getOperand(operandIndex); OperandSymbol oper = con.getOperand(operandIndex);
table.get(oper.scopeid).removeSymbol(oper); table.get(oper.scopeid).removeSymbol(oper);
symbollist.set(oper.id, null); symbollist.set(oper.id, null);
@ -382,8 +386,8 @@ public class SymbolTable {
// Renumber all the scopes and symbols // Renumber all the scopes and symbols
// so that there are no gaps // so that there are no gaps
private void renumber() { private void renumber() {
VectorSTL<SymbolScope> newtable = new VectorSTL<SymbolScope>(); VectorSTL<SymbolScope> newtable = new VectorSTL<>();
VectorSTL<SleighSymbol> newsymbol = new VectorSTL<SleighSymbol>(); VectorSTL<SleighSymbol> newsymbol = new VectorSTL<>();
// First renumber the scopes // First renumber the scopes
SymbolScope scope = null; SymbolScope scope = null;