From 40603ee962993148e8d1552487c5b071f7726621 Mon Sep 17 00:00:00 2001
From: emteere <47253321+emteere@users.noreply.github.com>
Date: Tue, 3 Dec 2024 21:17:27 +0000
Subject: [PATCH 1/4] GP-5025 Throw error when parsing #error during Cparsing,
various bug fixes including comment parsing, cparser/preprocessing parse
error switch, and L'\n' wide char parsing in pre-processor
---
.../data/parserprofiles/VisualStudio12_32.prf | 5 +-
.../data/parserprofiles/VisualStudio12_64.prf | 13 +-
.../data/parserprofiles/VisualStudio22_64.prf | 2 -
.../data/parserprofiles/generic_clib_32.prf | 5 +-
.../data/parserprofiles/generic_clib_64.prf | 5 +-
.../CreateDefaultGDTArchivesScript.java | 810 ++++++++++++++----
.../CreateUEFIGDTArchivesScript.java | 141 +++
.../plugin/core/cparser/CParserPlugin.java | 8 +-
.../app/util/cparser/C/CParserUtils.java | 8 +-
.../app/util/cparser/CPP/DefineTable.java | 1 +
.../javacc/ghidra/app/util/cparser/C/C.jj | 4 +-
.../javacc/ghidra/app/util/cparser/CPP/CPP.jj | 151 +++-
.../ghidra/app/util/cparser/CParserTest.java | 8 +-
.../ghidra/app/util/cparser/CParserTest.h | 2 +
.../app/util/cparser/PreProcessorTest.h | 53 +-
15 files changed, 971 insertions(+), 245 deletions(-)
create mode 100644 Ghidra/Features/Base/ghidra_scripts/CreateUEFIGDTArchivesScript.java
diff --git a/Ghidra/Features/Base/data/parserprofiles/VisualStudio12_32.prf b/Ghidra/Features/Base/data/parserprofiles/VisualStudio12_32.prf
index 2dd5df02d2..2a108c0430 100644
--- a/Ghidra/Features/Base/data/parserprofiles/VisualStudio12_32.prf
+++ b/Ghidra/Features/Base/data/parserprofiles/VisualStudio12_32.prf
@@ -80,7 +80,6 @@ isa_availability.h
mbdata.h
msdos.h
mtdll.h
-nlsdownlevel.h
nlsint.h
nmmintrin.h
oscalls.h
@@ -137,6 +136,9 @@ mmdeviceapi.h
mprapi.h
msctfmonitorapi.h
ndfapi.h
+winsock2.h
+ws2tcpip.h
+iphlpapi.h
netioapi.h
npapi.h
nspapi.h
@@ -171,7 +173,6 @@ wpapi.h
wpcapi.h
wscapi.h
wsdapi.h
-wspiapi.h
rpcproxy.h
-D_M_IX86=300
diff --git a/Ghidra/Features/Base/data/parserprofiles/VisualStudio12_64.prf b/Ghidra/Features/Base/data/parserprofiles/VisualStudio12_64.prf
index b30064ecc3..1793a6c2d4 100644
--- a/Ghidra/Features/Base/data/parserprofiles/VisualStudio12_64.prf
+++ b/Ghidra/Features/Base/data/parserprofiles/VisualStudio12_64.prf
@@ -80,7 +80,6 @@ isa_availability.h
mbdata.h
msdos.h
mtdll.h
-nlsdownlevel.h
nlsint.h
nmmintrin.h
oscalls.h
@@ -137,6 +136,9 @@ mmdeviceapi.h
mprapi.h
msctfmonitorapi.h
ndfapi.h
+winsock2.h
+ws2tcpip.h
+iphlpapi.h
netioapi.h
npapi.h
nspapi.h
@@ -171,12 +173,11 @@ wpapi.h
wpcapi.h
wscapi.h
wsdapi.h
-wspiapi.h
rpcproxy.h
--D_M_IX86=300
-D_MSC_VER=1200
-D_INTEGRAL_MAX_BITS=64
+-DNTDDI_VERSION=0x09000000
-DWINVER=0x0900
-D_AMD64_
-D_M_AMD64
@@ -204,10 +205,12 @@ rpcproxy.h
-v0
-D__inner_checkReturn=""
-/data/HeaderFiles/VC/VS12/include
/data/HeaderFiles/VC/VS12/src
+/data/HeaderFiles/VC/VS12/include
/data/HeaderFiles/VC/SDK/v7.1A/Include
-
+x86:LE:64:default
+
+windows
diff --git a/Ghidra/Features/Base/data/parserprofiles/VisualStudio22_64.prf b/Ghidra/Features/Base/data/parserprofiles/VisualStudio22_64.prf
index 4c06d1d14e..29f8ccfcf2 100644
--- a/Ghidra/Features/Base/data/parserprofiles/VisualStudio22_64.prf
+++ b/Ghidra/Features/Base/data/parserprofiles/VisualStudio22_64.prf
@@ -115,8 +115,6 @@ xenroll.h
af_irda.h
in6addr.h
mstcpip.h
-ws2def.h
-winsock.h
winsock2.h
nsemail.h
nspapi.h
diff --git a/Ghidra/Features/Base/data/parserprofiles/generic_clib_32.prf b/Ghidra/Features/Base/data/parserprofiles/generic_clib_32.prf
index 188be92604..e0691a8417 100644
--- a/Ghidra/Features/Base/data/parserprofiles/generic_clib_32.prf
+++ b/Ghidra/Features/Base/data/parserprofiles/generic_clib_32.prf
@@ -2,7 +2,7 @@ sys/types.h
types.h
stddef.h
stddef.h
-openssl/opensslconf-x86_64.h
+openssl/opensslconf.h
openssl/bn.h
openssl/ssl.h
openssl/asn1_mac.h
@@ -107,7 +107,6 @@ stdint.h
stdio.h
stdlib.h
string.h
-tgmath.h
time.h
wchar.h
wctype.h
@@ -220,6 +219,7 @@ arpa/telnet.h
arpa/tftp.h
-D_X86_
+-D__i386__
-D__STDC__
-D_GNU_SOURCE
-D__WORDSIZE=32
@@ -236,6 +236,7 @@ arpa/tftp.h
/data/HeaderFiles/linux/include
/data/HeaderFiles/linux/include/sys
/data/HeaderFiles/linux/gcc/include
+/data/HeaderFiles/linux/include/openssl
/data/HeaderFiles/linux/x86_64-redhat-linux5E/include
/data/HeaderFiles/linux/x86_64-redhat-linux5E/include/sys
diff --git a/Ghidra/Features/Base/data/parserprofiles/generic_clib_64.prf b/Ghidra/Features/Base/data/parserprofiles/generic_clib_64.prf
index af46b60039..c155225a23 100644
--- a/Ghidra/Features/Base/data/parserprofiles/generic_clib_64.prf
+++ b/Ghidra/Features/Base/data/parserprofiles/generic_clib_64.prf
@@ -2,7 +2,7 @@ sys/types.h
types.h
stddef.h
stddef.h
-openssl/opensslconf-x86_64.h
+openssl/opensslconf.h
openssl/bn.h
openssl/ssl.h
openssl/asn1_mac.h
@@ -107,7 +107,6 @@ stdint.h
stdio.h
stdlib.h
string.h
-tgmath.h
time.h
wchar.h
wctype.h
@@ -220,6 +219,7 @@ arpa/telnet.h
arpa/tftp.h
-D_X86_
+-D__x86_64__
-D__STDC__
-D_GNU_SOURCE
-D__WORDSIZE=64
@@ -236,6 +236,7 @@ arpa/tftp.h
/data/HeaderFiles/linux/include
/data/HeaderFiles/linux/include/sys
/data/HeaderFiles/linux/gcc/include
+/data/HeaderFiles/linux/include/openssl
/data/HeaderFiles/linux/x86_64-redhat-linux5E/include
/data/HeaderFiles/linux/x86_64-redhat-linux5E/include/sys
diff --git a/Ghidra/Features/Base/ghidra_scripts/CreateDefaultGDTArchivesScript.java b/Ghidra/Features/Base/ghidra_scripts/CreateDefaultGDTArchivesScript.java
index 68be22b86a..18adfc1438 100644
--- a/Ghidra/Features/Base/ghidra_scripts/CreateDefaultGDTArchivesScript.java
+++ b/Ghidra/Features/Base/ghidra_scripts/CreateDefaultGDTArchivesScript.java
@@ -50,7 +50,9 @@ public class CreateDefaultGDTArchivesScript extends GhidraScript {
parseGDT_VS12_32();
parseGDT_VS12_64();
-
+
+ parseGDT_WinVS22();
+ parseGDT_WinVS22_WDK();
}
private void parseHeaderFilesToGDT(File outputDir, String gdtName, String languageID, String compiler,
@@ -237,6 +239,9 @@ public class CreateDefaultGDTArchivesScript extends GhidraScript {
"mprapi.h",
"msctfmonitorapi.h",
"ndfapi.h",
+ "winsock2.h",
+ "ws2tcpip.h",
+ "iphlpapi.h",
"netioapi.h",
"npapi.h",
"nspapi.h",
@@ -271,7 +276,6 @@ public class CreateDefaultGDTArchivesScript extends GhidraScript {
"wpcapi.h",
"wscapi.h",
"wsdapi.h",
- "wspiapi.h",
"rpcproxy.h",
};
@@ -285,6 +289,7 @@ public class CreateDefaultGDTArchivesScript extends GhidraScript {
"-D_M_IX86=300",
"-D_MSC_VER=1200",
"-D_INTEGRAL_MAX_BITS=32",
+ "-DNTDDI_VERSION=0x09000000",
"-DWINVER=0x0900",
"-D_X86_",
"-D_WIN32",
@@ -316,181 +321,182 @@ public class CreateDefaultGDTArchivesScript extends GhidraScript {
public void parseGDT_VS12_64() throws Exception {
String filenames[] = {
- "sdkddkver.h",
- "sal.h",
- "assert.h",
- "conio.h",
- "crtdefs.h",
- "crtdbg.h",
- "crtwrn.h",
- "ctype.h",
- "basetsd.h",
- "WinDef.h",
- "WinNT.h",
- "delayimp.h",
- "direct.h",
- "dos.h",
- "errno.h",
- "excpt.h",
- "fcntl.h",
- "float.h",
- "fpieee.h",
- "io.h",
- "iso646.h",
- "limits.h",
- "locale.h",
- "malloc.h",
- "math.h",
- "mbctype.h",
- "mbstring.h",
- "memory.h",
- "minmax.h",
- "new.h",
- "omp.h",
- "pgobootrun.h",
- "process.h",
- "rtcapi.h",
- "search.h",
- "setjmp.h",
- "setjmpex.h",
- "share.h",
- "signal.h",
- "srv.h",
- "stdarg.h",
- "stddef.h",
- "stdexcpt.h",
- "stdio.h",
- "stdlib.h",
- "string.h",
- "tchar.h",
- "time.h",
- "use_ansi.h",
- "vadefs.h",
- "varargs.h",
- "wchar.h",
- "wctype.h",
- "xlocinfo.h",
- "xmath.h",
- "ymath.h",
- "yvals.h",
- "CommDlg.h",
- "WinUser.h",
- "WinNls.h",
- "internal.h",
- "strsafe.h",
- "align.h",
- "awint.h",
- "crtversion.h",
- "cruntime.h",
- "ctime.h",
- "cvt.h",
- "dbgint.h",
- "ehdata.h",
- "emmintrin.h",
- "errmsg.h",
- "fenv.h",
- "file2.h",
- "fltintrn.h",
- "immintrin.h",
- "internal_securecrt.h",
- "inttypes.h",
- "isa_availability.h",
- "mbdata.h",
- "msdos.h",
- "mtdll.h",
- "nlsdownlevel.h",
- "nlsint.h",
- "nmmintrin.h",
- "oscalls.h",
- "pmmintrin.h",
- "rtcsup.h",
- "rterr.h",
- "sect_attribs.h",
- "setlocal.h",
- "smmintrin.h",
- "stdbool.h",
- "stdint.h",
- "syserr.h",
- "targetver.h",
- "tmmintrin.h",
- "winheap.h",
- "wmmintrin.h",
- "wrapwin.h",
- "xkeycheck.h",
- "xmmintrin.h",
- "xmtx.h",
- "xtgmath.h",
- "xxcctype.h",
- "xxdftype.h",
- "xxfftype.h",
- "xxlftype.h",
- "xxwctype.h",
- "xxxprec.h",
- "shlobj.h",
- "evntprov.h",
- "uiautomation.h",
- "aclapi.h",
- "appcompatapi.h",
- "capi.h",
- "clusapi.h",
- "cryptuiapi.h",
- "cscapi.h",
- "devpropdef.h",
- "dhcpsapi.h",
- "dwmapi.h",
- "ehstorapi.h",
- "functiondiscoveryapi.h",
- "ipexport.h",
- "icmpapi.h",
- "iepmapi.h",
- "imapi.h",
- "ksopmapi.h",
- "locationapi.h",
- "lpmapi.h",
- "mapi.h",
- "mbnapi.h",
- "mfapi.h",
- "mgmtapi.h",
- "mmdeviceapi.h",
- "mprapi.h",
- "msctfmonitorapi.h",
- "ndfapi.h",
- "netioapi.h",
- "npapi.h",
- "nspapi.h",
- "ntdsapi.h",
- "ntmsapi.h",
- "ntsecapi.h",
- "patchapi.h",
- "portabledeviceapi.h",
- "portabledeviceconnectapi.h",
- "propapi.h",
- "psapi.h",
- "rdpencomapi.h",
- "resapi.h",
- "sapi.h",
- "searchapi.h",
- "sensapi.h",
- "sensorsapi.h",
- "setupapi.h",
- "shellapi.h",
- "shlwapi.h",
- "srrestoreptapi.h",
- "svrapi.h",
- "t2embapi.h",
- "tapi.h",
- "uiautomationcoreapi.h",
- "wcnapi.h",
- "wdsclientapi.h",
- "werapi.h",
- "windowssideshowapi.h",
- "wlanapi.h",
- "wpapi.h",
- "wpcapi.h",
- "wscapi.h",
- "wsdapi.h",
- "wspiapi.h",
- "rpcproxy.h",
+ "sdkddkver.h",
+ "sal.h",
+ "assert.h",
+ "conio.h",
+ "crtdefs.h",
+ "crtdbg.h",
+ "crtwrn.h",
+ "ctype.h",
+ "basetsd.h",
+ "WinDef.h",
+ "WinNT.h",
+ "delayimp.h",
+ "direct.h",
+ "dos.h",
+ "errno.h",
+ "excpt.h",
+ "fcntl.h",
+ "float.h",
+ "fpieee.h",
+ "io.h",
+ "iso646.h",
+ "limits.h",
+ "locale.h",
+ "malloc.h",
+ "math.h",
+ "mbctype.h",
+ "mbstring.h",
+ "memory.h",
+ "minmax.h",
+ "new.h",
+ "omp.h",
+ "pgobootrun.h",
+ "process.h",
+ "rtcapi.h",
+ "search.h",
+ "setjmp.h",
+ "setjmpex.h",
+ "share.h",
+ "signal.h",
+ "srv.h",
+ "stdarg.h",
+ "stddef.h",
+ "stdexcpt.h",
+ "stdio.h",
+ "stdlib.h",
+ "string.h",
+ "tchar.h",
+ "time.h",
+ "use_ansi.h",
+ "vadefs.h",
+ "varargs.h",
+ "wchar.h",
+ "wctype.h",
+ "xlocinfo.h",
+ "xmath.h",
+ "ymath.h",
+ "yvals.h",
+ "CommDlg.h",
+ "WinUser.h",
+ "WinNls.h",
+ "internal.h",
+ "strsafe.h",
+ "align.h",
+ "awint.h",
+ "crtversion.h",
+ "cruntime.h",
+ "ctime.h",
+ "cvt.h",
+ "dbgint.h",
+ "ehdata.h",
+ "emmintrin.h",
+ "errmsg.h",
+ "fenv.h",
+ "file2.h",
+ "fltintrn.h",
+ "immintrin.h",
+ "internal_securecrt.h",
+ "inttypes.h",
+ "isa_availability.h",
+ "mbdata.h",
+ "msdos.h",
+ "mtdll.h",
+ "nlsdownlevel.h",
+ "nlsint.h",
+ "nmmintrin.h",
+ "oscalls.h",
+ "pmmintrin.h",
+ "rtcsup.h",
+ "rterr.h",
+ "sect_attribs.h",
+ "setlocal.h",
+ "smmintrin.h",
+ "stdbool.h",
+ "stdint.h",
+ "syserr.h",
+ "targetver.h",
+ "tmmintrin.h",
+ "winheap.h",
+ "wmmintrin.h",
+ "wrapwin.h",
+ "xkeycheck.h",
+ "xmmintrin.h",
+ "xmtx.h",
+ "xtgmath.h",
+ "xxcctype.h",
+ "xxdftype.h",
+ "xxfftype.h",
+ "xxlftype.h",
+ "xxwctype.h",
+ "xxxprec.h",
+ "shlobj.h",
+ "evntprov.h",
+ "uiautomation.h",
+ "aclapi.h",
+ "appcompatapi.h",
+ "capi.h",
+ "clusapi.h",
+ "cryptuiapi.h",
+ "cscapi.h",
+ "devpropdef.h",
+ "dhcpsapi.h",
+ "dwmapi.h",
+ "ehstorapi.h",
+ "functiondiscoveryapi.h",
+ "ipexport.h",
+ "icmpapi.h",
+ "iepmapi.h",
+ "imapi.h",
+ "ksopmapi.h",
+ "locationapi.h",
+ "lpmapi.h",
+ "mapi.h",
+ "mbnapi.h",
+ "mfapi.h",
+ "mgmtapi.h",
+ "mmdeviceapi.h",
+ "mprapi.h",
+ "msctfmonitorapi.h",
+ "ndfapi.h",
+ "winsock2.h",
+ "ws2tcpip.h",
+ "iphlpapi.h",
+ "npapi.h",
+ "nspapi.h",
+ "ntdsapi.h",
+ "ntmsapi.h",
+ "ntsecapi.h",
+ "patchapi.h",
+ "portabledeviceapi.h",
+ "portabledeviceconnectapi.h",
+ "propapi.h",
+ "psapi.h",
+ "rdpencomapi.h",
+ "resapi.h",
+ "sapi.h",
+ "searchapi.h",
+ "sensapi.h",
+ "sensorsapi.h",
+ "setupapi.h",
+ "shellapi.h",
+ "shlwapi.h",
+ "srrestoreptapi.h",
+ "svrapi.h",
+ "t2embapi.h",
+ "tapi.h",
+ "uiautomationcoreapi.h",
+ "wcnapi.h",
+ "wdsclientapi.h",
+ "werapi.h",
+ "windowssideshowapi.h",
+ "wlanapi.h",
+ "wpapi.h",
+ "wpcapi.h",
+ "wscapi.h",
+ "wsdapi.h",
+ "rpcproxy.h",
};
String includePaths[] = {
@@ -502,6 +508,8 @@ public class CreateDefaultGDTArchivesScript extends GhidraScript {
String args[] = {
"-D_MSC_VER=1200",
"-D_INTEGRAL_MAX_BITS=64",
+ "-D_WIN32_WINNT=0x601",
+ "-DNTDDI_VERSION=0x06010000",
"-DWINVER=0x0900",
"-D_AMD64_",
"-D_M_AMD64",
@@ -539,7 +547,7 @@ public class CreateDefaultGDTArchivesScript extends GhidraScript {
"types.h",
"stddef.h",
"stddef.h",
- "openssl/opensslconf-x86_64.h",
+ "openssl/opensslconf.h",
"openssl/bn.h",
"openssl/ssl.h",
"openssl/asn1_mac.h",
@@ -644,7 +652,6 @@ public class CreateDefaultGDTArchivesScript extends GhidraScript {
"stdio.h",
"stdlib.h",
"string.h",
- "tgmath.h",
"time.h",
"wchar.h",
"wctype.h",
@@ -761,12 +768,14 @@ public class CreateDefaultGDTArchivesScript extends GhidraScript {
headerFilePath+"/linux/include",
headerFilePath+"/linux/include/sys",
headerFilePath+"/linux/gcc/include",
+ headerFilePath+"/linux/include/openssl",
headerFilePath+"/linux/x86_64-redhat-linux5E/include",
headerFilePath+"/linux/x86_64-redhat-linux5E/include/sys",
};
String args[] = {
"-D_X86_",
+ "-D__x86_64__",
"-D__STDC__",
"-D_GNU_SOURCE",
"-D__WORDSIZE=64",
@@ -792,7 +801,7 @@ public class CreateDefaultGDTArchivesScript extends GhidraScript {
"types.h",
"stddef.h",
"stddef.h",
- "openssl/opensslconf-x86_64.h",
+ "openssl/opensslconf.h",
"openssl/des.h",
"openssl/bn.h",
"openssl/ssl.h",
@@ -897,7 +906,6 @@ public class CreateDefaultGDTArchivesScript extends GhidraScript {
"stdio.h",
"stdlib.h",
"string.h",
- "tgmath.h",
"time.h",
"wchar.h",
"wctype.h",
@@ -1014,12 +1022,14 @@ public class CreateDefaultGDTArchivesScript extends GhidraScript {
headerFilePath+"/linux/include",
headerFilePath+"/linux/include/sys",
headerFilePath+"/linux/gcc/include",
+ headerFilePath+"/linux/include/openssl",
headerFilePath+"/linux/x86_64-redhat-linux5E/include",
headerFilePath+"/linux/x86_64-redhat-linux5E/include/sys",
};
String args[] = {
"-D_X86_",
+ "-D__i386__",
"-D__STDC__",
"-D_GNU_SOURCE",
"-D__WORDSIZE=32",
@@ -1036,4 +1046,442 @@ public class CreateDefaultGDTArchivesScript extends GhidraScript {
parseHeaderFilesToGDT(outputDirectory, "generic_clib_new", "x86:LE:32:default", "gcc", filenames, includePaths, args);
}
+
+
+ public void parseGDT_WinVS22() throws Exception {
+
+ String filenames[] = {
+ "# Core necessary files",
+ "winapifamily.h",
+ "winpackagefamily.h",
+ "sdkddkver.h",
+ "sal.h",
+ "no_sal2.h",
+ "corecrt.h",
+ "wtypes.h",
+ "winnt.h",
+ "winternl.h",
+ "#ntdef.h",
+
+ "# Common headers ",
+ "dos.h",
+ "errno.h",
+ "malloc.h",
+ "signal.h",
+ "stdalign.h",
+ "stddef.h",
+ "stdio.h",
+ "stdlib.h",
+ "assert.h",
+ "crtdbg.h",
+ "ctype.h",
+ "conio.h",
+ "direct.h",
+ "fcntl.h",
+ "float.h",
+ "fpieee.h",
+ "inttypes.h",
+ "io.h",
+ "locale.h",
+ "complex.h",
+ "math.h",
+ "mbctype.h",
+ "mbstring.h",
+ "memory.h",
+ "minmax.h",
+ "new.h",
+ "process.h",
+ "search.h",
+ "share.h",
+ "winbase.h",
+ "winuser.h",
+ "Windows.h",
+
+ "# Security and identity (https://docs.microsoft.com/en-us/windows/win32/api/_security/)",
+ "accctrl.h",
+ "aclapi.h",
+ "aclui.h",
+ "adtgen.h",
+ "authz.h",
+ "azroles.h",
+ "bcrypt.h",
+ "casetup.h",
+ "ccgplugins.h",
+ "celib.h",
+ "ntlsa.h",
+ "sspi.h",
+ "ntsecapi.h",
+ "ntsecpkg.h",
+ "schannel.h",
+ "certadm.h",
+ "certbcli.h",
+ "certcli.h",
+ "certenroll.h",
+ "certexit.h",
+ "certif.h",
+ "certmod.h",
+ "certpol.h",
+ "CertPolEng.h",
+ "certsrv.h",
+ "certview.h",
+ "credssp.h",
+ "cryptdlg.h",
+ "cryptuiapi.h",
+ "cryptxml.h",
+ "diagnosticdataquery.h",
+ "diagnosticdataquerytypes.h",
+ "dpapi.h",
+ "dssec.h",
+ "iads.h",
+ "IdentityCommon.h",
+ "IdentityProvider.h",
+ "identitystore.h",
+ "keycredmgr.h",
+ "lmaccess.h",
+ "lsalookup.h",
+ "mmcobj.h",
+ "mscat.h",
+ "mssip.h",
+ "namedpipeapi.h",
+ "ncrypt.h",
+ "ncryptprotect.h",
+ "npapi.h",
+ "processthreadsapi.h",
+ "sas.h",
+ "scesvc.h",
+ "sddl.h",
+ "securityappcontainer.h",
+ "securitybaseapi.h",
+ "slpublic.h",
+ "subauth.h",
+ "tokenbinding.h",
+ "tpmvscmgr.h",
+ "wincred.h",
+ "wincrypt.h",
+ "winnetwk.h",
+ "winreg.h",
+ "winsafer.h",
+ "winscard.h",
+ "winsvc.h",
+ "wintrust.h",
+ "winwlx.h",
+ "xenroll.h",
+
+ "# Windows sockets",
+ "af_irda.h",
+ "in6addr.h",
+ "mstcpip.h",
+ "winsock2.h",
+ "nsemail.h",
+ "nspapi.h",
+ "socketapi.h",
+ "# Nothing includes this; is it necessary?",
+ "#sporder.h",
+ "transportsettingcommon.h",
+ "ws2atm.h",
+ "ws2spi.h",
+ "MSWSock.h",
+ "ws2tcpip.h",
+ "wsipv6ok.h",
+ "WSNwLink.h",
+ "wsrm.h",
+ "mswsockdef.h",
+
+ "# Remote Procedure Call (RPC)",
+ "midles.h",
+ "midlbase.h",
+ "rpc.h",
+ "rpcndr.h",
+ "rpcasync.h",
+ "rpcdcep.h",
+ "rpcnsi.h",
+ "rpcproxy.h",
+ "rpcssl.h",
+
+ "# COM",
+ "accctrl.h",
+ "callobj.h",
+ "combaseapi.h",
+ "comcat.h",
+ "ctxtcall.h",
+ "dmerror.h",
+ "docobj.h",
+ "eventsys.h",
+ "initguid.h",
+ "guiddef.h",
+ "iaccess.h",
+ "hstring.h",
+ "IMessageDispatcher.h",
+ "MessageDispatcherApi.h",
+ "objbase.h",
+ "objidlbase.h",
+ "objidl.h",
+ "ocidl.h",
+ "ole.h",
+ "ole2.h",
+ "oledlg.h",
+ "oleidl.h",
+ "roapi.h",
+ "rpcdce.h",
+ "servprov.h",
+ "shobjidl.h",
+ "txlogpub.h",
+ "unknwnbase.h",
+ "unknwn.h",
+ "urlmon.h",
+ "vbinterf.h",
+ "winddi.h",
+ "winerror.h",
+ "wtypesbase.h",
+
+ "# COM+",
+ "comadmin.h",
+ "mtxdm.h",
+
+ "# More",
+ "inspectable.h",
+
+ "# Windows Internet",
+ "proofofpossessioncookieinfo.h",
+ "wininet.h",
+ "winineti.h",
+
+ "# Windows HTTP Services",
+ "winhttp.h",
+
+ "# Compression",
+ "compressapi.h",
+
+ "# TraceLogging",
+ "#traceloggingactivity.h",
+ "#traceloggingprovider.h",
+
+ "# Windows Error Reporting",
+ "errorrep.h",
+ "werapi.h",
+
+ "# Windows and MEssages",
+ "olectl.h",
+ "windef.h",
+ "windowsx.h",
+
+ "# Shell",
+ "appmgmt.h",
+ "appnotify.h",
+ "cpl.h",
+ "credentialprovider.h",
+ "dimm.h",
+ "imagetranscode.h",
+ "inputpanelconfiguration.h",
+ "intsafe.h",
+ "intshcut.h",
+ "mobsync.h",
+ "objectarray.h",
+ "pathcch.h",
+ "profinfo.h",
+ "propkeydef.h",
+ "scrnsave.h",
+ "shappmgr.h",
+ "shdeprecated.h",
+ "shidfact.h",
+ "shimgdata.h",
+ "shlwapi.h",
+ "shtypes.h",
+ "storageprovider.h",
+ "syncmgr.h",
+ "thumbcache.h",
+ "thumbnailstreamcache.h",
+ "tlogstg.h",
+ "UserEnv.h",
+
+ "# Windows Controls",
+ "commctrl.h",
+ "commoncontrols.h",
+ "dpa_dsa.h",
+ "prsht.h",
+ "richedit.h",
+ "richole.h",
+ "shlobj_core.h",
+ "shlobj.h",
+ "#textserv.h", // C++
+ "tom.h",
+ "uxtheme.h",
+
+ "# Menus and other resources",
+ "resourceindexer.h",
+ "strsafe.h",
+ "verrsrc.h",
+ "winver.h",
+
+ "# Windows Accessibility Features",
+ "oleacc.h",
+ "uiautomationcore.h",
+ "uiautomationclient.h",
+ "uiautomationcoreapi.h",
+
+ "# Internationalization",
+ "datetimeapi.h",
+ "elscore.h",
+ "gb18030.h",
+ "imepad.h",
+ "imm.h",
+ "immdev.h",
+ "msime.h",
+ "msimeapi.h",
+ "muiload.h",
+ "spellcheck.h",
+ "spellcheckprovider.h",
+ "stringapiset.h",
+ "usp10.h",
+ "winnls.h",
+
+ "# HTTP Server API",
+ "#http.h", // included by something else
+
+ "# IP Helper",
+ "#icmpapi.h", // Something wrong with IP_ADDR
+ "ifdef.h",
+ "inaddr.h",
+ "ip2string.h",
+ "ipexport.h",
+ "iphlpapi.h",
+ "iprtrmib.h",
+ "iptypes.h",
+ "nldef.h",
+ "tcpestats.h",
+
+ "# Network Management",
+ "atacct.h",
+ "lmalert.h",
+ "lmapibuf.h",
+ "lmat.h",
+ "lmaudit.h",
+ "lmconfig.h",
+ "lmerrlog.h",
+ "lmjoin.h",
+ "lmmsg.h",
+ "lmremutl.h",
+ "lmserver.h",
+ "lmsvc.h",
+ "lmuse.h",
+ "lmwksta.h"
+ };
+
+ String includePaths[] = {
+ headerFilePath+"/VC/VS22/Community/VC/Tools/MSVC/14.29.30133/include",
+ headerFilePath+"/VC/SDK/10/Include/10.0.22000.0/shared",
+ headerFilePath+"/VC/SDK/10/Include/10.0.22000.0/um",
+ headerFilePath+"/VC/SDK/10/Include/10.0.22000.0/km",
+ headerFilePath+"/VC/VS22/10.0.19041.0/shared",
+ headerFilePath+"/VC/VS22/10.0.19041.0/um",
+ headerFilePath+"/VC/VS22/10.0.19041.0/ucrt",
+ headerFilePath+"/VC/VS22/10.0.19041.0/winrt",
+ };
+
+ String args[] = {
+ "-D_MSC_VER=1924",
+ "-D_INTEGRAL_MAX_BITS=64",
+ "-DWINVER=0x0a00",
+ "-D_WIN32_WINNT=0x0a00",
+ "-D_AMD64_",
+ "-D_M_AMD64",
+ "-D_M_X64",
+ "-D_WIN64",
+ "-D_WIN32",
+ "-D_USE_ATTRIBUTES_FOR_SAL",
+ "-D_CRTBLD",
+ "-D_OPENMP_NOFORCE_MANIFEST",
+ "-DLPSKBINFO=LPARAM",
+ "-DCONST=const",
+ "-D_CRT_SECURE_NO_WARNINGS",
+ "-D_CRT_NONSTDC_NO_DEPRECATE",
+ "-D_CRT_NONSTDC_NO_WARNINGS",
+ "-D_CRT_OBSOLETE_NO_DEPRECATE",
+ "-D_ALLOW_KEYWORD_MACROS",
+ "-D_ASSERT_OK",
+ "-DSTRSAFE_NO_DEPRECATE",
+ "-D__possibly_notnullterminated",
+ "-Dtype_info=\"void *\"",
+ "-D_ThrowInfo=ThrowInfo",
+ "-D__unaligned=",
+ "-v0",
+ "-D__inner_checkReturn=",
+ "-DDECLSPEC_DEPRECATED_DDK",
+ "-DWINAPI_PARTITION_APP=1",
+ "-DWINAPI_PARTITION_SYSTEM=1",
+ "-DWINAPI_PARTITION_GAMES=1",
+ "-DSECURITY_WIN32",
+ "-DSIZE_T=size_t",
+ };
+
+ parseHeaderFilesToGDT(outputDirectory, "windows_vs22_64_new", "x86:LE:64:default", "windows", filenames, includePaths, args);
+ }
+
+
+ public void parseGDT_WinVS22_WDK() throws Exception {
+
+ String filenames[] = {
+ "# Core necessary files",
+
+ "# Windows Drivers WDK",
+ "initguid.h",
+ "ntddk.h",
+ "ntintsafe.h",
+ "wdf.h",
+ };
+
+ String includePaths[] = {
+ headerFilePath+"/VC/VS22/Community/VC/Tools/MSVC/14.29.30133/include",
+ headerFilePath+"/VC/SDK/10/Include/10.0.22000.0/shared",
+ headerFilePath+"/VC/SDK/10/Include/10.0.22000.0/um",
+ headerFilePath+"/VC/SDK/10/Include/10.0.22000.0/km",
+ headerFilePath+"/VC/SDK/10/Include/wdf/umdf/2.33",
+ headerFilePath+"/VC/VS22/10.0.19041.0/shared",
+ headerFilePath+"/VC/VS22/10.0.19041.0/um",
+ headerFilePath+"/VC/VS22/10.0.19041.0/ucrt",
+ headerFilePath+"/VC/VS22/10.0.19041.0/winrt",
+ };
+
+ String args[] = {
+ "-D_MSC_VER=1924",
+ "-D_INTEGRAL_MAX_BITS=64",
+ "-DWINVER=0x0a00",
+ "-D_WIN32_WINNT=0x0a00",
+ "-D_AMD64_",
+ "-D_M_AMD64",
+ "-D_M_X64",
+ "-D_WIN64",
+ "-D_WIN32",
+ "-D_USE_ATTRIBUTES_FOR_SAL",
+ "-D_CRTBLD",
+ "-D_OPENMP_NOFORCE_MANIFEST",
+ "-DLPSKBINFO=LPARAM",
+ "-DCONST=const",
+ "-D_CRT_SECURE_NO_WARNINGS",
+ "-D_CRT_NONSTDC_NO_DEPRECATE",
+ "-D_CRT_NONSTDC_NO_WARNINGS",
+ "-D_CRT_OBSOLETE_NO_DEPRECATE",
+ "-D_ALLOW_KEYWORD_MACROS",
+ "-D_ASSERT_OK",
+ "-DSTRSAFE_NO_DEPRECATE",
+ "-D__possibly_notnullterminated",
+ "-Dtype_info=\"void *\"",
+ "-D_ThrowInfo=ThrowInfo",
+ "-D__unaligned=",
+ "-v0",
+ "-D__inner_checkReturn=",
+ "-DDECLSPEC_DEPRECATED_DDK",
+ "-DWINAPI_PARTITION_APP=1",
+ "-DWINAPI_PARTITION_SYSTEM=1",
+ "-DWINAPI_PARTITION_GAMES=1",
+ "-DSECURITY_WIN32",
+ "-DSIZE_T=size_t",
+ };
+
+ File file = new File(outputDirectory+"/windows_vs22_64_new.gdt");
+ DataTypeManager vsDTMgr = FileDataTypeManager.openFileArchive(file, false);
+ DataTypeManager openTypes[] = { vsDTMgr };
+
+ parseHeaderFilesToGDT(openTypes, outputDirectory, "windows_vs22_wdk_64_new", "x86:LE:64:default", "windows", filenames, includePaths, args);
+ }
}
diff --git a/Ghidra/Features/Base/ghidra_scripts/CreateUEFIGDTArchivesScript.java b/Ghidra/Features/Base/ghidra_scripts/CreateUEFIGDTArchivesScript.java
new file mode 100644
index 0000000000..68a62be3f2
--- /dev/null
+++ b/Ghidra/Features/Base/ghidra_scripts/CreateUEFIGDTArchivesScript.java
@@ -0,0 +1,141 @@
+/* ###
+ * 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.
+ */
+//
+// Parses UEFI header file gdt archives from
+// git clone https://github.com/tianocore/edk2
+//
+// To replace existing header files and have the data type ID's synchronized
+//
+// Must run SynchronizeGDTCategoryPaths.java script with old and replacement GDT
+// archive to synchronize upper/lower case paths
+/// (only on windows archives)
+//
+// Then Run DataTypeArchiveTransformer in eclipse to synchronize old data types ID's
+// if an existing .gdt file is being replaced
+//
+//@category Data Types
+
+import java.io.File;
+import java.io.IOException;
+
+import ghidra.app.script.GhidraScript;
+import ghidra.app.util.cparser.C.CParserUtils;
+import ghidra.app.util.cparser.C.CParserUtils.CParseResults;
+import ghidra.app.util.cparser.C.ParseException;
+import ghidra.program.model.data.DataTypeManager;
+import ghidra.program.model.data.FileDataTypeManager;
+import ghidra.util.Msg;
+
+public class CreateUEFIGDTArchivesScript extends GhidraScript {
+
+ private File outputDirectory;
+
+ private static String headerFilePath = "/data/HeaderFiles/git/edk2";
+
+ @Override
+ protected void run() throws Exception {
+ outputDirectory = askDirectory("Select Directory for GDT files", "Select GDT Output Dir");
+
+ parseUEFIHeaders("X64", "x86:LE:64:default", "windows");
+ parseUEFIHeaders("Ia32", "x86:LE:32:default", "windows");
+
+ parseUEFIHeaders("AArch64", "AARCH64:LE:64:v8A", "windows");
+ parseUEFIHeaders("Arm", "ARM:LE:32:v8", "default");
+
+ parseUEFIHeaders("RiscV64", "RISCV:LE:64:RV64G", "gcc");
+ parseUEFIHeaders("LoongArch64", "Loongarch:LE:64:lp64d", "default");
+ }
+
+ private void parseHeaderFilesToGDT(File outputDir, String gdtName, String languageID, String compiler,
+ String[] filenames, String includePaths[], String[] args)
+ throws ParseException, ghidra.app.util.cparser.CPP.ParseException, IOException {
+ DataTypeManager openTypes[] = null;
+
+ parseHeaderFilesToGDT(openTypes, outputDir, gdtName, languageID, compiler, filenames, includePaths, args);
+ }
+
+ private void parseHeaderFilesToGDT(DataTypeManager openTypes[], File outputDir, String gdtName, String languageID, String compiler,
+ String[] filenames, String[] includePaths, String[] args)
+ throws ParseException, ghidra.app.util.cparser.CPP.ParseException, IOException {
+
+ String dataTypeFile = outputDir + File.separator + gdtName + ".gdt";
+
+ File f = getArchiveFile(dataTypeFile);
+
+ FileDataTypeManager dtMgr = FileDataTypeManager.createFileArchive(f,languageID, compiler);
+
+ CParseResults results = CParserUtils.parseHeaderFiles(openTypes, filenames, includePaths, args, dtMgr, monitor);
+
+ Msg.info(this, results.getFormattedParseMessage(null));
+
+ dtMgr.save();
+ dtMgr.close();
+ }
+
+ /**
+ * Turn string into a file, delete old archive if it exists
+ *
+ * @param dataTypeFile
+ *
+ * @return file
+ */
+ private File getArchiveFile(String dataTypeFile) {
+ File f = new File(dataTypeFile);
+ if (f.exists()) {
+ f.delete();
+ }
+ String lockFile = dataTypeFile + ".ulock";
+ File lf = new File(lockFile);
+ if (lf.exists()) {
+ lf.delete();
+ }
+ return f;
+ }
+
+ public void parseUEFIHeaders(String name, String languageID, String compiler) throws Exception {
+
+ String filenames[] = {
+ "ProcessorBind.h",
+ "Uefi/UefiBaseType.h",
+ "Uefi/UefiSpec.h",
+ "PiDxe.h",
+ "PiMm.h",
+ "PiPei.h",
+ "PiSmm.h",
+ "Library/DxeCoreEntryPoint.h",
+ "Library/PeiCoreEntryPoint.h",
+ "Library/PeimEntryPoint.h",
+ "Library/StandaloneMmDriverEntryPoint.h",
+ "Library/UefiApplicationEntryPoint.h",
+ "Library/UefiDriverEntryPoint.h",
+ headerFilePath+"/MdePkg/Include/Pi/",
+ headerFilePath+"/MdePkg/Include/Ppi/",
+ headerFilePath+"/MdePkg/Include/Protocol/",
+ headerFilePath+"/MdePkg/Include/IndustryStandard/",
+ };
+
+ String includePaths[] = {
+ headerFilePath+"/MdePkg/Include/"+name,
+ headerFilePath+"/MdePkg/Include",
+ };
+
+ String args[] = {
+ };
+
+ parseHeaderFilesToGDT(outputDirectory, "uefi_"+name, languageID, compiler, filenames, includePaths, args);
+ }
+
+}
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/cparser/CParserPlugin.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/cparser/CParserPlugin.java
index ac3ba4e266..148a4ca1d7 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/cparser/CParserPlugin.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/cparser/CParserPlugin.java
@@ -260,20 +260,22 @@ public class CParserPlugin extends ProgramPlugin {
}
protected String getFormattedParseMessage(String errMsg) {
- String message = "";
+ String message = "";
if (errMsg != null) {
message += errMsg + "\n\n";
+ message = HTMLUtilities.toHTML(message);
}
String msg = (results == null ? null : results.cParseMessages());
+
if (msg != null && msg.length() != 0) {
- message += "CParser Messages:\n" + msg + "\n\n";
+ message += "CParser Messages:
\n" + HTMLUtilities.toHTML(msg) + "
\n
\n";
}
msg = (results == null ? null : results.cppParseMessages());
if (msg != null && msg.length() != 0) {
- message += "PreProcessor Messages:\n" + msg;
+ message += "PreProcessor Messages:
\n" + HTMLUtilities.toHTML(msg);
}
return message;
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/cparser/C/CParserUtils.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/cparser/C/CParserUtils.java
index 8a4fb7af95..38ab475ae8 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/cparser/C/CParserUtils.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/cparser/C/CParserUtils.java
@@ -45,7 +45,7 @@ public class CParserUtils {
message += errMsg + "\n\n";
}
- String msg = cppParseMessages;
+ String msg = cParseMessages;
if (msg != null && msg.length() != 0) {
message += "CParser Messages:\n" + msg + "\n\n";
}
@@ -539,7 +539,7 @@ public class CParserUtils {
cppMessages = cpp.getParseMessages();
if (!parseSucceeded) {
- return new CParseResults(cpp, "", cppMessages, false);
+ return new CParseResults(cpp, cppMessages, "", false);
}
// process all the defines and add any that are integer values into
@@ -567,8 +567,8 @@ public class CParserUtils {
parserMessages = cParser.getParseMessages();
}
}
-
- return new CParseResults(cpp, parserMessages, cppMessages, cparseSucceeded);
+
+ return new CParseResults(cpp, cppMessages, parserMessages, cparseSucceeded);
}
private static String parseFile(String filename, TaskMonitor monitor, PreProcessor cpp)
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/cparser/CPP/DefineTable.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/cparser/CPP/DefineTable.java
index 26651775cc..42c173d0d7 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/cparser/CPP/DefineTable.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/cparser/CPP/DefineTable.java
@@ -388,6 +388,7 @@ public class DefineTable {
int replacedSubpieceLen = currKey.length();
if (argv == null && sublist.contains(currKey)) {
if (!initialList) {
+ // stop recursion of replacement
System.err.println("DONT Replace " + currKey + " in: " + buf);
}
return -1;
diff --git a/Ghidra/Features/Base/src/main/javacc/ghidra/app/util/cparser/C/C.jj b/Ghidra/Features/Base/src/main/javacc/ghidra/app/util/cparser/C/C.jj
index 9ccb2c9a58..49d6bd44d4 100644
--- a/Ghidra/Features/Base/src/main/javacc/ghidra/app/util/cparser/C/C.jj
+++ b/Ghidra/Features/Base/src/main/javacc/ghidra/app/util/cparser/C/C.jj
@@ -2029,13 +2029,13 @@ void StaticAssert() : {
Token t, message=null;
}
{
- ( ( t= ) "(" expr=ConstantExpression() [ "," message= ] ")" )
+ ( ( t= ) "(" expr=ConstantExpression() [ "," (message= | ("#" ) )+ ] ")" )
{
if (expr != null) {
Integer evalue = getConstantValue(expr,1);
if (evalue == 0) {
String smessage = (message == null ? "" : message.image);
- addNearParseMessage("Static_Asssert has failed " + " \"" + smessage + "\"");
+ addNearParseMessage("Warning: Static_Assert possibly failed " + " \"" + smessage + "\"");
}
}
}
diff --git a/Ghidra/Features/Base/src/main/javacc/ghidra/app/util/cparser/CPP/CPP.jj b/Ghidra/Features/Base/src/main/javacc/ghidra/app/util/cparser/CPP/CPP.jj
index 33560bbcb8..6ec2b81ae5 100644
--- a/Ghidra/Features/Base/src/main/javacc/ghidra/app/util/cparser/CPP/CPP.jj
+++ b/Ghidra/Features/Base/src/main/javacc/ghidra/app/util/cparser/CPP/CPP.jj
@@ -110,6 +110,7 @@ PARSER_BEGIN(PreProcessor)
package ghidra.app.util.cparser.CPP;
import ghidra.util.Msg;
+import ghidra.util.StringUtilities;
import ghidra.util.task.TaskMonitor;
import java.util.*;
@@ -281,6 +282,12 @@ public class PreProcessor {
BigInteger value = getLongValue(this.image);
comparison = value.compareTo(BigInteger.ZERO);
break;
+ case PreProcessor.CHAR_NUMERIC:
+ case PreProcessor.CHAR_LITERAL:
+ char ch = getCharacterValue(this.image);
+ BigInteger charValue = BigInteger.valueOf(ch);
+ comparison = charValue.compareTo(BigInteger.ZERO);
+ break;
case PreProcessor.ITEM:
case PreProcessor.MANIFEST:
case PreProcessor.VALUES:
@@ -314,6 +321,11 @@ public class PreProcessor {
case PreProcessor.INTEGER_LITERAL:
thisFP = new Double(getLongValue(this.image).doubleValue());
break;
+ case PreProcessor.CHAR_NUMERIC:
+ case PreProcessor.CHAR_LITERAL:
+ char ch = getCharacterValue(this.image);
+ thisFP = new Double((double)ch);
+ break;
default:
PPToken replVal = (PPToken) getDef(this); // not a PPToken
if (replVal == null) {
@@ -347,6 +359,11 @@ public class PreProcessor {
case PreProcessor.INTEGER_LITERAL:
thatFP = new Double(getLongValue(that.image).doubleValue());
break;
+ case PreProcessor.CHAR_NUMERIC:
+ case PreProcessor.CHAR_LITERAL:
+ char ch = getCharacterValue(this.image);
+ thisFP = new Double((double)ch);
+ break;
default:
PPToken replVal = (PPToken) getDef(that); // not a PPToken
if (replVal == null) {
@@ -432,7 +449,7 @@ public class PreProcessor {
}
PPToken t = new PPToken(result.toString());
t.kind = NUMERIC;
- t.setTruth(result != BigInteger.ZERO);
+ t.setTruth(!BigInteger.ZERO.equals(result));
return t;
}
@@ -655,7 +672,7 @@ public class PreProcessor {
if (verboseLevel == 5 || verboseLevel == 6) {
println("\t" + curFileStackTop() + "'" + key.beginLine
+ ": Defining text: " + key.image + " (");
- for (int i = 0; i < marg.size(); i++) {
+ for (int i = 0; marg!=null && i < marg.size(); i++) {
if (i == 0) {
print(((PPToken) marg.elementAt(i)).image);
} else if (i < marg.size() - 1) {
@@ -726,10 +743,22 @@ public class PreProcessor {
}
private void swapFileStreams(File incFile, FileInputStream fis) throws ParseException {
+ String fullPath = incFile.getAbsolutePath();
if (verboseLevel == 2)
- print(incFile.getAbsolutePath() + "\n");
+ print(fullPath + "\n");
else if (verboseLevel == 1)
- println("Parsing stream " + incFile.getAbsolutePath() + " ... ");
+ println("Parsing stream " + fullPath + " ... ");
+
+ boolean alreadyIncluded = addFile(fullPath);
+ if (!alreadyIncluded)
+ {
+ StringBuffer pad = new StringBuffer();
+ for (String element : fileStack) {
+ pad.append(" ");
+ }
+ addParseMessage(null, " " + pad + fullPath);
+ }
+
PreProcessor parser = null;
try {
//
@@ -738,19 +767,19 @@ public class PreProcessor {
int pos = -1;
int count = 0;
do {
- pos = fileStack.indexOf(incFile.getAbsolutePath(), pos + 1);
+ pos = fileStack.indexOf(fullPath, pos + 1);
if (pos >= 0) {
count++;
}
if (count > 5) {
- addParseMessage(incFile.getAbsolutePath(),
+ addParseMessage(fullPath,
"Error: Possible infinite inclusion recursion detected: \n" + fileStack);
return;
}
} while (pos != -1);
// check if this has already been done
- Integer val = alreadyDone.get(incFile.getAbsolutePath());
+ Integer val = alreadyDone.get(fullPath);
if (val == null) {
val = Integer.valueOf(0);
}
@@ -758,9 +787,9 @@ public class PreProcessor {
// still useful for debugging
val = val + 1;
- alreadyDone.put(incFile.getAbsolutePath(), val);
+ alreadyDone.put(fullPath, val);
- fileStack.push(incFile.getAbsolutePath());
+ fileStack.push(fullPath);
parser = new PreProcessor(this);
parser.ReInit(fis);
parser.Input();
@@ -857,7 +886,6 @@ public class PreProcessor {
File iFile = null;
int i;
- boolean alreadyIncluded = addFile(fn);
for (i = 0; i < pathList.size(); i++) {
iFile = getFile(pathList.elementAt(i), fn, xsym);
// don't include the same file name
@@ -886,13 +914,7 @@ public class PreProcessor {
if (verboseLevel == 2) {
print("Line " + inc.beginLine + ": " + curFileStackTop() + " => ");
}
- StringBuffer pad = new StringBuffer();
- for (String element : fileStack) {
- pad.append(" ");
- }
- if (!alreadyIncluded) {
- addParseMessage(null, " " + pad + iFile);
- }
+
swapFileStreams(iFile, fis);
if (verboseLevel == 1) {
addParseMessage(null, "Include depth " + fileStack.size() + ": Done!");
@@ -1239,6 +1261,17 @@ public class PreProcessor {
}
throw new NumberFormatException("Couldn't parse number: \'" + str + "\'");
}
+
+ private char getCharacterValue(String str) {
+ String charStr = str;
+ if (charStr.charAt(0) == 'L') {
+ charStr = charStr.substring(1);
+ }
+ // strip off "''"
+ charStr = charStr.substring(1, charStr.length()-1);
+ charStr = StringUtilities.convertEscapeSequences(charStr);
+ return charStr.charAt(0);
+ }
private void addParseMessage(String filename, String message) {
if (filename != null) {
@@ -1326,6 +1359,7 @@ public class PreProcessor {
this.shift = parent.shift;
this.alreadyDone = parent.alreadyDone;
this.verboseLevel = parent.verboseLevel;
+ this.parseMessages = parent.parseMessages;
}
public PreProcessor(String[] args) throws ParseException {
@@ -1536,7 +1570,7 @@ PPToken IFGroup() : { PPToken t, e, olde; }
} |
t=Else(){
if (execStack.size()==0) {
- addParseMessage(null, curFileStackTop()+"'"+t.beginLine+"Unbalanced IF directive detected");
+ addParseMessage(null, curFileStackTop()+"'"+t.beginLine+"Unbalanced ELSE directive detected");
throw new ParseException (curFileStackTop()+"'"+t.beginLine+"Unbalanced IF directive detected");
}
olde = (PPToken) execStack.pop();
@@ -1551,7 +1585,7 @@ PPToken IFGroup() : { PPToken t, e, olde; }
} |
t=EndIf(){
if (execStack.size()==0) {
- addParseMessage(null, curFileStackTop()+"'"+t.beginLine+"Unbalanced IF directive detected");
+ addParseMessage(null, curFileStackTop()+"'"+t.beginLine+"Unbalanced ENDIF directive detected");
throw new ParseException(curFileStackTop()+"'"+t.beginLine+"Unbalanced IF directive detected");
}
olde = (PPToken) execStack.pop();
@@ -1780,8 +1814,9 @@ PPToken Error() :
{Token t;}
{ t={
if (emitExecSwitch==true) {
- addParseMessage(null, curFileStackTop()+"'"+t.beginLine+" Compiler Error:");
+ addParseMessage(null, curFileStackTop()+"'"+t.beginLine+" #error Error:");
addParseMessage(null, t.image);
+ throw new ParseException("PreProcessor hit #error \"" + t.image + "\"");
}
return new PPToken(t);
}
@@ -2212,7 +2247,7 @@ PPToken Assertion() :
pt=Expression()
{
pt = new PPToken(pt);
- pt.setTruth(isDef(pt) || (pt.kind == FP_NUMERIC || pt.kind == NUMERIC)); // numbers are always defined
+ pt.setTruth(isDef(pt) || (pt.kind == FP_NUMERIC || pt.kind == NUMERIC || pt.kind == CHAR_NUMERIC)); // numbers are always defined
return pt;
})
|
@@ -2342,7 +2377,7 @@ PPToken ValueExpression() :
(
LOOKAHEAD(2)
- (t= | t= | t= | t= ) {
+ (t= | t= | t= | t= | t= ) {
if (verboseLevel()==7) print(t.image);
pt=new PPToken(t);
if (pt.compareToZero()==0) pt.setTruth(false);
@@ -2517,7 +2552,10 @@ TOKEN:
<#NOTWWSQLT: ~[" ","\t","\n","\r","<","\""]> |
<#NOTWSQLT: ~["\t","\n","\r","<","\""]> |
<#NOTVALCMT: ("/##/")> |
- (["u","l","L","U"])* | (["u","l","L","U"])* | (["u","l","L","U"])*> |
+ (["u","l","L","U"])* |
+ (["u","l","L","U"])* |
+ (["u","l","L","U"])* > |
+ <#CHAR_LITERAL: ("L")? "\'" (~["\'"])+ "\'" > |
<#DECIMAL_LITERAL: ["0"-"9"] (["0"-"9"])*> |
<#HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+> |
<#HEX_DIGIT: (["0"-"9","a"-"f","A"-"F"])> |
@@ -2609,6 +2647,7 @@ TOKEN : {
// |
)+ > |
)+ > |
+ )+ > |
|
> { parenNesting++; } : DIRECTIVE |
> { parenNesting--; } : DIRECTIVE |
@@ -2802,10 +2841,18 @@ TOKEN : {
)+>
}
+
SKIP : {
-//TOKEN : {
- <_ECMT3: (~["*"])* "*" ("*" | ~["*","/"] (~["*"])* "*")* "/"> : DEFAULT
+ <_ECMT_COMMENT_ns: ~["*"] > : COMMENT |
+ <_ECMT_COMMENT_s: "*" > : COMMENT_END
+}
+
+
+SKIP : {
+ <_ECMT_COMMENT_es: "*" > : COMMENT_END |
+ <_ECMT_COMMENT_eo: ~["*","/"] > : COMMENT |
+ <_ECMT_COMMENT_e: "/" > : DEFAULT
}
@@ -2815,8 +2862,15 @@ SKIP : {
SKIP : {
-//TOKEN : {
- <_ECMT10: (~["*"])* "*" ("*" | ~["*","/"] (~["*"])* "*")* "/"> : DIRECTIVE
+ <_ECMT_DIRECTIVECOMMENT_ns: ~["*"] > : DIRECTIVECOMMENT |
+ <_ECMT_DIRECTIVECOMMENT_s: "*" > : DIRECTIVECOMMENT_END
+}
+
+
+SKIP : {
+ <_ECMT_DIRECTIVECOMMENT_es: "*" > : DIRECTIVECOMMENT_END |
+ <_ECMT_DIRECTIVECOMMENT_eo: ~["*","/"] > : DIRECTIVECOMMENT |
+ <_ECMT_DIRECTIVECOMMENT_e: "/" > : DIRECTIVE
}
@@ -2841,12 +2895,21 @@ TOKEN : {
>
}
+
SKIP : {
- <_ECMT7: ~["*"] | "*" ~["/"] > : RVALUES_COMMENT |
- <_EECMT7: > : RVALUES
+ <_ECMT_RVALUES_ns: ~["*"] > : RVALUES_COMMENT |
+ <_ECMT_RVALUES_s: "*" > : RVALUES_COMMENT_END
}
+
+SKIP : {
+ <_ECMT_RVALUES_es: "*" > : RVALUES_COMMENT_END |
+ <_ECMT_RVALUES_eo: ~["*","/"] > : RVALUES_COMMENT |
+ <_ECMT_RVALUES_e: "/" > : RVALUES
+}
+
+
SKIP:
{
@@ -2868,14 +2931,27 @@ TOKEN : {
SKIP : {
- <_ECMT5: (~["*"])* "*" ("*" | ~["*","/"] (~["*"])* "*")* "/"> : MACROARGS |
- <_CMT5: (~["\n","\r"])+ > : MACROARGS |
+ <_ECMT_MACROARGS: > : MACROARGSCOMMENT |
+ <_CMT_MACROARGS: (~["\n","\r"])+ > : MACROARGS |
<_MWSP: ","> : MACROARGS |
<_COD3: > : MACROARGS |
<_MACWSP: > : MACROARGS
}
+
+SKIP : {
+ <_ECMT_MACROARGSns: ~["*"] > : MACROARGSCOMMENT |
+ <_ECMT_MACROARGSs: "*" > : MACROARGSCOMMENT_END
+}
+
+
+SKIP : {
+ <_ECMT_MACROARGSes: "*" > : MACROARGSCOMMENT_END |
+ <_ECMT_MACROARGSeo: ~["*","/"] > : MACROARGSCOMMENT |
+ <_ECMT_MACROARGSe: "/" > : MACROARGS
+}
+
SKIP : {
")" : MACROVALS
@@ -2918,7 +2994,14 @@ TOKEN:
SKIP : {
- <_ECMT9: ~["*"] | "*" ~["/"] > : MACROVALS_COMMENT |
- <_EEECMT9: > : MACROVALS |
- <_EECMT9: ()* > : DEFAULT
+ <_ECMT_MACROVALS_ns: ~["*"] > : MACROVALS_COMMENT |
+ <_ECMT_MACROVALS_s: "*" > : MACROVALS_COMMENT_END
+}
+
+
+SKIP : {
+ <_ECMT_MACROVALS_es: "*" > : MACROVALS_COMMENT_END |
+ <_ECMT_MACROVALS_eo: ~["*","/"] > : MACROVALS_COMMENT |
+ <_ECMT_MACROVALS_e: "/" > : MACROVALS |
+ <_ECMT_MACROVALS_ew: "/" ()* > : DEFAULT
}
diff --git a/Ghidra/Features/Base/src/test/java/ghidra/app/util/cparser/CParserTest.java b/Ghidra/Features/Base/src/test/java/ghidra/app/util/cparser/CParserTest.java
index e3b0058727..4ab5fdbeea 100644
--- a/Ghidra/Features/Base/src/test/java/ghidra/app/util/cparser/CParserTest.java
+++ b/Ghidra/Features/Base/src/test/java/ghidra/app/util/cparser/CParserTest.java
@@ -4,9 +4,9 @@
* 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.
@@ -246,9 +246,9 @@ public class CParserTest extends AbstractGhidraHeadlessIntegrationTest {
assertTrue("Duplicate ENUM message missing", parseMessages.contains("duplicate enum value: options_enum : PLUS_SET : 16"));
- assertTrue("Duplicate ENUM message missing", parseMessages.contains("Static_Asssert has failed \"\"math fail!\"\""));
+ assertTrue("Static assert fail missing", parseMessages.contains("Static_Assert possibly failed \"\"math fail!\"\""));
- assertTrue("Duplicate ENUM message missing", parseMessages.contains("Static_Asssert has failed \"\"1 + 1 == 3, fail!\"\""));
+ assertTrue("Static assert fail missing", parseMessages.contains("Static_Assert possibly failed \"\"1 + 1 == 3, fail!\"\""));
dt = dtMgr.getDataType(new CategoryPath("/"), "_IO_FILE_complete");
Structure sldt = (Structure) dt;
diff --git a/Ghidra/Features/Base/src/test/resources/ghidra/app/util/cparser/CParserTest.h b/Ghidra/Features/Base/src/test/resources/ghidra/app/util/cparser/CParserTest.h
index c0e162d7d9..7e9d27fad4 100644
--- a/Ghidra/Features/Base/src/test/resources/ghidra/app/util/cparser/CParserTest.h
+++ b/Ghidra/Features/Base/src/test/resources/ghidra/app/util/cparser/CParserTest.h
@@ -1235,6 +1235,8 @@ int check_assert(void)
int x;
static_assert(sizeof(int) > sizeof(char));
+
+ _Static_assert(sizeof(char) <= 1, "message " #Name " is broken " #Up );
}
struct statcheck {
diff --git a/Ghidra/Features/Base/src/test/resources/ghidra/app/util/cparser/PreProcessorTest.h b/Ghidra/Features/Base/src/test/resources/ghidra/app/util/cparser/PreProcessorTest.h
index cc3afcb769..72046da90e 100644
--- a/Ghidra/Features/Base/src/test/resources/ghidra/app/util/cparser/PreProcessorTest.h
+++ b/Ghidra/Features/Base/src/test/resources/ghidra/app/util/cparser/PreProcessorTest.h
@@ -4,9 +4,9 @@
* 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.
@@ -19,6 +19,24 @@
#undef a
#endif
+#ifdef __WCHAR_MAX__
+# define __WCHAR_MAX __WCHAR_MAX__
+#elif L'\0' - 1 > 0
+# define __WCHAR_MAX (0xffffffffu + L'\0')
+#else
+# define __WCHAR_MAX (0x7fffffff + L'\0')
+#endif
+
+/* test for comment parsing */
+# define AComment(a) B(a) /**/
+
+# define BComment(a) C(a) /***/
+# define CComment /****/
+
+# ifndef FOO
+#define DidFOO "true" /* test comment */
+# endif
+
/* definition coming from -D, should evaluate to true */
#if FROM_ARG_VALUE
@@ -171,10 +189,10 @@ int foo;
#define TWOFISH 2
#if (ONEFISH + TWOFISH + REDFISH + BLUEFISH) > 2
-#error "Too many fish"
#define TOO_MANY_FISH 0
int TooManyFish;
#else
+#error "Too few fish"
int NotEnoughFish;
#endif
@@ -536,5 +554,32 @@ D = DUAL_MULTILINE(2, "Caution: First line"
" second line"
" third line"
" fourth line")
-
+
+//
+// check calculations
+//
+#define NUMBER1 0x10000000
+#define NUMBER2 0x10000001
+#define NUMBER3 0xF0000002
+
+#if (NUMBER2 <= NUMBER1) || (NUMBER3 <= NUMBER2)
+#error new number must be greater than the old one
+#endif
+
+#if (NUMBER1 & 0xE0000000)
+#error NUMBER1 & 0xE0000000 should be false
+#endif
+
+#if (NUMBER2 & 0xE0000000)
+#error NUMBER2 & 0xE0000000 should be false
+#endif
+
+#if !(NUMBER3 & 0xE0000000)
+#error NUMBER3 & 0xE0000000 should be true
+#endif
+
+#if ((NUMBER2 & 0xE0000000) || (NUMBER2 & 0xE0000000)) || !(NUMBER3 & 0xE0000000)
+#error ((NUMBER2 & 0xE0000000) || (NUMBER2 & 0xE0000000)) || !(NUMBER3 & 0xE0000000) should be false
+#endif
+
theEnd();
From 553d7103b7ad9fdf46343ac5f3b593d13f83a810 Mon Sep 17 00:00:00 2001
From: emteere <47253321+emteere@users.noreply.github.com>
Date: Wed, 22 Jan 2025 22:16:52 +0000
Subject: [PATCH 2/4] GP-5025 Fix for comment parsing and commenting out of
#ifdefed out lines
---
.../CreateUEFIGDTArchivesScript.java | 7 +-
.../javacc/ghidra/app/util/cparser/CPP/CPP.jj | 88 ++++++++++++-------
.../app/util/cparser/PreProcessorTest.java | 28 ++++--
.../app/util/cparser/PreProcessorTest.h | 27 ++++++
.../ghidra/app/util/cparser/multinclude.h | 10 +--
5 files changed, 113 insertions(+), 47 deletions(-)
diff --git a/Ghidra/Features/Base/ghidra_scripts/CreateUEFIGDTArchivesScript.java b/Ghidra/Features/Base/ghidra_scripts/CreateUEFIGDTArchivesScript.java
index 68a62be3f2..02fadb008f 100644
--- a/Ghidra/Features/Base/ghidra_scripts/CreateUEFIGDTArchivesScript.java
+++ b/Ghidra/Features/Base/ghidra_scripts/CreateUEFIGDTArchivesScript.java
@@ -74,12 +74,9 @@ public class CreateUEFIGDTArchivesScript extends GhidraScript {
String dataTypeFile = outputDir + File.separator + gdtName + ".gdt";
File f = getArchiveFile(dataTypeFile);
-
- FileDataTypeManager dtMgr = FileDataTypeManager.createFileArchive(f,languageID, compiler);
- CParseResults results = CParserUtils.parseHeaderFiles(openTypes, filenames, includePaths, args, dtMgr, monitor);
-
- Msg.info(this, results.getFormattedParseMessage(null));
+ FileDataTypeManager dtMgr = CParserUtils.parseHeaderFiles(openTypes, filenames,
+ includePaths, args, f.getAbsolutePath(), languageID, compiler, monitor);
dtMgr.save();
dtMgr.close();
diff --git a/Ghidra/Features/Base/src/main/javacc/ghidra/app/util/cparser/CPP/CPP.jj b/Ghidra/Features/Base/src/main/javacc/ghidra/app/util/cparser/CPP/CPP.jj
index 6ec2b81ae5..6e9617b614 100644
--- a/Ghidra/Features/Base/src/main/javacc/ghidra/app/util/cparser/CPP/CPP.jj
+++ b/Ghidra/Features/Base/src/main/javacc/ghidra/app/util/cparser/CPP/CPP.jj
@@ -526,7 +526,7 @@ public class PreProcessor {
}
}
if (image.length() == 1 && image.startsWith("\n")) {
- image = (!emitExecSwitch ? "////\n" : "\n");
+ image = (!emitExecSwitch ? "///-\n" : "\n");
}
print(image);
}
@@ -858,11 +858,25 @@ public class PreProcessor {
return false;
}
- void bufAppendWithComment(PPToken buf, Token u) {
- if (emitExecSwitch==true)
- buf.append(u.image,true);
- else
- buf.append("//// " + u.image, false);
+// void bufAppendWithComment(PPToken buf, Token u) {
+// if (emitExecSwitch==true)
+// buf.append(u.image,true);
+// else
+// buf.append("///- " + u.image, false);
+// }
+
+ void bufAppendWithComment(PPToken buf, Token u, Token previous, boolean commentNL) {
+ String str = u.image;
+ if (!emitExecSwitch) {
+ if (commentNL) {
+ // if not emmitting, replace any embedded \n with a \n-comment
+ str = str.replace("\n", "\n///- ");
+ }
+ if (previous == null || previous.image.length() == 0) {
+ str = "///- " + str;
+ }
+ }
+ buf.append(str, emitExecSwitch);
}
// Parse include file
@@ -1079,9 +1093,9 @@ public class PreProcessor {
private void printCommentedLines(boolean emitSwitch, String line, String state) {
StringBuffer buf = new StringBuffer("///");
- buf.append(emitSwitch ? " " : "/" );
+ buf.append(emitSwitch ? "+ " : "- " );
buf.append(line);
- if (emitSwitch) {
+ if (emitSwitch && state != null) {
buf.append(" ===" + state);
}
buf.append("\n");
@@ -1538,7 +1552,7 @@ PPToken IFGroup() : { PPToken t, e, olde; }
}
olde = (PPToken) execStack.pop();
emitExecSwitch = olde.getEmitSave();
- printCommentedLines(emitExecSwitch, "#else if " + t.image, "" + t.getTruth());
+ printCommentedLines(emitExecSwitch, "#elif " + t.image, "" + t.getTruth());
e.setEmitSave(emitExecSwitch);
if (!olde.getTruth() && emitExecSwitch==true)
emitExecSwitch = e.getTruth();
@@ -1618,6 +1632,8 @@ PPToken Include() : {Token t;PPToken pt;int conditionDepth=execStack.size();}
if (emitExecSwitch==true) {
localPlace(pt, true);
println("\n#line "+t.beginLine+": \""+curFileStackTop()+"\"");
+ } else {
+ printCommentedLines(emitExecSwitch, "#include <"+t.beginLine+">", "");
}
}
|t={
@@ -1625,6 +1641,8 @@ PPToken Include() : {Token t;PPToken pt;int conditionDepth=execStack.size();}
if (emitExecSwitch==true) {
standardPlace(pt, true);
println("\n#line "+t.beginLine+": \""+curFileStackTop()+"\"");
+ } else {
+ printCommentedLines(emitExecSwitch, "#include \""+t.beginLine+"\"", "");
}
}
|t={
@@ -1738,6 +1756,7 @@ PPToken UnDef() : {Token t;}
if (isDef(pt)==true) {
UnDefine(pt);
}
+ printCommentedLines(emitExecSwitch, "#undef " + def.image, null);
return pt;
}
}
@@ -1762,8 +1781,13 @@ PPToken MacroVals() : {Token s,t,u=new Token();u.image="";}
PPToken Pragma() :
{Token t,u=null; }
{ (LOOKAHEAD(2)(t= { if (u==null) { u = t; } else { u.image += t.image; } } ))+ {
- PPToken pt = new PPToken(u);
- if (emitExecSwitch==true) println("#pragma " + defs.expand(u.image,true)); return pt;
+ PPToken pt = new PPToken("#pragma");
+ pt.append(u.image,emitExecSwitch);
+ if (emitExecSwitch==true) {
+ println("#pragma" + defs.expand(u.image,true));
+ } else {
+ printCommentedLines(emitExecSwitch, "#pragma" + u.image, null);
+ }
}
}
@@ -1813,6 +1837,7 @@ PPToken IfNDefExpr() :
PPToken Error() :
{Token t;}
{ t={
+ printCommentedLines(emitExecSwitch, "#error " + t.image, "Error!");
if (emitExecSwitch==true) {
addParseMessage(null, curFileStackTop()+"'"+t.beginLine+" #error Error:");
addParseMessage(null, t.image);
@@ -1825,6 +1850,7 @@ PPToken Error() :
PPToken Warning() :
{Token t;}
{ t={
+ printCommentedLines(emitExecSwitch, "#warning " + t.image, "Warning!");
if (emitExecSwitch==true) {
addParseMessage(null, curFileStackTop()+"'"+t.beginLine+" Warning: ");
addParseMessage(null, t.image);
@@ -1902,31 +1928,31 @@ PPToken QuotedValue() :
}
PPToken Text() :
-{Token u, nl, t = new Token(); PPToken buf = new PPToken(""); t.image="";}
+{Token u, nl, lastToken; PPToken buf = new PPToken(""); }
{
( LOOKAHEAD(3)
- (LOOKAHEAD(2)(u={ bufAppendWithComment(buf,u); }
- (LOOKAHEAD(2)nl=NewLines() {if (emitExecSwitch==true) buf.append(nl.image,true); else buf.append((u.image.length() == 0 ? "//// " : "") + nl.image, false); } )* |
+ (LOOKAHEAD(2)(u= { bufAppendWithComment(buf,u,lastToken,false); lastToken = u; }
+ (LOOKAHEAD(2) nl=NewLines() { bufAppendWithComment(buf,nl,lastToken,false); lastToken = null; } )* |
- u= {bufAppendWithComment(buf,u); } )
- [LOOKAHEAD(2)u=NewLines() {bufAppendWithComment(buf,u); }]
- [(LOOKAHEAD(2)(u=QuotedText() {bufAppendWithComment(buf,u); }
- [LOOKAHEAD(2)u=NewLines(){ bufAppendWithComment(buf,u); }] |
- u= {bufAppendWithComment(buf,u); })
- [LOOKAHEAD(2)t=NewLines() {if (emitExecSwitch==true) buf.append(t.image,true); else buf.append("//// " + u.image, false); }]
- [LOOKAHEAD(2)u= {bufAppendWithComment(buf,u); }]
- [LOOKAHEAD(2)u=NewLines() {bufAppendWithComment(buf,u); }])+]
- [LOOKAHEAD(2)u= {bufAppendWithComment(buf,u); }
- (LOOKAHEAD(2)u=NewLines(){ bufAppendWithComment(buf,u);})*])+|
+ u= { bufAppendWithComment(buf,u,lastToken,false); lastToken = u; } )
+ [LOOKAHEAD(2)nl=NewLines() { bufAppendWithComment(buf,nl,lastToken,false); lastToken = null; }]
+ [(LOOKAHEAD(2)(u=QuotedText() { bufAppendWithComment(buf,u,lastToken,true); lastToken = u; }
+ [LOOKAHEAD(2) nl=NewLines(){ bufAppendWithComment(buf,nl,lastToken,false); lastToken = null; }] |
+ u= { bufAppendWithComment(buf,u,lastToken,false); lastToken = u; })
+ [LOOKAHEAD(2) nl=NewLines() { bufAppendWithComment(buf,nl,lastToken,false); lastToken = null; } ]
+ [LOOKAHEAD(2) u= { bufAppendWithComment(buf,u,lastToken,false); lastToken = u; }]
+ [LOOKAHEAD(2) nl=NewLines() { bufAppendWithComment(buf,nl,lastToken,false); lastToken = null; }])+]
+ [LOOKAHEAD(2) u= { bufAppendWithComment(buf,u,lastToken,false); lastToken = u; }
+ (LOOKAHEAD(2) nl=NewLines(){ bufAppendWithComment(buf,nl,lastToken,false); lastToken = null; })*])+|
- (LOOKAHEAD(2)(u=QuotedText() {bufAppendWithComment(buf,u); }
- [LOOKAHEAD(2)u=NewLines(){ bufAppendWithComment(buf,u); }] |
- u= {bufAppendWithComment(buf,u); })
- [LOOKAHEAD(2)t=NewLines() {if (emitExecSwitch==true) buf.append(t.image,true); else buf.append("//// " + u.image, false); }]
- [LOOKAHEAD(2)u= {bufAppendWithComment(buf,u); }]
- [LOOKAHEAD(2)u=NewLines() {bufAppendWithComment(buf,u); }])+ |
+ (LOOKAHEAD(2)(u=QuotedText() { bufAppendWithComment(buf,u,lastToken,true); lastToken = u; }
+ [LOOKAHEAD(2) nl=NewLines(){ bufAppendWithComment(buf,nl,lastToken,false); lastToken = null; }] |
+ u= { bufAppendWithComment(buf, u,lastToken,false); lastToken = u; })
+ [LOOKAHEAD(2) nl=NewLines() { bufAppendWithComment(buf,nl,lastToken,false); lastToken = null; }]
+ [LOOKAHEAD(2) u= { bufAppendWithComment(buf, u,lastToken,false); lastToken = u; }]
+ [LOOKAHEAD(2) nl=NewLines() { bufAppendWithComment(buf, nl,lastToken,false); lastToken = null; }])+ |
- u=NewLines() {bufAppendWithComment(buf,u); }
+ nl=NewLines() { bufAppendWithComment(buf,nl); lastToken = null; }
) { return buf;}
}
diff --git a/Ghidra/Features/Base/src/test/java/ghidra/app/util/cparser/PreProcessorTest.java b/Ghidra/Features/Base/src/test/java/ghidra/app/util/cparser/PreProcessorTest.java
index fcbd7af84e..5a1d087d61 100644
--- a/Ghidra/Features/Base/src/test/java/ghidra/app/util/cparser/PreProcessorTest.java
+++ b/Ghidra/Features/Base/src/test/java/ghidra/app/util/cparser/PreProcessorTest.java
@@ -4,9 +4,9 @@
* 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.
@@ -91,7 +91,7 @@ public class PreProcessorTest extends AbstractGenericTest {
System.out.println(parser.getParseMessages());
// Uncomment to print out parse results
- // System.err.println(baos.toString());
+ //System.err.println(baos.toString());
dtMgr = new StandAloneDataTypeManager("parsed");
parser.getDefinitions().populateDefineEquates(null, dtMgr);
@@ -129,13 +129,29 @@ public class PreProcessorTest extends AbstractGenericTest {
"\" fourth line\")") != -1);
assertTrue("multi line #pragma failed ", results
- .indexOf("#pragma multiple lines pragma") != -1);
+ .indexOf("#pragma multiple lines pragma") != -1);
assertTrue("#pragma with comment failed ", results
- .indexOf("#pragma no comment here") != -1);
+ .indexOf("#pragma no comment here") != -1);
assertTrue("#pragma with EOL comment failed ", results
- .indexOf("#pragma with no EOL comment here") != -1);
+ .indexOf("#pragma with no EOL comment here") != -1);
+ }
+
+ @Test
+ public void testCommenting() throws Exception {
+
+ String results = baos.toString("ASCII");
+
+ assertTrue("IntShouldBeCommented", results
+ .indexOf("///- int IntShouldBeCommented;") != -1);
+ assertTrue("PragmaShouldBeCommented", results
+ .indexOf("///- #pragma PragmaShouldBeCommented") != -1);
+
+ assertTrue("IntShouldNotBeCommented", results
+ .indexOf("int IntShouldBeCommented;") != -1);
+ assertTrue("PragmaShouldNotBeCommented", results
+ .indexOf("#pragma PragmaShouldNotBeCommented") != -1);
}
@Test
diff --git a/Ghidra/Features/Base/src/test/resources/ghidra/app/util/cparser/PreProcessorTest.h b/Ghidra/Features/Base/src/test/resources/ghidra/app/util/cparser/PreProcessorTest.h
index 72046da90e..cb3c19204e 100644
--- a/Ghidra/Features/Base/src/test/resources/ghidra/app/util/cparser/PreProcessorTest.h
+++ b/Ghidra/Features/Base/src/test/resources/ghidra/app/util/cparser/PreProcessorTest.h
@@ -37,6 +37,16 @@
#define DidFOO "true" /* test comment */
# endif
+#ifdef NOFOO
+int IntShouldBeCommented;
+#pragma PragmaShouldBeCommented
+#endif
+
+#ifndef NOFOO
+int IntShouldNotBeCommented;
+#pragma PragmaShouldNotBeCommented;
+#endif
+
/* definition coming from -D, should evaluate to true */
#if FROM_ARG_VALUE
@@ -460,6 +470,23 @@ ldp LDP((
_Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Wmismatched-tags\"")
+/**
+ ** Multi line false ifdef with Quoted string
+ */
+
+#define __USE_GNU "1"
+
+#ifdef __USE_GNU
+extern int pthread_yield (void) __THROW;
+# ifdef __REDIRECT_NTH
+extern int __REDIRECT_NTH (pthread_yield, (void), sched_yield)
+ __attribute_deprecated_msg__ ("\
+pthread_yield is deprecated, use sched_yield instead");
+# else
+# define pthread_yield sched_yield
+# endif
+#endif
+
/**
** Protected from macro expansion
**/
diff --git a/Ghidra/Features/Base/src/test/resources/ghidra/app/util/cparser/multinclude.h b/Ghidra/Features/Base/src/test/resources/ghidra/app/util/cparser/multinclude.h
index d9df9c33f3..c298c2e5bc 100644
--- a/Ghidra/Features/Base/src/test/resources/ghidra/app/util/cparser/multinclude.h
+++ b/Ghidra/Features/Base/src/test/resources/ghidra/app/util/cparser/multinclude.h
@@ -4,9 +4,9 @@
* 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.
@@ -17,15 +17,15 @@
#define INCLUDE1
#pragma pack(push,1)
-#else if !defined(INCLUDE2)
+#elif !defined(INCLUDE2)
#define INCLUDE2
#pragma pack(push, 2)
-#else if !defined(INCLUDE3)
+#elif !defined(INCLUDE3)
#define INCLUDE3
#pragma pack(push, 4)
-#else if !defined(INCLUDE4)
+#elif !defined(INCLUDE4)
#define INCLUDE4
#pragma pack(push, 8)
From 4a321dda2ab1254d8646e433ca3dd198639072c3 Mon Sep 17 00:00:00 2001
From: emteere <47253321+emteere@users.noreply.github.com>
Date: Thu, 23 Jan 2025 22:08:57 +0000
Subject: [PATCH 3/4] GP-5025 Fixing issue with <> in comments on an include
line
---
.../javacc/ghidra/app/util/cparser/CPP/CPP.jj | 29 +++++++++++++++----
1 file changed, 24 insertions(+), 5 deletions(-)
diff --git a/Ghidra/Features/Base/src/main/javacc/ghidra/app/util/cparser/CPP/CPP.jj b/Ghidra/Features/Base/src/main/javacc/ghidra/app/util/cparser/CPP/CPP.jj
index 6e9617b614..c069535c1f 100644
--- a/Ghidra/Features/Base/src/main/javacc/ghidra/app/util/cparser/CPP/CPP.jj
+++ b/Ghidra/Features/Base/src/main/javacc/ghidra/app/util/cparser/CPP/CPP.jj
@@ -1261,6 +1261,7 @@ public class PreProcessor {
try {
if (str.endsWith("L") || str.endsWith("l") || str.endsWith("U")) {
str = str.substring(0, str.length() - 1);
+ return getLongValue(str);
}
if (str.startsWith("--")) {
@@ -1756,7 +1757,7 @@ PPToken UnDef() : {Token t;}
if (isDef(pt)==true) {
UnDefine(pt);
}
- printCommentedLines(emitExecSwitch, "#undef " + def.image, null);
+ printCommentedLines(emitExecSwitch, "#undef " + pt.image, null);
return pt;
}
}
@@ -1788,6 +1789,7 @@ PPToken Pragma() :
} else {
printCommentedLines(emitExecSwitch, "#pragma" + u.image, null);
}
+ return pt;
}
}
@@ -1928,7 +1930,7 @@ PPToken QuotedValue() :
}
PPToken Text() :
-{Token u, nl, lastToken; PPToken buf = new PPToken(""); }
+{Token u, nl, lastToken = null; PPToken buf = new PPToken(""); }
{
( LOOKAHEAD(3)
(LOOKAHEAD(2)(u= { bufAppendWithComment(buf,u,lastToken,false); lastToken = u; }
@@ -1952,7 +1954,10 @@ PPToken Text() :
[LOOKAHEAD(2) u= { bufAppendWithComment(buf, u,lastToken,false); lastToken = u; }]
[LOOKAHEAD(2) nl=NewLines() { bufAppendWithComment(buf, nl,lastToken,false); lastToken = null; }])+ |
- nl=NewLines() { bufAppendWithComment(buf,nl); lastToken = null; }
+ nl=NewLines() {
+ //bufAppendWithComment(buf,nl);
+ lastToken = null;
+ }
) { return buf;}
}
@@ -2722,7 +2727,7 @@ TOKEN : {
TOKEN : {
> : INCLUDE |
- ()* > : DEFAULT
+ ()* > : DEFAULT
}
@@ -2730,7 +2735,21 @@ SKIP : {
<_COD: > : INCLUDE |
<_WSP: > : INCLUDE |
<__LT: <_LT> > : STDPATH |
- <_QTE: > : RELPATH
+ <_QTE: > : RELPATH |
+ <_ECMT_INC: > : INCLUDE_COMMENT
+}
+
+
+SKIP : {
+ <_ECMT_INCLUDE_ns: ~["*"] > : INCLUDE_COMMENT |
+ <_ECMT_INCLUDE_s: "*" > : INCLUDE_COMMENT_END
+}
+
+
+SKIP : {
+ <_ECMT_INCLUDE_es: "*" > : INCLUDE_COMMENT_END |
+ <_ECMT_INCLUDE_eo: ~["*","/"] > : INCLUDE_COMMENT |
+ <_ECMT_INCLUDE_e: "/" > : INCLUDE
}
From 4ca5007bd0dee335ca4e5d6b0951d6c6df377465 Mon Sep 17 00:00:00 2001
From: emteere <47253321+emteere@users.noreply.github.com>
Date: Sun, 26 Jan 2025 18:28:20 +0000
Subject: [PATCH 4/4] GP-5025_emteere Tuned comparing of Enums and pathnames in
GDT's
---
.../Base/ghidra_scripts/CompareGDTs.java | 48 +++++++++++++++++--
1 file changed, 44 insertions(+), 4 deletions(-)
diff --git a/Ghidra/Features/Base/ghidra_scripts/CompareGDTs.java b/Ghidra/Features/Base/ghidra_scripts/CompareGDTs.java
index a2e399bd16..d2dac13c92 100644
--- a/Ghidra/Features/Base/ghidra_scripts/CompareGDTs.java
+++ b/Ghidra/Features/Base/ghidra_scripts/CompareGDTs.java
@@ -4,9 +4,9 @@
* 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.
@@ -22,10 +22,11 @@
import java.io.File;
import java.io.PrintWriter;
-import java.util.Iterator;
+import java.util.*;
import ghidra.app.script.GhidraScript;
import ghidra.program.model.data.*;
+import ghidra.program.model.data.Enum;
import ghidra.program.model.data.StandAloneDataTypeManager.ArchiveWarning;
import ghidra.util.UniversalID;
@@ -162,7 +163,22 @@ public class CompareGDTs extends GhidraScript {
return dtmArchive.findDataTypeForID(universalID);
}
}
- return dtmArchive.getDataType(dataType.getCategoryPath(), dataType.getName());
+
+ // find by exact path
+ DataType fdt = dtmArchive.getDataType(dataType.getCategoryPath(), dataType.getName());
+ if (fdt != null) {
+ return fdt;
+ }
+
+ // find by name
+ List list = new ArrayList();
+ dtmArchive.findDataTypes(dataType.getName(), list );
+ for (DataType dtc : list) {
+ if (dataType.getCategoryPath().getPath().toLowerCase().equals(dtc.getCategoryPath().getPath().toLowerCase())) {
+ return dtc;
+ }
+ }
+ return null;
}
private long outputWhereTypesDiffer(FileDataTypeManager dtmArchive1,
@@ -247,6 +263,10 @@ public class CompareGDTs extends GhidraScript {
Class> dtClass = dataType.getClass();
Class> sameNamedDtClass = matchingDataType.getClass();
if (dtClass == sameNamedDtClass) {
+ if (dataType instanceof Enum && (((Enum) dataType).getCount()==1)) {
+ // don't check single entry enums. Size will vary, and they are extracted defines
+ return checkEnum((Enum) dataType, (Enum) matchingDataType);
+ }
if (!dataType.isEquivalent(matchingDataType)) {
String message =
dataType.getPathName() + " (" + dtClass.getSimpleName() + ")";
@@ -258,6 +278,22 @@ public class CompareGDTs extends GhidraScript {
return false;
}
+ private boolean checkEnum(Enum e1, Enum e2) {
+ if (e1.getCount() != e2.getCount()) {
+ return true;
+ }
+ // Check that the name is the same
+ if (! e1.getNames()[0].equals(e2.getNames()[0])) {
+ return true;
+ }
+ // Check the value is the same
+ if (e1.getValues()[0] != e2.getValues()[0]) {
+ return true;
+ }
+
+ return false;
+ }
+
private boolean outputIfDifferentSizes(DataType dataType, FileDataTypeManager dtmArchive) {
if (!checkPointers && dataType instanceof Pointer) {
@@ -273,6 +309,10 @@ public class CompareGDTs extends GhidraScript {
Class> dtClass = dataType.getClass();
Class> sameNamedDtClass = matchingDataType.getClass();
if (dtClass == sameNamedDtClass) {
+ if (dataType instanceof Enum && (((Enum) dataType).getCount()==1)) {
+ // don't check single entry enums. Size will vary, and they are extracted defines
+ return checkEnum((Enum) dataType, (Enum) matchingDataType);
+ }
if (dataType.getLength() != matchingDataType.getLength()) {
String message = dataType.getPathName() + " (" + dtClass.getSimpleName() +
") " + dataType.getLength() + " != " + matchingDataType.getLength();