feat: cache vfunctions list

The vfunctions are collected and compared in two loops against all the
recoveredClasses, this takes time if the binary have many classes. This
commit makes the vfunctions list and the vftable address to be stored
in a map, making the vfunctions list and create happen only once.
This commit is contained in:
Emerson Pinter 2024-08-19 22:27:30 -03:00
parent 90f712fc00
commit cab8ed6068

View file

@ -137,6 +137,7 @@ public class RecoveredClassHelper {
protected final boolean createBookmarks; protected final boolean createBookmarks;
protected final boolean useShortTemplates; protected final boolean useShortTemplates;
protected final boolean nameVfunctions; protected final boolean nameVfunctions;
public HashMap<Address, Set<Function>> allVfunctions = new HashMap<>();
public RecoveredClassHelper(Program program, ServiceProvider serviceProvider, public RecoveredClassHelper(Program program, ServiceProvider serviceProvider,
FlatProgramAPI api, boolean createBookmarks, boolean useShortTemplates, FlatProgramAPI api, boolean createBookmarks, boolean useShortTemplates,
@ -478,20 +479,25 @@ public class RecoveredClassHelper {
return functionToLoadPcodeOps.get(function); return functionToLoadPcodeOps.get(function);
} }
public Set<Function> getAllVfunctions(List<Address> vftableAddresses) public Set<Function> getAllVfunctions(List<Address> vftableAddresses) throws CancelledException {
throws CancelledException {
Set<Function> allVfunctionsSet = new HashSet<Function>();
if (vftableAddresses.isEmpty()) { if (vftableAddresses.isEmpty()) {
return allVfunctionsSet; return Collections.emptySet();
} }
Set<Function> vfunctionSet = new HashSet<>();
for (Address vftableAddress : vftableAddresses) { for (Address vftableAddress : vftableAddresses) {
monitor.checkCancelled(); monitor.checkCancelled();
allVfunctionsSet.addAll(getVfunctions(vftableAddress)); if (!allVfunctions.containsKey(vftableAddress)) {
List<Function> funcList = getVfunctions(vftableAddress);
if (funcList == null) {
funcList = new ArrayList<>();
}
allVfunctions.put(vftableAddress, new HashSet<>(funcList));
}
vfunctionSet.addAll(allVfunctions.get(vftableAddress));
} }
return allVfunctionsSet; return vfunctionSet;
} }
public Set<Function> getAllClassFunctionsWithVtableRef(List<Address> vftables) public Set<Function> getAllClassFunctionsWithVtableRef(List<Address> vftables)