Skip to content

Commit 1035d3e

Browse files
committed
Tricore FCALL set calling convention automatically
1 parent c8246d6 commit 1035d3e

File tree

1 file changed

+112
-0
lines changed

1 file changed

+112
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/* ###
2+
* IP: GHIDRA
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package ghidra.app.plugin.core.analysis;
17+
18+
import java.math.BigInteger;
19+
20+
import ghidra.app.services.AbstractAnalyzer;
21+
import ghidra.app.services.AnalysisPriority;
22+
import ghidra.app.services.AnalyzerType;
23+
import ghidra.app.util.importer.MessageLog;
24+
import ghidra.program.model.address.AddressSetView;
25+
import ghidra.program.model.lang.Processor;
26+
import ghidra.program.model.lang.Register;
27+
import ghidra.program.model.lang.RegisterValue;
28+
import ghidra.program.model.listing.Function;
29+
import ghidra.program.model.listing.FunctionIterator;
30+
import ghidra.program.model.listing.Instruction;
31+
import ghidra.program.model.listing.InstructionIterator;
32+
import ghidra.program.model.listing.Program;
33+
import ghidra.program.model.symbol.SourceType;
34+
import ghidra.util.Msg;
35+
import ghidra.util.exception.CancelledException;
36+
import ghidra.util.exception.InvalidInputException;
37+
import ghidra.util.task.TaskMonitor;
38+
39+
public class TricoreFCallAnalyzer extends AbstractAnalyzer {
40+
41+
private static final String NAME = "Tricore FCall Analyzer";
42+
private static final String DESCRIPTION = "Analyzes Tricore programs to find routines called by FCALL opcode. This analyzer looks at the type of return used for the function to identify the calling convention.";
43+
44+
public TricoreFCallAnalyzer() {
45+
super(NAME, DESCRIPTION, AnalyzerType.FUNCTION_ANALYZER);
46+
setPriority(AnalysisPriority.FUNCTION_ANALYSIS);
47+
setDefaultEnablement(true);
48+
}
49+
50+
@Override
51+
public boolean canAnalyze(Program program) {
52+
// Only analyze Tricore Programs
53+
Processor processor = program.getLanguage().getProcessor();
54+
55+
boolean canDo = processor.equals(Processor.findOrPossiblyCreateProcessor("tricore"));
56+
return canDo;
57+
}
58+
59+
void checkReturn(Program program, Instruction instr) {
60+
String mnemonic = instr.getMnemonicString().toLowerCase();
61+
62+
if (instr == null || !instr.getFlowType().isTerminal()) {
63+
return;
64+
}
65+
if (mnemonic.equals("fret")) {
66+
setPrototypeModel(program, instr, "__fastcall");
67+
return;
68+
}
69+
}
70+
71+
private void setPrototypeModel(Program program, Instruction instr, String convention) {
72+
if (convention == null) {
73+
return;
74+
}
75+
76+
Function func = program.getFunctionManager().getFunctionContaining(instr.getMinAddress());
77+
if (func == null) {
78+
return;
79+
}
80+
81+
if (func.getSignatureSource() != SourceType.DEFAULT) {
82+
return;
83+
}
84+
85+
try {
86+
func.setCallingConvention(convention);
87+
} catch (InvalidInputException e) {
88+
Msg.error(this, "Unexpected Exception: " + e.getMessage(), e);
89+
}
90+
}
91+
92+
@Override
93+
public boolean added(Program program, AddressSetView set, TaskMonitor monitor, MessageLog log)
94+
throws CancelledException {
95+
96+
// get all functions within the set
97+
FunctionIterator functions = program.getFunctionManager().getFunctions(set, true);
98+
for (Function function : functions) {
99+
100+
// for each function body, search instructions
101+
AddressSetView body = function.getBody();
102+
InstructionIterator instructions = program.getListing().getInstructions(body, true);
103+
for (Instruction instr : instructions) {
104+
if (instr.getFlowType().isTerminal()) {
105+
checkReturn(program, instr);
106+
}
107+
}
108+
}
109+
return true;
110+
}
111+
112+
}

0 commit comments

Comments
 (0)