mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-06 03:50:02 +02:00
GP-2746 fixes for macros with no args, concatenated string
constants, #pragma in function call arguments
This commit is contained in:
parent
2a2b044940
commit
4fe2fc4b9e
6 changed files with 155 additions and 18 deletions
|
@ -378,7 +378,7 @@ public class DefineTable {
|
|||
System.err.println("DONT Replace " + currKey + " in: " + buf);
|
||||
return -1;
|
||||
}
|
||||
if (argv != null && argv.size() > 0) {
|
||||
if (argv != null) {
|
||||
// need to scan carefully, and recursively
|
||||
// there shouldn't be so many globals...
|
||||
// could be screwed up by so many things
|
||||
|
|
|
@ -1566,7 +1566,7 @@ Declaration StorageClassSpecifier(Declaration specDT) : {}
|
|||
|
|
||||
<THREADLOCAL>
|
||||
|
|
||||
<EXTERN> [ <STRING_LITERAL> ]
|
||||
<EXTERN> [ MultiLineString() ]
|
||||
|
|
||||
<TYPEDEF>
|
||||
{
|
||||
|
@ -1827,7 +1827,25 @@ void DeclConstant() : {}
|
|||
{
|
||||
<INTEGER_LITERAL> |
|
||||
<IDENTIFIER> [ ":" <INTEGER_LITERAL> ] |
|
||||
( "#" | ":" | <IDENTIFIER> | "(" ")" | <STRING_LITERAL> )
|
||||
( "#" | ":" | <IDENTIFIER> | "(" ")" | MultiLineString() )
|
||||
}
|
||||
|
||||
Token MultiLineString() : {
|
||||
Token t = null;
|
||||
Token r = null;
|
||||
}
|
||||
{
|
||||
(t = <STRING_LITERAL>
|
||||
{
|
||||
if (r == null) {
|
||||
r = t;
|
||||
} else {
|
||||
r.image = r.image.substring(0,r.image.length()) + t.image.substring(1);
|
||||
}
|
||||
}
|
||||
)+
|
||||
|
||||
{ return r; }
|
||||
}
|
||||
|
||||
void PragmaSpec() : {
|
||||
|
@ -2076,9 +2094,12 @@ Declaration SpecifierQualifierList() : {
|
|||
(
|
||||
dt = TypeSpecifier(dt)
|
||||
[
|
||||
LOOKAHEAD(SpecifierQualifierList() , { dt == null } )
|
||||
LOOKAHEAD(SpecifierQualifierList() , { dt == null || dt.getDataType() == null } )
|
||||
sdt = SpecifierQualifierList()
|
||||
]
|
||||
[
|
||||
sdt = TypeQualifier(sdt != null ? sdt : dt)
|
||||
]
|
||||
)
|
||||
|
|
||||
(
|
||||
|
@ -2372,7 +2393,7 @@ ArrayList<Declaration> ParameterList() : {
|
|||
ParameterDeclaration(list)
|
||||
(
|
||||
LOOKAHEAD(2)
|
||||
"," ParameterDeclaration(list)
|
||||
"," ParameterDeclaration(list)
|
||||
)*
|
||||
{
|
||||
return list;
|
||||
|
@ -2384,13 +2405,14 @@ void ParameterDeclaration(ArrayList<Declaration> list) : {
|
|||
Declaration dec= new Declaration();
|
||||
}
|
||||
{
|
||||
|
||||
dt = DeclarationSpecifiers(dec)
|
||||
(
|
||||
LOOKAHEAD(Declarator(dt))
|
||||
dec= Declarator(dt, null)
|
||||
|
|
||||
[ dec = AbstractDeclarator(dt) ]
|
||||
) [ "=" <INTEGER_LITERAL > ]
|
||||
) [ "=" <INTEGER_LITERAL > ] [PragmaSpec()]
|
||||
{
|
||||
if (dec == null) {
|
||||
dec = new Declaration(dt);
|
||||
|
@ -2951,7 +2973,7 @@ Object PrimaryExpression() : {
|
|||
|
||||
void ArgumentExpressionList() : {}
|
||||
{
|
||||
AssignmentExpression() ( "," AssignmentExpression() )*
|
||||
[ PragmaSpec() ] AssignmentExpression() ( "," [ PragmaSpec() ] AssignmentExpression() )* [ PragmaSpec() ]
|
||||
}
|
||||
|
||||
Object Constant() : {
|
||||
|
@ -3016,7 +3038,7 @@ Object Constant() : {
|
|||
}
|
||||
}
|
||||
|
|
||||
t = <STRING_LITERAL>
|
||||
t = MultiLineString()
|
||||
{
|
||||
obj = t.image;
|
||||
}
|
||||
|
|
|
@ -663,7 +663,9 @@ public class PreProcessor {
|
|||
}
|
||||
}
|
||||
if (emitExecSwitch == true) {
|
||||
if (marg != null) {
|
||||
setArg(key, marg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1593,13 +1595,13 @@ PPToken LineInfo() : {Token t; Token u;}
|
|||
}
|
||||
|
||||
|
||||
PPToken Define() : {Token t,u=null,v=null,w=null,x=null;Vector dargs = new Vector();}
|
||||
PPToken Define() : {Token t,u=null,v=null,w=null,x=null;Vector dargs = null; }
|
||||
{
|
||||
(LOOKAHEAD(2) // supports current lexer
|
||||
(t=<MANIFEST>
|
||||
[LOOKAHEAD(2) ((u=MacroArgs(){dargs.add(u);})+ | u=MacroVals() )
|
||||
[LOOKAHEAD(2) ({u=new Token(); if (dargs==null) { dargs = new Vector(); }} ( u=MacroArgs() { dargs.add(u);})* <MACROARGSEND> | u=MacroVals() )
|
||||
[(w=MacroVals(){ if (x==null) {
|
||||
if (dargs.size()>0) {
|
||||
if (dargs != null) {
|
||||
x=w;
|
||||
} else {
|
||||
x=u;x.image+=w.image;
|
||||
|
@ -1612,11 +1614,11 @@ PPToken Define() : {Token t,u=null,v=null,w=null,x=null;Vector dargs = new Vecto
|
|||
)+] ] ) |
|
||||
LOOKAHEAD(2) // questionable
|
||||
(t=<MANIFEST>
|
||||
u=MacroArgs(){dargs.add(u);}
|
||||
u=MacroArgs(){if (dargs==null) { dargs = new Vector(); } dargs.add(u);}
|
||||
[LOOKAHEAD(2)v=Define()]) |
|
||||
LOOKAHEAD(2) // questionable
|
||||
(t=<MANIFEST>
|
||||
[ (u=MacroArgs(){dargs.add(u);})+
|
||||
[ (u=MacroArgs(){if (dargs==null) { dargs = new Vector(); } dargs.add(u);})+
|
||||
[v=MacroVals()] ]) |
|
||||
(t=<MANIFEST> // questionable
|
||||
(<WS>)+ u=Define() )
|
||||
|
@ -1635,7 +1637,7 @@ PPToken Define() : {Token t,u=null,v=null,w=null,x=null;Vector dargs = new Vecto
|
|||
setDef(pt,pv);
|
||||
printCommentedLines(emitExecSwitch, "#define " + pt.image + " " + pv.image, "" + "DEFINED");
|
||||
} else if (u!=null) {
|
||||
if (dargs.size()>0) {
|
||||
if (dargs != null) {
|
||||
PPToken pv=new PPToken("");
|
||||
setMacro(pt,dargs,pv);
|
||||
printCommentedLines(emitExecSwitch, "#define " + pt.image + "("+dargs+") " + pv.image, "" + "DEFINED");
|
||||
|
@ -1648,7 +1650,7 @@ PPToken Define() : {Token t,u=null,v=null,w=null,x=null;Vector dargs = new Vecto
|
|||
} else {
|
||||
if (verboseLevel==5||verboseLevel==6) println("PreProcessor: "+curFileStackTop()+"'"+t.beginLine+": "+t.image+" aready defined. Undefine first.");
|
||||
}
|
||||
if (dargs!=null&&dargs.size()==0) dargs = null;
|
||||
|
||||
return pt;
|
||||
}
|
||||
}
|
||||
|
@ -2798,7 +2800,8 @@ TOKEN:
|
|||
<MACROARGS>
|
||||
TOKEN : {
|
||||
<MACROMV: <MANIFEST> > |
|
||||
<MACROMVTAG: "[" <MANIFEST > "]" >
|
||||
<MACROMVTAG: "[" <MANIFEST > "]" > |
|
||||
<MACROARGSEND: ")"> : MACROVALS
|
||||
}
|
||||
|
||||
<MACROARGS>
|
||||
|
@ -2806,7 +2809,7 @@ SKIP : {
|
|||
<_ECMT5: <CMT><ECMT>(~["*"])* "*" ("*" | ~["*","/"] (~["*"])* "*")* "/"> : MACROARGS |
|
||||
<_CMT5: <CMT><CMT>(~["\n","\r"])+ > : MACROARGS |
|
||||
<_MWSP: ","> : MACROARGS |
|
||||
<_EWSP: ")"> : MACROVALS |
|
||||
|
||||
<_COD3: <COD> > : MACROARGS |
|
||||
<_MACWSP: <WSP>> : MACROARGS
|
||||
}
|
||||
|
|
|
@ -81,6 +81,8 @@ public class PreProcessorTest extends AbstractGenericTest {
|
|||
catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
System.out.println(parser.getParseMessages());
|
||||
|
||||
// Uncomment to print out parse results
|
||||
// System.err.println(baos.toString());
|
||||
|
@ -106,6 +108,9 @@ public class PreProcessorTest extends AbstractGenericTest {
|
|||
|
||||
assertTrue("macro expansion _fpl(bob) failed ", results
|
||||
.indexOf("extern int __declspec(\"fp(\\\"l\\\", \" #bob \")\") __ifplbob;") != -1);
|
||||
|
||||
assertTrue("Expanded protected macro with args", results.contains("int (getc)(FILE * );"));
|
||||
assertTrue("Expanded protected macro with args", results.contains("int (getchar)(void);"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -18,13 +18,32 @@
|
|||
** Some data types are checked. More checking of the parsed information would be beneficial at some point.
|
||||
**/
|
||||
|
||||
|
||||
/**
|
||||
* Check initial anonymous __func_1, is give an name blarg
|
||||
* Note: This must be first function for junit tests to pass
|
||||
**/
|
||||
|
||||
void blarg(int *, long[][][]);
|
||||
|
||||
|
||||
/**
|
||||
** Function typedef use in function body
|
||||
**/
|
||||
typedef int ExternFunc(int);
|
||||
|
||||
void testFunc()
|
||||
{
|
||||
ExternFunc * func = (ExternFunc*)0;
|
||||
}
|
||||
|
||||
void testFunc()
|
||||
{
|
||||
typedef int InternFunc(int);
|
||||
|
||||
// TODO InternFunc * func = (InternFunc *) 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test arrays of anonymous functions in a structure
|
||||
**/
|
||||
|
@ -39,6 +58,7 @@ typedef struct SomeStruct {
|
|||
int finalMember;
|
||||
} SomeStruct;
|
||||
|
||||
|
||||
/**
|
||||
* Test forward declaration
|
||||
**/
|
||||
|
@ -53,6 +73,19 @@ typedef struct SomeStruct {
|
|||
} ThatStruct;
|
||||
|
||||
|
||||
/**
|
||||
* Test name used as field
|
||||
*/
|
||||
struct fieldname {
|
||||
unsigned char a, b, c;
|
||||
};
|
||||
|
||||
struct mainname {
|
||||
unsigned int field1;
|
||||
struct fieldname fieldname[256]; // field with same name as struct name
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Anonymous function parameter definitions
|
||||
**/
|
||||
|
@ -152,6 +185,27 @@ int (__stdcall * GetSectionBlock) (
|
|||
#pragma GCC poison (*(volatile uint8_t *)(0xB3))
|
||||
|
||||
#pragma our macros nachos (for use only within FileProvider.h)
|
||||
|
||||
#pragma warning (suppress: 28128)
|
||||
|
||||
int g(int a, int b, int c)
|
||||
{
|
||||
return a+b+c;
|
||||
}
|
||||
int f(void)
|
||||
{
|
||||
return g(1,
|
||||
2,3);
|
||||
}
|
||||
|
||||
int f(void)
|
||||
{
|
||||
return g(1,
|
||||
#pragma warning (suppress: 28128)
|
||||
2,3);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
** Packing tests
|
||||
|
@ -734,6 +788,23 @@ HandleToHandle64(
|
|||
return((void * __ptr64) h );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test const before / after TypeName
|
||||
**/
|
||||
typedef long long TEST_TYPE_A;
|
||||
|
||||
void funcA(TEST_TYPE_A const * arg);
|
||||
|
||||
void funcB(void)
|
||||
{
|
||||
funcA((const TEST_TYPE_A *)0);
|
||||
}
|
||||
|
||||
void funcB(void)
|
||||
{
|
||||
funcA((TEST_TYPE_A const *)0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
** pragma usage
|
||||
|
@ -1062,6 +1133,21 @@ unsigned char _interlockedbittestandset64(long long volatile *Base, long long Of
|
|||
|
||||
/**/
|
||||
|
||||
/**
|
||||
** Multi-Line String constants
|
||||
**/
|
||||
|
||||
void singleLineStrings(void)
|
||||
{
|
||||
char a[] = "Hello " "World";
|
||||
}
|
||||
void multilineStrings(void)
|
||||
{
|
||||
char b[] = "This is a "
|
||||
"multiline string.";
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
** #line in structure/function body
|
||||
|
|
|
@ -392,6 +392,27 @@ ldp LDP((
|
|||
_Pragma("clang diagnostic push") \
|
||||
_Pragma("clang diagnostic ignored \"-Wmismatched-tags\"")
|
||||
|
||||
/**
|
||||
** Protected from macro expansion
|
||||
**/
|
||||
|
||||
#define stdin (&__iob[0])
|
||||
#define stdout (&__iob[1])
|
||||
|
||||
int __filbuf(FILE * /*stream*/);
|
||||
|
||||
#define getc(p) \
|
||||
(--((p)->__icnt) >= 0 ? *((p)->__ptr)++ : __filbuf(p))
|
||||
#ifndef __cplusplus
|
||||
int (getc)(FILE * /*stream*/);
|
||||
#endif
|
||||
|
||||
#define getchar() getc(stdin)
|
||||
#ifndef __cplusplus
|
||||
int (getchar)(void);
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
** Vararg defined
|
||||
**/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue