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/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(); 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..02fadb008f --- /dev/null +++ b/Ghidra/Features/Base/ghidra_scripts/CreateUEFIGDTArchivesScript.java @@ -0,0 +1,138 @@ +/* ### + * 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 = CParserUtils.parseHeaderFiles(openTypes, filenames, + includePaths, args, f.getAbsolutePath(), languageID, compiler, monitor); + + 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..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 @@ -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; } @@ -509,7 +526,7 @@ public class PreProcessor { } } if (image.length() == 1 && image.startsWith("\n")) { - image = (!emitExecSwitch ? "////\n" : "\n"); + image = (!emitExecSwitch ? "///-\n" : "\n"); } print(image); } @@ -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(); @@ -829,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 @@ -857,7 +900,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 +928,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!"); @@ -1057,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"); @@ -1225,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("--")) { @@ -1239,6 +1276,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 +1374,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 { @@ -1504,7 +1553,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(); @@ -1536,7 +1585,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 +1600,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(); @@ -1584,6 +1633,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={ @@ -1591,6 +1642,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={ @@ -1704,6 +1757,7 @@ PPToken UnDef() : {Token t;} if (isDef(pt)==true) { UnDefine(pt); } + printCommentedLines(emitExecSwitch, "#undef " + pt.image, null); return pt; } } @@ -1728,8 +1782,14 @@ 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); + } + return pt; } } @@ -1779,9 +1839,11 @@ PPToken IfNDefExpr() : PPToken Error() : {Token t;} { t={ + printCommentedLines(emitExecSwitch, "#error " + t.image, "Error!"); 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); } @@ -1790,6 +1852,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); @@ -1867,31 +1930,34 @@ PPToken QuotedValue() : } PPToken Text() : -{Token u, nl, t = new Token(); PPToken buf = new PPToken(""); t.image="";} +{Token u, nl, lastToken = null; 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;} } @@ -2212,7 +2278,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 +2408,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 +2583,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 +2678,7 @@ TOKEN : { // | )+ > | )+ > | + )+ > | | > { parenNesting++; } : DIRECTIVE | > { parenNesting--; } : DIRECTIVE | @@ -2657,7 +2727,7 @@ TOKEN : { TOKEN : { > : INCLUDE | - ()* > : DEFAULT + ()* > : DEFAULT } @@ -2665,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 } @@ -2802,10 +2886,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 +2907,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 +2940,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 +2976,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 +3039,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/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/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..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 @@ -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,34 @@ #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 + +#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 @@ -171,10 +199,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 @@ -442,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 **/ @@ -536,5 +581,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(); 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)