GP-4376 Updated gcc class recovery to allow for special typeinfos that

are not in program memory or external block. Also updated to add a check
for unhandled relocations. Also updated to allow for non-mangled
typeinfo-name strings.
This commit is contained in:
ghidra007 2024-03-06 17:00:26 +00:00
parent 3e35b4d4a7
commit b04d5335ca
5 changed files with 318 additions and 128 deletions

View file

@ -80,6 +80,7 @@ import ghidra.program.model.data.*;
import ghidra.program.model.listing.*;
import ghidra.program.model.mem.MemoryBlock;
import ghidra.program.model.reloc.Relocation;
import ghidra.program.model.reloc.Relocation.Status;
import ghidra.program.model.reloc.RelocationTable;
import ghidra.program.model.symbol.Symbol;
import ghidra.program.util.GhidraProgramUtilities;
@ -210,8 +211,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
if (!runGcc) {
return;
}
//run fixup old elf relocations script
runScript("FixElfExternalOffsetDataRelocationScript.java");
recoverClassesFromRTTI = new RTTIGccClassRecoverer(currentProgram, state.getTool(),
this, BOOKMARK_FOUND_FUNCTIONS, USE_SHORT_TEMPLATE_NAMES_IN_STRUCTURE_FIELDS,
nameVfunctions, hasDebugSymbols, monitor);
@ -232,9 +232,6 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
return;
}
//run fixup old elf relocations script
runScript("FixElfExternalOffsetDataRelocationScript.java");
hasDebugSymbols = isDwarfLoadedInProgram();
if (hasDwarf() && !hasDebugSymbols) {
println(
@ -379,7 +376,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
DWARFProgram.DWARF_ROOT_NAME) || options.getBoolean("DWARF Loaded", false));
}
public String validate() throws CancelledException {
public String validate() throws Exception {
if (currentProgram == null) {
return ("There is no open program");
@ -417,6 +414,8 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
// check that gcc loader or mingw analyzer has fixed the relocations correctly
if (isGcc()) {
runScript("FixElfExternalOffsetDataRelocationScript.java");
// first check that there is even rtti by searching the special string in memory
if (!isStringInProgramMemory("class_type_info")) {
return ("This program does not contain RTTI.");
@ -432,7 +431,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
"contact the Ghidra team so this issue can be fixed.");
}
if (hasUnhandledRelocations()) {
if (hasRelocationIssue()) {
return ("This program has unhandled elf relocations so cannot continue. Please " +
"contact the Ghidra team for assistance.");
}
@ -442,7 +441,13 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
}
private boolean hasUnhandledRelocations() throws CancelledException {
/**
* Method to determine if the gcc relocations needed to find the special typeinfos/vtables
* have any issues that would keep script from running correctly.
* @return true if there are any issues with the relocations, false otherwise
* @throws CancelledException if cancelled
*/
private boolean hasRelocationIssue() throws CancelledException {
RelocationTable relocationTable = currentProgram.getRelocationTable();
@ -452,17 +457,39 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
monitor.checkCancelled();
Relocation r = relocations.next();
if (r.getSymbolName().contains("class_type_info") &&
(r.getStatus() != Relocation.Status.APPLIED &&
r.getStatus() != Relocation.Status.APPLIED_OTHER &&
r.getStatus() != Relocation.Status.SKIPPED)) {
return true;
}
String symbolName = r.getSymbolName();
if (symbolName != null && symbolName.contains("class_type_info")) {
Status status = r.getStatus();
// if any relocations for special typeinfo class symbols have failed then there
// is an issue
if (status == Status.FAILURE) {
return true;
}
// if any relocations for special typeinfo class symbols are unsupported then
// determine where the symbol is located before determining if it is an issue
if(status == Status.UNSUPPORTED) {
//if relocation symbol is the same as the symbol at the relcation address
//then this situation is not an issue - it indicates a copy relocation at the
//location of the special typeinfo vtable which is a use case that can be handled
Address address = r.getAddress();
Symbol symbolAtAddress = currentProgram.getSymbolTable().getSymbol(symbolName, address, currentProgram.getGlobalNamespace());
if(symbolAtAddress != null) {
continue;
}
return true;
}
}
}
return false;
}
private void analyzeProgramChanges(AddressSetView beforeChanges) throws Exception {
AddressSetView addressSet = currentProgram.getChanges().getAddressSet();

View file

@ -15,10 +15,7 @@
*/
package classrecovery;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.*;
import ghidra.program.model.address.Address;
import ghidra.program.model.symbol.Namespace;
@ -30,7 +27,7 @@ public class GccTypeinfo extends Typeinfo {
private static final String VMI_CLASS_TYPEINFO_NAMESPACE = "__vmi_class_type_info";
boolean isSpecialTypeinfo;
GccTypeinfo inheritedSpecialTypeinfo = null;
Namespace inheritedSpecialTypeinfoNamespace = null;
Address vtableAddress;
boolean inProgramMemory;
String mangledNamespaceString = null;
@ -53,13 +50,13 @@ public class GccTypeinfo extends Typeinfo {
return inProgramMemory;
}
public void setInheritedSpecialTypeinfo(GccTypeinfo specialTypeinfo) {
inheritedSpecialTypeinfo = specialTypeinfo;
public void setInheritedSpecialTypeinfoNamespace(Namespace specialTypeinfoNamespace) {
inheritedSpecialTypeinfoNamespace = specialTypeinfoNamespace;
}
public GccTypeinfo getInheritedSpecialTypeinfo() {
return inheritedSpecialTypeinfo;
public Namespace getInheritedSpecialTypeinfoNamespace() {
return inheritedSpecialTypeinfoNamespace;
}
@ -156,21 +153,21 @@ public class GccTypeinfo extends Typeinfo {
}
public boolean isClassTypeinfo() {
if(inheritedSpecialTypeinfo.getNamespace().getName().equals(CLASS_TYPEINFO_NAMESPACE)) {
if (inheritedSpecialTypeinfoNamespace.getName().equals(CLASS_TYPEINFO_NAMESPACE)) {
return true;
}
return false;
}
public boolean isSiClassTypeinfo() {
if(inheritedSpecialTypeinfo.getNamespace().getName().equals(SI_CLASS_TYPEINFO_NAMESPACE)) {
if (inheritedSpecialTypeinfoNamespace.getName().equals(SI_CLASS_TYPEINFO_NAMESPACE)) {
return true;
}
return false;
}
public boolean isVmiClassTypeinfo() {
if(inheritedSpecialTypeinfo.getNamespace().getName().equals(VMI_CLASS_TYPEINFO_NAMESPACE)) {
if (inheritedSpecialTypeinfoNamespace.getName().equals(VMI_CLASS_TYPEINFO_NAMESPACE)) {
return true;
}
return false;

View file

@ -19,6 +19,8 @@ package classrecovery;
import java.io.UnsupportedEncodingException;
import java.util.*;
import org.apache.commons.lang3.StringUtils;
import ghidra.app.cmd.label.DemanglerCmd;
import ghidra.app.plugin.core.analysis.ReferenceAddressPair;
import ghidra.app.util.NamespaceUtils;
@ -101,6 +103,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
protected final FunctionManager functionManager;
protected final Listing listing;
protected final Memory memory;
public RTTIGccClassRecoverer(Program program, ServiceProvider serviceProvider,
FlatProgramAPI api, boolean createBookmarks, boolean useShortTemplates,
@ -113,6 +116,9 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
functionManager = program.getFunctionManager();
listing = program.getListing();
memory = program.getMemory();
}
@Override
@ -156,7 +162,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
List<GccTypeinfo> specialTypeinfos = createSpecialTypeinfos();
if (specialTypeinfos.isEmpty()) {
Msg.debug(this, "Could not create special typeinfos");
return null;
}
Msg.debug(this, "Creating Special Vtables");
@ -169,7 +174,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
if (specialVtables.size() != specialTypeinfos.size()) {
Msg.debug(this, "Not equal number of special vtables and special typeinfos");
return null;
}
setComponentOffset();
@ -355,7 +359,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
// in a non-loaded section that isn't real memory then it shouldn't be the case where the
// typeinfo is at the same location as the vtable since it should have enough memory and
// real bytes that point to a real typeinfo in program memory
if (hasAssociatedFileByes(vtableAddress)) {
if (isLoadedAndInitializedMemory(vtableAddress)) {
return null;
}
@ -381,7 +385,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
}
private boolean hasAssociatedFileByes(Address address) {
private boolean isLoadedAndInitializedMemory(Address address) {
if (inExternalBlock(address)) {
return false;
@ -391,9 +395,9 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
}
Memory memory = program.getMemory();
long fileOffset = memory.getAddressSourceInfo(address).getFileOffset();
if (fileOffset == -1) {
return false;
AddressSetView initMem = memory.getLoadedAndInitializedAddressSet();
if (initMem.contains(address)) {
return true;
}
return true;
@ -451,7 +455,6 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
return null;
}
// TODO: can this be used for regular ones too?
private Symbol findTypeinfoSymbolUsingMangledNamespaceString(String mangledNamespace,
String namespaceName) throws CancelledException {
@ -2220,6 +2223,19 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
SpecialVtable specialVtable = new SpecialVtable(program, vtableAddress, typeinfoRef,
isExternal, vtableSymbol.getParentNamespace(), monitor);
if (specialTypeinfo != null) {
specialTypeinfo.setVtableAddress(vtableAddress);
}
if (!specialVtable.isExternal()) {
specialVtable.applyVtableData();
vtableToSizeMap.put(specialVtable.getAddress(), specialVtable.getLength());
createVtableLabel(specialVtable);
createVtableComment(specialVtable);
createVfunctionSymbol(specialVtable);
}
return specialVtable;
}
@ -2362,9 +2378,14 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
typeinfoSymbol = createDemangledTypeinfoSymbol(typeinfoAddress);
if (typeinfoSymbol == null) {
Msg.debug(this, "Could not create demangled typeinfo symbol at " +
typeinfoAddress.toString());
continue;
//If no mangled class name, check for non-mangled pascal type class name
typeinfoSymbol =
createTypeinfoSymbolFromNonMangledString(typeinfoAddress);
if (typeinfoSymbol == null) {
Msg.debug(this, "Could not create typeinfo symbol at " +
typeinfoAddress.toString());
continue;
}
}
}
@ -2374,9 +2395,9 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
if (specialTypeinfoNamespaceName == null) {
continue;
}
GccTypeinfo specialTypeinfo =
getTypeinfo(specialTypeinfoNamespaceName, specialTypeinfos);
typeinfo.setInheritedSpecialTypeinfo(specialTypeinfo);
typeinfo.setInheritedSpecialTypeinfoNamespace(specialVtable.getNamespace());
typeinfos.add(typeinfo);
continue;
}
@ -2390,7 +2411,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
for (GccTypeinfo typeinfo : typeinfos) {
monitor.checkCancelled();
Address typeinfoAddress = typeinfo.getAddress();
if (typeinfo.getInheritedSpecialTypeinfo() == null) {
if (typeinfo.getInheritedSpecialTypeinfoNamespace() == null) {
typeinfosToRemove.add(typeinfo);
continue;
@ -2436,9 +2457,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
continue;
}
// TODO: update the typeinfo with the correct namespace based on the structure
String namespaceName = typeinfo.getInheritedSpecialTypeinfo().getNamespace().getName();
String namespaceName = typeinfo.getInheritedSpecialTypeinfoNamespace().getName();
// if typeinfo inherits class_type_info then no Base to update
if (namespaceName.equals(CLASS_TYPEINFO_NAMESPACE)) {
@ -2652,6 +2671,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
// ok if has symbol at the actual addr so don't check it
if (offset == 0) {
offset++;
continue;
}
@ -2848,6 +2868,103 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
return newSymbol;
}
private Symbol createTypeinfoSymbolFromNonMangledString(Address typeinfoAddress)
throws DuplicateNameException, InvalidInputException, CancelledException {
Address typeinfoNameAddress = getTypeinfoNameAddress(typeinfoAddress);
if (typeinfoNameAddress == null) {
Msg.debug(this,
"Could not get typeinfo-name address from " + typeinfoAddress.toString());
return null;
}
String typeinfoNameString = getStringFromMemory(typeinfoNameAddress);
if (typeinfoNameString == null) {
Msg.debug(this, "Could not get typeinfo string from " + typeinfoNameAddress.toString());
return null;
}
// get length from start of string
String lenString = getAsciiLengthString(typeinfoNameString);
if (lenString.isEmpty()) {
Msg.debug(this,
"Could not get typeinfo-name string len from " + typeinfoNameAddress.toString());
return null;
}
// convert lenString to int len
try {
int len = Integer.parseInt(lenString);
// get className from string - if not exactly the correct len then return null
String className = typeinfoNameString.substring(lenString.length());
if (className.length() != len) {
Msg.debug(this, "Expected typeinfo-name to be len " + len + " but it was " +
className.length());
return null;
}
program.getListing()
.clearCodeUnits(typeinfoNameAddress,
typeinfoNameAddress.add(typeinfoNameString.length()), true);
boolean created = createString(typeinfoNameAddress, typeinfoNameString.length());
if (!created) {
Msg.debug(this, "Could not create string at " + typeinfoNameAddress);
}
// create typeinfo name symbol
Namespace classNamespace =
symbolTable.getOrCreateNameSpace(globalNamespace, className, SourceType.ANALYSIS);
Symbol typeinfoNameSymbol = symbolTable.createLabel(typeinfoNameAddress,
"typeinfo-name", classNamespace, SourceType.ANALYSIS);
typeinfoNameSymbol.setPrimary();
// create the new typeinfo symbol in the demangled namespace
Symbol typeinfoSymbol = symbolTable.createLabel(typeinfoAddress, "typeinfo",
classNamespace, SourceType.ANALYSIS);
typeinfoSymbol.setPrimary();
api.setPlateComment(typeinfoAddress, "typeinfo for " + classNamespace.getName(true));
return typeinfoSymbol;
}
catch (NumberFormatException ex) {
return null;
}
}
private String getAsciiLengthString(String string) throws CancelledException {
boolean isDigit = true;
int len = 0;
String lenString = new String();
while (isDigit) {
monitor.checkCancelled();
String charString = string.substring(len, len);
if (!StringUtils.isNumeric(charString)) {
return lenString;
}
lenString.concat(charString);
len++;
}
return lenString;
}
private boolean isAllAscii(Address address, int len) throws CancelledException {
for (int i = 0; i < len; i++) {
monitor.checkCancelled();
if (!isAscii(address.add(i))) {
return false;
}
}
return true;
}
private boolean isTypeinfoNameString(String string) {
DemangledObject demangledObject = DemanglerUtil.demangle(string);
@ -2934,6 +3051,14 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
}
private String getStringFromMemory(Address address, int len) {
TerminatedStringDataType sdt = new TerminatedStringDataType();
MemBuffer buf = new DumbMemBufferImpl(program.getMemory(), address);
return (String) sdt.getValue(buf, sdt.getDefaultSettings(), len);
}
private int getStringLen(Address addr) {
int len = 0;
@ -3544,80 +3669,91 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
}
private Address findSpecialVtable(GccTypeinfo specialTypeinfo,
List<GccTypeinfo> specialTypeinfos) throws CancelledException {
String namespaceName = specialTypeinfo.getNamespace().getName();
String mangledNamespaceString = specialTypeinfo.getMangledNamespaceString();
// try finding with normal symbol name and namespace
Symbol vtableSymbol =
getSymbolInNamespaces(SPECIAL_CLASS_NAMESPACE, namespaceName, VTABLE_LABEL);
if (vtableSymbol == null) {
// then try finding with mangled symbol
vtableSymbol =
findAndReturnDemangledSymbol(MANGLED_VTABLE_PREFIX + mangledNamespaceString,
SPECIAL_CLASS_NAMESPACE, namespaceName, VTABLE_LABEL);
// then try finding top of special vtable by finding ref to special typeinfo
if (vtableSymbol == null) {
Address vtableAddress = findSpecialVtableUsingSpecialTypeinfo(
specialTypeinfo.getAddress(), specialTypeinfos);
if (vtableAddress == null) {
return null;
}
try {
vtableSymbol = symbolTable.createLabel(vtableAddress, VTABLE_LABEL,
specialTypeinfo.getNamespace(), SourceType.ANALYSIS);
api.setPlateComment(vtableAddress,
"vtable for " + specialTypeinfo.getNamespace());
}
catch (InvalidInputException e) {
// ignore
}
}
}
if (vtableSymbol != null) {
return vtableSymbol.getAddress();
}
return null;
}
private List<SpecialVtable> findSpecialVtables(List<GccTypeinfo> specialTypeinfos)
throws Exception {
List<SpecialVtable> specialVtables = new ArrayList<SpecialVtable>();
for (GccTypeinfo specialTypeinfo : specialTypeinfos) {
monitor.checkCancelled();
Map<String, String> namespaceMap = new HashMap<String, String>();
namespaceMap.put(CLASS_TYPEINFO_NAMESPACE, MANGLED_CLASS_TYPEINFO_NAMESPACE);
namespaceMap.put(SI_CLASS_TYPEINFO_NAMESPACE, MANGLED_SI_CLASS_TYPEINFO_NAMESPACE);
namespaceMap.put(VMI_CLASS_TYPEINFO_NAMESPACE, MANGLED_VMI_CLASS_TYPEINFO_NAMESPACE);
Address vtableAddress = findSpecialVtable(specialTypeinfo, specialTypeinfos);
for (String namespaceName : namespaceMap.keySet()) {
GccTypeinfo specTypeinfo = getSpecialTypeinfo(specialTypeinfos, namespaceName);
Address vtableAddress = findSpecialVtableAddress(namespaceName,
namespaceMap.get(namespaceName), specialTypeinfos);
if (vtableAddress == null) {
continue;
}
SpecialVtable specialVtable = createSpecialVtable(vtableAddress, specialTypeinfo);
if (specialVtable != null) {
specialVtables.add(specialVtable);
specialTypeinfo.setVtableAddress(vtableAddress);
if (!specialVtable.isExternal()) {
specialVtable.applyVtableData();
vtableToSizeMap.put(specialVtable.getAddress(), specialVtable.getLength());
createVtableLabel(specialVtable);
createVtableComment(specialVtable);
createVfunctionSymbol(specialVtable);
}
}
SpecialVtable specialVtable =
createSpecialVtable(vtableAddress, specTypeinfo);
specialVtables.add(specialVtable);
}
return specialVtables;
}
private Address findSpecialVtableAddress(String namespaceName, String mangledNamespace,
List<GccTypeinfo> specialTypeinfos) throws CancelledException {
//First try to find with special symbols
Symbol vtableSymbol = getSymbolInNamespaces(namespaceName, mangledNamespace, VTABLE_LABEL);
if (vtableSymbol != null) {
return vtableSymbol.getAddress();
}
// then try finding with mangled symbol
vtableSymbol = findAndReturnDemangledSymbol(MANGLED_VTABLE_PREFIX + mangledNamespace,
SPECIAL_CLASS_NAMESPACE, namespaceName, VTABLE_LABEL);
if (vtableSymbol != null) {
return vtableSymbol.getAddress();
}
//Then with special typeinfo if there is one
GccTypeinfo specTypeinfo = getSpecialTypeinfo(specialTypeinfos, namespaceName);
if (specTypeinfo != null) {
Address vtableAddress = findSpecialVtableUsingSpecialTypeinfo(specTypeinfo.getAddress(),
specialTypeinfos);
if (vtableAddress == null) {
return null;
}
try {
vtableSymbol = symbolTable.createLabel(vtableAddress, VTABLE_LABEL,
specTypeinfo.getNamespace(), SourceType.ANALYSIS);
api.setPlateComment(vtableAddress, "vtable for " + specTypeinfo.getNamespace());
return vtableSymbol.getAddress();
}
catch (InvalidInputException e) {
Msg.warn(this,
"Found vtable at " + vtableAddress + " but cannot create symbol" + e);
return null;
}
}
return null;
}
private GccTypeinfo getSpecialTypeinfo(List<GccTypeinfo> specialTypeinfos,
String namespaceName) {
for (GccTypeinfo specialTypeinfo : specialTypeinfos) {
if (specialTypeinfo.getNamespace().getName().equals(namespaceName)) {
return specialTypeinfo;
}
}
return null;
}
/*
* Method to find special vtable using special typeinfo references. This
* assumption that vtable is defaultPtrSize above ref to single specialTypeinfo

View file

@ -15,9 +15,15 @@
*/
package classrecovery;
import java.util.List;
import ghidra.program.model.address.Address;
import ghidra.program.model.listing.Program;
import ghidra.program.model.reloc.Relocation;
import ghidra.program.model.reloc.Relocation.Status;
import ghidra.program.model.reloc.RelocationTable;
import ghidra.program.model.symbol.Namespace;
import ghidra.program.model.symbol.Symbol;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor;
@ -47,6 +53,19 @@ public class SpecialVtable extends Vtable {
typeinfoRefAddress = vtableAddress.add(defaultPointerSize);
// check for vtable has memory but all zeros or has possible invalid values which in both
// cases would make the pointer to special typeinfo invalid
if (hasSpecialCopyUnhandledRelocation(vtableAddress)) {
isConstruction = false;
isPrimary = true;
typeinfoAddress = null;
length = 3 * defaultPointerSize; //actually prob 11*defPtr but are all zeros in this case
hasVfunctions = true; // they are null though so will count as num=0, need this to be true so check for refs to vfunction top will work
numVfunctions = 0;
vfunctionTop = vtableAddress.add(2 * defaultPointerSize);
return;
}
setTypeinfoAddress();
@ -71,7 +90,9 @@ public class SpecialVtable extends Vtable {
isConstruction = false;
classNamespace = typeinfoNamespace;
if (classNamespace == null) {
classNamespace = typeinfoNamespace;
}
setLength();
@ -82,4 +103,34 @@ public class SpecialVtable extends Vtable {
return refFromTypeinfos;
}
private boolean hasSpecialCopyUnhandledRelocation(Address address) {
RelocationTable relocationTable = program.getRelocationTable();
List<Relocation> relocations = relocationTable.getRelocations(address);
for (Relocation relocation : relocations) {
Status status = relocation.getStatus();
if (status == Status.UNSUPPORTED) {
String symbolName = relocation.getSymbolName();
if (symbolName == null || !symbolName.contains("class_type_info")) {
continue;
}
//if relocation symbol is the same as the symbol at the relcation address
//then this situation is not an issue - it indicates a copy relocation at the
//location of the special typeinfo vtable which is a use case that can be handled
Symbol symbolAtAddress = program.getSymbolTable()
.getSymbol(symbolName, address, program.getGlobalNamespace());
if (symbolAtAddress != null) {
return true;
}
}
}
return false;
}
}

View file

@ -80,7 +80,9 @@ public class Vtable {
this.monitor = monitor;
this.typeinfoRefAddress = typeinfoRef.getAddress();
this.typeinfo = (GccTypeinfo) typeinfoRef.getReferencedTypeinfo();
this.typeinfoNamespace = typeinfo.getNamespace();
if (this.typeinfo != null) {
this.typeinfoNamespace = typeinfo.getNamespace();
}
AddressSpace addressSpace = vtableAddress.getAddressSpace();
defaultPointerSize = addressSpace.getPointerSize();
@ -390,9 +392,6 @@ public class Vtable {
*/
private boolean isPossibleFunctionPointer(Address address) throws CancelledException {
// TODO: make one that works for all casea in helper
// TODO: make sure it recognizes the external functions
long longValue = extendedFlatAPI.getLongValueAt(address);
Register lowBitCodeMode = program.getRegister("LowBitCodeMode");
@ -606,26 +605,6 @@ public class Vtable {
return internalVtables;
}
// TODO: put in helper or ext api
private boolean inExternalBlock(Address address) {
MemoryBlock externalBlock = getExternalBlock();
if (externalBlock == null) {
return false;
}
if (externalBlock.contains(address)) {
return true;
}
return false;
}
private MemoryBlock getExternalBlock() {
return program.getMemory().getBlock("EXTERNAL");
}
public void setIsConstructionVtable(Boolean setting) {
isConstruction = setting;
}