Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Ghidra/Features/Decompiler/src/decompile/cpp/pcodeparse.y
Original file line number Diff line number Diff line change
Expand Up @@ -741,6 +741,7 @@ int4 PcodeSnippet::lex(void)
yylval.operandsym = (OperandSymbol *)sym;
return OPERANDSYM;
case SleighSymbol::start_symbol:
case SleighSymbol::offset_symbol:
case SleighSymbol::end_symbol:
case SleighSymbol::next2_symbol:
case SleighSymbol::flowdest_symbol:
Expand Down
9 changes: 9 additions & 0 deletions Ghidra/Features/Decompiler/src/decompile/cpp/semantics.cc
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ uintb ConstTpl::fix(const ParserWalker &walker) const
switch(type) {
case j_start:
return walker.getAddr().getOffset(); // Fill in starting address placeholder with real address
case j_offset:
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_next2:
Expand Down Expand Up @@ -318,6 +320,10 @@ void ConstTpl::encode(Encoder &encoder) const
encoder.openElement(sla::ELEM_CONST_START);
encoder.closeElement(sla::ELEM_CONST_START);
break;
case j_offset:
encoder.openElement(sla::ELEM_CONST_OFFSET);
encoder.closeElement(sla::ELEM_CONST_OFFSET);
break;
case j_next:
encoder.openElement(sla::ELEM_CONST_NEXT);
encoder.closeElement(sla::ELEM_CONST_NEXT);
Expand Down Expand Up @@ -417,6 +423,9 @@ void ConstTpl::decode(Decoder &decoder)
else if (el == sla::ELEM_CONST_FLOWDEST_SIZE) {
type = j_flowdest_size;
}
else if (el == sla::ELEM_CONST_OFFSET) {
type = j_offset;
}
else
throw LowlevelError("Bad constant type");
decoder.closeElement(el);
Expand Down
2 changes: 1 addition & 1 deletion Ghidra/Features/Decompiler/src/decompile/cpp/semantics.hh
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class ConstTpl {
public:
enum const_type { real=0, handle=1, j_start=2, j_next=3, j_next2=4, j_curspace=5,
j_curspace_size=6, spaceid=7, j_relative=8,
j_flowref=9, j_flowref_size=10, j_flowdest=11, j_flowdest_size=12 };
j_flowref=9, j_flowref_size=10, j_flowdest=11, j_flowdest_size=12, j_offset=13 };
enum v_field { v_space=0, v_offset=1, v_size=2, v_offset_plus=3 };
private:
const_type type;
Expand Down
4 changes: 4 additions & 0 deletions Ghidra/Features/Decompiler/src/decompile/cpp/slaformat.cc
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,10 @@ ElementId ELEM_CONST_FLOWREF = ElementId("const_flowref", 85, FORMAT_SCOPE);
ElementId ELEM_CONST_FLOWREF_SIZE = ElementId("const_flowref_size", 86, FORMAT_SCOPE);
ElementId ELEM_CONST_FLOWDEST = ElementId("const_flowdest", 87, FORMAT_SCOPE);
ElementId ELEM_CONST_FLOWDEST_SIZE = ElementId("const_flowdest_size", 88, FORMAT_SCOPE);
ElementId ELEM_OFFSET_EXP = ElementId("offset_exp", 89, FORMAT_SCOPE);
ElementId ELEM_OFFSET_SYM = ElementId("offset_sym", 90, FORMAT_SCOPE);
ElementId ELEM_OFFSET_SYM_HEAD = ElementId("offset_sym_head", 91, FORMAT_SCOPE);
ElementId ELEM_CONST_OFFSET = ElementId("const_offset", 92, FORMAT_SCOPE);

/// The bytes of the header are read from the stream and verified against the required form and current version.
/// If the form matches, \b true is returned. No additional bytes are read.
Expand Down
4 changes: 4 additions & 0 deletions Ghidra/Features/Decompiler/src/decompile/cpp/slaformat.hh
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,10 @@ extern ElementId ELEM_CONST_FLOWREF; ///< SLA format element "const_flowref"
extern ElementId ELEM_CONST_FLOWREF_SIZE; ///< SLA format element "const_flowref_size"
extern ElementId ELEM_CONST_FLOWDEST; ///< SLA format element "const_flowdest"
extern ElementId ELEM_CONST_FLOWDEST_SIZE; ///< SLA format element "const_flowdest_size"
extern ElementId ELEM_OFFSET_EXP; ///< SLA format element "offset_exp"
extern ElementId ELEM_OFFSET_SYM; ///< SLA format element "operand_offset_sym"
extern ElementId ELEM_OFFSET_SYM_HEAD; ///< SLA format element "operand_offset_sym_head"
extern ElementId ELEM_CONST_OFFSET; ///< SLA format element "offset_start"

extern bool isSlaFormat(istream &s); ///< Verify a .sla file header at the current point of the given stream
extern void writeSlaHeader(ostream &s); ///< Write a .sla file header to the given stream
Expand Down
4 changes: 3 additions & 1 deletion Ghidra/Features/Decompiler/src/decompile/cpp/slgh_compile.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1796,7 +1796,7 @@ SleighCompile::SleighCompile(void)
}

/// Create the address spaces: \b const, \b unique, and \b other.
/// Define the special symbols: \b inst_start, \b inst_next, \b inst_next2, \b epsilon.
/// Define the special symbols: \b inst_start, \b operand_offset, \b inst_next, \b inst_next2, \b epsilon.
/// Define the root subtable symbol: \b instruction
void SleighCompile::predefinedSymbols(void)

Expand All @@ -1818,6 +1818,8 @@ void SleighCompile::predefinedSymbols(void)
symtab.addSymbol(spacesym);
StartSymbol *startsym = new StartSymbol("inst_start",getConstantSpace());
symtab.addSymbol(startsym);
OffsetSymbol *offsetsym = new OffsetSymbol("operand_offset",getConstantSpace());
symtab.addSymbol(offsetsym);
EndSymbol *endsym = new EndSymbol("inst_next",getConstantSpace());
symtab.addSymbol(endsym);
Next2Symbol *next2sym = new Next2Symbol("inst_next2",getConstantSpace());
Expand Down
16 changes: 16 additions & 0 deletions Ghidra/Features/Decompiler/src/decompile/cpp/slghpatexpress.cc
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,8 @@ PatternExpression *PatternExpression::decodeExpression(Decoder &decoder,Translat
res = new MinusExpression();
else if (el == sla::ELEM_NOT_EXP)
res = new NotExpression();
else if (el == sla::ELEM_OFFSET_EXP)
res = new OffsetInstructionValue();
else
return (PatternExpression *)0;

Expand Down Expand Up @@ -711,6 +713,20 @@ void StartInstructionValue::decode(Decoder &decoder,Translate *trans)
decoder.closeElement(el);
}

void OffsetInstructionValue::encode(Encoder &encoder) const

{
encoder.openElement(sla::ELEM_OFFSET_EXP);
encoder.closeElement(sla::ELEM_OFFSET_EXP);
}

void OffsetInstructionValue::decode(Decoder &decoder,Translate *trans)

{
uint4 el = decoder.openElement(sla::ELEM_OFFSET_EXP);
decoder.closeElement(el);
}

void EndInstructionValue::encode(Encoder &encoder) const

{
Expand Down
14 changes: 14 additions & 0 deletions Ghidra/Features/Decompiler/src/decompile/cpp/slghpatexpress.hh
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,20 @@ public:
virtual void encode(Encoder &encoder) const;
virtual void decode(Decoder &decoder,Translate *trans);
};

class OffsetInstructionValue : public PatternValue {
public:
OffsetInstructionValue(void) {}
virtual intb getValue(ParserWalker &walker) const {
return (intb)walker.getOffset(-1);
}
virtual TokenPattern genMinPattern(const vector<TokenPattern> &ops) const { return TokenPattern(); }
virtual TokenPattern genPattern(intb val) const { return TokenPattern(); }
virtual intb minValue(void) const { return (intb)0; }
virtual intb maxValue(void) const { return (intb)0; }
virtual void encode(Encoder &encoder) const;
virtual void decode(Decoder &decoder,Translate *trans);
};

class EndInstructionValue : public PatternValue {
public:
Expand Down
69 changes: 68 additions & 1 deletion Ghidra/Features/Decompiler/src/decompile/cpp/slghsymbol.cc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* ###
#/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -224,6 +224,8 @@ void SymbolTable::decodeSymbolHeader(Decoder &decoder)
sym = new OperandSymbol();
else if (el == sla::ELEM_START_SYM_HEAD)
sym = new StartSymbol();
else if (el == sla::ELEM_OFFSET_SYM_HEAD)
sym = new OffsetSymbol();
else if (el == sla::ELEM_END_SYM_HEAD)
sym = new EndSymbol();
else if (el == sla::ELEM_NEXT2_SYM_HEAD)
Expand Down Expand Up @@ -1137,6 +1139,71 @@ void StartSymbol::decode(Decoder &decoder,SleighBase *trans)
decoder.closeElement(sla::ELEM_START_SYM.getId());
}

OffsetSymbol::OffsetSymbol(const string &nm,AddrSpace *cspc) : SpecificSymbol(nm)

{
const_space = cspc;
patexp = new OffsetInstructionValue();
patexp->layClaim();
}

OffsetSymbol::~OffsetSymbol(void)

{
if (patexp != (PatternExpression *)0)
PatternExpression::release(patexp);
}

VarnodeTpl *OffsetSymbol::getVarnode(void) const

{ // Returns current operand offset as a constant
ConstTpl spc(const_space);
ConstTpl off(ConstTpl::j_offset);
ConstTpl sz_zero;
return new VarnodeTpl(spc,off,sz_zero);
}

void OffsetSymbol::getFixedHandle(FixedHandle &hand,ParserWalker &walker) const

{
hand.space = walker.getCurSpace();
hand.offset_space = (AddrSpace *)0;
hand.offset_offset = walker.getAddr().getOffset(); // Get starting address of instruction
hand.size = hand.space->getAddrSize();
}

void OffsetSymbol::print(ostream &s,ParserWalker &walker) const

{
intb val = (intb) walker.getAddr().getOffset();
s << "0x" << std::hex << val << std::dec;
}

void OffsetSymbol::encode(Encoder &encoder) const

{
encoder.openElement(sla::ELEM_OFFSET_SYM);
encoder.writeUnsignedInteger(sla::ATTRIB_ID, getId());
encoder.closeElement(sla::ELEM_OFFSET_SYM);
}

void OffsetSymbol::encodeHeader(Encoder &encoder) const

{
encoder.openElement(sla::ELEM_OFFSET_SYM_HEAD);
SleighSymbol::encodeHeader(encoder);
encoder.closeElement(sla::ELEM_OFFSET_SYM_HEAD);
}

void OffsetSymbol::decode(Decoder &decoder,SleighBase *trans)

{
const_space = trans->getConstantSpace();
patexp = new StartInstructionValue();
patexp->layClaim();
decoder.closeElement(sla::ELEM_OFFSET_SYM.getId());
}

EndSymbol::EndSymbol(const string &nm,AddrSpace *cspc) : SpecificSymbol(nm)

{
Expand Down
19 changes: 18 additions & 1 deletion Ghidra/Features/Decompiler/src/decompile/cpp/slghsymbol.hh
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class SleighSymbol {
public:
enum symbol_type { space_symbol, token_symbol, userop_symbol, value_symbol, valuemap_symbol,
name_symbol, varnode_symbol, varnodelist_symbol, operand_symbol,
start_symbol, end_symbol, next2_symbol, subtable_symbol, macro_symbol, section_symbol,
start_symbol, offset_symbol, end_symbol, next2_symbol, subtable_symbol, macro_symbol, section_symbol,
bitrange_symbol, context_symbol, epsilon_symbol, label_symbol, flowdest_symbol, flowref_symbol,
dummy_symbol };
private:
Expand Down Expand Up @@ -373,6 +373,23 @@ public:
virtual void decode(Decoder &decoder,SleighBase *trans);
};

class OffsetSymbol : public SpecificSymbol {
AddrSpace *const_space;
PatternExpression *patexp;
public:
OffsetSymbol(void) { patexp = (PatternExpression *)0; } // For use with decode
OffsetSymbol(const string &nm,AddrSpace *cspc);
virtual ~OffsetSymbol(void);
virtual VarnodeTpl *getVarnode(void) const;
virtual PatternExpression *getPatternExpression(void) const { return patexp; }
virtual void getFixedHandle(FixedHandle &hand,ParserWalker &walker) const;
virtual void print(ostream &s,ParserWalker &walker) const;
virtual symbol_type getType(void) const { return offset_symbol; }
virtual void encode(Encoder &encoder) const;
virtual void encodeHeader(Encoder &encoder) const;
virtual void decode(Decoder &decoder,SleighBase *trans);
};

class EndSymbol : public SpecificSymbol {
AddrSpace *const_space;
PatternExpression *patexp;
Expand Down
7 changes: 7 additions & 0 deletions Ghidra/Features/Decompiler/src/main/doc/sleigh.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1097,6 +1097,10 @@ We list all of the symbols that are predefined by SLEIGH.
<td><code>epsilon</code></td>
<td>A special identifier indicating an empty bit pattern.</td>
</tr>
<tr>
<td><code>operand_offset</code></td>
<td>Offset of the address of the current operand. Useful for variable-length instructions.</td>
</tr>
</tbody>
</table>
</informalexample>
Expand All @@ -1113,6 +1117,9 @@ identifiers are address spaces. The <emphasis>epsilon</emphasis>
identifier is inherited from SLED and is a specific symbol equivalent
to the constant zero. The <emphasis>instruction</emphasis> identifier
is the root instruction table.
<emphasis>operand_offset</emphasis> was introduced to support VAX
variable-length, multi-operand instructions. PC-relative addressing in
VAX is relative to the operand address, not the instruction address.
</para>
</sect2>
</sect1>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,7 @@ specific_symbol[String purpose] returns [SpecificSymbol symbol]
if (sym == null) {
unknownSymbolError($s.getText(), find($s), "start, end, next2, operand, epsilon, or varnode", purpose);
} else if(sym.getType() != symbol_type.start_symbol
&& sym.getType() != symbol_type.offset_symbol
&& sym.getType() != symbol_type.end_symbol
&& sym.getType() != symbol_type.next2_symbol
&& sym.getType() != symbol_type.flowdest_symbol
Expand Down Expand Up @@ -841,6 +842,7 @@ pattern_symbol[String purpose] returns [PatternExpression expr]
}
$expr = os.getPatternExpression();
} else if(sym.getType() == symbol_type.start_symbol
|| sym.getType() == symbol_type.offset_symbol
|| sym.getType() == symbol_type.end_symbol
|| sym.getType() == symbol_type.next2_symbol
|| sym.getType() == symbol_type.flowdest_symbol
Expand Down Expand Up @@ -876,6 +878,7 @@ pattern_symbol2[String purpose] returns [PatternExpression expr]
if (sym == null) {
unknownSymbolError($s.getText(), find($s), "start, end, next2, operand, epsilon, or varnode", purpose);
} else if(sym.getType() == symbol_type.start_symbol
|| sym.getType() == symbol_type.offset_symbol
|| sym.getType() == symbol_type.end_symbol
|| sym.getType() == symbol_type.next2_symbol
|| sym.getType() == symbol_type.flowdest_symbol
Expand Down Expand Up @@ -949,6 +952,7 @@ cstatement[VectorSTL<ContextChange> r]
|| sym.getType() == symbol_type.name_symbol
|| sym.getType() == symbol_type.varnodelist_symbol
|| sym.getType() == symbol_type.start_symbol
|| sym.getType() == symbol_type.offset_symbol
|| sym.getType() == symbol_type.end_symbol
|| sym.getType() == symbol_type.next2_symbol
|| sym.getType() == symbol_type.flowdest_symbol
Expand Down Expand Up @@ -1184,6 +1188,7 @@ assignment returns [VectorSTL<OpTpl> value]
bitSym.getBitOffset(),
bitSym.numBits(),e);
} else if(sym.getType() != symbol_type.start_symbol
&& sym.getType() != symbol_type.offset_symbol
&& sym.getType() != symbol_type.end_symbol
&& sym.getType() != symbol_type.next2_symbol
&& sym.getType() != symbol_type.flowdest_symbol
Expand Down Expand Up @@ -1528,6 +1533,7 @@ expr_apply returns [Object value]
pcode.reportError(find($t), "macro invocation not allowed as expression");
}
} else if(sym.getType() == symbol_type.start_symbol
|| sym.getType() == symbol_type.offset_symbol
|| sym.getType() == symbol_type.end_symbol
|| sym.getType() == symbol_type.next2_symbol
|| sym.getType() == symbol_type.flowdest_symbol
Expand Down
Loading