Merge remote-tracking branch 'origin/GP-5603_ghizard_PDB_CPP_nonspeculative_class_layout_when_vbt_not_found--SQUASHED'

This commit is contained in:
Ryan Kurtz
2025-04-22 14:13:20 -04:00
10 changed files with 6400 additions and 144 deletions
@@ -391,7 +391,8 @@ public class CppCompositeType {
createMembersOnlyClassLayout(monitor);
break;
case CLASS_HIERARCHY:
createHierarchicalClassLayout(vxtManager, monitor);
case CLASS_HIERARCHY_SPECULATIVE:
createHierarchicalClassLayout(vxtManager, layoutOptions, monitor);
// Next line for developer testing cfb432
//System.out.print(summarizedClassVxtPtrInfo);
break;
@@ -817,7 +818,8 @@ public class CppCompositeType {
//==============================================================================================
//==============================================================================================
private void createHierarchicalClassLayout(MsftVxtManager vxtManager, TaskMonitor monitor)
private void createHierarchicalClassLayout(MsftVxtManager vxtManager,
ObjectOrientedClassLayout layoutOptions, TaskMonitor monitor)
throws PdbException, CancelledException {
initLayoutAlgorithmData();
@@ -827,7 +829,7 @@ public class CppCompositeType {
findOrAllocateMainVftPtr(vxtManager);
findOrAllocateMainVbtPtr(vxtManager);
createClassLayout(vxtManager, monitor);
createClassLayout(vxtManager, layoutOptions, monitor);
finalizeAllVxtParentage();
@@ -1045,7 +1047,8 @@ public class CppCompositeType {
* @throws CancelledException upon user cancellation
* @throws PdbException up issue with finding the vbt or assigning offsets to virtual bases
*/
private void createClassLayout(MsftVxtManager vxtManager, TaskMonitor monitor)
private void createClassLayout(MsftVxtManager vxtManager,
ObjectOrientedClassLayout layoutOptions, TaskMonitor monitor)
throws CancelledException, PdbException {
List<ClassPdbMember> selfBaseMembers = getSelfBaseClassMembers();
mainVft = getMainVft(vxtManager);
@@ -1082,16 +1085,11 @@ public class CppCompositeType {
// updateVbtFromSelf(vbt);
// }
}
assignVirtualBaseOffsets();
String baseComment = (mainVbt instanceof ProgramVirtualBaseTable) ? VIRTUAL_BASE_COMMENT
: VIRTUAL_BASE_SPECULATIVE_COMMENT;
TreeMap<Long, ClassPdbMember> virtualBasePdbMembers =
getVirtualBaseClassMembers(baseComment);
findVirtualBaseVxtPtrs(vxtManager);
TreeMap<Long, ClassPdbMember> allMembers = new TreeMap<>();
allMembers.put(0L, directClassPdbMember);
TreeMap<Long, ClassPdbMember> virtualBasePdbMembers =
processVirtualBaseClasses(vxtManager, layoutOptions);
allMembers.putAll(virtualBasePdbMembers);
List<ClassPdbMember> am = new ArrayList<>(allMembers.values());
@@ -1448,6 +1446,58 @@ public class CppCompositeType {
return newParentage;
}
private TreeMap<Long, ClassPdbMember> processVirtualBaseClasses(MsftVxtManager vxtManager,
ObjectOrientedClassLayout layoutOptions)
throws PdbException {
if (mainVbt instanceof PlaceholderVirtualBaseTable pvbt &&
layoutOptions == ObjectOrientedClassLayout.CLASS_HIERARCHY &&
virtualLayoutBaseClasses.size() > 0) {
TreeMap<Long, ClassPdbMember> virtualBasePdbMembers = provideVirtualBaseFillerBytes();
return virtualBasePdbMembers;
}
// Below processes CLASS_HIERARCHY with ProgramVirtualBaseTable and also processes
// CLASS_HIERARCHY_SPECULATIVE
assignVirtualBaseOffsets();
String baseComment = (mainVbt instanceof ProgramVirtualBaseTable) ? VIRTUAL_BASE_COMMENT
: VIRTUAL_BASE_SPECULATIVE_COMMENT;
TreeMap<Long, ClassPdbMember> virtualBasePdbMembers =
getVirtualBaseClassMembers(baseComment);
findVirtualBaseVxtPtrs(vxtManager);
return virtualBasePdbMembers;
}
private TreeMap<Long, ClassPdbMember> provideVirtualBaseFillerBytes() throws PdbException {
TreeMap<Long, ClassPdbMember> fillerForVirtualBasePdbMembers = new TreeMap<>();
int numVirtualBases = virtualLayoutBaseClasses.size();
if (numVirtualBases == 0) {
return fillerForVirtualBasePdbMembers;
}
int offset = selfBaseType.getLength();
int fillerSize = size - offset;
StringBuilder builder = new StringBuilder();
builder.append("Filler for " + numVirtualBases + " Unplaceable Virtual Base");
builder.append(numVirtualBases == 1 ? ":" : "s:");
boolean first = true;
for (VirtualLayoutBaseClass base : virtualLayoutBaseClasses) {
CppCompositeType cppBaseType = base.getBaseClassType();
if (!first) {
builder.append(";");
}
first = false;
builder.append(" ");
builder.append(cppBaseType.getName());
}
String comment = builder.toString();
ArrayDataType fillerDataType = new ArrayDataType(CharDataType.dataType, fillerSize);
boolean isFlexArray = (fillerSize == 0);
// This does not have attributes
ClassPdbMember fillerPdbMember =
new ClassPdbMember("", fillerDataType, isFlexArray, offset, comment);
fillerForVirtualBasePdbMembers.put((long) offset, fillerPdbMember);
return fillerForVirtualBasePdbMembers;
}
/**
* Uses the main virtual base table to assign offsets for the virtual bases
* @throws PdbException if a virtual base offset cannot be identified
@@ -32,7 +32,13 @@ public enum ObjectOrientedClassLayout {
* Include base class hierarchies and other C++-isms into a class layout that is suited for
* understanding the hierarchies and components from the Structure Editor perspective
*/
CLASS_HIERARCHY("Class Hierarchy (Experimental)");
CLASS_HIERARCHY("Class Hierarchy (Experimental)"),
/**
* Same as {@link #CLASS_HIERARCHY}, but also performs speculative virtual class placement
* if an in-memory Virtual Base Table is not found. This is risky, and not an advised
* solution
*/
CLASS_HIERARCHY_SPECULATIVE("Class Hierarchy (Missing VBT Speculatation - Risky)");
private final String label;
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -135,10 +135,31 @@ abstract public class ProgramCreator {
return builder.toString();
}
/**
* Modifies an original expected result to look like a result that used speculative
* placement of virtual base classes
* @param original the original result
* @return the result with the modifications
*/
protected static String convertCommentsToSpeculative(String original) {
return original.replace("Virtual Base", "Virtual Base - Speculative Placement");
}
/**
* Takes an original expected result, and at the specified starting line ('\n' delimited)
* index, replace the remaing expected result with the replacement String (can be multiple
* lines)
* @param orig the original expected result
* @param startLine the line to start the replacement
* @param replacement the String used to replace the remainder of the original String
* @return the result
*/
protected static String doReplacement(String orig, int startLine, String replacement) {
List<String> lines = List.of(orig.split("\\n"));
List<String> newLines = lines.subList(0, startLine);
return String.join("\n", newLines) + "\n" + replacement;
}
private String programName;
private String languageId;
private String compilerSpec;
@@ -1592,6 +1592,36 @@ public class Vftm32ProgramCreator extends ProgramCreator {
return expected;
}
private static String getFillerStructQ4() {
String expected =
//@formatter:off
"""
/Q4NS::Q4
pack()
Structure Q4NS::Q4 {
0 Q4NS::Q4 16 "Self Base"
16 char[8] 8 "Filler for 1 Unplaceable Virtual Base: P1NS::P1"
}
Length: 24 Alignment: 4
/P2NS::P2
pack()
Structure P2NS::P2 {
0 pointer 4 {vfptr} ""
4 int 4 p2 ""
}
Length: 8 Alignment: 4
/Q4NS::Q4/!internal/Q4NS::Q4
pack()
Structure Q4NS::Q4 {
0 P2NS::P2 8 "Base"
8 pointer 4 {vbptr} ""
12 int 4 q4 ""
}
Length: 16 Alignment: 4""";
//@formatter:on
return expected;
}
private static String getSpeculatedStructQ4() {
return convertCommentsToSpeculative(getExpectedStructQ4());
}
@@ -1788,6 +1818,36 @@ public class Vftm32ProgramCreator extends ProgramCreator {
return expected;
}
private static String getFillerStructQ5() {
String expected =
//@formatter:off
"""
/Q5NS::Q5
pack()
Structure Q5NS::Q5 {
0 Q5NS::Q5 16 "Self Base"
16 char[8] 8 "Filler for 1 Unplaceable Virtual Base: P2NS::P2"
}
Length: 24 Alignment: 4
/P1NS::P1
pack()
Structure P1NS::P1 {
0 pointer 4 {vfptr} ""
4 int 4 p1 ""
}
Length: 8 Alignment: 4
/Q5NS::Q5/!internal/Q5NS::Q5
pack()
Structure Q5NS::Q5 {
0 P1NS::P1 8 "Base"
8 pointer 4 {vbptr} ""
12 int 4 q5 ""
}
Length: 16 Alignment: 4""";
//@formatter:on
return expected;
}
private static String getSpeculatedStructQ5() {
return convertCommentsToSpeculative(getExpectedStructQ5());
}
@@ -1984,6 +2044,36 @@ public class Vftm32ProgramCreator extends ProgramCreator {
return expected;
}
private static String getFillerStructQ6() {
String expected =
//@formatter:off
"""
/Q6NS::Q6
pack()
Structure Q6NS::Q6 {
0 Q6NS::Q6 16 "Self Base"
16 char[8] 8 "Filler for 1 Unplaceable Virtual Base: P2NS::P2"
}
Length: 24 Alignment: 4
/P1NS::P1
pack()
Structure P1NS::P1 {
0 pointer 4 {vfptr} ""
4 int 4 p1 ""
}
Length: 8 Alignment: 4
/Q6NS::Q6/!internal/Q6NS::Q6
pack()
Structure Q6NS::Q6 {
0 P1NS::P1 8 "Base"
8 pointer 4 {vbptr} ""
12 int 4 q6 ""
}
Length: 16 Alignment: 4""";
//@formatter:on
return expected;
}
private static String getSpeculatedStructQ6() {
return convertCommentsToSpeculative(getExpectedStructQ6());
}
@@ -2187,6 +2277,29 @@ public class Vftm32ProgramCreator extends ProgramCreator {
return expected;
}
private static String getFillerStructQ7() {
String expected =
//@formatter:off
"""
/Q7NS::Q7
pack()
Structure Q7NS::Q7 {
0 Q7NS::Q7 12 "Self Base"
12 char[16] 16 "Filler for 2 Unplaceable Virtual Bases: P1NS::P1; P2NS::P2"
}
Length: 28 Alignment: 4
/Q7NS::Q7/!internal/Q7NS::Q7
pack()
Structure Q7NS::Q7 {
0 pointer 4 {vfptr} ""
4 pointer 4 {vbptr} ""
8 int 4 q7 ""
}
Length: 12 Alignment: 4""";
//@formatter:on
return expected;
}
private static String getSpeculatedStructQ7() {
return convertCommentsToSpeculative(getExpectedStructQ7());
}
@@ -2481,6 +2594,29 @@ public class Vftm32ProgramCreator extends ProgramCreator {
return expected;
}
private static String getFillerStructR1() {
String expected =
//@formatter:off
"""
/R1NS::R1
pack()
Structure R1NS::R1 {
0 R1NS::R1 12 "Self Base"
12 char[40] 40 "Filler for 2 Unplaceable Virtual Bases: Q1NS::Q1; Q2NS::Q2"
}
Length: 52 Alignment: 4
/R1NS::R1/!internal/R1NS::R1
pack()
Structure R1NS::R1 {
0 pointer 4 {vfptr} ""
4 pointer 4 {vbptr} ""
8 int 4 r1 ""
}
Length: 12 Alignment: 4""";
//@formatter:on
return expected;
}
private static String getSpeculatedStructR1() {
return convertCommentsToSpeculative(getExpectedStructR1());
}
@@ -2667,6 +2803,16 @@ public class Vftm32ProgramCreator extends ProgramCreator {
expectedStructs.put(R1, getExpectedStructR1());
}
private static final Map<ClassID, String> fillerStructs = new LinkedHashMap<>();
static {
fillerStructs.putAll(expectedStructs);
fillerStructs.put(Q4, getFillerStructQ4());
fillerStructs.put(Q5, getFillerStructQ5());
fillerStructs.put(Q6, getFillerStructQ6());
fillerStructs.put(Q7, getFillerStructQ7());
fillerStructs.put(R1, getFillerStructR1());
}
private static final Map<ClassID, String> speculatedStructs = new LinkedHashMap<>();
static {
speculatedStructs.put(P1, getSpeculatedStructP1());
@@ -2739,6 +2885,10 @@ public class Vftm32ProgramCreator extends ProgramCreator {
return expectedStructs;
}
public Map<ClassID, String> getFillerStructs() {
return fillerStructs;
}
public Map<ClassID, String> getSpeculatedStructs() {
return speculatedStructs;
}
@@ -1612,6 +1612,36 @@ public class Vftm64ProgramCreator extends ProgramCreator {
return expected;
}
private static String getFillerStructQ4() {
String expected =
//@formatter:off
"""
/Q4NS::Q4
pack()
Structure Q4NS::Q4 {
0 Q4NS::Q4 32 "Self Base"
32 char[16] 16 "Filler for 1 Unplaceable Virtual Base: P1NS::P1"
}
Length: 48 Alignment: 8
/P2NS::P2
pack()
Structure P2NS::P2 {
0 pointer 8 {vfptr} ""
8 int 4 p2 ""
}
Length: 16 Alignment: 8
/Q4NS::Q4/!internal/Q4NS::Q4
pack()
Structure Q4NS::Q4 {
0 P2NS::P2 16 "Base"
16 pointer 8 {vbptr} ""
24 int 4 q4 ""
}
Length: 32 Alignment: 8""";
//@formatter:on
return expected;
}
private static String getSpeculatedStructQ4() {
return convertCommentsToSpeculative(getExpectedStructQ4());
}
@@ -1811,6 +1841,36 @@ public class Vftm64ProgramCreator extends ProgramCreator {
return expected;
}
private static String getFillerStructQ5() {
String expected =
//@formatter:off
"""
/Q5NS::Q5
pack()
Structure Q5NS::Q5 {
0 Q5NS::Q5 32 "Self Base"
32 char[16] 16 "Filler for 1 Unplaceable Virtual Base: P2NS::P2"
}
Length: 48 Alignment: 8
/P1NS::P1
pack()
Structure P1NS::P1 {
0 pointer 8 {vfptr} ""
8 int 4 p1 ""
}
Length: 16 Alignment: 8
/Q5NS::Q5/!internal/Q5NS::Q5
pack()
Structure Q5NS::Q5 {
0 P1NS::P1 16 "Base"
16 pointer 8 {vbptr} ""
24 int 4 q5 ""
}
Length: 32 Alignment: 8""";
//@formatter:on
return expected;
}
private static String getSpeculatedStructQ5() {
return convertCommentsToSpeculative(getExpectedStructQ5());
}
@@ -2010,6 +2070,36 @@ public class Vftm64ProgramCreator extends ProgramCreator {
return expected;
}
private static String getFillerStructQ6() {
String expected =
//@formatter:off
"""
/Q6NS::Q6
pack()
Structure Q6NS::Q6 {
0 Q6NS::Q6 32 "Self Base"
32 char[16] 16 "Filler for 1 Unplaceable Virtual Base: P2NS::P2"
}
Length: 48 Alignment: 8
/P1NS::P1
pack()
Structure P1NS::P1 {
0 pointer 8 {vfptr} ""
8 int 4 p1 ""
}
Length: 16 Alignment: 8
/Q6NS::Q6/!internal/Q6NS::Q6
pack()
Structure Q6NS::Q6 {
0 P1NS::P1 16 "Base"
16 pointer 8 {vbptr} ""
24 int 4 q6 ""
}
Length: 32 Alignment: 8""";
//@formatter:on
return expected;
}
private static String getSpeculatedStructQ6() {
return convertCommentsToSpeculative(getExpectedStructQ6());
}
@@ -2216,6 +2306,29 @@ public class Vftm64ProgramCreator extends ProgramCreator {
return expected;
}
private static String getFillerStructQ7() {
String expected =
//@formatter:off
"""
/Q7NS::Q7
pack()
Structure Q7NS::Q7 {
0 Q7NS::Q7 24 "Self Base"
24 char[32] 32 "Filler for 2 Unplaceable Virtual Bases: P1NS::P1; P2NS::P2"
}
Length: 56 Alignment: 8
/Q7NS::Q7/!internal/Q7NS::Q7
pack()
Structure Q7NS::Q7 {
0 pointer 8 {vfptr} ""
8 pointer 8 {vbptr} ""
16 int 4 q7 ""
}
Length: 24 Alignment: 8""";
//@formatter:on
return expected;
}
private static String getSpeculatedStructQ7() {
return convertCommentsToSpeculative(getExpectedStructQ7());
}
@@ -2517,6 +2630,29 @@ public class Vftm64ProgramCreator extends ProgramCreator {
return expected;
}
private static String getFillerStructR1() {
String expected =
//@formatter:off
"""
/R1NS::R1
pack()
Structure R1NS::R1 {
0 R1NS::R1 24 "Self Base"
24 char[80] 80 "Filler for 2 Unplaceable Virtual Bases: Q1NS::Q1; Q2NS::Q2"
}
Length: 104 Alignment: 8
/R1NS::R1/!internal/R1NS::R1
pack()
Structure R1NS::R1 {
0 pointer 8 {vfptr} ""
8 pointer 8 {vbptr} ""
16 int 4 r1 ""
}
Length: 24 Alignment: 8""";
//@formatter:on
return expected;
}
private static String getSpeculatedStructR1() {
return convertCommentsToSpeculative(getExpectedStructR1());
}
@@ -2703,6 +2839,16 @@ public class Vftm64ProgramCreator extends ProgramCreator {
expectedStructs.put(R1, getExpectedStructR1());
}
private static final Map<ClassID, String> fillerStructs = new LinkedHashMap<>();
static {
fillerStructs.putAll(expectedStructs);
fillerStructs.put(Q4, getFillerStructQ4());
fillerStructs.put(Q5, getFillerStructQ5());
fillerStructs.put(Q6, getFillerStructQ6());
fillerStructs.put(Q7, getFillerStructQ7());
fillerStructs.put(R1, getFillerStructR1());
}
private static final Map<ClassID, String> speculatedStructs = new LinkedHashMap<>();
static {
speculatedStructs.put(P1, getSpeculatedStructP1());
@@ -2775,6 +2921,10 @@ public class Vftm64ProgramCreator extends ProgramCreator {
return expectedStructs;
}
public Map<ClassID, String> getFillerStructs() {
return fillerStructs;
}
public Map<ClassID, String> getSpeculatedStructs() {
return speculatedStructs;
}
@@ -68,6 +68,8 @@ public class CppCompositeTypeTest extends AbstractGenericTest {
private static ObjectOrientedClassLayout classLayoutChoice =
ObjectOrientedClassLayout.CLASS_HIERARCHY;
private static ObjectOrientedClassLayout speculativeLayoutChoice =
ObjectOrientedClassLayout.CLASS_HIERARCHY_SPECULATIVE;
private DataTypeManager dtm32 = new StandAloneDataTypeManager("32-bit win", dataOrg32);
private DataTypeManager dtm64 = new StandAloneDataTypeManager("64-bit win", dataOrg64);
@@ -2073,17 +2075,11 @@ public class CppCompositeTypeTest extends AbstractGenericTest {
egray832Creator.getExpectedVxtPtrSummaries();
Map<ClassID, Map<String, String>> expectedVxtStructs =
egray832Creator.getExpectedVxtStructs();
int txID = program.startTransaction("Processing data.");
boolean commit = false;
try {
createAndTestStructures(program, dtm, pdb, is64Bit, vxtManager, expectedResults,
expectedVxtPtrSummaries);
dtm.withTransaction("Processing data.", () -> {
createAndTestStructures(program, dtm, classLayoutChoice, pdb, is64Bit, vxtManager,
expectedResults, expectedVxtPtrSummaries);
vxtManager.doTableLayouts(dtm);
commit = true;
}
finally {
program.endTransaction(txID, commit);
}
});
checkVxtStructures(dtm, expectedVxtStructs);
}
@@ -2092,9 +2088,28 @@ public class CppCompositeTypeTest extends AbstractGenericTest {
* @throws Exception upon error
*/
@Test
public void testEgray8_32_speculative() throws Exception {
public void testEgray8_32_noProgram() throws Exception {
boolean is64Bit = false;
Program program = null;
MockPdb pdb = egray832Pdb;
DataTypeManager dtm = dtm32;
MsftVxtManager vxtManager = egray832VxtManagerNoProgram;
Map<ClassID, String> expectedResults = egray832Creator.getFillerStructs();
dtm.withTransaction("Processing data.", () -> {
createAndTestStructures(program, dtm, classLayoutChoice, pdb, is64Bit, vxtManager,
expectedResults, null);
vxtManager.doTableLayouts(dtm);
});
// Not checking vxt structures here.
}
/**
* Tests the classes and artifacts of egray8 32-bit program PDB (speculative)
* @throws Exception upon error
*/
@Test
public void testEgray8_32_noProgram_speculative() throws Exception {
boolean is64Bit = false;
Program program = null;
MockPdb pdb = egray832Pdb;
DataTypeManager dtm = dtm32;
@@ -2104,17 +2119,11 @@ public class CppCompositeTypeTest extends AbstractGenericTest {
egray832Creator.getSpeculatedVxtPtrSummaries();
Map<ClassID, Map<String, String>> expectedVxtStructs =
egray832Creator.getSpeculatedVxtStructs();
int txID = dtm.startTransaction("Processing data.");
boolean commit = false;
try {
createAndTestStructures(program, dtm, pdb, is64Bit, vxtManager, expectedResults,
expectedVxtPtrSummaries);
dtm.withTransaction("Processing data.", () -> {
createAndTestStructures(program, dtm, speculativeLayoutChoice, pdb, is64Bit, vxtManager,
expectedResults, expectedVxtPtrSummaries);
vxtManager.doTableLayouts(dtm);
commit = true;
}
finally {
dtm.endTransaction(txID, commit);
}
});
checkVxtStructures(dtm, expectedVxtStructs);
}
@@ -2135,17 +2144,11 @@ public class CppCompositeTypeTest extends AbstractGenericTest {
egray864Creator.getExpectedVxtPtrSummaries();
Map<ClassID, Map<String, String>> expectedVxtStructs =
egray864Creator.getExpectedVxtStructs();
int txID = program.startTransaction("Processing data.");
boolean commit = false;
try {
createAndTestStructures(program, dtm, pdb, is64Bit, vxtManager, expectedResults,
expectedVxtPtrSummaries);
dtm.withTransaction("Processing data.", () -> {
createAndTestStructures(program, dtm, classLayoutChoice, pdb, is64Bit, vxtManager,
expectedResults, expectedVxtPtrSummaries);
vxtManager.doTableLayouts(dtm);
commit = true;
}
finally {
program.endTransaction(txID, commit);
}
});
checkVxtStructures(dtm, expectedVxtStructs);
}
@@ -2154,9 +2157,28 @@ public class CppCompositeTypeTest extends AbstractGenericTest {
* @throws Exception upon error
*/
@Test
public void testEgray8_64_speculative() throws Exception {
public void testEgray8_64_noProgram() throws Exception {
boolean is64Bit = false;
Program program = null;
MockPdb pdb = egray864Pdb;
DataTypeManager dtm = dtm64;
MsftVxtManager vxtManager = egray864VxtManagerNoProgram;
Map<ClassID, String> expectedResults = egray864Creator.getFillerStructs();
dtm.withTransaction("Processing data.", () -> {
createAndTestStructures(program, dtm, classLayoutChoice, pdb, is64Bit, vxtManager,
expectedResults, null);
vxtManager.doTableLayouts(dtm);
});
// Not checking vxt structures here.
}
/**
* Tests the classes and artifacts of egray8 64-bit program PDB (speculative)
* @throws Exception upon error
*/
@Test
public void testEgray8_64_noProgram_speculative() throws Exception {
boolean is64Bit = false;
Program program = null;
MockPdb pdb = egray864Pdb;
DataTypeManager dtm = dtm64;
@@ -2166,17 +2188,11 @@ public class CppCompositeTypeTest extends AbstractGenericTest {
egray864Creator.getSpeculatedVxtPtrSummaries();
Map<ClassID, Map<String, String>> expectedVxtStructs =
egray864Creator.getSpeculatedVxtStructs();
int txID = dtm.startTransaction("Processing data.");
boolean commit = false;
try {
createAndTestStructures(program, dtm, pdb, is64Bit, vxtManager, expectedResults,
expectedVxtPtrSummaries);
dtm.withTransaction("Processing data.", () -> {
createAndTestStructures(program, dtm, speculativeLayoutChoice, pdb, is64Bit, vxtManager,
expectedResults, expectedVxtPtrSummaries);
vxtManager.doTableLayouts(dtm);
commit = true;
}
finally {
dtm.endTransaction(txID, commit);
}
});
checkVxtStructures(dtm, expectedVxtStructs);
}
@@ -2197,17 +2213,11 @@ public class CppCompositeTypeTest extends AbstractGenericTest {
vftm32Creator.getExpectedVxtPtrSummaries();
Map<ClassID, Map<String, String>> expectedVxtStructs =
vftm32Creator.getExpectedVxtStructs();
int txID = program.startTransaction("Processing data.");
boolean commit = false;
try {
createAndTestStructures(program, dtm, pdb, is64Bit, vxtManager, expectedResults,
expectedVxtPtrSummaries);
dtm.withTransaction("Processing data.", () -> {
createAndTestStructures(program, dtm, classLayoutChoice, pdb, is64Bit, vxtManager,
expectedResults, expectedVxtPtrSummaries);
vxtManager.doTableLayouts(dtm);
commit = true;
}
finally {
program.endTransaction(txID, commit);
}
});
checkVxtStructures(dtm, expectedVxtStructs);
}
@@ -2216,9 +2226,28 @@ public class CppCompositeTypeTest extends AbstractGenericTest {
* @throws Exception upon error
*/
@Test
public void testVftm_32_speculative() throws Exception {
public void testVftm_32_noProgram() throws Exception {
boolean is64Bit = false;
Program program = null;
MockPdb pdb = vftm32Pdb;
DataTypeManager dtm = dtm32;
MsftVxtManager vxtManager = vftm32VxtManagerNoProgram;
Map<ClassID, String> expectedResults = vftm32Creator.getFillerStructs();
dtm.withTransaction("Processing data.", () -> {
createAndTestStructures(program, dtm, classLayoutChoice, pdb, is64Bit, vxtManager,
expectedResults, null);
vxtManager.doTableLayouts(dtm);
});
// Not checking vxt structures here.
}
/**
* Tests the classes and artifacts of vftm 32-bit program PDB (speculative)
* @throws Exception upon error
*/
@Test
public void testVftm_32_noProgram_speculative() throws Exception {
boolean is64Bit = false;
Program program = null;
MockPdb pdb = vftm32Pdb;
DataTypeManager dtm = dtm32;
@@ -2228,17 +2257,11 @@ public class CppCompositeTypeTest extends AbstractGenericTest {
vftm32Creator.getSpeculatedVxtPtrSummaries();
Map<ClassID, Map<String, String>> expectedVxtStructs =
vftm32Creator.getSpeculatedVxtStructs();
int txID = dtm.startTransaction("Processing data.");
boolean commit = false;
try {
createAndTestStructures(program, dtm, pdb, is64Bit, vxtManager, expectedResults,
expectedVxtPtrSummaries);
dtm.withTransaction("Processing data.", () -> {
createAndTestStructures(program, dtm, speculativeLayoutChoice, pdb, is64Bit, vxtManager,
expectedResults, expectedVxtPtrSummaries);
vxtManager.doTableLayouts(dtm);
commit = true;
}
finally {
dtm.endTransaction(txID, commit);
}
});
checkVxtStructures(dtm, expectedVxtStructs);
}
@@ -2259,17 +2282,11 @@ public class CppCompositeTypeTest extends AbstractGenericTest {
vftm64Creator.getExpectedVxtPtrSummaries();
Map<ClassID, Map<String, String>> expectedVxtStructs =
vftm64Creator.getExpectedVxtStructs();
int txID = program.startTransaction("Processing data.");
boolean commit = false;
try {
createAndTestStructures(program, dtm, pdb, is64Bit, vxtManager, expectedResults,
expectedVxtPtrSummaries);
dtm.withTransaction("Processing data.", () -> {
createAndTestStructures(program, dtm, classLayoutChoice, pdb, is64Bit, vxtManager,
expectedResults, expectedVxtPtrSummaries);
vxtManager.doTableLayouts(dtm);
commit = true;
}
finally {
program.endTransaction(txID, commit);
}
});
checkVxtStructures(dtm, expectedVxtStructs);
}
@@ -2278,9 +2295,28 @@ public class CppCompositeTypeTest extends AbstractGenericTest {
* @throws Exception upon error
*/
@Test
public void testVftm_64_speculative() throws Exception {
boolean is64Bit = true;
public void testVftm_64_noProgram() throws Exception {
boolean is64Bit = false;
Program program = null;
MockPdb pdb = vftm64Pdb;
DataTypeManager dtm = dtm64;
MsftVxtManager vxtManager = vftm64VxtManagerNoProgram;
Map<ClassID, String> expectedResults = vftm64Creator.getFillerStructs();
dtm.withTransaction("Processing data.", () -> {
createAndTestStructures(program, dtm, classLayoutChoice, pdb, is64Bit, vxtManager,
expectedResults, null);
vxtManager.doTableLayouts(dtm);
});
// Not checking vxt structures here.
}
/**
* Tests the classes and artifacts of vftm 64-bit program PDB (speculative)
* @throws Exception upon error
*/
@Test
public void testVftm_64_noProgram_speculative() throws Exception {
boolean is64Bit = true;
Program program = null;
MockPdb pdb = vftm64Pdb;
DataTypeManager dtm = dtm64;
@@ -2290,17 +2326,11 @@ public class CppCompositeTypeTest extends AbstractGenericTest {
vftm64Creator.getSpeculatedVxtPtrSummaries();
Map<ClassID, Map<String, String>> expectedVxtStructs =
vftm64Creator.getSpeculatedVxtStructs();
int txID = dtm.startTransaction("Processing data.");
boolean commit = false;
try {
createAndTestStructures(program, dtm, pdb, is64Bit, vxtManager, expectedResults,
expectedVxtPtrSummaries);
dtm.withTransaction("Processing data.", () -> {
createAndTestStructures(program, dtm, speculativeLayoutChoice, pdb, is64Bit, vxtManager,
expectedResults, expectedVxtPtrSummaries);
vxtManager.doTableLayouts(dtm);
commit = true;
}
finally {
dtm.endTransaction(txID, commit);
}
});
checkVxtStructures(dtm, expectedVxtStructs);
}
@@ -2321,20 +2351,34 @@ public class CppCompositeTypeTest extends AbstractGenericTest {
cfb432Creator.getExpectedVxtPtrSummaries();
Map<ClassID, Map<String, String>> expectedVxtStructs =
cfb432Creator.getExpectedVxtStructs();
int txID = program.startTransaction("Processing data.");
boolean commit = false;
try {
createAndTestStructures(program, dtm, pdb, is64Bit, vxtManager, expectedResults,
expectedVxtPtrSummaries);
dtm.withTransaction("Processing data.", () -> {
createAndTestStructures(program, dtm, classLayoutChoice, pdb, is64Bit, vxtManager,
expectedResults, expectedVxtPtrSummaries);
vxtManager.doTableLayouts(dtm);
commit = true;
}
finally {
program.endTransaction(txID, commit);
}
});
checkVxtStructures(dtm, expectedVxtStructs);
}
/**
* Tests the classes and artifacts of cfb4 32-bit program PDB (speculative)
* @throws Exception upon error
*/
@Test
public void testCfb4_32_noProgram() throws Exception {
boolean is64Bit = false;
Program program = null;
MockPdb pdb = cfb432Pdb;
DataTypeManager dtm = dtm32;
MsftVxtManager vxtManager = cfb432VxtManagerNoProgram;
Map<ClassID, String> expectedResults = cfb432Creator.getFillerStructs();
dtm.withTransaction("Processing data.", () -> {
createAndTestStructures(program, dtm, classLayoutChoice, pdb, is64Bit, vxtManager,
expectedResults, null);
vxtManager.doTableLayouts(dtm);
});
// Not checking vxt structures here.
}
/**
* Tests the classes and artifacts of cfb4 32-bit program PDB (speculative)
* @throws Exception upon error
@@ -2342,7 +2386,6 @@ public class CppCompositeTypeTest extends AbstractGenericTest {
@Test
public void testCfb4_32_speculative() throws Exception {
boolean is64Bit = false;
Program program = null;
MockPdb pdb = cfb432Pdb;
DataTypeManager dtm = dtm32;
@@ -2352,23 +2395,17 @@ public class CppCompositeTypeTest extends AbstractGenericTest {
cfb432Creator.getSpeculatedVxtPtrSummaries();
Map<ClassID, Map<String, String>> expectedVxtStructs =
cfb432Creator.getSpeculatedVxtStructs();
int txID = dtm.startTransaction("Processing data.");
boolean commit = false;
try {
createAndTestStructures(program, dtm, pdb, is64Bit, vxtManager, expectedResults,
expectedVxtPtrSummaries);
dtm.withTransaction("Processing data.", () -> {
createAndTestStructures(program, dtm, speculativeLayoutChoice, pdb, is64Bit, vxtManager,
expectedResults, expectedVxtPtrSummaries);
vxtManager.doTableLayouts(dtm);
commit = true;
}
finally {
dtm.endTransaction(txID, commit);
}
});
checkVxtStructures(dtm, expectedVxtStructs);
}
//==============================================================================================
/**
* Tests the classes and artifacts of cfb4 32-bit program
* Tests the classes and artifacts of cfb4 64-bit program
* @throws Exception upon error
*/
@Test
@@ -2383,17 +2420,11 @@ public class CppCompositeTypeTest extends AbstractGenericTest {
cfb464Creator.getExpectedVxtPtrSummaries();
Map<ClassID, Map<String, String>> expectedVxtStructs =
cfb464Creator.getExpectedVxtStructs();
int txID = program.startTransaction("Processing data.");
boolean commit = false;
try {
createAndTestStructures(program, dtm, pdb, is64Bit, vxtManager, expectedResults,
expectedVxtPtrSummaries);
dtm.withTransaction("Processing data.", () -> {
createAndTestStructures(program, dtm, classLayoutChoice, pdb, is64Bit, vxtManager,
expectedResults, expectedVxtPtrSummaries);
vxtManager.doTableLayouts(dtm);
commit = true;
}
finally {
program.endTransaction(txID, commit);
}
});
checkVxtStructures(dtm, expectedVxtStructs);
}
@@ -2402,9 +2433,28 @@ public class CppCompositeTypeTest extends AbstractGenericTest {
* @throws Exception upon error
*/
@Test
public void testCfb4_64_speculative() throws Exception {
boolean is64Bit = true;
public void testCfb4_64_noProgram() throws Exception {
boolean is64Bit = false;
Program program = null;
MockPdb pdb = cfb464Pdb;
DataTypeManager dtm = dtm64;
MsftVxtManager vxtManager = cfb464VxtManagerNoProgram;
Map<ClassID, String> expectedResults = cfb464Creator.getFillerStructs();
dtm.withTransaction("Processing data.", () -> {
createAndTestStructures(program, dtm, classLayoutChoice, pdb, is64Bit, vxtManager,
expectedResults, null);
vxtManager.doTableLayouts(dtm);
});
// Not checking vxt structures here.
}
/**
* Tests the classes and artifacts of cfb4 64-bit program PDB (speculative)
* @throws Exception upon error
*/
@Test
public void testCfb4_64_noProgram_speculative() throws Exception {
boolean is64Bit = true;
Program program = null;
MockPdb pdb = cfb464Pdb;
DataTypeManager dtm = dtm64;
@@ -2414,35 +2464,33 @@ public class CppCompositeTypeTest extends AbstractGenericTest {
cfb464Creator.getSpeculatedVxtPtrSummaries();
Map<ClassID, Map<String, String>> expectedVxtStructs =
cfb464Creator.getSpeculatedVxtStructs();
int txID = dtm.startTransaction("Processing data.");
boolean commit = false;
try {
createAndTestStructures(program, dtm, pdb, is64Bit, vxtManager, expectedResults,
expectedVxtPtrSummaries);
dtm.withTransaction("Processing data.", () -> {
createAndTestStructures(program, dtm, speculativeLayoutChoice, pdb, is64Bit, vxtManager,
expectedResults, expectedVxtPtrSummaries);
vxtManager.doTableLayouts(dtm);
commit = true;
}
finally {
dtm.endTransaction(txID, commit);
}
});
checkVxtStructures(dtm, expectedVxtStructs);
}
//==============================================================================================
//==============================================================================================
private void createAndTestStructures(Program program, DataTypeManager dtm, MockPdb pdb,
boolean is64Bit, MsftVxtManager vxtManager, Map<ClassID, String> expectedResults,
private void createAndTestStructures(Program program, DataTypeManager dtm,
ObjectOrientedClassLayout layoutChoice, MockPdb pdb, boolean is64Bit,
MsftVxtManager vxtManager, Map<ClassID, String> expectedResults,
Map<ClassID, Map<String, String>> expectedVxtPtrSummaries) throws Exception {
for (CppCompositeType cppType : pdb.getCppTypes()) {
ClassID id = cppType.getClassId();
cppType.createLayout(classLayoutChoice, vxtManager, monitor);
cppType.createLayout(layoutChoice, vxtManager, monitor);
Composite composite = pdb.resolveType(dtm, cppType);
String expected = expectedResults.get(id);
if (expected == null || expected.equals("NOT YET DETERMINED")) {
continue;
}
CompositeTestUtils.assertExpectedComposite(this, expected, composite, true);
if (expectedVxtPtrSummaries == null) {
continue;
}
Map<String, String> expectedSummary = expectedVxtPtrSummaries.get(id);
Map<String, String> vxtPtrSummary = cppType.getVxtPtrSummary();
assertEquals(expectedSummary.size(), vxtPtrSummary.size());