From 6ed4ce628c8ed1a45f4180c6912db874ca16b8ea Mon Sep 17 00:00:00 2001 From: caheckman <48068198+caheckman@users.noreply.github.com> Date: Tue, 20 Oct 2020 11:23:59 -0400 Subject: [PATCH] token endianness --- .../Decompiler/src/decompile/cpp/slgh_compile.cc | 9 +++++++-- .../Decompiler/src/decompile/cpp/slgh_compile.hh | 2 +- .../Decompiler/src/decompile/cpp/slghparse.y | 4 +++- .../Decompiler/src/decompile/cpp/slghscan.l | 8 ++++---- .../main/antlr/ghidra/sleigh/grammar/BaseLexer.g | 1 + .../antlr/ghidra/sleigh/grammar/SleighCompiler.g | 12 +++++++++++- .../main/antlr/ghidra/sleigh/grammar/SleighEcho.g | 1 + .../antlr/ghidra/sleigh/grammar/SleighParser.g | 1 + .../plugin/processors/sleigh/SleighLanguage.java | 4 ++-- .../pcodeCPort/slgh_compile/SleighCompile.java | 15 +++++++++++---- 10 files changed, 42 insertions(+), 15 deletions(-) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/slgh_compile.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/slgh_compile.cc index 481c702c0a..64d30b516a 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/slgh_compile.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/slgh_compile.cc @@ -1987,7 +1987,7 @@ bool SleighCompile::undefinePreprocValue(const string &nm) // Functions needed by the parser -TokenSymbol *SleighCompile::defineToken(string *name,uintb *sz) +TokenSymbol *SleighCompile::defineToken(string *name,uintb *sz,int4 endian) { uint4 size = *sz; @@ -1998,7 +1998,12 @@ TokenSymbol *SleighCompile::defineToken(string *name,uintb *sz) } else size = size/8; - Token *newtoken = new Token(*name,size,isBigEndian(),tokentable.size()); + bool isBig; + if (endian ==0) + isBig = isBigEndian(); + else + isBig = (endian > 0); + Token *newtoken = new Token(*name,size,isBig,tokentable.size()); tokentable.push_back(newtoken); delete name; TokenSymbol *res = new TokenSymbol(newtoken); diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/slgh_compile.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/slgh_compile.hh index 185efa346c..30a7d1c284 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/slgh_compile.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/slgh_compile.hh @@ -261,7 +261,7 @@ public: bool undefinePreprocValue(const string &nm); // Parser functions - TokenSymbol *defineToken(string *name,uintb *sz); + TokenSymbol *defineToken(string *name,uintb *sz,int4 endian); void addTokenField(TokenSymbol *sym,FieldQuality *qual); bool addContextField(VarnodeSymbol *sym,FieldQuality *qual); void newSpace(SpaceQuality *qual); diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/slghparse.y b/Ghidra/Features/Decompiler/src/decompile/cpp/slghparse.y index 4bcc73bf9f..c34f5a4656 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/slghparse.y +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/slghparse.y @@ -181,7 +181,9 @@ aligndef: DEFINE_KEY ALIGN_KEY '=' INTEGER ';' { slgh->setAlignment(*$4); delete ; tokendef: tokenprop ';' {} ; -tokenprop: DEFINE_KEY TOKEN_KEY STRING '(' INTEGER ')' { $$ = slgh->defineToken($3,$5); } +tokenprop: DEFINE_KEY TOKEN_KEY STRING '(' INTEGER ')' { $$ = slgh->defineToken($3,$5,0); } + | DEFINE_KEY TOKEN_KEY STRING '(' INTEGER ')' ENDIAN_KEY '=' LITTLE_KEY { $$ = slgh->defineToken($3,$5,-1); } + | DEFINE_KEY TOKEN_KEY STRING '(' INTEGER ')' ENDIAN_KEY '=' BIG_KEY { $$ = slgh->defineToken($3,$5,1); } | tokenprop fielddef { $$ = $1; slgh->addTokenField($1,$2); } | DEFINE_KEY TOKEN_KEY anysymbol { string errmsg=$3->getName()+": redefined as a token"; yyerror(errmsg.c_str()); YYERROR; } ; diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/slghscan.l b/Ghidra/Features/Decompiler/src/decompile/cpp/slghscan.l index 0675c29872..0115555194 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/slghscan.l +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/slghscan.l @@ -494,7 +494,7 @@ int4 scan_number(char *numtext,YYSTYPE *lval,bool signednum) [(),\-] { yylval.ch = yytext[0]; return yytext[0]; } \: { BEGIN(print); slgh->calcContextLayout(); yylval.ch = yytext[0]; return yytext[0]; } \{ { BEGIN(sem); yylval.ch = yytext[0]; return yytext[0]; } -#.*$ +#.* [\r\ \t\v]+ \n { slgh->nextLine(); } macro { BEGIN(macroblock); return MACRO_KEY; } @@ -540,7 +540,7 @@ with { BEGIN(pattern); withsection = 1; slgh->calcContextLayout(); return WITH values { return VALUES_KEY; } variables { return VARIABLES_KEY; } pcodeop { return PCODEOP_KEY; } -#.*$ +#.* [a-zA-Z_.][a-zA-Z0-9_.]* { return find_symbol(); } [0-9]|[1-9][0-9]+ { return scan_number(yytext,&yylval,false); } 0x[0-9a-fA-F]+ { return scan_number(yytext,&yylval,false); } @@ -582,7 +582,7 @@ with { BEGIN(pattern); withsection = 1; slgh->calcContextLayout(); return WITH \| { yylval.ch = yytext[0]; return (actionon==0) ? yytext[0] : OP_OR; } \^ { return OP_XOR; } [=(),:;+\-*/~<>] { yylval.ch = yytext[0]; return yytext[0]; } -#.*$ +#.* [a-zA-Z_.][a-zA-Z0-9_.]* { return find_symbol(); } [0-9]|[1-9][0-9]+ { return scan_number(yytext,&yylval,true); } 0x[0-9a-fA-F]+ { return scan_number(yytext,&yylval,true); } @@ -648,7 +648,7 @@ with { BEGIN(pattern); withsection = 1; slgh->calcContextLayout(); return WITH build { return BUILD_KEY; } local { return LOCAL_KEY; } [=(),:\[\];!&|^+\-*/%~<>] { yylval.ch = yytext[0]; return yytext[0]; } -#.*$ +#.* [a-zA-Z_.][a-zA-Z0-9_.]* { return find_symbol(); } [0-9]|[1-9][0-9]+ { return scan_number(yytext,&yylval,false); } 0x[0-9a-fA-F]+ { return scan_number(yytext,&yylval,false); } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/BaseLexer.g b/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/BaseLexer.g index f578ac40d8..aaec246069 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/BaseLexer.g +++ b/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/BaseLexer.g @@ -119,6 +119,7 @@ tokens { OP_SUBTABLE; OP_TABLE; OP_TOKEN; + OP_TOKEN_ENDIAN; OP_TRUNCATION_SIZE; OP_TYPE; OP_UNIMPL; 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 2e12078835..45f4069e5f 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 @@ -183,10 +183,20 @@ tokendef if (sym != null) { redefinedError(sym, n, "token"); } else { - $tokendef::tokenSymbol = sc.defineToken(find(n), $n.value.getText(), $i.value.intValue()); + $tokendef::tokenSymbol = sc.defineToken(find(n), $n.value.getText(), $i.value.intValue(), 0); } } } fielddefs) + | ^(OP_TOKEN_ENDIAN n=specific_identifier["token definition"] i=integer s=endian { + if (n != null) { + SleighSymbol sym = sc.findSymbol($n.value.getText()); + if (sym != null) { + redefinedError(sym, n, "token"); + } else { + $tokendef::tokenSymbol = sc.defineToken(find(n), $n.value.getText(), $i.value.intValue(), $s.value ==0 ? -1 : 1); + } + } + } fielddefs) ; fielddefs diff --git a/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/SleighEcho.g b/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/SleighEcho.g index 2d3fc5bbae..fcb42e4c19 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/SleighEcho.g +++ b/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/SleighEcho.g @@ -60,6 +60,7 @@ aligndef tokendef : ^(OP_TOKEN n=identifier i=integer { out("define token " + $n.value + "(" + $i.value + ")"); } fielddefs) + | ^(OP_TOKEN_ENDIAN n=identifier i=integer s=endian { out("define token endian" + $n.value + "(" + $i.value + ")"); } fielddefs) ; fielddefs diff --git a/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/SleighParser.g b/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/SleighParser.g index 74f75b56e0..6beda0844a 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/SleighParser.g +++ b/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/SleighParser.g @@ -74,6 +74,7 @@ aligndef tokendef : lc=KEY_DEFINE KEY_TOKEN identifier LPAREN integer rp=RPAREN fielddefs[$rp] -> ^(OP_TOKEN[$lc, "define token"] identifier integer fielddefs) + | lc=KEY_DEFINE KEY_TOKEN identifier LPAREN integer RPAREN rp=KEY_ENDIAN ASSIGN endian fielddefs[$rp] -> ^(OP_TOKEN_ENDIAN[$lc, "define token"] identifier integer endian fielddefs) ; fielddefs[Token lc] diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/SleighLanguage.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/SleighLanguage.java index 7501eb3626..c900152a38 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/SleighLanguage.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/SleighLanguage.java @@ -889,9 +889,9 @@ public class SleighLanguage implements Language { } boolean isBigEndian = SpecXmlUtils.decodeBoolean(el.getAttribute("bigendian")); // check the instruction endianess, not the program data endianess - if (isBigEndian ^ description.getInstructionEndian().isBigEndian()) { + if (isBigEndian ^ description.getEndian().isBigEndian()) { throw new SleighException( - ".ldefs says " + getLanguageID() + " is " + description.getInstructionEndian() + + ".ldefs says " + getLanguageID() + " is " + description.getEndian() + " but .sla says " + el.getAttribute("bigendian")); } uniqueBase = SpecXmlUtils.decodeLong(el.getAttribute("uniqbase")); 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 e96ee6ba85..ad779e50bc 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 @@ -529,8 +529,8 @@ public class SleighCompile extends SleighBase { static int findCollision(Map local2Operand, ArrayList locals, int operand) { Integer boxOperand = Integer.valueOf(operand); - for (int i = 0; i < locals.size(); ++i) { - Integer previous = local2Operand.putIfAbsent(locals.get(i), boxOperand); + for (Long local : locals) { + Integer previous = local2Operand.putIfAbsent(local, boxOperand); if (previous != null) { if (previous.intValue() != operand) { return previous.intValue(); @@ -842,7 +842,7 @@ public class SleighCompile extends SleighBase { } // Parser functions - public TokenSymbol defineToken(Location location, String name, long sz) { + public TokenSymbol defineToken(Location location, String name, long sz, int endian) { entry("defineToken", location, name, sz); int size = (int) sz; if ((size & 7) != 0) { @@ -853,8 +853,15 @@ public class SleighCompile extends SleighBase { else { size = size / 8; } + boolean isBig; + if (endian == 0) { + isBig = isBigEndian(); + } + else { + isBig = (endian > 0); + } ghidra.pcodeCPort.context.Token newtoken = - new ghidra.pcodeCPort.context.Token(name, size, isBigEndian(), tokentable.size()); + new ghidra.pcodeCPort.context.Token(name, size, isBig, tokentable.size()); tokentable.push_back(newtoken); TokenSymbol res = new TokenSymbol(location, newtoken); addSymbol(res);