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 66e0e9d022..9ccb2c9a58 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 @@ -5,9 +5,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. @@ -83,6 +83,7 @@ package ghidra.app.util.cparser.C; import ghidra.program.model.data.*; import ghidra.program.model.data.Enum; +import ghidra.program.model.lang.CompilerSpec; import ghidra.util.Msg; import ghidra.util.task.TaskMonitor; import ghidra.util.InvalidNameException; @@ -656,24 +657,42 @@ public class CParser { * @param funcDT function data type to qualify */ private void applyFunctionQualifiers(Declaration dec, FunctionDefinition funcDT) { - List qualifierList = dec.getQualifiers(); - if (qualifierList.contains(NORETURN) ) { - funcDT.setNoReturn(true); - } - // TODO: switch to setting calling convention by string identifier - for (Integer qualifier : qualifierList) { - switch (qualifier) { - case CDECL: - funcDT.setGenericCallingConvention(GenericCallingConvention.cdecl); - break; - case STDCALL: - funcDT.setGenericCallingConvention(GenericCallingConvention.stdcall); - break; - case FASTCALL: - funcDT.setGenericCallingConvention(GenericCallingConvention.fastcall); - break; - } - } + List qualifierList = dec.getQualifiers(); + if (qualifierList.contains(NORETURN)) { + funcDT.setNoReturn(true); + } + + String convention = null; + for (Integer qualifier : qualifierList) { + switch (qualifier) { + case CDECL: + convention = CompilerSpec.CALLING_CONVENTION_cdecl; + break; + case STDCALL: + convention = CompilerSpec.CALLING_CONVENTION_stdcall; + break; + case FASTCALL: + convention = CompilerSpec.CALLING_CONVENTION_fastcall; + break; + case VECTORCALL: + convention = CompilerSpec.CALLING_CONVENTION_vectorcall; + break; + case RUSTCALL: + convention = CompilerSpec.CALLING_CONVENTION_rustcall; + break; + case PASCALCALL: + convention = CompilerSpec.CALLING_CONVENTION_pascal; + break; + } + } + if (convention != null) { + try { + funcDT.setCallingConvention(convention); + } + catch (InvalidInputException e) { + // should not happen + } + } } private Integer getConstantValue (Object obj, int defaultValue) { @@ -1164,8 +1183,6 @@ TOKEN : | | - - | | {parenNesting=-1; SwitchTo(PRAGMALINE); } @@ -1174,10 +1191,18 @@ TOKEN : | | + + | | | + + | + + | + + | | @@ -1799,6 +1824,9 @@ Declaration TypeQualifier(Declaration dec) : {} | { dec.addQualifier(STDCALL); } | { dec.addQualifier(FASTCALL); } | + { dec.addQualifier(VECTORCALL); } | + { dec.addQualifier(RUSTCALL); } | + { dec.addQualifier(PASCALCALL); } | { dec.addQualifier(NORETURN); } | | | 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 7cfcec29bd..c0e162d7d9 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 @@ -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. @@ -149,8 +149,14 @@ void __cdecl _Once(_Once_t *, void (__cdecl *)(void)); void __stdcall _Twice(void (__cdecl *)(void)); +void __vectorcall _Vect(void (__cdecl *)(void)); + +void __rustcall _Rusty(void (__cdecl *)(void)); + void _Thrice(void (__cdecl *)(void)); +void _Iron(void (__rustcall *)(void)); + /** ** use of long as an attribute **/