mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-12-11 05:33:19 +00:00
Merge remote-tracking branch 'origin/GP-3275_ghizard_MDMang_accessible_VxT_nested_parent_info--SQUASHED'
This commit is contained in:
commit
17a2dcd2ef
@ -15,6 +15,9 @@
|
||||
*/
|
||||
package mdemangler.typeinfo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import mdemangler.*;
|
||||
import mdemangler.datatype.modifier.MDCVMod;
|
||||
import mdemangler.naming.MDQualification;
|
||||
@ -24,23 +27,37 @@ import mdemangler.naming.MDQualification;
|
||||
* derivatives actually do anything at this time, but they are two very
|
||||
* different types of tables in C++ and serve as place holders for future
|
||||
* processing. I created MDVxTable, where the 'x' is 'b' or 'f' of
|
||||
* MDVbTable or MDVfTable, respectively.
|
||||
* MDVbTable or MDVfTable, respectively.
|
||||
*/
|
||||
public class MDVxTable extends MDTypeInfo {
|
||||
|
||||
private MDCVMod cvmod;
|
||||
private List<MDQualification> nestedQualifications;
|
||||
private boolean goodNestedTermination;
|
||||
|
||||
// String name = "";
|
||||
|
||||
public MDVxTable(MDMang dmang) {
|
||||
super(dmang);
|
||||
mdtype = new MDType(dmang);
|
||||
cvmod = new MDCVMod(dmang);
|
||||
nestedQualifications = new ArrayList<>();
|
||||
goodNestedTermination = false;
|
||||
}
|
||||
|
||||
public MDCVMod getCVMod() {
|
||||
return cvmod;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of MDQualification that I believe show the nested ownership within
|
||||
* class parents
|
||||
* @return the list of qualifications
|
||||
*/
|
||||
public List<MDQualification> getNestedQualifications() {
|
||||
return nestedQualifications;
|
||||
}
|
||||
|
||||
public boolean isConst() {
|
||||
return cvmod.isConst();
|
||||
}
|
||||
@ -65,37 +82,47 @@ public class MDVxTable extends MDTypeInfo {
|
||||
@Override
|
||||
protected void parseInternal() throws MDException {
|
||||
cvmod.parse();
|
||||
boolean first = true;
|
||||
StringBuilder modNameBuilder = new StringBuilder();
|
||||
while ((dmang.peek() != '@') && (dmang.peek() != MDMang.DONE)) {
|
||||
MDQualification qualification = new MDQualification(dmang);
|
||||
qualification.parse();
|
||||
StringBuilder qnameBuilder = new StringBuilder();
|
||||
qualification.insert(qnameBuilder);
|
||||
if (first) {
|
||||
dmang.appendString(modNameBuilder, qnameBuilder.toString());
|
||||
first = false;
|
||||
}
|
||||
else {
|
||||
dmang.appendString(modNameBuilder, "'s `");
|
||||
dmang.appendString(modNameBuilder, qnameBuilder.toString());
|
||||
}
|
||||
nestedQualifications.add(qualification);
|
||||
}
|
||||
// The first @ terminates the qualifier, the second terminates the qualified name
|
||||
// (which is a list of qualifiers). If there is a third, it likely terminates the
|
||||
// list of qualified names outside of the MDVxTable.
|
||||
if (dmang.peek() == '@') {
|
||||
dmang.increment();
|
||||
if (!first) {
|
||||
dmang.insertString(modNameBuilder, "{for `");
|
||||
dmang.appendString(modNameBuilder, "'}");
|
||||
}
|
||||
goodNestedTermination = true;
|
||||
}
|
||||
else {
|
||||
dmang.insertString(modNameBuilder, "{for ??}");
|
||||
}
|
||||
nameModifier = modNameBuilder.toString();
|
||||
nameModifier = generateNameModifier();
|
||||
}
|
||||
|
||||
String generateNameModifier() {
|
||||
if (!goodNestedTermination) {
|
||||
return "{for ??}";
|
||||
}
|
||||
if (nestedQualifications.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
boolean first = true;
|
||||
StringBuilder modNameBuilder = new StringBuilder();
|
||||
dmang.appendString(modNameBuilder, "{for `");
|
||||
for (MDQualification qualification : nestedQualifications) {
|
||||
StringBuilder qnameBuilder = new StringBuilder();
|
||||
qualification.insert(qnameBuilder);
|
||||
if (first) {
|
||||
first = false;
|
||||
}
|
||||
else {
|
||||
dmang.appendString(modNameBuilder, "'s `");
|
||||
}
|
||||
dmang.appendString(modNameBuilder, qnameBuilder.toString());
|
||||
}
|
||||
dmang.appendString(modNameBuilder, "'}");
|
||||
return modNameBuilder.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -15,12 +15,17 @@
|
||||
*/
|
||||
package mdemangler;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import generic.test.AbstractGenericTest;
|
||||
import ghidra.app.util.demangler.DemangledObject;
|
||||
import mdemangler.naming.MDQualification;
|
||||
import mdemangler.object.MDObjectCPP;
|
||||
import mdemangler.typeinfo.MDVxTable;
|
||||
|
||||
/**
|
||||
* This class performs extra demangler testing for special cases that do not fit
|
||||
@ -53,4 +58,26 @@ public class MDMangExtraTest extends AbstractGenericTest {
|
||||
demangled = item.toString();
|
||||
assertEquals(functionNamespaceTruth, demangled);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVxTableNestedQualifications() throws Exception {
|
||||
// Test string taken from MDMangBaseTest
|
||||
String mangled = "??_7a@b@@6Bc@d@e@@f@g@h@@i@j@k@@@";
|
||||
String truth = "const b::a::`vftable'{for `e::d::c's `h::g::f's `k::j::i'}";
|
||||
|
||||
MDMangGhidra demangler = new MDMangGhidra();
|
||||
MDParsableItem item = demangler.demangle(mangled, true);
|
||||
|
||||
String demangled = item.toString();
|
||||
assertEquals(truth, demangled);
|
||||
|
||||
MDObjectCPP cppItem = (MDObjectCPP) item;
|
||||
MDVxTable vxTable = (MDVxTable) cppItem.getTypeInfo();
|
||||
List<MDQualification> qualifications = vxTable.getNestedQualifications();
|
||||
assertEquals(3, qualifications.size());
|
||||
assertEquals("e::d::c", qualifications.get(0).toString());
|
||||
assertEquals("h::g::f", qualifications.get(1).toString());
|
||||
assertEquals("k::j::i", qualifications.get(2).toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user