mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-28 23:21:46 +00:00
GP-1744_emteere CParser fixes for Macros, pragma(push), reincluded header files, unicode BOM files, #if/defined() on values, and full evaluation of macro expansion. Added output of more information in CParser prefixed with /// comments. Reparsed current standard data archives with correct 64/32 data organizations. Use dtMgr for all new data types in preparation for Data Organization changes.
This commit is contained in:
parent
026fad27ab
commit
33fe035d84
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -27,6 +27,8 @@ import ghidra.util.Msg;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class DefineTable {
|
public class DefineTable {
|
||||||
|
private static final int ARBITRARY_MAX_REPLACEMENTS = 900000;
|
||||||
|
|
||||||
// Hastable for storing #defs
|
// Hastable for storing #defs
|
||||||
Hashtable<String, PPToken> defs = new Hashtable<String, PPToken>();
|
Hashtable<String, PPToken> defs = new Hashtable<String, PPToken>();
|
||||||
|
|
||||||
@ -267,40 +269,32 @@ public class DefineTable {
|
|||||||
* return a string with all the macros substitute starting at pos in the input string.
|
* return a string with all the macros substitute starting at pos in the input string.
|
||||||
* @param image string to expand
|
* @param image string to expand
|
||||||
* @param pos position within string to start expanding
|
* @param pos position within string to start expanding
|
||||||
* @return
|
* @return string with all substitutions applied
|
||||||
*/
|
*/
|
||||||
private String macroSub(String image, int pos, ArrayList<String> sublist) {
|
private String macroSub(String image, int pos, ArrayList<String> sublist) {
|
||||||
int replaceCount = 0;
|
int replaceCount = 0;
|
||||||
|
|
||||||
StringBuffer buf = new StringBuffer(image);
|
StringBuffer buf = new StringBuffer(image);
|
||||||
|
int lastReplPos = pos;
|
||||||
|
|
||||||
// don't replace an infinite number of times.
|
// don't replace an infinite number of times. Fail safe for possible ininite loop
|
||||||
//HashMap<String,Integer> lastReplStrings = new HashMap<String,Integer>();
|
while (pos < buf.length() && replaceCount < ARBITRARY_MAX_REPLACEMENTS) {
|
||||||
while (pos < buf.length() && replaceCount < 900000) {
|
// clear list of used macros when move past replacement area
|
||||||
|
if (pos == lastReplPos) {
|
||||||
|
sublist = new ArrayList<String> (); // ok to clear list of used macro names
|
||||||
|
}
|
||||||
String defName = getDefineAt(buf, pos);
|
String defName = getDefineAt(buf, pos);
|
||||||
if (shouldReplace(buf, defName, pos)) {
|
if (shouldReplace(buf, defName, pos)) {
|
||||||
// stop recursion on the same replacement string
|
// stop recursion on the same replacement string
|
||||||
// if (lastReplStrings.containsKey(defName)) {
|
int replPos = replace(buf, defName, pos, sublist);
|
||||||
// int lastpos = lastReplStrings.get(defName);
|
|
||||||
// Vector<PPToken> argv = getArgs(defName);
|
if (replPos == -1) {
|
||||||
// // if it has no args, don't replace already replaced.
|
// if no replacement string, move on
|
||||||
// if (argv == null && pos < lastpos) {
|
|
||||||
// System.out.println("Already did : " + defName);
|
|
||||||
// System.out.println(" No repl at " + pos + " lastpos " + lastpos + " : " + buf);
|
|
||||||
// pos++;
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
// lastReplStrings.remove(defName);
|
|
||||||
// }
|
|
||||||
int newpos = replace(buf, defName, pos, sublist);
|
|
||||||
// is there a replacement string
|
|
||||||
if (newpos == -1) {
|
|
||||||
pos++;
|
pos++;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
//System.err.println(" replace " + defName + " with " + buf.substring(pos,newpos));
|
// replaced text, update the last place a replacement was made
|
||||||
//lastReplStrings.put(defName,pos + defName.length());
|
lastReplPos = replPos;
|
||||||
pos = newpos;
|
|
||||||
replaceCount++;
|
replaceCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -308,7 +302,7 @@ public class DefineTable {
|
|||||||
pos++;
|
pos++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (replaceCount >= 100000) {
|
if (replaceCount >= ARBITRARY_MAX_REPLACEMENTS) {
|
||||||
System.err.println(" replace " + image + " hit limit");
|
System.err.println(" replace " + image + " hit limit");
|
||||||
}
|
}
|
||||||
return buf.toString();
|
return buf.toString();
|
||||||
@ -319,7 +313,6 @@ public class DefineTable {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//String nextRepl = "";
|
|
||||||
int currIndex = buf.indexOf(defName, pos);
|
int currIndex = buf.indexOf(defName, pos);
|
||||||
if (currIndex < 0) {
|
if (currIndex < 0) {
|
||||||
return false; // nothing to replace
|
return false; // nothing to replace
|
||||||
@ -342,25 +335,6 @@ public class DefineTable {
|
|||||||
return false; // no need to replace
|
return false; // no need to replace
|
||||||
}
|
}
|
||||||
|
|
||||||
// // check that macro argv arguments match
|
|
||||||
// Vector<PPToken> argv = getArgs(defName);
|
|
||||||
// if (argv != null && argv.size() > 0) {
|
|
||||||
// // need to scan carefully, and recursively
|
|
||||||
// // there shouldn't be so many globals...
|
|
||||||
// // could be screwed up by so many things
|
|
||||||
// String parms = getParams(buf, currIndex + defName.length(),
|
|
||||||
// (char) 0);
|
|
||||||
//
|
|
||||||
// int parmslen = parms.length();
|
|
||||||
// if (parmslen < 2) {
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
// parms = parms.trim();
|
|
||||||
// if (!parms.startsWith("(") || !parms.endsWith(")")) {
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -423,19 +397,9 @@ public class DefineTable {
|
|||||||
|
|
||||||
replacedSubpieceLen += parmslen;
|
replacedSubpieceLen += parmslen;
|
||||||
}
|
}
|
||||||
// you may add an else if{} block to warn of malformed macros
|
|
||||||
// but the actual culprit may be the Define() non-terminal
|
|
||||||
//if (replString != null)
|
|
||||||
// nextRepl += replString;
|
|
||||||
|
|
||||||
sublist = new ArrayList<String>(sublist);
|
|
||||||
sublist.add(currKey);
|
sublist.add(currKey);
|
||||||
String newReplString = macroSub(replacementString, 0, sublist);
|
|
||||||
if (newReplString != null) {
|
|
||||||
replacementString = newReplString;
|
|
||||||
}
|
|
||||||
buf.replace(currIndex, currIndex + replacedSubpieceLen, replacementString);
|
buf.replace(currIndex, currIndex + replacedSubpieceLen, replacementString);
|
||||||
//nextRepl += image.substring(currIndex + currKey.length());
|
|
||||||
return currIndex + replacementString.length();
|
return currIndex + replacementString.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -543,19 +507,25 @@ public class DefineTable {
|
|||||||
if (pos >= len) {
|
if (pos >= len) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
char ch = buf.charAt(pos);
|
char ch = buf.charAt(pos);
|
||||||
|
char lastChar = 0;
|
||||||
boolean hitQuote = false;
|
boolean hitQuote = false;
|
||||||
|
boolean hitTick = false;
|
||||||
|
|
||||||
while (pos < len) {
|
while (pos < len) {
|
||||||
ch = buf.charAt(pos++);
|
ch = buf.charAt(pos++);
|
||||||
if (ch == '"') {
|
if (ch == '"' && lastChar != '\\') {
|
||||||
hitQuote = !hitQuote;
|
hitQuote = !hitQuote;
|
||||||
}
|
}
|
||||||
if (!hitQuote && ch == endChar && depth == 0) {
|
if (ch == '\'' && lastChar != '\\') {
|
||||||
|
hitTick = !hitTick;
|
||||||
|
}
|
||||||
|
if (!(hitQuote||hitTick) && ch == endChar && depth == 0) {
|
||||||
pos--;
|
pos--;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!hitQuote && ch == ')') {
|
if (!(hitQuote||hitTick) && ch == ')') {
|
||||||
depth--;
|
depth--;
|
||||||
if (depth == 0 && endChar == 0) {
|
if (depth == 0 && endChar == 0) {
|
||||||
break;
|
break;
|
||||||
@ -566,9 +536,10 @@ public class DefineTable {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!hitQuote && ch == '(') {
|
if (!(hitQuote||hitTick) && ch == '(') {
|
||||||
depth++;
|
depth++;
|
||||||
}
|
}
|
||||||
|
lastChar = ch;
|
||||||
}
|
}
|
||||||
return buf.substring(start, pos);
|
return buf.substring(start, pos);
|
||||||
}
|
}
|
||||||
|
@ -52,8 +52,22 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
options {
|
options {
|
||||||
|
// Methods and class variables should not be static to allow multiple parsers to be in use.
|
||||||
|
// This is at the expense of some speed.
|
||||||
STATIC= false;
|
STATIC= false;
|
||||||
|
|
||||||
|
// Don't interpret unicode escape sequences, they can appear in embedded text in macros and strings,
|
||||||
|
// which if interpreted can mess up parsing if they are pre-interpreted by the input stream.
|
||||||
|
JAVA_UNICODE_ESCAPE = false;
|
||||||
|
|
||||||
|
// However, if the file has real embedded unicode characters, such as some microsoft header files,
|
||||||
|
// they need to be read correctly by the parser. An example is the embedded code at the beginning
|
||||||
|
// of a file that states that it is in unicode. The characters might be all ascii, which for parsing
|
||||||
|
// purposes is most likely the case.
|
||||||
|
UNICODE_INPUT = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -89,9 +103,12 @@ public class CParser {
|
|||||||
private Map<String, DataType> enums = new HashMap<String, DataType>();
|
private Map<String, DataType> enums = new HashMap<String, DataType>();
|
||||||
|
|
||||||
private Map<String, DataType> declarations = new HashMap<String, DataType>();
|
private Map<String, DataType> declarations = new HashMap<String, DataType>();
|
||||||
|
|
||||||
|
private Map<String, DataType> internalTypes = new HashMap<String, DataType>();
|
||||||
|
|
||||||
private DataType lastDataType = null;
|
private DataType lastDataType = null;
|
||||||
private boolean storeNewDT = true;
|
private boolean storeNewDT = true;
|
||||||
|
private String possiblyUndefinedType = null;
|
||||||
|
|
||||||
DataTypeManager dtMgr = null;
|
DataTypeManager dtMgr = null;
|
||||||
private DataTypeManager[] subDTMgrs = new DataTypeManager[0];
|
private DataTypeManager[] subDTMgrs = new DataTypeManager[0];
|
||||||
@ -181,7 +198,7 @@ public class CParser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dt = new TypedefDataType(type, dt);
|
dt = new TypedefDataType(CategoryPath.ROOT, type, dt, dtMgr);
|
||||||
dt = addDef(types, type, dt);
|
dt = addDef(types, type, dt);
|
||||||
return dt;
|
return dt;
|
||||||
}
|
}
|
||||||
@ -223,6 +240,7 @@ public class CParser {
|
|||||||
return dt;
|
return dt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
possiblyUndefinedType = type;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -320,6 +338,20 @@ public class CParser {
|
|||||||
table.put(name, dt);
|
table.put(name, dt);
|
||||||
return dt;
|
return dt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// resolve data types using data type manager so that data organization is considered
|
||||||
|
//
|
||||||
|
private DataType resolveInternal(DataType datatype) {
|
||||||
|
DataType existingDT = internalTypes.get(datatype.getName());
|
||||||
|
if (existingDT != null) {
|
||||||
|
return existingDT;
|
||||||
|
}
|
||||||
|
existingDT = datatype.copy(dtMgr);
|
||||||
|
|
||||||
|
internalTypes.put(datatype.getName(), existingDT);
|
||||||
|
|
||||||
|
return existingDT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// rename a data type in the given table
|
// rename a data type in the given table
|
||||||
@ -440,7 +472,7 @@ public class CParser {
|
|||||||
if (currentFuncDT != null) {
|
if (currentFuncDT != null) {
|
||||||
return currentFuncDT;
|
return currentFuncDT;
|
||||||
}
|
}
|
||||||
return new FunctionDefinitionDataType(ANONYMOUS_FUNC_PREFIX+func_cnt++);
|
return new FunctionDefinitionDataType(CategoryPath.ROOT, ANONYMOUS_FUNC_PREFIX+func_cnt++, dtMgr);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkReturnDataType(DataType retDT) throws ParseException {
|
private void checkReturnDataType(DataType retDT) throws ParseException {
|
||||||
@ -688,7 +720,9 @@ public class CParser {
|
|||||||
if (headerFileName != null) {
|
if (headerFileName != null) {
|
||||||
parseMessage += " in " + headerFileName + " near line " + subLinenum + "\n";
|
parseMessage += " in " + headerFileName + " near line " + subLinenum + "\n";
|
||||||
}
|
}
|
||||||
|
parseMessage += "Error: " + e.getMessage() + "\n";
|
||||||
parseMessage += " near token: " + e.currentToken + "\n";
|
parseMessage += " near token: " + e.currentToken + "\n";
|
||||||
|
parseMessage += "Possibly Undefined : " + possiblyUndefinedType + "\n";
|
||||||
parseMessage += " Last Valid Datatype: "
|
parseMessage += " Last Valid Datatype: "
|
||||||
+ (lastDataType == null ? "- none -" : lastDataType.getDisplayName()) + "\n";
|
+ (lastDataType == null ? "- none -" : lastDataType.getDisplayName()) + "\n";
|
||||||
parseMessage += " Check around CParserPlugin.out around line: "
|
parseMessage += " Check around CParserPlugin.out around line: "
|
||||||
@ -800,7 +834,9 @@ TOKEN_MGR_DECLS :
|
|||||||
|
|
||||||
SKIP :
|
SKIP :
|
||||||
{
|
{
|
||||||
" "
|
"\ufeff" // BOM character at beginning of file
|
||||||
|
|
|
||||||
|
" "
|
||||||
|
|
|
|
||||||
"\f"
|
"\f"
|
||||||
|
|
|
|
||||||
@ -1262,7 +1298,7 @@ DataType ObjcDef() : {
|
|||||||
{
|
{
|
||||||
( nameTok=<OBJC_IDENTIFIER> ) ( <OBJC_IDENTIFIER> | <OBJC_IGNORE> | <OBJC2_IGNORE> )* ( <OBJC_SEMI> | <OBJC2_END> )
|
( nameTok=<OBJC_IDENTIFIER> ) ( <OBJC_IDENTIFIER> | <OBJC_IGNORE> | <OBJC2_IGNORE> )* ( <OBJC_SEMI> | <OBJC2_END> )
|
||||||
{
|
{
|
||||||
return addTypedef(nameTok.image, VoidDataType.dataType);
|
return addTypedef(nameTok.image, resolveInternal(VoidDataType.dataType));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1381,33 +1417,33 @@ Declaration BuiltInTypeSpecifier(Declaration dec) : {
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
(
|
(
|
||||||
<VOID> { dec.setDataType(VoidDataType.dataType); }
|
<VOID> { dec.setDataType(resolveInternal(VoidDataType.dataType)); }
|
||||||
|
|
|
|
||||||
<CHAR> { dt = dec.getDataType();
|
<CHAR> { dt = dec.getDataType();
|
||||||
if (dt != null) {
|
if (dt != null) {
|
||||||
if (dt == UnsignedIntegerDataType.dataType) {
|
if (dt == resolveInternal(UnsignedIntegerDataType.dataType)) {
|
||||||
dt = UnsignedCharDataType.dataType;
|
dt = resolveInternal(UnsignedCharDataType.dataType);
|
||||||
} else if (dt == IntegerDataType.dataType) {
|
} else if (dt == resolveInternal(IntegerDataType.dataType)) {
|
||||||
dt = CharDataType.dataType;
|
dt = resolveInternal(CharDataType.dataType);
|
||||||
} else {
|
} else {
|
||||||
throw new ParseException("Bad datatype " + dt + " char");
|
throw new ParseException("Bad datatype " + dt + " char");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
dt = CharDataType.dataType;
|
dt = resolveInternal(CharDataType.dataType);
|
||||||
}
|
}
|
||||||
dec.setDataType(dt);
|
dec.setDataType(dt);
|
||||||
}
|
}
|
||||||
|
|
|
|
||||||
<WCHAR> { dec.setDataType(WideCharDataType.dataType); }
|
<WCHAR> { dec.setDataType(resolveInternal(WideCharDataType.dataType)); }
|
||||||
|
|
|
|
||||||
<SHORT> { dt = dec.getDataType();
|
<SHORT> { dt = dec.getDataType();
|
||||||
if (dt == null) {
|
if (dt == null) {
|
||||||
dt = ShortDataType.dataType;
|
dt = resolveInternal(ShortDataType.dataType);
|
||||||
} else if (dt == UnsignedIntegerDataType.dataType) {
|
} else if (dt == resolveInternal(UnsignedIntegerDataType.dataType)) {
|
||||||
dt = UnsignedShortDataType.dataType;
|
dt = resolveInternal(UnsignedShortDataType.dataType);
|
||||||
} else if (dt == IntegerDataType.dataType) {
|
} else if (dt == resolveInternal(IntegerDataType.dataType)) {
|
||||||
dt = ShortDataType.dataType;
|
dt = resolveInternal(ShortDataType.dataType);
|
||||||
} else {
|
} else {
|
||||||
throw new ParseException("Bad datatype " + dt + " short");
|
throw new ParseException("Bad datatype " + dt + " short");
|
||||||
}
|
}
|
||||||
@ -1420,21 +1456,21 @@ Declaration BuiltInTypeSpecifier(Declaration dec) : {
|
|||||||
|
|
|
|
||||||
<INT> { dt = dec.getDataType();
|
<INT> { dt = dec.getDataType();
|
||||||
if (dt == null ) {
|
if (dt == null ) {
|
||||||
dec.setDataType(IntegerDataType.dataType);
|
dec.setDataType(resolveInternal(IntegerDataType.dataType));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
|
||||||
<LONG> { dt = dec.getDataType();
|
<LONG> { dt = dec.getDataType();
|
||||||
if ( dt == null) {
|
if ( dt == null) {
|
||||||
dt = LongDataType.dataType;
|
dt = resolveInternal(LongDataType.dataType);
|
||||||
} else if ( dt == UnsignedIntegerDataType.dataType) {
|
} else if ( dt == resolveInternal(UnsignedIntegerDataType.dataType)) {
|
||||||
dt = UnsignedLongDataType.dataType;
|
dt = resolveInternal(UnsignedLongDataType.dataType);
|
||||||
} else if (dt == IntegerDataType.dataType) {
|
} else if (dt == resolveInternal(IntegerDataType.dataType)) {
|
||||||
dt = LongDataType.dataType;
|
dt = resolveInternal(LongDataType.dataType);
|
||||||
} else if (dt == LongDataType.dataType) {
|
} else if (dt == resolveInternal(LongDataType.dataType)) {
|
||||||
dt = LongLongDataType.dataType;
|
dt = resolveInternal(LongLongDataType.dataType);
|
||||||
} else if (dt == UnsignedLongDataType.dataType) {
|
} else if (dt == resolveInternal(UnsignedLongDataType.dataType)) {
|
||||||
dt = UnsignedLongLongDataType.dataType;
|
dt = resolveInternal(UnsignedLongLongDataType.dataType);
|
||||||
} else {
|
} else {
|
||||||
throw new ParseException("Bad datatype " + dt + " long");
|
throw new ParseException("Bad datatype " + dt + " long");
|
||||||
}
|
}
|
||||||
@ -1447,20 +1483,20 @@ Declaration BuiltInTypeSpecifier(Declaration dec) : {
|
|||||||
|
|
|
|
||||||
<FLOAT> { dt = dec.getDataType();
|
<FLOAT> { dt = dec.getDataType();
|
||||||
if ( dt == null) {
|
if ( dt == null) {
|
||||||
dt = FloatDataType.dataType;
|
dt = resolveInternal(FloatDataType.dataType);
|
||||||
} else if ( dt == LongDataType.dataType) {
|
} else if ( dt == resolveInternal(LongDataType.dataType)) {
|
||||||
dt = DoubleDataType.dataType;
|
dt = resolveInternal(DoubleDataType.dataType);
|
||||||
} else {
|
} else {
|
||||||
throw new ParseException("Bad datatype " + dt + " long");
|
throw new ParseException("Bad datatype " + dt + " long");
|
||||||
}
|
}
|
||||||
dec.setDataType(dt);
|
dec.setDataType(dt);
|
||||||
}
|
}
|
||||||
|
|
|
|
||||||
<DOUBLE> { dec.setDataType(new DoubleDataType()); }
|
<DOUBLE> { dec.setDataType(resolveInternal(DoubleDataType.dataType)); }
|
||||||
|
|
|
|
||||||
<SIGNED> { dt = dec.getDataType();
|
<SIGNED> { dt = dec.getDataType();
|
||||||
if ( dt == null) {
|
if ( dt == null) {
|
||||||
dt = IntegerDataType.dataType;
|
dt = resolveInternal(IntegerDataType.dataType);
|
||||||
} else {
|
} else {
|
||||||
// data type already set, don't do anything?
|
// data type already set, don't do anything?
|
||||||
dt = dt;
|
dt = dt;
|
||||||
@ -1475,13 +1511,13 @@ Declaration BuiltInTypeSpecifier(Declaration dec) : {
|
|||||||
|
|
|
|
||||||
<UNSIGNED> { dt = dec.getDataType();
|
<UNSIGNED> { dt = dec.getDataType();
|
||||||
if ( dt == null) {
|
if ( dt == null) {
|
||||||
dt = UnsignedIntegerDataType.dataType;
|
dt = resolveInternal(UnsignedIntegerDataType.dataType);
|
||||||
} else if (dt == ShortDataType.dataType) {
|
} else if (dt == resolveInternal(ShortDataType.dataType)) {
|
||||||
dt = UnsignedShortDataType.dataType;
|
dt = resolveInternal(UnsignedShortDataType.dataType);
|
||||||
} else if (dt == LongDataType.dataType) {
|
} else if (dt == resolveInternal(LongDataType.dataType)) {
|
||||||
dt = UnsignedLongDataType.dataType;
|
dt = resolveInternal(UnsignedLongDataType.dataType);
|
||||||
} else if (dt == LongLongDataType.dataType) {
|
} else if (dt == resolveInternal(LongLongDataType.dataType)) {
|
||||||
dt = UnsignedLongLongDataType.dataType;
|
dt = resolveInternal(UnsignedLongLongDataType.dataType);
|
||||||
} else {
|
} else {
|
||||||
throw new ParseException("Bad datatype " + dt + " unsigned");
|
throw new ParseException("Bad datatype " + dt + " unsigned");
|
||||||
}
|
}
|
||||||
@ -1492,13 +1528,13 @@ Declaration BuiltInTypeSpecifier(Declaration dec) : {
|
|||||||
dec = BuiltInDeclarationSpecifier(dec)
|
dec = BuiltInDeclarationSpecifier(dec)
|
||||||
]
|
]
|
||||||
|
|
|
|
||||||
<INT8> { dec.setDataType(SignedByteDataType.dataType); }
|
<INT8> { dec.setDataType(resolveInternal(SignedByteDataType.dataType)); }
|
||||||
|
|
|
|
||||||
<INT16> { dec.setDataType(ShortDataType.dataType); }
|
<INT16> { dec.setDataType(resolveInternal(ShortDataType.dataType)); }
|
||||||
|
|
|
|
||||||
<INT32> { dec.setDataType(IntegerDataType.dataType); }
|
<INT32> { dec.setDataType(resolveInternal(IntegerDataType.dataType)); }
|
||||||
|
|
|
|
||||||
<INT64> { dec.setDataType(LongLongDataType.dataType); }
|
<INT64> { dec.setDataType(resolveInternal(LongLongDataType.dataType)); }
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return dec;
|
return dec;
|
||||||
@ -1631,8 +1667,7 @@ void PragmaSpecifier() : {
|
|||||||
packSize = popPack(ID);
|
packSize = popPack(ID);
|
||||||
newPackVal = null;
|
newPackVal = null;
|
||||||
}
|
}
|
||||||
else if (ds1.image.equals("push")) {
|
else if (ds1.image.equals("push") && ds2 != null) {
|
||||||
// push current and set value
|
|
||||||
try {
|
try {
|
||||||
// check if second arg is an integer
|
// check if second arg is an integer
|
||||||
int ival = Integer.parseInt(ds2.image);
|
int ival = Integer.parseInt(ds2.image);
|
||||||
@ -1750,7 +1785,7 @@ DataType StructOrUnionSpecifier() : {
|
|||||||
Composite StructOrUnion() : {Composite comp;}
|
Composite StructOrUnion() : {Composite comp;}
|
||||||
{
|
{
|
||||||
(
|
(
|
||||||
<STRUCT> ( DeclSpec() )* { comp = new StructureDataType(ANONYMOUS_STRUCT_PREFIX + cnt++, 0);
|
<STRUCT> ( DeclSpec() | PragmaSpec() )* { comp = new StructureDataType(CategoryPath.ROOT, ANONYMOUS_STRUCT_PREFIX + cnt++, 0, dtMgr);
|
||||||
|
|
||||||
// Always set the packing, because by default structures should be aligned
|
// Always set the packing, because by default structures should be aligned
|
||||||
if (packSize > 0) {
|
if (packSize > 0) {
|
||||||
@ -1762,7 +1797,7 @@ Composite StructOrUnion() : {Composite comp;}
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
|
||||||
<UNION> ( DeclSpec() )* { comp = new UnionDataType(ANONYMOUS_UNION_PREFIX + cnt++);
|
<UNION> ( DeclSpec() )* { comp = new UnionDataType(CategoryPath.ROOT, ANONYMOUS_UNION_PREFIX + cnt++, dtMgr);
|
||||||
|
|
||||||
// Always set the packing, because by default structures should be aligned
|
// Always set the packing, because by default structures should be aligned
|
||||||
if (packSize > 0) {
|
if (packSize > 0) {
|
||||||
@ -1821,6 +1856,7 @@ void StructDeclaration(Composite comp, CompositeHandler compositeHandler) : {
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
LineDef() |
|
LineDef() |
|
||||||
|
PragmaSpec() |
|
||||||
(
|
(
|
||||||
[ dt = SpecifierQualifierList() ]
|
[ dt = SpecifierQualifierList() ]
|
||||||
[
|
[
|
||||||
@ -1928,7 +1964,7 @@ DataType EnumSpecifier() : {
|
|||||||
[ t= <IDENTIFIER> ] "{" list= EnumeratorList() "}"
|
[ t= <IDENTIFIER> ] "{" list= EnumeratorList() "}"
|
||||||
{
|
{
|
||||||
String enumName= (t != null ? t.image : ("enum_" + cnt++));
|
String enumName= (t != null ? t.image : ("enum_" + cnt++));
|
||||||
EnumDataType enuum= new EnumDataType(enumName, 4);
|
EnumDataType enuum= new EnumDataType(CategoryPath.ROOT, enumName, 4, dtMgr);
|
||||||
for (EnumMember member : list) {
|
for (EnumMember member : list) {
|
||||||
try {
|
try {
|
||||||
enuum.add(member.name, member.value);
|
enuum.add(member.name, member.value);
|
||||||
@ -2147,7 +2183,7 @@ Declaration ParameterTypeList(FunctionDefinitionDataType funcDT, DataType retDT)
|
|||||||
{
|
{
|
||||||
checkReturnDataType(retDT);
|
checkReturnDataType(retDT);
|
||||||
if (funcDT == null) {
|
if (funcDT == null) {
|
||||||
funcDT= new FunctionDefinitionDataType(ANONYMOUS_FUNC_PREFIX);
|
funcDT= new FunctionDefinitionDataType(CategoryPath.ROOT, ANONYMOUS_FUNC_PREFIX, dtMgr);
|
||||||
}
|
}
|
||||||
funcDT.setVarArgs(varargs!=null);
|
funcDT.setVarArgs(varargs!=null);
|
||||||
ParameterDefinition[] variables= new ParameterDefinition[list.size()];
|
ParameterDefinition[] variables= new ParameterDefinition[list.size()];
|
||||||
@ -2260,13 +2296,13 @@ void Designator() : { }
|
|||||||
"." <IDENTIFIER>
|
"." <IDENTIFIER>
|
||||||
}
|
}
|
||||||
|
|
||||||
DataType TypeName() : {
|
Declaration TypeName() : {
|
||||||
Declaration dt = null;
|
Declaration dec = null;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
dt = SpecifierQualifierList() [ AbstractDeclarator(new Declaration()) ]
|
dec = SpecifierQualifierList() [ dec = AbstractDeclarator(new Declaration(dec)) ]
|
||||||
{
|
{
|
||||||
return dt.getDataType();
|
return dec;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2608,9 +2644,10 @@ Object CastExpression() : {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Object UnaryExpression() : {
|
Object UnaryExpression() : {
|
||||||
DataType dt = null;
|
|
||||||
Object obj = null;
|
Object obj = null;
|
||||||
Token op = null;
|
Token op = null;
|
||||||
|
Token id = null;
|
||||||
|
Declaration dec = null;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
(
|
(
|
||||||
@ -2633,13 +2670,19 @@ Object UnaryExpression() : {
|
|||||||
|
|
|
|
||||||
<SIZEOF>
|
<SIZEOF>
|
||||||
(
|
(
|
||||||
"(" (dt = TypeName() | <IDENTIFIER> | obj = ConstantExpression() ) ")"
|
"(" ( dec = TypeName() | id = <IDENTIFIER> | obj = ConstantExpression() ) ")"
|
||||||
{
|
{
|
||||||
if (dt != null) {
|
if (obj != null && obj instanceof String) {
|
||||||
obj = Long.valueOf(dt.getLength());
|
|
||||||
} else if (obj != null && obj instanceof String) {
|
|
||||||
obj = Long.valueOf(((String) obj).length() - 1); // will include "" plus \0
|
obj = Long.valueOf(((String) obj).length() - 1); // will include "" plus \0
|
||||||
}
|
}
|
||||||
|
else if (dec != null) {
|
||||||
|
obj = Long.valueOf(dec.getDataType().getLength());
|
||||||
|
}
|
||||||
|
else if (id != null) {
|
||||||
|
// TODO: try to look up the type of the identifier
|
||||||
|
// TODO: Throw error if identifier is not defined
|
||||||
|
// may need to actually track declarations!
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -124,12 +124,6 @@ public class CParserTest extends AbstractGenericTest {
|
|||||||
return dtm;
|
return dtm;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testPreProcessor() throws Exception {
|
|
||||||
// TODO: parse a header file with lots of CPP defines, etc
|
|
||||||
// TODO: Do a simple parse to make sure the data came out correctly
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testHeaderParsing() throws Exception {
|
public void testHeaderParsing() throws Exception {
|
||||||
// Uncomment to save the parse results to a GDT file to check out
|
// Uncomment to save the parse results to a GDT file to check out
|
||||||
@ -154,6 +148,11 @@ public class CParserTest extends AbstractGenericTest {
|
|||||||
DataType dt;
|
DataType dt;
|
||||||
String str;
|
String str;
|
||||||
|
|
||||||
|
dt = dtMgr.getDataType(new CategoryPath("/"), "_IO_FILE_complete");
|
||||||
|
Structure sldt = (Structure) dt;
|
||||||
|
DataTypeComponent data3 = sldt.getComponent(2);
|
||||||
|
assertEquals("Computed Array correct", 40, data3.getLength());
|
||||||
|
|
||||||
dt = dtMgr.getDataType(new CategoryPath("/"), "fnptr"); // typedef int (*fnptr)(struct fstruct);
|
dt = dtMgr.getDataType(new CategoryPath("/"), "fnptr"); // typedef int (*fnptr)(struct fstruct);
|
||||||
// "fnptr" named typedef of pointer to "int fnptr(fstruct )" --- should an anonymous function name be used?
|
// "fnptr" named typedef of pointer to "int fnptr(fstruct )" --- should an anonymous function name be used?
|
||||||
|
|
||||||
|
@ -20,24 +20,44 @@ import static org.junit.Assert.*;
|
|||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.*;
|
||||||
|
|
||||||
import generic.test.AbstractGenericTest;
|
import generic.test.AbstractGenericTest;
|
||||||
|
import ghidra.app.util.cparser.CPP.ParseException;
|
||||||
import ghidra.app.util.cparser.CPP.PreProcessor;
|
import ghidra.app.util.cparser.CPP.PreProcessor;
|
||||||
import ghidra.program.model.data.*;
|
import ghidra.program.model.data.*;
|
||||||
import ghidra.program.model.data.Enum;
|
import ghidra.program.model.data.Enum;
|
||||||
|
|
||||||
public class PreProcessorTest extends AbstractGenericTest {
|
public class PreProcessorTest extends AbstractGenericTest {
|
||||||
|
private static String resourceName = "PreProcessorTest.h";
|
||||||
|
private static CategoryPath path = new CategoryPath(new CategoryPath("/PreProcessorTest.h"), "defines");
|
||||||
|
|
||||||
|
// must get rid of after all tests
|
||||||
|
private static StandAloneDataTypeManager dtMgr;
|
||||||
|
private static ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
private static PreProcessor parser;
|
||||||
|
|
||||||
|
long value;
|
||||||
|
String defname;
|
||||||
|
|
||||||
public PreProcessorTest() {
|
public PreProcessorTest() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@BeforeClass
|
||||||
public void testHeaderParsing() throws Exception {
|
public static void init() {
|
||||||
PreProcessor parser = new PreProcessor();
|
URL url = PreProcessorTest.class.getResource(resourceName);
|
||||||
|
|
||||||
|
String[] args = new String[] {"-I"+url.getPath()+"/..","-DFROM_ARG_VALUE=300", "-DFROM_ARG_DEF", "-DFROM_ARG_EMPTY=\"\""};
|
||||||
|
parser = null;
|
||||||
|
try {
|
||||||
|
parser = new PreProcessor(args);
|
||||||
|
}
|
||||||
|
catch (ParseException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
||||||
parser.setOutputStream(baos);
|
parser.setOutputStream(baos);
|
||||||
|
|
||||||
//// String[] args = new String[] {"-I/local/VisualStudio/Windows/v7.0a/Include", "-I/local/VisualStudio/VS12/include", "-D_WIN32", "-D_CRT_SECURE_NO_WARNINGS"};
|
//// String[] args = new String[] {"-I/local/VisualStudio/Windows/v7.0a/Include", "-I/local/VisualStudio/VS12/include", "-D_WIN32", "-D_CRT_SECURE_NO_WARNINGS"};
|
||||||
@ -53,14 +73,25 @@ public class PreProcessorTest extends AbstractGenericTest {
|
|||||||
//// fullName = "adoguids.h";
|
//// fullName = "adoguids.h";
|
||||||
//// parser.parse(fullName);
|
//// parser.parse(fullName);
|
||||||
|
|
||||||
String resourceName = "PreProcessorTest.h";
|
|
||||||
URL url = PreProcessorTest.class.getResource(resourceName);
|
|
||||||
|
|
||||||
parser.parse(url.getFile());
|
parser.parse(url.getFile());
|
||||||
|
|
||||||
// Uncomment to print out parse results
|
// Uncomment to print out parse results
|
||||||
System.err.println(baos.toString());
|
// System.err.println(baos.toString());
|
||||||
|
|
||||||
|
dtMgr = new StandAloneDataTypeManager("parsed");
|
||||||
|
parser.getDefinitions().populateDefineEquates(dtMgr);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void destroy() {
|
||||||
|
dtMgr = null;
|
||||||
|
baos = null;
|
||||||
|
parser = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHeaderParsed() throws Exception {
|
||||||
|
|
||||||
String results = baos.toString("ASCII");
|
String results = baos.toString("ASCII");
|
||||||
int end = results.lastIndexOf(";") + 1;
|
int end = results.lastIndexOf(";") + 1;
|
||||||
String endStr = results.substring(end - 9, end);
|
String endStr = results.substring(end - 9, end);
|
||||||
@ -68,15 +99,15 @@ public class PreProcessorTest extends AbstractGenericTest {
|
|||||||
|
|
||||||
assertTrue("macro expansion _fpl(bob) failed ", results
|
assertTrue("macro expansion _fpl(bob) failed ", results
|
||||||
.indexOf("extern int __declspec(\"fp(\\\"l\\\", \" #bob \")\") __ifplbob;") != -1);
|
.indexOf("extern int __declspec(\"fp(\\\"l\\\", \" #bob \")\") __ifplbob;") != -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDefines() throws Exception {
|
||||||
|
long value;
|
||||||
|
String defname;
|
||||||
|
|
||||||
StandAloneDataTypeManager dtMgr = new StandAloneDataTypeManager("parsed");
|
value = 32516;
|
||||||
parser.getDefinitions().populateDefineEquates(dtMgr);
|
defname = "DefVal1";
|
||||||
|
|
||||||
CategoryPath path = new CategoryPath("/PreProcessorTest.h");
|
|
||||||
path = new CategoryPath(path, "defines");
|
|
||||||
|
|
||||||
long value = 32516;
|
|
||||||
String defname = "DefVal1";
|
|
||||||
checkDefine(dtMgr, path, value, defname);
|
checkDefine(dtMgr, path, value, defname);
|
||||||
|
|
||||||
value = 0x06010000 + 0xf1;
|
value = 0x06010000 + 0xf1;
|
||||||
@ -129,10 +160,145 @@ public class PreProcessorTest extends AbstractGenericTest {
|
|||||||
defname = "isDefineOnValue";
|
defname = "isDefineOnValue";
|
||||||
value = 1;
|
value = 1;
|
||||||
checkDefine(dtMgr, path, value, defname);
|
checkDefine(dtMgr, path, value, defname);
|
||||||
|
|
||||||
|
defname = "DID_EXPANSION";
|
||||||
|
value = 1;
|
||||||
|
checkDefine(dtMgr, path, value, defname);
|
||||||
|
|
||||||
defname = "BIGNUM";
|
defname = "BIGNUM";
|
||||||
value = 64 * 16 + 16;
|
value = 64 * 16 + 16;
|
||||||
checkDefine(dtMgr, path, value, defname);
|
checkDefine(dtMgr, path, value, defname);
|
||||||
|
|
||||||
|
defname = "NEWLINETEST1";
|
||||||
|
value = 1;
|
||||||
|
checkDefine(dtMgr, path, value, defname);
|
||||||
|
|
||||||
|
defname = "NEWLINETEST2";
|
||||||
|
value = 2;
|
||||||
|
checkDefine(dtMgr, path, value, defname);
|
||||||
|
|
||||||
|
defname = "NEWLINETEST3";
|
||||||
|
value = 3;
|
||||||
|
checkDefine(dtMgr, path, value, defname);
|
||||||
|
|
||||||
|
|
||||||
|
defname = "SEPERATORC";
|
||||||
|
String defval = parser.getDef(defname);
|
||||||
|
assertEquals(defval, "','");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDefinesArgValue() {
|
||||||
|
defname = "DID_ARG_VALUE";
|
||||||
|
value = 1;
|
||||||
|
checkDefine(dtMgr, path, value, defname);
|
||||||
|
|
||||||
|
// This is from a -D arg define, not from a file
|
||||||
|
CategoryPath argCategoryPath = new CategoryPath(CategoryPath.ROOT, "defines");
|
||||||
|
defname = "FROM_ARG_VALUE";
|
||||||
|
value = 300;
|
||||||
|
checkDefine(dtMgr, argCategoryPath, value, defname);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDefinesArgEmpty() {
|
||||||
|
defname = "DID_ARG_EMPTY";
|
||||||
|
value = 1;
|
||||||
|
checkDefine(dtMgr, path, value, defname);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDefinesArgDef() {
|
||||||
|
defname = "DID_ARG_DEF";
|
||||||
|
value = 1;
|
||||||
|
checkDefine(dtMgr, path, value, defname);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDefinesArgIsDefValue() {
|
||||||
|
defname = "DID_ARG_ISDEF_VALUE";
|
||||||
|
value = 1;
|
||||||
|
checkDefine(dtMgr, path, value, defname);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDefinesArgIsDefEmpty() {
|
||||||
|
defname = "DID_ARG_ISDEF_EMPTY";
|
||||||
|
value = 1;
|
||||||
|
checkDefine(dtMgr, path, value, defname);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDefinesArgIsDefDef() {
|
||||||
|
defname = "DID_ARG_ISDEF_DEF";
|
||||||
|
value = 1;
|
||||||
|
checkDefine(dtMgr, path, value, defname);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFileDefinesValue() {
|
||||||
|
defname = "DID_FILE_VALUE";
|
||||||
|
value = 1;
|
||||||
|
checkDefine(dtMgr, path, value, defname);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDefinesFileEmpty() {
|
||||||
|
defname = "DID_FILE_EMPTY";
|
||||||
|
value = 1;
|
||||||
|
checkDefine(dtMgr, path, value, defname);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDefinesFileDef() {
|
||||||
|
defname = "DID_FILE_DEF";
|
||||||
|
value = 1;
|
||||||
|
checkDefine(dtMgr, path, value, defname);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDefinesFileIsDefValue() {
|
||||||
|
defname = "DID_FILE_ISDEF_VALUE";
|
||||||
|
value = 1;
|
||||||
|
checkDefine(dtMgr, path, value, defname);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDefinesFileIsDefEmpty() {
|
||||||
|
defname = "DID_FILE_ISDEF_EMPTY";
|
||||||
|
value = 1;
|
||||||
|
checkDefine(dtMgr, path, value, defname);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDefinesFileIsDefDef() {
|
||||||
|
defname = "DID_FILE_ISDEF_DEF";
|
||||||
|
value = 1;
|
||||||
|
checkDefine(dtMgr, path, value, defname);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMultipleInclude() {
|
||||||
|
defname = "INCLUDE1";
|
||||||
|
String defval = parser.getDef(defname);
|
||||||
|
assertNotNull("Had 1 duplicate include", defval);
|
||||||
|
|
||||||
|
defname = "INCLUDE2";
|
||||||
|
defval = parser.getDef(defname);
|
||||||
|
assertNotNull("Had 2 duplicate include", defval);
|
||||||
|
|
||||||
|
defname = "INCLUDE3";
|
||||||
|
defval = parser.getDef(defname);
|
||||||
|
assertNotNull("Had 3 duplicate include", defval);
|
||||||
|
|
||||||
|
defname = "INCLUDE4";
|
||||||
|
defval = parser.getDef(defname);
|
||||||
|
assertNotNull("Had 4 duplicate include", defval);
|
||||||
|
|
||||||
|
defname = "INCLUDE5";
|
||||||
|
defval = parser.getDef(defname);
|
||||||
|
// if a define is not defined, getDef() returns name of define as value
|
||||||
|
assertEquals("No INCLUDE5 define", "INCLUDE5", defval);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkDefine(StandAloneDataTypeManager dtMgr, CategoryPath path, long value,
|
private void checkDefine(StandAloneDataTypeManager dtMgr, CategoryPath path, long value,
|
||||||
|
@ -18,6 +18,26 @@
|
|||||||
** Some data types are checked. More checking of the parsed information would be beneficial at some point.
|
** Some data types are checked. More checking of the parsed information would be beneficial at some point.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
|
void blarg(int *);
|
||||||
|
|
||||||
|
void * foo;
|
||||||
|
|
||||||
|
typedef void *bar;
|
||||||
|
|
||||||
|
typedef int size_t;
|
||||||
|
typedef int pid_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct _IO_FILE_complete
|
||||||
|
{
|
||||||
|
size_t __pad5;
|
||||||
|
int _mode;
|
||||||
|
/* Make sure we don't get into trouble again. */
|
||||||
|
char _unused2[15 * sizeof (int) - 4 * sizeof (void **) - sizeof (size_t)];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
** use of long as an attribute
|
** use of long as an attribute
|
||||||
@ -60,7 +80,7 @@ int (__stdcall * GetSectionBlock) (
|
|||||||
#pragma pack(push, 4)
|
#pragma pack(push, 4)
|
||||||
|
|
||||||
__pragma(pack(push, MyName, 8))
|
__pragma(pack(push, MyName, 8))
|
||||||
struct packed8 {
|
struct __declspec(align(16)) __pragma(warning(push)) __pragma(warning(disable:4845)) __declspec(no_init_all) __pragma(warning(pop)) packed8 {
|
||||||
char a;
|
char a;
|
||||||
short b;
|
short b;
|
||||||
int c;
|
int c;
|
||||||
@ -91,6 +111,10 @@ struct packed1 {
|
|||||||
char a;
|
char a;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#pragma pack(push);
|
||||||
|
#pragma pack(1);
|
||||||
|
#pragma pack(pop);
|
||||||
|
|
||||||
#pragma pack(); // reset to none
|
#pragma pack(); // reset to none
|
||||||
|
|
||||||
struct packed_none {
|
struct packed_none {
|
||||||
|
@ -13,8 +13,125 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* definition coming from -D, should evaluate to true */
|
||||||
|
#if FROM_ARG_VALUE
|
||||||
|
#define DID_ARG_VALUE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if FROM_ARG_DEF
|
||||||
|
#define DID_ARG_DEF 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if FROM_ARG_EMPTY
|
||||||
|
#define DID_ARG_EMPTY 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(FROM_ARG_VALUE)
|
||||||
|
#define DID_ARG_ISDEF_VALUE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(FROM_ARG_DEF)
|
||||||
|
#define DID_ARG_ISDEF_DEF 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(FROM_ARG_EMPTY)
|
||||||
|
#define DID_ARG_ISDEF_EMPTY 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Defined checks from file */
|
||||||
|
#define FROM_FILE_VALUE 300
|
||||||
|
#define FROM_FILE_EMPTY ""
|
||||||
|
#define FROM_FILE_DEF
|
||||||
|
|
||||||
|
#if FROM_FILE_VALUE
|
||||||
|
#define DID_FILE_VALUE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if FROM_FILE_EMPTY
|
||||||
|
#define DID_FILE_EMPTY 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if FROM_FILE_DEF
|
||||||
|
#define DID_FILE_DEF 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(FROM_FILE_VALUE)
|
||||||
|
#define DID_FILE_ISDEF_VALUE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(FROM_FILE_EMPTY)
|
||||||
|
#define DID_FILE_ISDEF_EMPTY 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(FROM_FILE_DEF)
|
||||||
|
#define DID_FILE_ISDEF_DEF 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "multinclude.h"
|
||||||
|
|
||||||
|
#include "multinclude.h"
|
||||||
|
|
||||||
|
#include "multinclude.h"
|
||||||
|
|
||||||
|
#include "multinclude.h"
|
||||||
|
|
||||||
|
#define __TEXT(quote) quote
|
||||||
|
|
||||||
|
#define TEXT(quote) __TEXT(quote)
|
||||||
|
|
||||||
|
#define SEPERATORC TEXT(',')
|
||||||
|
|
||||||
|
#define RtlZeroMemory(Destination,Length) memset((Destination),0,(Length))
|
||||||
|
|
||||||
|
#define ZeroMemory RtlZeroMemory
|
||||||
|
|
||||||
|
|
||||||
|
#define foo ZeroMemory(&Filter->gf_group, sizeof(Filter->gf_group));
|
||||||
|
|
||||||
|
int foo;
|
||||||
|
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#define PTYPE 4
|
||||||
|
|
||||||
|
#define TYPE2 2 /* 2 */
|
||||||
|
#define TYPE3 3 /* 3 */
|
||||||
|
#define TYPE4 4 /* 4 */
|
||||||
|
#define TYPE5 5 /* 5 */
|
||||||
|
#define TYPE6 6 /* 6 */
|
||||||
|
|
||||||
|
#ifndef P1
|
||||||
|
#define P1 \
|
||||||
|
(PTYPE == TYPE3 || \
|
||||||
|
PTYPE == TYPE4 || \
|
||||||
|
PTYPE == TYPE5 )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef P2
|
||||||
|
#define P2 \
|
||||||
|
(PTYPE == TYPE5 || \
|
||||||
|
PTYPE == TYPE6)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef P3
|
||||||
|
#define P3 \
|
||||||
|
(PTYPE == TYPE1 || \
|
||||||
|
PTYPE == TYPE5 )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define PPTYPE(Partition) (Partition)
|
||||||
|
|
||||||
|
#if PPTYPE(P1 | P2 | P3)
|
||||||
|
#define DID_EXPANSION 1
|
||||||
|
#else
|
||||||
|
#define DID_EXPANSION 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifndef _CRTIMP
|
#ifndef _CRTIMP
|
||||||
#define _VCRT_DEFINED_CRTIMP
|
#define _VCRT_DEFINED_CRTIMP
|
||||||
@ -39,6 +156,8 @@
|
|||||||
#error "Too many fish"
|
#error "Too many fish"
|
||||||
#define TOO_MANY_FISH 0
|
#define TOO_MANY_FISH 0
|
||||||
int TooManyFish;
|
int TooManyFish;
|
||||||
|
#else
|
||||||
|
int NotEnoughFish;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define TEST1 one
|
#define TEST1 one
|
||||||
@ -98,10 +217,10 @@ int TEST_FAILED;
|
|||||||
#define AVERSION enum AVERSION
|
#define AVERSION enum AVERSION
|
||||||
AVERSION
|
AVERSION
|
||||||
{
|
{
|
||||||
AVERSION_5 = 1,
|
AVERSION_5 = 1, // version 5
|
||||||
AVERSION_6,
|
AVERSION_6, // version 6
|
||||||
AVERSION_7,
|
AVERSION_7, // version 7
|
||||||
AVERSION_8,
|
AVERSION_8, // version 9
|
||||||
};
|
};
|
||||||
|
|
||||||
#define Group(a,b)
|
#define Group(a,b)
|
||||||
@ -146,7 +265,9 @@ _fpl(bob)
|
|||||||
EXTERN_C const GUID DECLSPEC_SELECTANY name \
|
EXTERN_C const GUID DECLSPEC_SELECTANY name \
|
||||||
= { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
|
= { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
|
||||||
|
|
||||||
BUILD_GUID(LIBID_ADO20,0x##00000200,0x##0000,0x##0010,0x##80,0x##00,0x##00,0x##AA,0x##00,0x##6D,0x##2E,0x##A4)
|
BUILD_GUID(LIBID_ADO20,0x##00000200,0x##0000,
|
||||||
|
0x##0010,0x##80,0x##00,0x##00,
|
||||||
|
0x##AA,0x##00,0x##6D,0x##2E,0x##A4)
|
||||||
|
|
||||||
|
|
||||||
#define ___POSIX_C_DEPRECATED_STARTING_199506L
|
#define ___POSIX_C_DEPRECATED_STARTING_199506L
|
||||||
@ -276,5 +397,26 @@ int does_not_has_include();
|
|||||||
# include_next <float.h>
|
# include_next <float.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
#define NEWLINETEST1 0 // uh oh
|
||||||
|
#else
|
||||||
|
#define NEWLINETEST1 1 // strange
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define NEWLINETEST2 2 /* Comment with */
|
||||||
|
/* linefeed */
|
||||||
|
#define NEWLINETEST3 3
|
||||||
|
|
||||||
|
// Should be blank line below
|
||||||
|
#define AVALUE 1
|
||||||
|
// Should be blank line above
|
||||||
|
|
||||||
|
// 5 blank lines below
|
||||||
|
#if 0
|
||||||
|
#define BVALUE 0
|
||||||
|
#else
|
||||||
|
#define BVALUE 2
|
||||||
|
#endif
|
||||||
|
// 5 blank lines above
|
||||||
|
|
||||||
theEnd();
|
theEnd();
|
||||||
|
@ -0,0 +1,34 @@
|
|||||||
|
/* ###
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
#ifndef INCLUDE1
|
||||||
|
#define INCLUDE1
|
||||||
|
#pragma pack(push,1)
|
||||||
|
|
||||||
|
#else if !defined(INCLUDE2)
|
||||||
|
#define INCLUDE2
|
||||||
|
#pragma pack(push, 2)
|
||||||
|
|
||||||
|
#else if !defined(INCLUDE3)
|
||||||
|
#define INCLUDE3
|
||||||
|
#pragma pack(push, 4)
|
||||||
|
|
||||||
|
#else if !defined(INCLUDE4)
|
||||||
|
#define INCLUDE4
|
||||||
|
#pragma pack(push, 8)
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define INCLUDE5 // never gets to this
|
||||||
|
#endif
|
@ -56,7 +56,7 @@ public class AddressEvaluator {
|
|||||||
}
|
}
|
||||||
else if (obj instanceof Long) {
|
else if (obj instanceof Long) {
|
||||||
try {
|
try {
|
||||||
return af.getDefaultAddressSpace().getAddress(((Long) obj).longValue());
|
return af.getDefaultAddressSpace().getAddress(((Long) obj).longValue(), true);
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
// ignore
|
// ignore
|
||||||
@ -100,7 +100,7 @@ public class AddressEvaluator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// = must be followed by =, others can be followed
|
// = must be followed by =, others can be followed
|
||||||
if (tok.equals("=") || tok.equals("!") || tok.equals("<") || tok.equals(">")) {
|
if ("=!<>|&".contains(tok)) {
|
||||||
lookahead = parser.nextToken();
|
lookahead = parser.nextToken();
|
||||||
tok = checkDoubleToken(tok, lookahead);
|
tok = checkDoubleToken(tok, lookahead);
|
||||||
// if tok is now longer, consumed lookahead
|
// if tok is now longer, consumed lookahead
|
||||||
@ -151,6 +151,18 @@ public class AddressEvaluator {
|
|||||||
return "!=";
|
return "!=";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "|":
|
||||||
|
if (lookahead.equals("|")) {
|
||||||
|
return "||";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "&":
|
||||||
|
if (lookahead.equals("&")) {
|
||||||
|
return "&&";
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return tok;
|
return tok;
|
||||||
@ -365,6 +377,14 @@ public class AddressEvaluator {
|
|||||||
if (!evaluateOperator(list, Operator.LESSEQUALS, Operator.GREATEREQUALS)) {
|
if (!evaluateOperator(list, Operator.LESSEQUALS, Operator.GREATEREQUALS)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!evaluateOperator(list, Operator.LOG_AND, null)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!evaluateOperator(list, Operator.LOG_OR, null)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if (list.size() != 1) {
|
if (list.size() != 1) {
|
||||||
return null;
|
return null;
|
||||||
@ -498,6 +518,18 @@ public class AddressEvaluator {
|
|||||||
return diff > 0L ? 1L : 0L;
|
return diff > 0L ? 1L : 0L;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (op == Operator.LOG_AND) {
|
||||||
|
if ((v1 instanceof Long) && (v2 instanceof Long)) {
|
||||||
|
boolean test = (((Long) v1).longValue()) != 0 && (((Long) v2).longValue()) != 0;
|
||||||
|
return test ? 1L : 0L;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (op == Operator.LOG_OR) {
|
||||||
|
if ((v1 instanceof Long) && (v2 instanceof Long)) {
|
||||||
|
boolean test = (((Long) v1).longValue()) != 0 || (((Long) v2).longValue()) != 0;
|
||||||
|
return test ? 1L : 0L;
|
||||||
|
}
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -544,6 +576,8 @@ class Operator {
|
|||||||
static Operator RIGHTSHIFT = new Operator(">>");
|
static Operator RIGHTSHIFT = new Operator(">>");
|
||||||
static Operator LEFT_PAREN = new Operator("(");
|
static Operator LEFT_PAREN = new Operator("(");
|
||||||
static Operator RIGHT_PAREN = new Operator(")");
|
static Operator RIGHT_PAREN = new Operator(")");
|
||||||
|
static Operator LOG_OR = new Operator("||");
|
||||||
|
static Operator LOG_AND = new Operator("&&");
|
||||||
static Operator EQUALS = new Operator("==");
|
static Operator EQUALS = new Operator("==");
|
||||||
static Operator NOTEQUALS = new Operator("!=");
|
static Operator NOTEQUALS = new Operator("!=");
|
||||||
static Operator LESS = new Operator("<");
|
static Operator LESS = new Operator("<");
|
||||||
@ -622,6 +656,12 @@ class Operator {
|
|||||||
else if (tok.equals(">=")) {
|
else if (tok.equals(">=")) {
|
||||||
return GREATEREQUALS;
|
return GREATEREQUALS;
|
||||||
}
|
}
|
||||||
|
else if (tok.equals("||")) {
|
||||||
|
return LOG_OR;
|
||||||
|
}
|
||||||
|
else if (tok.equals("&&")) {
|
||||||
|
return LOG_AND;
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user