mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 10:19:23 +02:00
GP-5074 - CPP PDB vxtable datatype composition
This commit is contained in:
parent
ce6bef1e12
commit
edb277177d
27 changed files with 1545 additions and 533 deletions
|
@ -0,0 +1,108 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.program.model.gclass;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import ghidra.app.util.SymbolPath;
|
||||
import ghidra.program.model.data.CategoryPath;
|
||||
|
||||
/**
|
||||
* Unique ID of a Program Class Type. Not sure if there will be different implementation for
|
||||
* definition vs. compiled vs. program vs. debug.
|
||||
*/
|
||||
public class ClassID implements Comparable<ClassID> {
|
||||
// All of the internals of this might change, but we need something to work with for now.
|
||||
// It might end up being a hash/guid/long value.
|
||||
// We were trying to use DataTypePath, but that doesn't work in light of conflicts, as we
|
||||
// started with a DataTypePath for the type, which later got resolved to a .conflict (so
|
||||
// DataTypePath changed out from underneath us).
|
||||
private final SymbolPath symbolPath;
|
||||
private final CategoryPath categoryPath;
|
||||
static final int classNameHash = Objects.hash(ClassID.class.getName());
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param categoryPath the category path for the claass
|
||||
* @param symbolPath the symbol path for the class
|
||||
*/
|
||||
public ClassID(CategoryPath categoryPath, SymbolPath symbolPath) {
|
||||
this.categoryPath = categoryPath;
|
||||
this.symbolPath = symbolPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the category path
|
||||
* @return the category path
|
||||
*/
|
||||
public CategoryPath getCategoryPath() {
|
||||
return categoryPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the symbol path
|
||||
* @return the symbol path
|
||||
*/
|
||||
public SymbolPath getSymbolPath() {
|
||||
return symbolPath;
|
||||
}
|
||||
|
||||
// Might want to do something with data type ID if resolved
|
||||
// long doIt(DataTypeManager dtm, DataType dt) {
|
||||
// int x = DataTypeUtilities.getConflictValue(dt);
|
||||
// long dataTypeID;
|
||||
// dataTypeID = dtm.getID(dt);
|
||||
// UniversalID uid = dt.getUniversalID();
|
||||
// return dataTypeID;
|
||||
// }
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s --- %s", categoryPath, symbolPath);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(ClassID o) {
|
||||
int ret;
|
||||
ret = symbolPath.compareTo(o.symbolPath);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
return categoryPath.compareTo(o.categoryPath);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(categoryPath, symbolPath);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
ClassID other = (ClassID) obj;
|
||||
return Objects.equals(categoryPath, other.categoryPath) &&
|
||||
Objects.equals(symbolPath, other.symbolPath);
|
||||
}
|
||||
|
||||
}
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
package ghidra.program.model.gclass;
|
||||
|
||||
import ghidra.app.util.SymbolPath;
|
||||
import ghidra.program.model.data.*;
|
||||
|
||||
/**
|
||||
|
@ -40,6 +41,11 @@ public class ClassUtils {
|
|||
*/
|
||||
public static final PointerDataType VXPTR_TYPE = new PointerDataType();
|
||||
|
||||
/**
|
||||
* The standard prefix used for the special symbol. Private for now.
|
||||
*/
|
||||
private static final String VTABLE_PREFIX = "VTABLE_";
|
||||
|
||||
/**
|
||||
* private constructor -- no instances
|
||||
*/
|
||||
|
@ -54,8 +60,27 @@ public class ClassUtils {
|
|||
*/
|
||||
public static CategoryPath getClassInternalsPath(Composite composite) {
|
||||
DataTypePath dtp = composite.getDataTypePath();
|
||||
return new CategoryPath(new CategoryPath(dtp.getCategoryPath(), dtp.getDataTypeName()),
|
||||
"!internal");
|
||||
return getClassInternalsPath(dtp.getCategoryPath(), dtp.getDataTypeName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the category for class internals for the ClassID
|
||||
* @param id the class ID
|
||||
* @return the category path
|
||||
*/
|
||||
public static CategoryPath getClassInternalsPath(ClassID id) {
|
||||
CategoryPath cp = recurseGetCategoryPath(id.getCategoryPath(), id.getSymbolPath());
|
||||
return cp.extend("!internal");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the category for class internals
|
||||
* @param path the category path of the class composite
|
||||
* @param className the name of the class
|
||||
* @return the category path
|
||||
*/
|
||||
public static CategoryPath getClassInternalsPath(CategoryPath path, String className) {
|
||||
return new CategoryPath(new CategoryPath(path, className), "!internal");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -92,4 +117,46 @@ public class ClassUtils {
|
|||
return composite;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the standard special name for a virtual table (e.g., vbtable, vftable) that is
|
||||
* keyed off of by the Decompiler during flattening and replacing of types within a class
|
||||
* structure. More details to come
|
||||
* @param ptrOffsetInClass the offset of the special field within the class
|
||||
* @return the special name
|
||||
*/
|
||||
public static String getSpecialVxTableName(long ptrOffsetInClass) {
|
||||
return String.format("%s%08x", VTABLE_PREFIX, ptrOffsetInClass);
|
||||
}
|
||||
|
||||
public static DataType getVftDefaultEntry(DataTypeManager dtm) {
|
||||
return new PointerDataType(dtm);
|
||||
}
|
||||
|
||||
public static DataType getVbtDefaultEntry(DataTypeManager dtm) {
|
||||
return new IntegerDataType(dtm);
|
||||
}
|
||||
|
||||
public static int getVftEntrySize(DataTypeManager dtm) {
|
||||
return dtm.getDataOrganization().getPointerSize();
|
||||
}
|
||||
|
||||
public static int getVbtEntrySize(DataTypeManager dtm) {
|
||||
return dtm.getDataOrganization().getIntegerSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get a category path from a base category path and symbol path
|
||||
* @param category the {@ink CategoryPath} on which to build
|
||||
* @param symbolPath the current {@link SymbolPath} from which the current name is pulled.
|
||||
* @return the new {@link CategoryPath} for the recursion level
|
||||
*/
|
||||
private static CategoryPath recurseGetCategoryPath(CategoryPath category,
|
||||
SymbolPath symbolPath) {
|
||||
SymbolPath parent = symbolPath.getParent();
|
||||
if (parent != null) {
|
||||
category = recurseGetCategoryPath(category, parent);
|
||||
}
|
||||
return new CategoryPath(category, symbolPath.getName());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue