GP-4408 Refactor of FillOutStructureCmd. Added FillOutStructureHelper and additional DecompilerUtils methods.

This commit is contained in:
ghidra1
2024-04-03 09:53:53 -04:00
parent 434c3f315d
commit 624a3c4e9e
25 changed files with 1281 additions and 1810 deletions

View File

@@ -17,84 +17,28 @@
package classrecovery;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
import ghidra.app.cmd.label.DemanglerCmd;
import ghidra.app.plugin.core.analysis.ReferenceAddressPair;
import ghidra.app.util.NamespaceUtils;
import ghidra.app.util.demangler.DemangledObject;
import ghidra.app.util.demangler.DemanglerUtil;
import ghidra.framework.plugintool.PluginTool;
import ghidra.framework.plugintool.ServiceProvider;
import ghidra.program.flatapi.FlatProgramAPI;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressIterator;
import ghidra.program.model.address.AddressOutOfBoundsException;
import ghidra.program.model.address.AddressRange;
import ghidra.program.model.address.AddressRangeIterator;
import ghidra.program.model.address.AddressSet;
import ghidra.program.model.address.AddressSetView;
import ghidra.program.model.data.ArrayDataType;
import ghidra.program.model.data.CategoryPath;
import ghidra.program.model.data.CharDataType;
import ghidra.program.model.data.DataType;
import ghidra.program.model.data.DataTypeComponent;
import ghidra.program.model.data.DataTypeConflictHandler;
import ghidra.program.model.data.DataUtilities;
import ghidra.program.model.address.*;
import ghidra.program.model.data.*;
import ghidra.program.model.data.DataUtilities.ClearDataMode;
import ghidra.program.model.data.InvalidDataTypeException;
import ghidra.program.model.data.LongDataType;
import ghidra.program.model.data.LongLongDataType;
import ghidra.program.model.data.Pointer;
import ghidra.program.model.data.PointerDataType;
import ghidra.program.model.data.PointerTypedef;
import ghidra.program.model.data.StringDataType;
import ghidra.program.model.data.Structure;
import ghidra.program.model.data.StructureDataType;
import ghidra.program.model.data.TerminatedStringDataType;
import ghidra.program.model.data.UnsignedIntegerDataType;
import ghidra.program.model.lang.Register;
import ghidra.program.model.listing.Bookmark;
import ghidra.program.model.listing.BookmarkType;
import ghidra.program.model.listing.CircularDependencyException;
import ghidra.program.model.listing.Data;
import ghidra.program.model.listing.Function;
import ghidra.program.model.listing.FunctionManager;
import ghidra.program.model.listing.Instruction;
import ghidra.program.model.listing.InstructionIterator;
import ghidra.program.model.listing.Listing;
import ghidra.program.model.listing.Program;
import ghidra.program.model.mem.DumbMemBufferImpl;
import ghidra.program.model.mem.MemBuffer;
import ghidra.program.model.mem.Memory;
import ghidra.program.model.mem.MemoryAccessException;
import ghidra.program.model.mem.MemoryBlock;
import ghidra.program.model.listing.*;
import ghidra.program.model.mem.*;
import ghidra.program.model.scalar.Scalar;
import ghidra.program.model.symbol.Namespace;
import ghidra.program.model.symbol.Reference;
import ghidra.program.model.symbol.ReferenceIterator;
import ghidra.program.model.symbol.ReferenceManager;
import ghidra.program.model.symbol.SourceType;
import ghidra.program.model.symbol.Symbol;
import ghidra.program.model.symbol.SymbolIterator;
import ghidra.program.model.symbol.*;
import ghidra.program.model.util.CodeUnitInsertionException;
import ghidra.program.util.ProgramLocation;
import ghidra.program.util.ProgramMemoryUtil;
import ghidra.util.Msg;
import ghidra.util.bytesearch.GenericByteSequencePattern;
import ghidra.util.bytesearch.GenericMatchAction;
import ghidra.util.bytesearch.Match;
import ghidra.util.bytesearch.MemoryBytePatternSearcher;
import ghidra.util.exception.CancelledException;
import ghidra.util.exception.DuplicateNameException;
import ghidra.util.exception.InvalidInputException;
import ghidra.util.bytesearch.*;
import ghidra.util.exception.*;
import ghidra.util.task.TaskMonitor;
public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
@@ -151,23 +95,20 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
private Map<RecoveredClass, Map<RecoveredClass, Long>> classToParentOffsetMap =
new HashMap<RecoveredClass, Map<RecoveredClass, Long>>();
private Map<RecoveredClass, List<Vftable>> classToVftableMap = new HashMap<>();
boolean isDwarfLoaded;
boolean replaceClassStructs;
FunctionManager functionManager = null;
Listing listing;
protected final FunctionManager functionManager;
protected final Listing listing;
public RTTIGccClassRecoverer(Program program, ProgramLocation location, PluginTool tool,
FlatProgramAPI api,
boolean createBookmarks, boolean useShortTemplates, boolean nameVfunctions,
boolean isDwarfLoaded,
TaskMonitor monitor) throws Exception {
public RTTIGccClassRecoverer(Program program, ServiceProvider serviceProvider,
FlatProgramAPI api, boolean createBookmarks, boolean useShortTemplates,
boolean nameVfunctions, boolean isDwarfLoaded, TaskMonitor monitor) throws Exception {
super(program, location, tool, api, createBookmarks, useShortTemplates, nameVfunctions,
super(program, serviceProvider, api, createBookmarks, useShortTemplates, nameVfunctions,
isDwarfLoaded, monitor);
this.isDwarfLoaded = isDwarfLoaded;
functionManager = program.getFunctionManager();
@@ -208,8 +149,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
List<ReferenceAddressPair> directReferenceList = new ArrayList<ReferenceAddressPair>();
ProgramMemoryUtil.loadDirectReferenceList(program, 1, initializedMem.getMinAddress(),
initializedMem,
directReferenceList, monitor);
initializedMem, directReferenceList, monitor);
createGlobalDirectRefMap(directReferenceList);
Msg.debug(this, "Creating Special Typeinfos");
@@ -287,7 +227,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
/**
* Method to update the labels of vftables that belong to classes with multiple vftables in
* order to distinguish which base class the vftable is for.
* @param recoveredClasses the list of RecoveredClass objects
* @throws CancelledException if cancelled
* @throws InvalidInputException if bad chars trying to label
* @throws DuplicateNameException if duplicate name
@@ -364,8 +303,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
}
private GccTypeinfo findSpecialTypeinfoSymbol(String namespaceName,
String mangledNamespaceString)
throws CancelledException {
String mangledNamespaceString) throws CancelledException {
// try finding with normal symbol name and namespace
Symbol typeinfoSymbol =
@@ -384,9 +322,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
if (typeinfoSymbol == null) {
// then try finding with mangled namespace string in memory
typeinfoSymbol =
findTypeinfoSymbolUsingMangledNamespaceString(mangledNamespaceString,
namespaceName);
typeinfoSymbol = findTypeinfoSymbolUsingMangledNamespaceString(
mangledNamespaceString, namespaceName);
}
}
}
@@ -397,8 +334,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
}
private Symbol findTypeinfoUsingNotInProgramMemoryVtableSymbol(String namespaceName,
String mangledNamespaceString)
throws CancelledException {
String mangledNamespaceString) throws CancelledException {
// try finding with normal symbol name and namespace
Symbol vtableSymbol =
@@ -433,8 +369,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
Symbol typeinfoSymbol;
try {
typeinfoSymbol = symbolTable.createLabel(vtableAddress, "typeinfo",
vtableSymbol.getParentNamespace(),
SourceType.ANALYSIS);
vtableSymbol.getParentNamespace(), SourceType.ANALYSIS);
// api.setPlateComment(typeinfoAddress, "typeinfo for " + namespace);
}
catch (InvalidInputException e) {
@@ -484,8 +419,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
// TODO: this assumes only one and returns the first found - have never seen
// more than one but should probably check
private Symbol findAndReturnDemangledSymbol(String mangledSymbolName,
String specialClassNamespaceName,
String classNamespaceName, String label) {
String specialClassNamespaceName, String classNamespaceName, String label) {
SymbolIterator symbolIterator = symbolTable.getSymbolIterator(mangledSymbolName, true);
if (symbolIterator.hasNext()) {
@@ -504,9 +438,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
}
try {
Symbol demangledSymbol =
symbolTable.createLabel(symbolAddress, label, classNamespace,
SourceType.ANALYSIS);
Symbol demangledSymbol = symbolTable.createLabel(symbolAddress, label,
classNamespace, SourceType.ANALYSIS);
demangledSymbol.setPrimary();
return demangledSymbol;
}
@@ -520,8 +453,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
// TODO: can this be used for regular ones too?
private Symbol findTypeinfoSymbolUsingMangledNamespaceString(String mangledNamespace,
String namespaceName)
throws CancelledException {
String namespaceName) throws CancelledException {
Symbol specialTypeinfoSymbol = findTypeinfoUsingMangledString(mangledNamespace);
if (specialTypeinfoSymbol == null) {
@@ -539,9 +471,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
boolean isExternal =
typeinfoAddress.isExternalAddress() || inExternalBlock(typeinfoAddress);
GccTypeinfo gccTypeinfo =
new GccTypeinfo(typeinfoSymbol.getAddress(), typeinfoSymbol.getParentNamespace(),
isSpecial, !isExternal);
GccTypeinfo gccTypeinfo = new GccTypeinfo(typeinfoSymbol.getAddress(),
typeinfoSymbol.getParentNamespace(), isSpecial, !isExternal);
return gccTypeinfo;
}
@@ -578,10 +509,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
boolean isGcc;
boolean isCompilerSpecGcc = program.getCompilerSpec()
.getCompilerSpecID()
.getIdAsString()
.equalsIgnoreCase("gcc");
boolean isCompilerSpecGcc =
program.getCompilerSpec().getCompilerSpecID().getIdAsString().equalsIgnoreCase("gcc");
if (isCompilerSpecGcc) {
return true;
}
@@ -605,8 +534,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
byte[] maskBytes = { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff };
Address found = program.getMemory()
.findBytes(commentBlock.getStart(), commentBlock.getEnd(), gccBytes,
maskBytes, true, monitor);
.findBytes(commentBlock.getStart(), commentBlock.getEnd(), gccBytes, maskBytes,
true, monitor);
if (found == null) {
isGcc = false;
}
@@ -726,9 +655,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
// parent isn't a known class - cannot continue processing recoveredClass
if (parentClass == null) {
Msg.error(this,
"Removing class: " + recoveredClass.getName() + " from list to" +
" process since parent information is not availalbe.");
Msg.error(this, "Removing class: " + recoveredClass.getName() +
" from list to" + " process since parent information is not availalbe.");
recoveredClasses.remove(recoveredClass);
}
continue;
@@ -801,9 +729,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
Vtable vtable = processMainVtable(mainVtable, map.get(mainVtable));
if (vtable == null) {
Msg.debug(this,
"MISSING expected vtable for simple class " +
typeinfo.getNamespace().getName(true));
Msg.debug(this, "MISSING expected vtable for simple class " +
typeinfo.getNamespace().getName(true));
continue;
}
@@ -1051,8 +978,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
}
private boolean isPossibleVttStart(Address address, List<Vtable> vtables,
List<Address> knownVtts)
throws CancelledException {
List<Address> knownVtts) throws CancelledException {
// make list of all vtable tops and vftable tops
List<Address> vtableAndVftableAddrs = getListOfVtableAndVftableTops(vtables);
@@ -1164,7 +1090,9 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
* construction ones to the passed in list
*
* @param typeinfo
* @param map
* @param constructionVtables
* @param numBaseRefs
* @return address of main vtable for this class
* @throws CancelledException
*/
@@ -1468,8 +1396,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
}
private Address getMainVtableUsingSymbols(List<Address> vtableAddresses,
List<Address> constructionVtables)
throws CancelledException {
List<Address> constructionVtables) throws CancelledException {
List<Address> mainVtableCandidates = new ArrayList<Address>();
for (Address vtableAddress : vtableAddresses) {
@@ -1662,8 +1589,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
}
symbolTable.createLabel(vtableAddress, internalString + constructionString + VTABLE_LABEL,
classNamespace,
SourceType.ANALYSIS);
classNamespace, SourceType.ANALYSIS);
}
@@ -1690,8 +1616,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
}
symbolTable.createLabel(vtable.getVfunctionTop(),
internalString + constructionString + VFTABLE_LABEL,
classNamespace, SourceType.ANALYSIS);
internalString + constructionString + VFTABLE_LABEL, classNamespace,
SourceType.ANALYSIS);
}
@@ -1871,8 +1797,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
Namespace newNamespace;
try {
newNamespace = NamespaceUtils.createNamespaceHierarchy(name,
namespaceIn.getParentNamespace(), program,
SourceType.ANALYSIS);
namespaceIn.getParentNamespace(), program, SourceType.ANALYSIS);
}
catch (InvalidInputException e) {
return null;
@@ -1893,8 +1818,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
}
public Map<Address, Set<Address>> findTypeinfoReferencesNotInTypeinfoStructsOld(
List<Address> typeinfoAddresses)
throws CancelledException {
List<Address> typeinfoAddresses) throws CancelledException {
MemoryBytePatternSearcher searcher = new MemoryBytePatternSearcher("Typeinfo References");
@@ -1934,7 +1858,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
searchSet.add(addressRange.getMinAddress(), addressRange.getMaxAddress());
}
Map<Address, Set<Address>> directRefMap = new HashMap<Address, Set<Address>>();
Map<Address, Set<Address>> refMap = new HashMap<Address, Set<Address>>();
AddressIterator addrIter =
initializedSet.getAddresses(initializedSet.getMinAddress(), true);
@@ -1944,11 +1868,11 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
// check direct refs to see if they are in undefined area or not in function
byte[] bytes = ProgramMemoryUtil.getDirectAddressBytes(program, address);
addByteSearchPatternDirRefs(searcher, directRefMap, address, bytes, monitor);
addByteSearchPatternDirRefs(searcher, refMap, address, bytes, monitor);
}
searcher.search(program, searchSet, monitor);
return directRefMap;
return refMap;
}
/**
@@ -1997,8 +1921,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
}
public Map<Address, Set<Address>> findTypeinfoReferencesNotInTypeinfoStructs(
List<GccTypeinfo> typeinfos)
throws CancelledException {
List<GccTypeinfo> typeinfos) throws CancelledException {
MemoryBytePatternSearcher searcher = new MemoryBytePatternSearcher("Typeinfo References");
@@ -2104,8 +2027,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
* @param taskMonitor a cancellable monitor
*/
private void addByteSearchPattern(MemoryBytePatternSearcher searcher,
Map<Address, Set<Address>> typeinfoRefMap,
Address typeinfoAddress, byte[] bytes, TaskMonitor taskMonitor) {
Map<Address, Set<Address>> typeinfoRefMap, Address typeinfoAddress, byte[] bytes,
TaskMonitor taskMonitor) {
// no pattern bytes.
if (bytes == null) {
@@ -2195,8 +2118,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
* @throws CancelledException if cancelled
*/
private Vtable processVtable(Address vtableAddress, GccTypeinfoRef typeinfoRef,
Boolean isConstruction)
throws CancelledException {
Boolean isConstruction) throws CancelledException {
Vtable vtable = null;
boolean isSpecial = false;
@@ -2296,9 +2218,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
api.clearListing(vtableAddress);
SpecialVtable specialVtable =
new SpecialVtable(program, vtableAddress, typeinfoRef, isExternal,
vtableSymbol.getParentNamespace(), monitor);
SpecialVtable specialVtable = new SpecialVtable(program, vtableAddress, typeinfoRef,
isExternal, vtableSymbol.getParentNamespace(), monitor);
return specialVtable;
}
@@ -2421,9 +2342,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
.equals(VMI_CLASS_TYPEINFO_NAMESPACE)) {
specialTypeinfoNamespaceName = VMI_CLASS_TYPEINFO_NAMESPACE;
typeinfoToStructuretypeMap.put(typeinfoAddress, VMI_CLASS_TYPE_INFO_STRUCTURE);
Structure vmiClassTypeinfoStructure =
getOrCreateVmiTypeinfoStructure(typeinfoAddress,
baseClassTypeInfoStructure);
Structure vmiClassTypeinfoStructure = getOrCreateVmiTypeinfoStructure(
typeinfoAddress, baseClassTypeInfoStructure);
if (vmiClassTypeinfoStructure != null) {
newStructure =
applyTypeinfoStructure(vmiClassTypeinfoStructure, typeinfoAddress);
@@ -2500,8 +2420,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
}
private void updateTypeinfosWithBases(List<GccTypeinfo> typeinfos,
Map<Address, GccTypeinfo> typeinfoMap)
throws CancelledException {
Map<Address, GccTypeinfo> typeinfoMap) throws CancelledException {
List<GccTypeinfo> invalidTypeinfos = new ArrayList<GccTypeinfo>();
for (GccTypeinfo typeinfo : typeinfos) {
@@ -2549,9 +2468,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
// SI_CLASS_TYPE_INFO_STRUCTURE
if (!isTypeinfoStruct(siTypeinfoStructure)) {
throw new IllegalArgumentException(
siTypeinfoStructure.getAddressString(false, false) +
" is not a typeinfo structure");
throw new IllegalArgumentException(siTypeinfoStructure.getAddressString(false, false) +
" is not a typeinfo structure");
}
Data baseClassPointer = siTypeinfoStructure.getComponent(2);
@@ -2604,9 +2522,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
extendedFlatAPI.getReferencedAddress(baseClassStructureAddress, false);
if (baseTypeinfoAddress == null) {
Msg.debug(this,
typeinfo.getAddress() +
": invalid typeinfo - cannot get address at baseTypeinfo[" + i + "]");
Msg.debug(this, typeinfo.getAddress() +
": invalid typeinfo - cannot get address at baseTypeinfo[" + i + "]");
return false;
}
@@ -2674,8 +2591,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
DataType inheritanceFlagDataType = inheritanceFlagComponent.getDataType();
MemBuffer buf = new DumbMemBufferImpl(program.getMemory(), flagAddress);
Scalar scalar = (Scalar) inheritanceFlagDataType.getValue(buf,
inheritanceFlagDataType.getDefaultSettings(),
inheritanceFlagDataType.getLength());
inheritanceFlagDataType.getDefaultSettings(), inheritanceFlagDataType.getLength());
long inheritanceFlagValue = scalar.getUnsignedValue();
return inheritanceFlagValue;
}
@@ -2693,8 +2609,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
DataType numBaseClassesDataType = numBaseClassesComponent.getDataType();
MemBuffer buf = new DumbMemBufferImpl(program.getMemory(), numBaseClassesAddress);
Scalar scalar = (Scalar) numBaseClassesDataType.getValue(buf,
numBaseClassesDataType.getDefaultSettings(),
numBaseClassesDataType.getLength());
numBaseClassesDataType.getDefaultSettings(), numBaseClassesDataType.getLength());
int numBaseClasses = (int) scalar.getUnsignedValue();
return numBaseClasses;
@@ -2810,9 +2725,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
}
// get or create the vmiClassTypeInfoStruct
Structure vmiClassTypeinfoStructure =
(Structure) dataTypeManager.getDataType(classDataTypesCategoryPath,
VMI_CLASS_TYPE_INFO_STRUCTURE + numBases);
Structure vmiClassTypeinfoStructure = (Structure) dataTypeManager
.getDataType(classDataTypesCategoryPath, VMI_CLASS_TYPE_INFO_STRUCTURE + numBases);
if (vmiClassTypeinfoStructure == null) {
vmiClassTypeinfoStructure =
createVmiClassTypeInfoStructure(baseClassTypeInfoStructure, numBases);
@@ -2821,7 +2735,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
}
private Symbol createDemangledTypeinfoSymbol(Address typeinfoAddress)
throws DuplicateNameException, InvalidInputException, CancelledException {
throws DuplicateNameException, InvalidInputException {
// TODO: 1. see if there is a mangled name that didn't get demangled at
// TODO: 2 - refactor the three places that call this to just call getSymbolAt
@@ -2919,9 +2833,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
Namespace classNamespace = typeinfoNameSymbol.getParentNamespace();
if (classNamespace.isGlobal()) {
Msg.debug(this,
typeinfoAddress.toString() +
"Could not create a class namespace for demangled namespace string ");
Msg.debug(this, typeinfoAddress.toString() +
"Could not create a class namespace for demangled namespace string ");
return null;
}
@@ -2987,7 +2900,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
private String getDefinedStringAt(Address address) {
Listing listing = program.getListing();
Data stringData = listing.getDataAt(address);
if (stringData == null) {
@@ -3218,15 +3130,11 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
}
public void assignConstructorsAndDestructorsUsingExistingNameNew(
List<RecoveredClass> recoveredClasses)
throws CancelledException, InvalidInputException, DuplicateNameException,
CircularDependencyException {
List<RecoveredClass> recoveredClasses) throws CancelledException, InvalidInputException,
DuplicateNameException, CircularDependencyException {
Iterator<RecoveredClass> recoveredClassIterator = recoveredClasses.iterator();
while (recoveredClassIterator.hasNext()) {
for (RecoveredClass recoveredClass : recoveredClasses) {
monitor.checkCancelled();
RecoveredClass recoveredClass = recoveredClassIterator.next();
Namespace classNamespace = recoveredClass.getClassNamespace();
String name = classNamespace.getName();
SymbolIterator classSymbols = symbolTable.getSymbols(classNamespace);
@@ -3353,8 +3261,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
}
private void removeFromIndeterminateLists(List<RecoveredClass> recoveredClasses,
Function function)
throws CancelledException {
Function function) throws CancelledException {
for (RecoveredClass recoveredClass : recoveredClasses) {
monitor.checkCancelled();
@@ -3373,8 +3280,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
if (hasExternalRelocations()) {
PointerTypedef classTypeInfoPtr =
new PointerTypedef(null, null, -1, program.getDataTypeManager(),
componentOffset);
new PointerTypedef(null, null, -1, program.getDataTypeManager(), componentOffset);
classTypeInfoStructure.add(classTypeInfoPtr, "classTypeinfoPtr", null);
}
@@ -3393,18 +3299,15 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
}
private StructureDataType createSiClassTypeInfoStructure(
StructureDataType classTypeInfoStructure)
throws CancelledException {
StructureDataType classTypeInfoStructure) throws CancelledException {
StructureDataType siClassTypeInfoStructure =
new StructureDataType(classDataTypesCategoryPath,
SI_CLASS_TYPE_INFO_STRUCTURE, 0, dataTypeManager);
StructureDataType siClassTypeInfoStructure = new StructureDataType(
classDataTypesCategoryPath, SI_CLASS_TYPE_INFO_STRUCTURE, 0, dataTypeManager);
CharDataType characterDT = new CharDataType();
PointerTypedef classTypeInfoPtr =
new PointerTypedef(null, null, -1, program.getDataTypeManager(),
componentOffset);
new PointerTypedef(null, null, -1, program.getDataTypeManager(), componentOffset);
siClassTypeInfoStructure.add(classTypeInfoPtr, "classTypeinfoPtr", null);
DataType charPointer = dataTypeManager.getPointer(characterDT);
@@ -3420,12 +3323,10 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
}
private StructureDataType createBaseClassTypeInfoStructure(
StructureDataType classTypeInfoStructure)
throws InvalidDataTypeException {
StructureDataType classTypeInfoStructure) throws InvalidDataTypeException {
StructureDataType baseclassTypeInfoStructure =
new StructureDataType(classDataTypesCategoryPath,
BASE_CLASS_TYPE_INFO_STRUCTURE, 0, dataTypeManager);
StructureDataType baseclassTypeInfoStructure = new StructureDataType(
classDataTypesCategoryPath, BASE_CLASS_TYPE_INFO_STRUCTURE, 0, dataTypeManager);
DataType classTypeInfoPointer = dataTypeManager.getPointer(classTypeInfoStructure);
@@ -3460,8 +3361,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
}
private StructureDataType createVmiClassTypeInfoStructure(
StructureDataType baseClassTypeInfoStructure,
int numBaseClasses) throws CancelledException {
StructureDataType baseClassTypeInfoStructure, int numBaseClasses)
throws CancelledException {
StructureDataType vmiClassTypeInfoStructure =
new StructureDataType(classDataTypesCategoryPath,
@@ -3471,8 +3372,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
UnsignedIntegerDataType unsignedIntDT = new UnsignedIntegerDataType();
PointerTypedef classTypeInfoPtr =
new PointerTypedef(null, null, -1, program.getDataTypeManager(),
componentOffset);
new PointerTypedef(null, null, -1, program.getDataTypeManager(), componentOffset);
vmiClassTypeInfoStructure.add(classTypeInfoPtr, "classTypeinfoPtr", null);
DataType charPointer = dataTypeManager.getPointer(characterDT);
@@ -3564,8 +3464,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
* @throws CancelledException if cancelled
*/
private List<RecoveredClass> addClassParentsAndFlagsForVmiClass(RecoveredClass recoveredClass,
GccTypeinfo typeinfo)
throws CancelledException {
GccTypeinfo typeinfo) throws CancelledException {
long inheritanceFlagValue = typeinfo.getInheritanceFlagValue();
@@ -3646,8 +3545,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
}
private Address findSpecialVtable(GccTypeinfo specialTypeinfo,
List<GccTypeinfo> specialTypeinfos)
throws CancelledException {
List<GccTypeinfo> specialTypeinfos) throws CancelledException {
String namespaceName = specialTypeinfo.getNamespace().getName();
String mangledNamespaceString = specialTypeinfo.getMangledNamespaceString();
@@ -3663,9 +3561,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
// then try finding top of special vtable by finding ref to special typeinfo
if (vtableSymbol == null) {
Address vtableAddress =
findSpecialVtableUsingSpecialTypeinfo(specialTypeinfo.getAddress(),
specialTypeinfos);
Address vtableAddress = findSpecialVtableUsingSpecialTypeinfo(
specialTypeinfo.getAddress(), specialTypeinfos);
if (vtableAddress == null) {
return null;
@@ -3673,14 +3570,13 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
try {
vtableSymbol = symbolTable.createLabel(vtableAddress, VTABLE_LABEL,
specialTypeinfo.getNamespace(),
SourceType.ANALYSIS);
specialTypeinfo.getNamespace(), SourceType.ANALYSIS);
api.setPlateComment(vtableAddress,
"vtable for " + specialTypeinfo.getNamespace());
}
catch (InvalidInputException e) {
vtableSymbol = null;
// ignore
}
}
@@ -3729,8 +3625,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
* len between the two
*/
private Address findSpecialVtableUsingSpecialTypeinfo(Address typeinfoAddress,
List<GccTypeinfo> specialTypeinfos)
throws CancelledException {
List<GccTypeinfo> specialTypeinfos) throws CancelledException {
List<Address> referencesTo = getAllReferencesTo(typeinfoAddress);
@@ -3805,8 +3700,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
try {
symbolTable.createLabel(findSingleMangledString, mangledNamespaceString,
globalNamespace,
SourceType.ANALYSIS);
globalNamespace, SourceType.ANALYSIS);
}
catch (InvalidInputException e) {
@@ -4096,7 +3990,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
monitor.checkCancelled();
baseOffsets.add(baseTypeinfo.getOffset());
}
if (baseOffsets.size() != vftableAddresses.size()) {
@@ -4127,13 +4020,12 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
continue;
}
recoveredClass.addVftableToBaseClassMapping(correspondingVftableAddress, baseClass);
//TODO: populate the new Vftable objects
}
}
}
/**
* Use information from RTTI Base class Arrays to create class hierarchy lists
* and maps
@@ -4188,10 +4080,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
RecoveredClass recoveredClass = recoveredClassIterator.next();
List<RecoveredClass> parentList = recoveredClass.getParentList();
Iterator<RecoveredClass> parentIterator = parentList.iterator();
while (parentIterator.hasNext()) {
for (RecoveredClass parentClass : parentList) {
monitor.checkCancelled();
RecoveredClass parentClass = parentIterator.next();
recoveredClass.addClassHierarchyMapping(parentClass,
parentClass.getClassHierarchy());
}
@@ -4224,10 +4114,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
private boolean hasVirtualAncestor(RecoveredClass recoveredClass) throws CancelledException {
List<RecoveredClass> classHierarchy = recoveredClass.getClassHierarchy();
Iterator<RecoveredClass> classIterator = classHierarchy.iterator();
while (classIterator.hasNext()) {
for (RecoveredClass ancestor : classHierarchy) {
monitor.checkCancelled();
RecoveredClass ancestor = classIterator.next();
if (ancestor.inheritsVirtualAncestor()) {
return true;
}
@@ -4287,11 +4175,9 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
classHierarchyList.add(recoveredClass);
List<RecoveredClass> parentList = recoveredClass.getParentList();
Iterator<RecoveredClass> parentIterator = parentList.iterator();
while (parentIterator.hasNext()) {
for (RecoveredClass parentClass : parentList) {
monitor.checkCancelled();
RecoveredClass parentClass = parentIterator.next();
if (nonInheritedClasses.contains(parentClass)) {
classHierarchyList.addAll(parentClass.getClassHierarchy());
continue;
@@ -4403,8 +4289,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
disassemble = api.disassemble(address);
Bookmark bookmark = getBookmarkAt(possibleFunctionPointer, BookmarkType.ERROR,
"Bad Instruction",
"conflicting data");
"Bad Instruction", "conflicting data");
if (bookmark != null) {
api.removeBookmark(bookmark);
}
@@ -4418,8 +4303,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
}
private Bookmark getBookmarkAt(Address address, String bookmarkType, String category,
String commentContains)
throws CancelledException {
String commentContains) throws CancelledException {
Bookmark[] bookmarks = program.getBookmarkManager().getBookmarks(address);
@@ -4544,10 +4428,9 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
for (RecoveredClass parent : parentList) {
monitor.checkCancelled();
if (parent.getName().endsWith("_class_type_info")) {
Msg.debug(this,
"Not creating class data type for " +
recoveredClass.getClassNamespace().getName(true) +
" because it has a parent that is one of the special typeinfo classes.");
Msg.debug(this, "Not creating class data type for " +
recoveredClass.getClassNamespace().getName(true) +
" because it has a parent that is one of the special typeinfo classes.");
return;
}
}
@@ -4570,8 +4453,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
recoveredClass.getClassNamespace().getName(true));
}
updateClassFunctionsNotUsingNewClassStructure(recoveredClass,
classStructure);
updateClassFunctionsNotUsingNewClassStructure(recoveredClass, classStructure);
// return in this case because if there is no vftable for a class the script cannot
// identify any member functions so there is no need to process the rest of this
// method
@@ -4664,8 +4546,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
// simple case the offset for vftablePtr is 0
// if can fit or grow structure, add the vftablePtr to it
EditStructureUtils.addDataTypeToStructure(classStructureDataType, 0,
classVftablePointer,
CLASS_VTABLE_PTR_FIELD_EXT, monitor);
classVftablePointer, CLASS_VTABLE_PTR_FIELD_EXT, monitor);
}
// if single inheritance or multi non-virtual (wouldn't have called this method
// if it were virtually inherited) put parent struct and data into class struct
@@ -4674,18 +4555,16 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
Map<Integer, RecoveredClass> orderToParentMap =
classToParentOrderMap.get(recoveredClass);
if (orderToParentMap == null || orderToParentMap.isEmpty()) {
Msg.error(this,
"Vmi class " + recoveredClass.getClassNamespace().getName(true) +
" should have a parent in the classToParentOrderMap but doesn't");
Msg.error(this, "Vmi class " + recoveredClass.getClassNamespace().getName(true) +
" should have a parent in the classToParentOrderMap but doesn't");
return null;
}
Map<RecoveredClass, Long> parentToOffsetMap =
classToParentOffsetMap.get(recoveredClass);
if (parentToOffsetMap.isEmpty()) {
Msg.error(this,
"Vmi class " + recoveredClass.getClassNamespace().getName(true) +
" should have a parent in the classToParentOffsetMap but doesn't");
Msg.error(this, "Vmi class " + recoveredClass.getClassNamespace().getName(true) +
" should have a parent in the classToParentOffsetMap but doesn't");
return null;
}
@@ -4705,8 +4584,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
if (baseClassStructure == null) {
Msg.error(this, "Parent structure: " +
parent.getClassNamespace().getName(true) +
" should exist but doesn't.");
parent.getClassNamespace().getName(true) + " should exist but doesn't.");
return null;
}
// if it fits at offset or is at the end and class structure can be grown,
@@ -4728,22 +4606,19 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
int dataLen = UNKNOWN;
if (dataOffset != NONE) {
dataLen = EditStructureUtils.getNumberOfUndefinedsStartingAtOffset(
classStructureDataType, dataOffset,
monitor);
classStructureDataType, dataOffset, monitor);
}
if (dataLen != UNKNOWN && dataLen > 0) {
Structure recoveredClassDataStruct =
createClassMemberDataStructure(recoveredClass, classStructureDataType,
dataLen, dataOffset);
Structure recoveredClassDataStruct = createClassMemberDataStructure(recoveredClass,
classStructureDataType, dataLen, dataOffset);
if (recoveredClassDataStruct != null) {
// if it fits at offset or is at the end and class structure can be grown,
// copy the whole baseClass structure to the class Structure at the given offset
EditStructureUtils.addDataTypeToStructure(classStructureDataType, dataOffset,
recoveredClassDataStruct,
"data", monitor);
recoveredClassDataStruct, "data", monitor);
}
}