File 0003-Introduce-operand_offset.patch of Package ghidra

From 2a17fb2d601ee11124c87bd4135396e281221cf9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Klaus=20K=C3=A4mpf?= <kkaempf@gmail.com>
Date: Sun, 30 Oct 2022 20:01:10 +0100
Subject: [PATCH 03/12] Introduce operand_offset
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Klaus Kämpf <kkaempf@gmail.com>
---
 .../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 387f38512..a2e3e1b0f 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> VARSYM
 %token <operandsym> OPERANDSYM
 %token <startsym> STARTSYM
+%token <offsetsym> OFFSETSYM
 %token <endsym> ENDSYM
 %token <next2sym> NEXT2SYM
 %token <labelsym> 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 2e3531ea2..c154d4401 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 8e283dca0..80be32f51 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 b40f74389..1875a56c9 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 0ee2acf82..8fcfcd7a4 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> VARLISTSYM
 %token <operandsym> OPERANDSYM
 %token <startsym> STARTSYM
+%token <offsetsym> OFFSETSYM
 %token <endsym> ENDSYM
 %token <next2sym> NEXT2SYM
 %token <macrosym> 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 5418473ab..745de1bb4 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 48af95afc..df59c01b7 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 << "<start_exp/>"; }
   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<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 saveXml(ostream &s) const { s << "<offset_exp/>"; }
+  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 32c766097..44802493d 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 b8735099a..f96d01885 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")
@@ -1197,6 +1199,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 << "<offset_sym";
+  SleighSymbol::saveXmlHeader(s);
+  s << "/>\n";
+}
+
+void OffsetSymbol::saveXmlHeader(ostream &s) const
+
+{
+  s << "<offset_sym_head";
+  SleighSymbol::saveXmlHeader(s);
+  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 2fc1e1921..0183bc33d 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;
-- 
2.43.0

openSUSE Build Service is sponsored by