diff --git a/Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RTTIGccClassRecoverer.java b/Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RTTIGccClassRecoverer.java
index 2c419fda54..6f02ec70d0 100644
--- a/Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RTTIGccClassRecoverer.java
+++ b/Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RTTIGccClassRecoverer.java
@@ -231,7 +231,11 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
private void processGccRTTI() throws CancelledException, Exception {
// create the appropriate type of type info struct at the various typeinfo symbol locations
- createTypeinfoStructs();
+ List
typeinfoAddresses = createTypeinfoStructs();
+
+ if (typeinfoAddresses.isEmpty()) {
+ return;
+ }
processVtables();
@@ -240,11 +244,16 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
recoveredClasses = recoverClassesFromVftables(vftableSymbols, true, true);
- // find all typeinfo symbols and get their class namespace and create RecoveredClass object
- List typeinfoSymbols = extendedFlatAPI.getListOfSymbolsInAddressSet(
- program.getAddressFactory().getAddressSet(), "typeinfo", true);
+ // find all valid typeinfo symbols and get their class namespace and create RecoveredClass
+ // object
+ AddressSet nonExecutableAddressSet = program.getAddressFactory()
+ .getAddressSet()
+ .subtract(program.getMemory().getExecuteSet());
- // create class objects for each typeinfo struct and make a class to typeinfo mapping for each
+ List typeinfoSymbols =
+ extendedFlatAPI.getListOfSymbolsInAddressSet(nonExecutableAddressSet, "typeinfo", true);
+
+ // create class objects for each typeinfo struct and make class to typeinfo mapping for each
createClassesFromTypeinfoSymbols(typeinfoSymbols);
updateClassesWithParentsAndFlags(typeinfoSymbols);
@@ -312,7 +321,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
}
}
- Address specialTypeinfoRef = extendedFlatAPI.getSingleReferencedAddress(typeinfoAddress);
+ Address specialTypeinfoRef =
+ extendedFlatAPI.getSingleReferencedAddress(typeinfoAddress);
if (specialTypeinfoRef == null) {
if (DEBUG) {
Msg.debug(this,
@@ -328,7 +338,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
if (!hasExternalBlock()) {
if (DEBUG) {
Msg.debug(this,
- "Special typeinfo reference is not equal to one of the three special type infos. Cannot process typeinfo struct at " +
+ "Special typeinfo reference is not equal to one of the three special " +
+ "type infos. Cannot process typeinfo struct at " +
typeinfoAddress.toString());
}
continue;
@@ -338,7 +349,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
if (!isSpecialVtable(specialTypeinfoRef)) {
if (DEBUG) {
Msg.debug(this,
- "Special typeinfo reference is not equal to one of the three special type infos. Cannot process typeinfo struct at " +
+ "Special typeinfo reference is not equal to one of the three special " +
+ "type infos. Cannot process typeinfo struct at " +
typeinfoAddress.toString());
}
continue;
@@ -451,7 +463,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
while (vtableIterator.hasNext()) {
-
monitor.checkCanceled();
Symbol vtableSymbol = vtableIterator.next();
@@ -801,7 +812,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
// if not already named a construction-vtable then check to see if it is one so it can
// be renamed and the new namespace figured out
- // know it isn't null because the of the vtable symbol iterator used to call this method in the first place
+ // know it isn't null because the of the vtable symbol iterator used to call this method in
+ // the first place
Symbol vtableSymbol = symbolTable.getPrimarySymbol(vtableAddress);
if (!vtableSymbol.getName().equals("construction-vtable") && listOfAllVtables != null) {
// get first VTT before this vtable
@@ -1039,7 +1051,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
if (pointer == null) {
return false;
}
- // check to see if pointer is to the class vftable or to a class internal vtable or to itself
+ // check if pointer is to the class vftable or to a class internal vtable or to itself
// if not one of those things it isn't a VTT
Symbol symbol = symbolTable.getPrimarySymbol(pointer);
if ((!symbol.getName().equals(VFTABLE_LABEL) ||
@@ -1156,7 +1168,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
return false;
}
- List referenceFromAddresses = extendedFlatAPI.getReferenceFromAddresses(address);
+ List referenceFromAddresses =
+ extendedFlatAPI.getReferenceFromAddresses(address);
if (referenceFromAddresses.size() > 0) {
return false;
@@ -1316,8 +1329,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
api.createData(address, pointer);
Address referencedAddress = extendedFlatAPI.getSingleReferencedAddress(address);
- // if it isn't a valid pointer, clear what we just created and increment to offset so
- // the next can be checked
+ // if it isn't a valid pointer, clear what we just created and increment to offset
+ // so the next can be checked
if (referencedAddress == null || !programAddressSet.contains(referencedAddress)) {
api.clearListing(address);
api.createData(address, longDT);
@@ -1342,7 +1355,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
* @throws CancelledException if cancelled
* @throws Exception if could not apply a type info structure
*/
- private void createTypeinfoStructs() throws CancelledException, Exception {
+ private List createTypeinfoStructs() throws CancelledException, Exception {
StructureDataType classTypeInfoStructure = createClassTypeInfoStructure();
StructureDataType siClassTypeInfoStructure =
@@ -1367,12 +1380,13 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
}
if (typeinfoAddresses.isEmpty()) {
- return;
+ return typeinfoAddresses;
}
for (Address typeinfoAddress : typeinfoAddresses) {
- Address specialTypeinfoRef = extendedFlatAPI.getSingleReferencedAddress(typeinfoAddress);
+ Address specialTypeinfoRef =
+ extendedFlatAPI.getSingleReferencedAddress(typeinfoAddress);
if (specialTypeinfoRef == null) {
continue;
}
@@ -1439,6 +1453,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
}
}
+ return typeinfoAddresses;
}
private Data applyTypeinfoStructure(Structure typeInfoStructure, Address typeinfoAddress)
@@ -1582,8 +1597,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
return null;
}
- Address stringReference =
- extendedFlatAPI.getSingleReferencedAddress(address.add(typeinfoNameComponent.getOffset()));
+ Address stringReference = extendedFlatAPI
+ .getSingleReferencedAddress(address.add(typeinfoNameComponent.getOffset()));
Data stringData = api.getDataAt(stringReference);
if (stringData == null) {
@@ -1610,8 +1625,12 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
List typeinfoAddresses = new ArrayList();
- List typeinfoSymbols = extendedFlatAPI.getListOfSymbolsInAddressSet(
- program.getAddressFactory().getAddressSet(), "typeinfo", true);
+ AddressSet nonExecutableAddressSet = program.getAddressFactory()
+ .getAddressSet()
+ .subtract(program.getMemory().getExecuteSet());
+
+ List typeinfoSymbols =
+ extendedFlatAPI.getListOfSymbolsInAddressSet(nonExecutableAddressSet, "typeinfo", true);
Iterator typeinfoIterator = typeinfoSymbols.iterator();
while (typeinfoIterator.hasNext()) {
@@ -1645,14 +1664,18 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
List typeinfoAddresses = new ArrayList();
+ AddressSetView executeSet = program.getMemory().getExecuteSet();
+
Iterator bookmarksIterator =
program.getBookmarkManager().getBookmarksIterator(BookmarkType.ERROR);
while (bookmarksIterator.hasNext()) {
monitor.checkCanceled();
Bookmark bookmark = bookmarksIterator.next();
+ Address bookmarkAddress = bookmark.getAddress();
if (bookmark.getCategory().equals("EXTERNAL Relocation") &&
- bookmarkContainsSpecialTypeinfoName(bookmark.getComment())) {
- typeinfoAddresses.add(bookmark.getAddress());
+ bookmarkContainsSpecialTypeinfoName(bookmark.getComment()) &&
+ !executeSet.contains(bookmarkAddress)) {
+ typeinfoAddresses.add(bookmarkAddress);
}
}
return typeinfoAddresses;
@@ -1679,7 +1702,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
* @throws CancelledException if cancelled
*/
private boolean hasExternalRelocationRefs() throws CancelledException {
- // if no external block then there won't be any refernces to special typeinfos in the external
+ // if no external block then there won't be any refernces to special typeinfos in external
// block so return empty list
if (!hasExternalBlock()) {
return false;
@@ -1703,13 +1726,18 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
*/
private List getTypeinfoAddressesUsingSpecialTypeinfos() throws CancelledException {
+ AddressSetView executeSet = program.getMemory().getExecuteSet();
List specialTypeinfoRefs = new ArrayList();
if (class_type_info != null) {
Reference[] refsToClassTypeinfo = api.getReferencesTo(class_type_info);
for (Reference ref : refsToClassTypeinfo) {
monitor.checkCanceled();
- specialTypeinfoRefs.add(ref.getFromAddress());
+ Address typeinfoAddress = ref.getFromAddress();
+ if (executeSet.contains(typeinfoAddress)) {
+ continue;
+ }
+ specialTypeinfoRefs.add(typeinfoAddress);
}
}
@@ -1717,7 +1745,11 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
Reference[] refsToSiClassTypeinfo = api.getReferencesTo(si_class_type_info);
for (Reference ref : refsToSiClassTypeinfo) {
monitor.checkCanceled();
- specialTypeinfoRefs.add(ref.getFromAddress());
+ Address typeinfoAddress = ref.getFromAddress();
+ if (executeSet.contains(typeinfoAddress)) {
+ continue;
+ }
+ specialTypeinfoRefs.add(typeinfoAddress);
}
}
@@ -1725,7 +1757,11 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
Reference[] refsToVmiClassTypeinfo = api.getReferencesTo(vmi_class_type_info);
for (Reference ref : refsToVmiClassTypeinfo) {
monitor.checkCanceled();
- specialTypeinfoRefs.add(ref.getFromAddress());
+ Address typeinfoAddress = ref.getFromAddress();
+ if (executeSet.contains(typeinfoAddress)) {
+ continue;
+ }
+ specialTypeinfoRefs.add(typeinfoAddress);
}
}
@@ -1896,7 +1932,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
* @param recoveredClass the given class
* @param typeinfoAddress the address of the typeinfo
* @return list of parents for the given class
- * @throws Exception if cannot access the given typeinfo structure, one of its components, or it is not a vmi structure
+ * @throws Exception if cannot access the given typeinfo structure, one of its components,
+ * or it is not a vmi structure
*/
private List addGccClassParentsFromVmiStruct(RecoveredClass recoveredClass,
Address typeinfoAddress) throws Exception {
@@ -1947,6 +1984,13 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
numBaseClassesDataType.getDefaultSettings(), numBaseClassesDataType.getLength());
int numBaseClasses = (int) scalar.getUnsignedValue();
+ if (numBaseClasses < 0) {
+ throw new IllegalArgumentException("Could not process vmi class " +
+ recoveredClass.getName() +
+ " because getting the number of bases from the vmi typeinfo structure at address " +
+ typeinfoAddress.toString());
+ }
+
if (numBaseClasses > 1) {
recoveredClass.setHasMultipleInheritance(true);
recoveredClass.setHasSingleInheritance(false);
@@ -2123,8 +2167,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
}
/**
- * Method to find the (up to three) special gcc vtables and replace the incorrectly made array with the
- * correct data types. Also creates a type info symbol at the correct offset in the table.
+ * Method to find the (up to three) special gcc vtables and replace the incorrectly made array
+ * with the correct data types. Also creates typeinfo symbol at the correct offset in the table.
* @return true if all found tables have a typeinfo symbol created successfully
* @throws CancelledException if cancelled
* @throws InvalidInputException if bad characters creating labels
@@ -2154,7 +2198,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
si_class_type_info = createSpecialVtable(si_class_type_info_vtable);
if (si_class_type_info == null) {
Msg.debug(this,
- "__si_class_type_info typeinfo not found -- cannot continue gcc rtti processing");
+ "__si_class_type_info typeinfo not found -- cannot continue gcc rtti " +
+ "processing");
return false;
}
}
@@ -2168,7 +2213,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
vmi_class_type_info = createSpecialVtable(vmi_class_type_info_vtable);
if (vmi_class_type_info == null) {
Msg.debug(this,
- "__vmi_class_type_info typeinfo not found -- cannot continue gcc rtti processing");
+ "__vmi_class_type_info typeinfo not found -- cannot continue gcc rtti " +
+ "processing");
return false;
}
}
@@ -2176,7 +2222,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
if (class_type_info_vtable == null && si_class_type_info_vtable == null &&
vmi_class_type_info_vtable == null) {
Msg.debug(this,
- "Since there are no class typeinfo tables this program does not appear to have RTTI.");
+ "Since there are no class typeinfo tables this program does not appear to have " +
+ "RTTI.");
return false;
}
return true;
@@ -2269,7 +2316,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
continue;
}
- Address vftableAddress = extendedFlatAPI.getAddress(typeinfoAddress, defaultPointerSize);
+ Address vftableAddress =
+ extendedFlatAPI.getAddress(typeinfoAddress, defaultPointerSize);
// no valid address here so continue
if (vftableAddress == null) {
//createNewClass(vtableNamespace, false);
@@ -2350,7 +2398,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
recoveredClasses.add(recoveredClass);
}
- Address specialTypeinfoRef = extendedFlatAPI.getSingleReferencedAddress(typeinfoAddress);
+ Address specialTypeinfoRef =
+ extendedFlatAPI.getSingleReferencedAddress(typeinfoAddress);
if (specialTypeinfoRef == null) {
if (DEBUG) {
Msg.debug(this,
@@ -2470,8 +2519,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
}
// update the inherits virtual ancestor flag using ancestors - previously was only done for
- // parents but now have all classes with flag set for direct parent so can get the other ancestors
- // too
+ // parents but now have all classes with flag set for direct parent so can get the other
+ // ancestors too
recoveredClassIterator = recoveredClasses.iterator();
while (recoveredClassIterator.hasNext()) {
monitor.checkCanceled();
@@ -2750,7 +2799,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
}
/**
- * Method to create all the class data types for the current class, name all the class functions, and put them all into the class namespace
+ * Method to create all the class data types for the current class, name all the class
+ * functions, and put them all into the class namespace
* @param recoveredClass current class
* @throws CancelledException when cancelled
* @throws Exception naming exception
@@ -2791,8 +2841,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
// then filled in later
Map vfPointerDataTypes = createEmptyVfTableStructs(recoveredClass);
- // create current class structure and add pointer to vftable, all parent member data strutures,
- // and class member data structure
+ // create current class structure and add pointer to vftable, all parent member data
+ // structures, and class member data structure
Structure classStruct = createSimpleClassStructure(recoveredClass, vfPointerDataTypes);
// Now that we have a class data type
@@ -2809,10 +2859,9 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
// createInlinedDestructorComments(recoveredClass);
// createIndeterminateInlineComments(recoveredClass);
- // add label on constructor destructor functions that could not be determined which were which
+ // add label on constructor destructor functions that could not be determined
createIndeterminateLabels(recoveredClass, classStruct);
-
// This is done after the class structure is created and added to the dtmanager
// because if done before the class structures are created
// then empty classes will get auto-created in the wrong place
@@ -2830,8 +2879,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
CategoryPath classPath = recoveredClass.getClassPath();
- // get either existing structure if prog has a structure created by pdb or computed structure
- // from decompiled construtor(s) info
+ // get either existing structure if prog has a structure created by pdb or computed
+ // structure from decompiled construtor(s) info
Structure classStructure;
if (recoveredClass.hasExistingClassStructure()) {
classStructure = recoveredClass.getExistingClassStructure();
@@ -2858,11 +2907,10 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
// simple case the offset for vftablePtr is 0
if (EditStructureUtils.canAdd(classStructureDataType, 0,
- classVftablePointer.getLength(),
- monitor)) {
+ classVftablePointer.getLength(), monitor)) {
classStructureDataType =
- EditStructureUtils.addDataTypeToStructure(classStructureDataType,
- 0, classVftablePointer, CLASS_VTABLE_PTR_FIELD_EXT, monitor);
+ EditStructureUtils.addDataTypeToStructure(classStructureDataType, 0,
+ classVftablePointer, CLASS_VTABLE_PTR_FIELD_EXT, monitor);
}
}
@@ -2898,8 +2946,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
int parentOffset = parentOffsetLong.intValue();
Structure baseClassStructure = getClassStructureFromDataTypeManager(parent);
- // if we can't get the parent throw exception because it shouldn't get here if the parent
- // doesn't exist
+ // if we can't get the parent throw exception because it shouldn't get here if the
+ // parent doesn't exist
if (baseClassStructure == null) {
throw new Exception(parent.getClassNamespace().getName(true) +
" : structure should exist but doesn't.");
@@ -2907,10 +2955,9 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
if (EditStructureUtils.canAdd(classStructureDataType, parentOffset,
baseClassStructure.getLength(), monitor)) {
- classStructureDataType =
- EditStructureUtils.addDataTypeToStructure(classStructureDataType,
- parentOffset,
- baseClassStructure, baseClassStructure.getName(), monitor);
+ classStructureDataType = EditStructureUtils.addDataTypeToStructure(
+ classStructureDataType, parentOffset, baseClassStructure,
+ baseClassStructure.getName(), monitor);
}
}
@@ -2920,9 +2967,8 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
int dataOffset = getDataOffset(recoveredClass, classStructureDataType);
int dataLen = UNKNOWN;
if (dataOffset != NONE) {
- dataLen =
- EditStructureUtils.getNumberOfUndefinedsStartingAtOffset(classStructureDataType,
- dataOffset, monitor);
+ dataLen = EditStructureUtils.getNumberOfUndefinedsStartingAtOffset(
+ classStructureDataType, dataOffset, monitor);
}
if (dataLen != UNKNOWN && dataLen > 0) {
@@ -2932,8 +2978,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
if (recoveredClassDataStruct != null) {
classStructureDataType = EditStructureUtils.addDataTypeToStructure(
- classStructureDataType,
- dataOffset, recoveredClassDataStruct, "data", monitor);
+ classStructureDataType, dataOffset, recoveredClassDataStruct, "data", monitor);
}
}