From 17c875e23d827974011c14cf4010c33a8b15a125 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Klaus=20K=C3=A4mpf?= Date: Sun, 30 Oct 2022 20:01:10 +0100 Subject: [PATCH 1/2] Introduce operand_offset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Klaus Kämpf --- .../Decompiler/src/decompile/cpp/pcodeparse.y | 6 ++ .../Decompiler/src/decompile/cpp/semantics.cc | 8 +++ .../Decompiler/src/decompile/cpp/semantics.hh | 2 +- .../src/decompile/cpp/slgh_compile.cc | 2 + .../Decompiler/src/decompile/cpp/slghparse.y | 4 ++ .../src/decompile/cpp/slghpatexpress.cc | 2 + .../src/decompile/cpp/slghpatexpress.hh | 14 ++++ .../Decompiler/src/decompile/cpp/slghscan.l | 3 + .../src/decompile/cpp/slghsymbol.cc | 66 +++++++++++++++++++ .../src/decompile/cpp/slghsymbol.hh | 19 +++++- 10 files changed, 124 insertions(+), 2 deletions(-) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/pcodeparse.y b/Ghidra/Features/Decompiler/src/decompile/cpp/pcodeparse.y index 387f38512ce..a2e3e1b0f91 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/pcodeparse.y +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/pcodeparse.y @@ -39,6 +39,7 @@ extern int pcodeerror(const char *str ); UserOpSymbol *useropsym; LabelSymbol *labelsym; StartSymbol *startsym; + OffsetSymbol *offsetsym; EndSymbol *endsym; Next2Symbol *next2sym; OperandSymbol *operandsym; @@ -78,6 +79,7 @@ extern int pcodeerror(const char *str ); %token VARSYM %token OPERANDSYM %token STARTSYM +%token OFFSETSYM %token ENDSYM %token NEXT2SYM %token LABELSYM @@ -225,6 +227,7 @@ label: '<' LABELSYM '>' { $$ = $2; } specificsymbol: VARSYM { $$ = $1; } | OPERANDSYM { $$ = $1; } | STARTSYM { $$ = $1; } + | OFFSETSYM { $$ = $1; } | ENDSYM { $$ = $1; } | NEXT2SYM { $$ = $1; } ; @@ -752,6 +755,9 @@ int4 PcodeSnippet::lex(void) case SleighSymbol::start_symbol: yylval.startsym = (StartSymbol *)sym; return STARTSYM; + case SleighSymbol::offset_symbol: + yylval.offsetsym = (OffsetSymbol *)sym; + return OFFSETSYM; case SleighSymbol::end_symbol: yylval.endsym = (EndSymbol *)sym; return ENDSYM; diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/semantics.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/semantics.cc index 2e3531ea27e..c154d440168 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/semantics.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/semantics.cc @@ -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: @@ -350,6 +352,9 @@ void ConstTpl::saveXml(ostream &s) const case j_start: s << "start\"/>"; break; + case j_offset: + s << "operand_offset\"/>"; + break; case j_next: s << "next\"/>"; break; @@ -408,6 +413,9 @@ void ConstTpl::restoreXml(const Element *el,const AddrSpaceManager *manage) else if (typestring=="start") { type = j_start; } + else if (typestring=="operand_offset") { + type = j_offset; + } else if (typestring=="next") { type = j_next; } diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/semantics.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/semantics.hh index 8e283dca0f2..80be32f5100 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/semantics.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/semantics.hh @@ -34,7 +34,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; diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/slgh_compile.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/slgh_compile.cc index b40f74389e5..1875a56c986 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/slgh_compile.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/slgh_compile.cc @@ -1817,6 +1817,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()); diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/slghparse.y b/Ghidra/Features/Decompiler/src/decompile/cpp/slghparse.y index 0ee2acf8260..8fcfcd7a414 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/slghparse.y +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/slghparse.y @@ -59,6 +59,7 @@ extern int sleigherror(const char *str ); LabelSymbol *labelsym; SubtableSymbol *subtablesym; StartSymbol *startsym; + OffsetSymbol *offsetsym; EndSymbol *endsym; Next2Symbol *next2sym; OperandSymbol *operandsym; @@ -123,6 +124,7 @@ extern int sleigherror(const char *str ); %token VARLISTSYM %token OPERANDSYM %token STARTSYM +%token OFFSETSYM %token ENDSYM %token NEXT2SYM %token MACROSYM @@ -504,6 +506,7 @@ specificsymbol: VARSYM { $$ = $1; } | SPECSYM { $$ = $1; } | OPERANDSYM { $$ = $1; } | STARTSYM { $$ = $1; } + | OFFSETSYM { $$ = $1; } | ENDSYM { $$ = $1; } | NEXT2SYM { $$ = $1; } ; @@ -579,6 +582,7 @@ anysymbol: SPACESYM { $$ = $1; } | VARLISTSYM { $$ = $1; } | OPERANDSYM { $$ = $1; } | STARTSYM { $$ = $1; } + | OFFSETSYM { $$ = $1; } | ENDSYM { $$ = $1; } | NEXT2SYM { $$ = $1; } | BITSYM { $$ = $1; } diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/slghpatexpress.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/slghpatexpress.cc index 5d6a2b9b48d..8253bd1a3eb 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/slghpatexpress.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/slghpatexpress.cc @@ -478,6 +478,8 @@ PatternExpression *PatternExpression::restoreExpression(const Element *el,Transl res = new OperandValue(); else if (nm == "start_exp") res = new StartInstructionValue(); + else if (nm == "offset_exp") + res = new OperandOffsetValue(); else if (nm == "end_exp") res = new EndInstructionValue(); else if (nm == "plus_exp") diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/slghpatexpress.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/slghpatexpress.hh index c260fde8299..7cfc0916e8b 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/slghpatexpress.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/slghpatexpress.hh @@ -153,6 +153,20 @@ public: virtual void saveXml(ostream &s) const { s << ""; } virtual void restoreXml(const Element *el,Translate *trans) {} }; + +class OperandOffsetValue : public PatternValue { +public: + OperandOffsetValue(void) {} + virtual intb getValue(ParserWalker &walker) const { + return (intb)walker.getOffset(-1); + } + virtual TokenPattern genMinPattern(const vector &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 saveXml(ostream &s) const { s << ""; } + virtual void restoreXml(const Element *el,Translate *trans) {} +}; class EndInstructionValue : public PatternValue { public: diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/slghscan.l b/Ghidra/Features/Decompiler/src/decompile/cpp/slghscan.l index 32c7660970a..44802493d9c 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/slghscan.l +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/slghscan.l @@ -431,6 +431,9 @@ int4 find_symbol(void) { case SleighSymbol::start_symbol: sleighlval.startsym = (StartSymbol *)sym; return STARTSYM; + case SleighSymbol::offset_symbol: + sleighlval.offsetsym = (OffsetSymbol *)sym; + return OFFSETSYM; case SleighSymbol::end_symbol: sleighlval.endsym = (EndSymbol *)sym; return ENDSYM; diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/slghsymbol.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/slghsymbol.cc index b308e1b7100..497a29477b3 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/slghsymbol.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/slghsymbol.cc @@ -254,6 +254,8 @@ void SymbolTable::restoreSymbolHeader(const Element *el) sym = new OperandSymbol(); else if (el->getName() == "start_sym_head") sym = new StartSymbol(); + else if (el->getName() == "offset_sym_head") + sym = new OffsetSymbol(); else if (el->getName() == "end_sym_head") sym = new EndSymbol(); else if (el->getName() == "next2_sym_head") @@ -1196,6 +1198,70 @@ void StartSymbol::restoreXml(const Element *el,SleighBase *trans) patexp->layClaim(); } +OffsetSymbol::OffsetSymbol(const string &nm,AddrSpace *cspc) : SpecificSymbol(nm) + +{ + const_space = cspc; + patexp = new OperandOffsetValue(); + 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::saveXml(ostream &s) const + +{ + s << "\n"; +} + +void OffsetSymbol::saveXmlHeader(ostream &s) const + +{ + s << "\n"; +} + +void OffsetSymbol::restoreXml(const Element *el,SleighBase *trans) + +{ + const_space = trans->getConstantSpace(); + patexp = new OperandOffsetValue(); + patexp->layClaim(); +} + EndSymbol::EndSymbol(const string &nm,AddrSpace *cspc) : SpecificSymbol(nm) { diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/slghsymbol.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/slghsymbol.hh index 2fc1e192163..0183bc33ddd 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/slghsymbol.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/slghsymbol.hh @@ -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, dummy_symbol }; private: @@ -376,6 +376,23 @@ public: virtual void restoreXml(const Element *el,SleighBase *trans); }; +class OffsetSymbol : public SpecificSymbol { + AddrSpace *const_space; + PatternExpression *patexp; +public: + OffsetSymbol(void) { patexp = (PatternExpression *)0; } // For use with restoreXml + 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 saveXml(ostream &s) const; + virtual void saveXmlHeader(ostream &s) const; + virtual void restoreXml(const Element *el,SleighBase *trans); +}; + class EndSymbol : public SpecificSymbol { AddrSpace *const_space; PatternExpression *patexp; From 607ae4a31b4d919eaa78969e26dfcd3b17748871 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Klaus=20K=C3=A4mpf?= Date: Sun, 30 Oct 2022 22:18:33 +0100 Subject: [PATCH 2/2] Add operand_offset to sleigh Java MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Klaus Kämpf --- .../ghidra/sleigh/grammar/SleighCompiler.g | 6 + .../sleigh/SleighAssemblerBuilder.java | 3 + .../expression/OffsetInstructionValue.java | 83 +++++++++++++ .../sleigh/expression/PatternExpression.java | 2 + .../sleigh/symbol/OffsetSymbol.java | 82 +++++++++++++ .../processors/sleigh/symbol/SymbolTable.java | 2 + .../ghidra/pcodeCPort/semantics/ConstTpl.java | 9 +- .../slgh_compile/SleighCompile.java | 2 + .../pcodeCPort/slgh_compile/Yylval.java | 1 + .../OffsetInstructionValue.java | 67 +++++++++++ .../slghpatexpress/PatternExpression.java | 3 + .../pcodeCPort/slghsymbol/OffsetSymbol.java | 109 ++++++++++++++++++ .../pcodeCPort/slghsymbol/SymbolTable.java | 3 + .../pcodeCPort/slghsymbol/symbol_type.java | 1 + .../program/model/lang/PcodeParser.java | 1 + 15 files changed, 373 insertions(+), 1 deletion(-) create mode 100644 Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/expression/OffsetInstructionValue.java create mode 100644 Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/symbol/OffsetSymbol.java create mode 100644 Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slghpatexpress/OffsetInstructionValue.java create mode 100644 Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slghsymbol/OffsetSymbol.java diff --git a/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/SleighCompiler.g b/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/SleighCompiler.g index 8935b88f248..9c90e9feadd 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/SleighCompiler.g +++ b/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/SleighCompiler.g @@ -342,6 +342,7 @@ specific_symbol[String purpose] returns [SpecificSymbol symbol] if (sym == null) { unknownSymbolError($s.getText(), find($s), "start, end, next2, operand, epsilon, or varnode", purpose); } else if(sym.getType() != symbol_type.start_symbol + && sym.getType() != symbol_type.offset_symbol && sym.getType() != symbol_type.end_symbol && sym.getType() != symbol_type.next2_symbol && sym.getType() != symbol_type.operand_symbol @@ -839,6 +840,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.epsilon_symbol @@ -872,6 +874,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.operand_symbol @@ -943,6 +946,7 @@ cstatement[VectorSTL 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.operand_symbol @@ -1170,6 +1174,7 @@ assignment returns [VectorSTL value] if (sym == null) { $value = pcode.newOutput(find(id), false, e, $id.getText()); } 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.operand_symbol @@ -1486,6 +1491,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.operand_symbol diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/SleighAssemblerBuilder.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/SleighAssemblerBuilder.java index 1a6f544b1a9..282731ef3c1 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/SleighAssemblerBuilder.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/SleighAssemblerBuilder.java @@ -570,6 +570,9 @@ else if (sym instanceof VarnodeSymbol) { else if (sym instanceof StartSymbol) { // Ignore. We handle inst_start in semantic processing } + else if (sym instanceof OffsetSymbol) { + // Ignore. We handle inst_start in semantic processing + } else if (sym instanceof EndSymbol) { // Ignore. We handle inst_next in semantic processing } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/expression/OffsetInstructionValue.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/expression/OffsetInstructionValue.java new file mode 100644 index 00000000000..db872ec164d --- /dev/null +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/expression/OffsetInstructionValue.java @@ -0,0 +1,83 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * Created on Feb 8, 2005 + * + */ +package ghidra.app.plugin.processors.sleigh.expression; + +import 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 offset value of the current instructions address + */ +public class OffsetInstructionValue extends PatternValue { + private static final int HASH = "[operand_offset]".hashCode(); + + @Override + public int hashCode() { + return HASH; + } + + @Override + public boolean equals(Object obj) { + return obj instanceof OffsetInstructionValue; + } + + /* (non-Javadoc) + * @see ghidra.app.plugin.processors.sleigh.expression.PatternValue#minValue() + */ + @Override + public long minValue() { + return 0; + } + + /* (non-Javadoc) + * @see ghidra.app.plugin.processors.sleigh.expression.PatternValue#maxValue() + */ + @Override + public long maxValue() { + return 0; + } + + /* (non-Javadoc) + * @see ghidra.app.plugin.processors.sleigh.expression.PatternExpression#getValue(ghidra.app.plugin.processors.sleigh.ParserWalker) + */ + @Override + public long getValue(ParserWalker walker) throws MemoryAccessException { + return walker.getOffset(-1); + } + + /* (non-Javadoc) + * @see ghidra.app.plugin.processors.sleigh.PatternExpression#restoreXml(org.jdom.Element) + */ + @Override + public void restoreXml(XmlPullParser parser, SleighLanguage lang) { + parser.discardSubTree("offset_exp"); + // Nothing to do + } + + @Override + public String toString() { + return "[operand_offset]"; + } +} diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/expression/PatternExpression.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/expression/PatternExpression.java index 69b6f9c3cbf..920ea9238fd 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/expression/PatternExpression.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/expression/PatternExpression.java @@ -49,6 +49,8 @@ else if (nm.equals("operand_exp")) res = new OperandValue(); else if (nm.equals("start_exp")) res = new StartInstructionValue(); + else if (nm.equals("offset_exp")) + res = new OffsetInstructionValue(); else if (nm.equals("end_exp")) res = new EndInstructionValue(); else if (nm.equals("next2_exp")) diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/symbol/OffsetSymbol.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/symbol/OffsetSymbol.java new file mode 100644 index 00000000000..86f096fbe53 --- /dev/null +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/symbol/OffsetSymbol.java @@ -0,0 +1,82 @@ +/* ### + * IP: GHIDRA + * REVIEWED: YES + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * Created on Feb 8, 2005 + * + */ +package ghidra.app.plugin.processors.sleigh.symbol; + +import ghidra.app.plugin.processors.sleigh.*; +import ghidra.app.plugin.processors.sleigh.expression.*; +import ghidra.program.model.mem.*; +import ghidra.xml.*; + +import java.util.*; + +/** + * + * + * TripleSymbol with semantic value equal to offset of instruction's + * current address + */ +public class OffsetSymbol extends SpecificSymbol { + + private PatternExpression patexp; + + /* (non-Javadoc) + * @see ghidra.app.plugin.processors.sleigh.symbol.TripleSymbol#getPatternExpression() + */ + @Override + public PatternExpression getPatternExpression() { + return patexp; + } + + /* (non-Javadoc) + * @see ghidra.app.plugin.processors.sleigh.symbol.TripleSymbol#getFixedHandle(ghidra.app.plugin.processors.sleigh.FixedHandle, ghidra.app.plugin.processors.sleigh.ParserWalker) + */ + @Override + public void getFixedHandle(FixedHandle hand, ParserWalker walker) { + hand.space = walker.getCurSpace(); + hand.offset_space = null; + hand.offset_offset = walker.getAddr().getOffset(); + hand.size = hand.space.getPointerSize(); + } + + /* (non-Javadoc) + * @see ghidra.app.plugin.processors.sleigh.symbol.TripleSymbol#print(ghidra.app.plugin.processors.sleigh.ParserWalker) + */ + @Override + public String print(ParserWalker walker) throws MemoryAccessException { + long val = walker.getAddr().getOffset(); + return "0x" + Long.toHexString(val); + } + + @Override + public void printList(ParserWalker walker, ArrayList list) { + list.add(walker.getParentHandle()); + } + /* (non-Javadoc) + * @see ghidra.app.plugin.processors.sleigh.symbol.Symbol#restoreXml(org.jdom.Element, ghidra.app.plugin.processors.sleigh.SleighLanguage) + */ + @Override + public void restoreXml(XmlPullParser parser, SleighLanguage sleigh) { + XmlElement element = parser.start("offset_sym"); + patexp = new OffsetInstructionValue(); + parser.end(element); + } + +} diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/symbol/SymbolTable.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/symbol/SymbolTable.java index dd9cec532c7..0cc6a2a810f 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/symbol/SymbolTable.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/symbol/SymbolTable.java @@ -150,6 +150,8 @@ else if (el.getName().equals("operand_sym_head")) sym = new OperandSymbol(); else if (el.getName().equals("start_sym_head")) sym = new StartSymbol(); + else if (el.getName().equals("offset_sym_head")) + sym = new OffsetSymbol(); else if (el.getName().equals("end_sym_head")) sym = new EndSymbol(); else if (el.getName().equals("next2_sym_head")) diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/semantics/ConstTpl.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/semantics/ConstTpl.java index 341877dae8b..5c14e3bbcd0 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/semantics/ConstTpl.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/semantics/ConstTpl.java @@ -46,7 +46,8 @@ public enum const_type { j_flowref, j_flowref_size, j_flowdest, - j_flowdest_size + j_flowdest_size, + j_offset } public enum v_field { @@ -297,6 +298,9 @@ public void saveXml(PrintStream s) { case j_start: s.append("start\"/>"); break; + case j_offset: + s.append("offset\"/>"); + break; case j_next: s.append("next\"/>"); break; @@ -351,6 +355,9 @@ else if (typestring.equals("handle")) { else if (typestring.equals("start")) { type = const_type.j_start; } + else if (typestring.equals("offset")) { + type = const_type.j_offset; + } else if (typestring.equals("next")) { type = const_type.j_next; } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slgh_compile/SleighCompile.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slgh_compile/SleighCompile.java index 4a8e710b3b6..aa1b3686e36 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slgh_compile/SleighCompile.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slgh_compile/SleighCompile.java @@ -287,6 +287,8 @@ private void predefinedSymbols() { symtab.addSymbol(spacesym); StartSymbol startsym = new StartSymbol(location, "inst_start", getConstantSpace()); symtab.addSymbol(startsym); + OffsetSymbol offsetsym = new OffsetSymbol(location, "operand_offset", getConstantSpace()); + symtab.addSymbol(offsetsym); EndSymbol endsym = new EndSymbol(location, "inst_next", getConstantSpace()); symtab.addSymbol(endsym); Next2Symbol next2sym = new Next2Symbol(location, "inst_next2", getConstantSpace()); diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slgh_compile/Yylval.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slgh_compile/Yylval.java index f165ca6b8b3..dc574000152 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slgh_compile/Yylval.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slgh_compile/Yylval.java @@ -30,6 +30,7 @@ class Yylval { VarnodeListSymbol varlistsym; OperandSymbol operandsym; StartSymbol startsym; + OffsetSymbol offsetsym; EndSymbol endsym; Next2Symbol next2sym; SubtableSymbol subtablesym; diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slghpatexpress/OffsetInstructionValue.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slghpatexpress/OffsetInstructionValue.java new file mode 100644 index 00000000000..e5bb4b893ea --- /dev/null +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slghpatexpress/OffsetInstructionValue.java @@ -0,0 +1,67 @@ +/* ### + * IP: GHIDRA + * REVIEWED: YES + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.pcodeCPort.slghpatexpress; + +import generic.stl.VectorSTL; +import ghidra.app.plugin.processors.sleigh.ParserWalker; +import ghidra.pcodeCPort.translate.Translate; +import ghidra.sleigh.grammar.Location; + +import java.io.PrintStream; + +import org.jdom.Element; + +public class OffsetInstructionValue extends PatternValue { + + public OffsetInstructionValue(Location location) { + super(location); + } + + public long getValue(ParserWalker pos) { + return pos.getOffset(-1); + } + + @Override + public TokenPattern genMinPattern(VectorSTL 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(""); + } + + @Override + public void restoreXml(Element el, Translate trans) { + } + +} diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slghpatexpress/PatternExpression.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slghpatexpress/PatternExpression.java index 2842fa83af3..315450dd8e4 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slghpatexpress/PatternExpression.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slghpatexpress/PatternExpression.java @@ -84,6 +84,9 @@ else if (nm.equals("operand_exp")) { else if (nm.equals("start_exp")) { res = new StartInstructionValue(null); } + else if (nm.equals("offset_exp")) { + res = new OffsetInstructionValue(null); + } else if (nm.equals("end_exp")) { res = new EndInstructionValue(null); } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slghsymbol/OffsetSymbol.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slghsymbol/OffsetSymbol.java new file mode 100644 index 00000000000..95214daba55 --- /dev/null +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slghsymbol/OffsetSymbol.java @@ -0,0 +1,109 @@ +/* ### + * IP: GHIDRA + * REVIEWED: YES + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.pcodeCPort.slghsymbol; + +import ghidra.app.plugin.processors.sleigh.ParserWalker; +import ghidra.app.plugin.processors.sleigh.FixedHandle; +import ghidra.pcodeCPort.semantics.ConstTpl; +import ghidra.pcodeCPort.semantics.VarnodeTpl; +import ghidra.pcodeCPort.sleighbase.SleighBase; +import ghidra.pcodeCPort.slghpatexpress.PatternExpression; +import ghidra.pcodeCPort.slghpatexpress.OffsetInstructionValue; +import ghidra.pcodeCPort.space.AddrSpace; +import ghidra.sleigh.grammar.Location; + +import java.io.PrintStream; + +import org.jdom.Element; + +public class OffsetSymbol extends SpecificSymbol { + private AddrSpace const_space; + private PatternExpression patexp; + + OffsetSymbol(Location location) { + super(location); + patexp = null; + } // For use with restoreXml + + @Override + public PatternExpression getPatternExpression() { + return patexp; + } + + @Override + public symbol_type getType() { + return symbol_type.offset_symbol; + } + + public OffsetSymbol(Location location, String nm, AddrSpace cspc) { + super(location, nm); + const_space = cspc; + patexp = new OffsetInstructionValue(location); + patexp.layClaim(); + } + + @Override + public void dispose() { + if (patexp != null) { + PatternExpression.release(patexp); + } + } + +// Returns current instruction offset as a constant + @Override + public VarnodeTpl getVarnode() { + ConstTpl spc = new ConstTpl(const_space); + ConstTpl off = new ConstTpl(ConstTpl.const_type.j_offset); + ConstTpl sz_zero = new ConstTpl(); + return new VarnodeTpl(location, spc, off, sz_zero); + } + + 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.getPointerSize(); + } + + 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(""); + } + + @Override + public void saveXmlHeader(PrintStream s) { + s.append("\n"); + } + + @Override + public void restoreXml(Element el, SleighBase trans) { + const_space = trans.getConstantSpace(); + patexp = new OffsetInstructionValue(null); + patexp.layClaim(); + } + +} diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slghsymbol/SymbolTable.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slghsymbol/SymbolTable.java index 76f476a8d2b..2ce004ddf3f 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slghsymbol/SymbolTable.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slghsymbol/SymbolTable.java @@ -297,6 +297,9 @@ else if (el.getName().equals("operand_sym_head")) { else if (el.getName().equals("start_sym_head")) { sym = new StartSymbol(location); } + else if (el.getName().equals("offset_sym_head")) { + sym = new OffsetSymbol(location); + } else if (el.getName().equals("end_sym_head")) { sym = new EndSymbol(location); } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slghsymbol/symbol_type.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slghsymbol/symbol_type.java index 272b5fe643d..cc3b29f27b8 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slghsymbol/symbol_type.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slghsymbol/symbol_type.java @@ -26,6 +26,7 @@ public enum symbol_type { varnodelist_symbol, operand_symbol, start_symbol, // inst_start, inst_ref, inst_def + offset_symbol, end_symbol, // inst_next next2_symbol, // inst_next2 subtable_symbol, diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/PcodeParser.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/PcodeParser.java index 19d8622dd6f..7dc03922643 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/PcodeParser.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/PcodeParser.java @@ -84,6 +84,7 @@ private void initializeSymbols() { Location internalLoc = Location.INTERNALLY_DEFINED; symbolMap.put("inst_start", new StartSymbol(internalLoc, "inst_start", getConstantSpace())); + symbolMap.put("operand_offset", new OffsetSymbol(internalLoc, "operand_offset", getConstantSpace())); symbolMap.put("inst_next", new EndSymbol(internalLoc, "inst_next", getConstantSpace())); symbolMap.put("inst_next2", new Next2Symbol(internalLoc, "inst_next2", getConstantSpace())); symbolMap.put("inst_ref", new FlowRefSymbol(internalLoc, "inst_ref", getConstantSpace()));