GP-1051 - Demangler - fixed spaces inside of namespaces for demangled

address tables
This commit is contained in:
dragonmacher 2021-06-22 18:02:27 -04:00
parent 82c8ba1a1c
commit a74b0c7871
3 changed files with 63 additions and 37 deletions

View file

@ -32,10 +32,10 @@ public class DemangledAddressTable extends DemangledObject {
/** /**
* Constructor * Constructor
* *
* @param mangled the source mangled string * @param mangled the source mangled string
* @param originalDemangled the original demangled string * @param originalDemangled the original demangled string
* @param name the name of the address table * @param name the name of the address table
* @param calculateLength true if the length of this address table should be calculdated at * @param calculateLength true if the length of this address table should be calculdated at
* analysis time * analysis time
*/ */
public DemangledAddressTable(String mangled, String originalDemangled, String name, public DemangledAddressTable(String mangled, String originalDemangled, String name,
@ -56,7 +56,7 @@ public class DemangledAddressTable extends DemangledObject {
@Override @Override
public String getSignature(boolean format) { public String getSignature(boolean format) {
StringBuffer buffer = new StringBuffer(); StringBuilder buffer = new StringBuilder();
if (specialPrefix != null) { if (specialPrefix != null) {
buffer.append(specialPrefix); buffer.append(specialPrefix);
@ -120,11 +120,11 @@ public class DemangledAddressTable extends DemangledObject {
} }
/** /**
* Perform a best guess at the length of an address table assuming that * Perform a best guess at the length of an address table assuming that
* another label (or end of block) can be used to identify the end. * another label (or end of block) can be used to identify the end.
* @param program the program * @param program the program
* @param address start of address table * @param address start of address table
* @return maximum length of table or -1 if address does not reside * @return maximum length of table or -1 if address does not reside
* within an initialized memory block * within an initialized memory block
*/ */
private static int guessTableLength(Program program, Address address) { private static int guessTableLength(Program program, Address address) {
@ -191,7 +191,7 @@ public class DemangledAddressTable extends DemangledObject {
if (!mem.contains(refAddr)) { if (!mem.contains(refAddr)) {
// terminate table early if pointer reference address does not exist // terminate table early if pointer reference address does not exist
// within memory (demangled address tables should only refer to entities // within memory (demangled address tables should only refer to entities
// contained within program memory). // contained within program memory).
return; return;
} }

View file

@ -245,7 +245,7 @@ public class GnuDemanglerParser {
* -'for' or 'to' (capture group 3) | (capture group 1) * -'for' or 'to' (capture group 3) | (capture group 1)
* -a space -+ * -a space -+
* -optional text (capture group 4) * -optional text (capture group 4)
* *
* Note: capture group 1 is the combination of groups 2 and 3 with trailing space * Note: capture group 1 is the combination of groups 2 and 3 with trailing space
* *
* Examples: * Examples:
@ -313,7 +313,7 @@ public class GnuDemanglerParser {
/** /**
* Pattern to catch literal strings of the form: * Pattern to catch literal strings of the form:
* *
* -1l * -1l
* 2l * 2l
* 0u * 0u
@ -365,7 +365,7 @@ public class GnuDemanglerParser {
return operatorHandler; return operatorHandler;
} }
// Note: this really is a 'special handler' check that used to be handled above. However, // Note: this really is a 'special handler' check that used to be handled above. However,
// some demangled operator strings begin with this text. If we do this check above, // some demangled operator strings begin with this text. If we do this check above,
// then we will not correctly handle those operators. // then we will not correctly handle those operators.
if (mangledSource.startsWith("_ZZ")) { if (mangledSource.startsWith("_ZZ")) {
@ -490,14 +490,14 @@ public class GnuDemanglerParser {
private LambdaName getLambdaName(String name) { private LambdaName getLambdaName(String name) {
if (!name.startsWith("{")) { if (!name.startsWith("{")) {
// the text must start with the lambda syntax; ignore lambdas that are internal to // the text must start with the lambda syntax; ignore lambdas that are internal to
// the given name // the given name
return null; return null;
} }
// This replacement string will leave the initial 'lambda' text and replace all others // This replacement string will leave the initial 'lambda' text and replace all others
// with a placeholder value. This allows us to use a simple regex pattern when pulling // with a placeholder value. This allows us to use a simple regex pattern when pulling
// the lambda apart. This is required to handle the case where a lambda expression // the lambda apart. This is required to handle the case where a lambda expression
// contains a nested lambda expression. // contains a nested lambda expression.
LambdaReplacedString replacedString = new LambdaReplacedString(name); LambdaReplacedString replacedString = new LambdaReplacedString(name);
String updatedName = replacedString.getModifiedText(); String updatedName = replacedString.getModifiedText();
@ -552,20 +552,8 @@ public class GnuDemanglerParser {
String name = itemText.substring(pos + 2); String name = itemText.substring(pos + 2);
DemangledObject item = parseFunctionOrVariable(name); DemangledObject item = parseFunctionOrVariable(name);
// DemangledType namespaceType = createNamespaceDemangledType(parent);
// Convert the parent type to a suitable namespace. The parent type may have spaces item.setNamespace(namespaceType);
// in its name, which is not allowed in an applied namespace.
//
// We may eventually want to move this logic into the DemangledObject's
// createNamespace() method. This would also apply to the convertToNamespaces()
// method in this class.
//
String namespaceName = parent.getNamespaceName();
String escapedName = removeBadSpaces(namespaceName);
DemangledType type = new DemangledType(mangledSource, demangledSource, escapedName);
type.setNamespace(parent.getNamespace());
item.setNamespace(type);
return item; return item;
} }
@ -758,7 +746,7 @@ public class GnuDemanglerParser {
} }
// note: we should only encounter literals as template arguments. Function parameters // note: we should only encounter literals as template arguments. Function parameters
// and return types should never be literals. // and return types should never be literals.
if (isLiteral(fullDatatype)) { if (isLiteral(fullDatatype)) {
return createLiteral(fullDatatype); return createLiteral(fullDatatype);
} }
@ -814,7 +802,7 @@ public class GnuDemanglerParser {
// //
// Check for array case // Check for array case
// //
// remove the templates to allow us to use a simpler regex when checking for arrays // remove the templates to allow us to use a simpler regex when checking for arrays
DemangledDataType newDt = tryToParseArrayPointerOrReference(dt, datatype); DemangledDataType newDt = tryToParseArrayPointerOrReference(dt, datatype);
if (newDt != null) { if (newDt != null) {
dt = newDt; dt = newDt;
@ -834,7 +822,7 @@ public class GnuDemanglerParser {
String fullText = lambdaName.getFullText(); String fullText = lambdaName.getFullText();
dt.setName(fullText); dt.setName(fullText);
int offset = fullText.indexOf('('); int offset = fullText.indexOf('(');
// to to the end of the lambda, which is its length, minus our position // to to the end of the lambda, which is its length, minus our position
// inside the lambda // inside the lambda
int remaining = fullText.length() - offset; int remaining = fullText.length() - offset;
i = i + remaining; // end of lambda's closing '}' i = i + remaining; // end of lambda's closing '}'
@ -1583,11 +1571,30 @@ public class GnuDemanglerParser {
DemangledObject doBuild(Demangled namespace) { DemangledObject doBuild(Demangled namespace) {
DemangledAddressTable addressTable = DemangledAddressTable addressTable =
new DemangledAddressTable(mangledSource, demangled, name, true); new DemangledAddressTable(mangledSource, demangled, name, true);
addressTable.setNamespace(namespace); DemangledType namespaceType = createNamespaceDemangledType(namespace);
addressTable.setNamespace(namespaceType);
return addressTable; return addressTable;
} }
} }
//
// Convert the given demangled object into a suitable namespace. The given type may have spaces
// in its name, which is not allowed in an *applied* namespace.
//
// We may eventually want to move this logic into the DemangledObject's createNamespace()
// method. This would also apply to the convertToNamespaces() method in this class. The
// reasoning is that this parser should create namespaces just as they are given to the parser,
// while the code responsible for applying the namespace should be responsible for domain
// logic, such as removing spaces in the namespace name.
//
private DemangledType createNamespaceDemangledType(Demangled namespace) {
String namespaceName = namespace.getNamespaceName();
String escapedName = removeBadSpaces(namespaceName);
DemangledType type = new DemangledType(mangledSource, demangledSource, escapedName);
type.setNamespace(namespace.getNamespace());
return type;
}
private class OverloadOperatorHandler extends OperatorHandler { private class OverloadOperatorHandler extends OperatorHandler {
OverloadOperatorHandler(String demangled) { OverloadOperatorHandler(String demangled) {
@ -2088,8 +2095,8 @@ public class GnuDemanglerParser {
/** /**
* A class that allows us to pass around string content that has had some of its text * A class that allows us to pass around string content that has had some of its text
* replaced with temporary values. Clients can also use this class to get back the original * replaced with temporary values. Clients can also use this class to get back the original
* text. * text.
*/ */
private abstract class ReplacedString { private abstract class ReplacedString {

View file

@ -540,6 +540,25 @@ public class GnuDemanglerParserTest extends AbstractGenericTest {
assertEquals("class_with_trailing_numbers1234::typeinfo", object.getSignature(false)); assertEquals("class_with_trailing_numbers1234::typeinfo", object.getSignature(false));
} }
@Test
public void testTypeInfo_AddressTable_InFunctionNamespace() throws Exception {
String mangled =
"_ZTIFR17ClimateAttributesPSt4pairISt17reference_wrapperI5BiomeES2_I24IWorldRegistriesProviderEEE";
String demangled = process.demangle(mangled);
assertEquals(
"typeinfo for ClimateAttributes& (std::pair<std::reference_wrapper<Biome>, std::reference_wrapper<IWorldRegistriesProvider> >*)",
demangled);
DemangledObject object = parser.parse(mangled, demangled);
String namespaceString =
"ClimateAttributes&(std::pair<std::reference_wrapper<Biome>,std::reference_wrapper<IWorldRegistriesProvider>>*)";
assertType(object, DemangledAddressTable.class);
assertName(object, "typeinfo", namespaceString);
assertEquals(namespaceString + "::typeinfo", object.getSignature(false));
}
@Test @Test
public void testTypeInfo() throws Exception { public void testTypeInfo() throws Exception {
String mangled = "_ZTIN4Arts28FileInputStream_impl_FactoryE"; String mangled = "_ZTIN4Arts28FileInputStream_impl_FactoryE";
@ -1085,7 +1104,7 @@ public class GnuDemanglerParserTest extends AbstractGenericTest {
/* /*
Note: the empty template type: '<, std...' Note: the empty template type: '<, std...'
<, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>> <, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>
@ -1147,7 +1166,7 @@ public class GnuDemanglerParserTest extends AbstractGenericTest {
lambda contents - lambdas in templates and as a parameter lambda contents - lambdas in templates and as a parameter
bool (*** bool (***
const* std:: const* std::
__addressof< __addressof<
Bedrock:: Bedrock::
@ -1237,7 +1256,7 @@ public class GnuDemanglerParserTest extends AbstractGenericTest {
assertType(object, DemangledFunction.class); assertType(object, DemangledFunction.class);
//@formatter:off //@formatter:off
String expected = String expected =
"void (* " + "void (* " +
"entt::" + "entt::" +
"basic_registry::" + "basic_registry::" +
@ -1848,16 +1867,16 @@ public class GnuDemanglerParserTest extends AbstractGenericTest {
// //
// Test to ensure proper handling of 'float AvoidBlockGoal::Definition::* const&' // Test to ensure proper handling of 'float AvoidBlockGoal::Definition::* const&'
// which is a const reference to a floating point member of the class // which is a const reference to a floating point member of the class
// AvoidBlockGoal::Definition // AvoidBlockGoal::Definition
// //
/* /*
Demangled: Demangled:
auto && JsonUtil:: auto && JsonUtil::
addMember<std::shared_ptr<JsonUtil::JsonSchemaObjectNode<JsonUtil::EmptyClass,AvoidBlockGoal::Definition>>,AvoidBlockGoal::Definition,float> addMember<std::shared_ptr<JsonUtil::JsonSchemaObjectNode<JsonUtil::EmptyClass,AvoidBlockGoal::Definition>>,AvoidBlockGoal::Definition,float>
( (
std::shared_ptr<JsonUtil::JsonSchemaObjectNode<JsonUtil::EmptyClass,AvoidBlockGoal::Definition>>, std::shared_ptr<JsonUtil::JsonSchemaObjectNode<JsonUtil::EmptyClass,AvoidBlockGoal::Definition>>,