mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-08-08 07:40:39 -09:00
Merge remote-tracking branch 'origin/GP-6703_ghizard_Minor_MDMang_tweaks'
This commit is contained in:
@@ -192,4 +192,10 @@ public class MDCharacterIterator {
|
||||
public boolean positionStartsWith(String substring) {
|
||||
return string.regionMatches(index, substring, 0, substring.length());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return string + "\n" + " ".repeat(index) + "^";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -637,7 +637,8 @@ public class MDSpecialName extends MDParsableItem {
|
||||
}
|
||||
break;
|
||||
case 'F': {
|
||||
dmang.parseInfoPush(3, "dynamic atexit destructor operator");
|
||||
dmang.parseInfoPush(3,
|
||||
"dynamic atexit destructor operator for [Object]");
|
||||
StringBuilder builder = new StringBuilder();
|
||||
// TODO... 20160812: This looks like new ObjectCPP and ObjectC
|
||||
if (dmang.peek() == '?') {
|
||||
@@ -672,17 +673,17 @@ public class MDSpecialName extends MDParsableItem {
|
||||
}
|
||||
break;
|
||||
case 'G':
|
||||
dmang.parseInfoPush(3, "vector copy constructor");
|
||||
dmang.parseInfoPush(3, "vector copy constructor iterator");
|
||||
name = "`vector copy constructor iterator'";
|
||||
dmang.parseInfoPop();
|
||||
break;
|
||||
case 'H':
|
||||
dmang.parseInfoPush(3, "vector vbase copy constructor");
|
||||
dmang.parseInfoPush(3, "vector vbase copy constructor iterator");
|
||||
name = "`vector vbase copy constructor iterator'";
|
||||
dmang.parseInfoPop();
|
||||
break;
|
||||
case 'I':
|
||||
dmang.parseInfoPush(3, "managed vector copy constructor");
|
||||
dmang.parseInfoPush(3, "managed vector copy constructor iterator");
|
||||
name = "`managed vector copy constructor iterator'";
|
||||
dmang.parseInfoPop();
|
||||
break;
|
||||
@@ -692,7 +693,7 @@ public class MDSpecialName extends MDParsableItem {
|
||||
dmang.parseInfoPop();
|
||||
break;
|
||||
case 'K':
|
||||
dmang.parseInfoPush(3, "udl");
|
||||
dmang.parseInfoPush(3, "user defined literal");
|
||||
// Our test has manufactured symbol "??__Kabc@def@@3HA"
|
||||
// 20170329: Confirmed that this is not a MDReusableName with
|
||||
// manufactured symbol "??__Kabc@def@0@3HA"
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* 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.
|
||||
@@ -16,9 +16,13 @@
|
||||
package mdemangler.template;
|
||||
|
||||
import mdemangler.*;
|
||||
import mdemangler.datatype.MDDataType;
|
||||
import mdemangler.datatype.MDDataTypeParser;
|
||||
import mdemangler.naming.MDFragmentName;
|
||||
import mdemangler.object.MDObject;
|
||||
import mdemangler.object.MDObjectCPP;
|
||||
import mdemangler.typeinfo.MDTypeInfo;
|
||||
import mdemangler.typeinfo.MDTypeInfoParser;
|
||||
|
||||
/**
|
||||
* This class represents a the template constant portion of a
|
||||
@@ -66,24 +70,17 @@ public class MDTemplateConstant extends MDParsableItem {
|
||||
// name = "&" + object;
|
||||
}
|
||||
break;
|
||||
case '2': // TODO: Currently, we have no test data for this.
|
||||
a = new MDSignedEncodedNumber(dmang);
|
||||
a.parse();
|
||||
String aStr = a.toString();
|
||||
// 20140630: seems that '\'' is not there in $2a'b (documentation
|
||||
// notation failure--the single quote (any type) is not really in the
|
||||
// mangled string)
|
||||
b = new MDSignedEncodedNumber(dmang);
|
||||
b.parse();
|
||||
if (aStr.charAt(0) == '-') {
|
||||
name = "-";
|
||||
aStr = aStr.substring(1, aStr.length());
|
||||
case '2':
|
||||
// This is not perect. The newer encoding might not get tripped
|
||||
// up by attempting to demangle with the older scheme or vice versa.
|
||||
int currentIndex = dmang.getIndex();
|
||||
try {
|
||||
name = parseFloatingPointConstant();
|
||||
}
|
||||
name += aStr.charAt(0) + ".";
|
||||
if (aStr.length() > 1) {
|
||||
name += aStr.substring(1, aStr.length());
|
||||
catch (MDException e) {
|
||||
dmang.setIndex(currentIndex);
|
||||
name = parseInitializedTemplateConstant();
|
||||
}
|
||||
name += "e" + b;
|
||||
break;
|
||||
case 'D':
|
||||
a = new MDSignedEncodedNumber(dmang);
|
||||
@@ -102,7 +99,7 @@ public class MDTemplateConstant extends MDParsableItem {
|
||||
case 'F':
|
||||
// 20140630: seems that '\'' is not there in $Fa'b (documentation
|
||||
// notation failure--the single quote (any type) is not really in the
|
||||
// mangled string)
|
||||
// mangled string)
|
||||
a = new MDSignedEncodedNumber(dmang);
|
||||
a.parse();
|
||||
b = new MDSignedEncodedNumber(dmang);
|
||||
@@ -112,7 +109,7 @@ public class MDTemplateConstant extends MDParsableItem {
|
||||
case 'G':
|
||||
// 20140630: seems that '\'' is not there in $Ga'b'c (documentation
|
||||
// notation failure--the single quote (any type) is not really in the
|
||||
// mangled string)
|
||||
// mangled string)
|
||||
a = new MDSignedEncodedNumber(dmang);
|
||||
a.parse();
|
||||
b = new MDSignedEncodedNumber(dmang);
|
||||
@@ -140,7 +137,7 @@ public class MDTemplateConstant extends MDParsableItem {
|
||||
case 'I': { // Used in some cases ($$issue!!!!!!)
|
||||
// 20140630: seems that '\'' is not there in $Ix'y (documentation
|
||||
// notation failure--the single quote (any type) is not really in the
|
||||
// mangled string)
|
||||
// mangled string)
|
||||
// It also seems that the second parameter CAN be negative: $Ixa, where
|
||||
// x is some object, and a is some signed number
|
||||
// Do not do a pushModifierContext here.
|
||||
@@ -165,7 +162,7 @@ public class MDTemplateConstant extends MDParsableItem {
|
||||
case 'J': { // Used in some cases ($$issue!!!!!!)
|
||||
// 20140630: seems that '\'' is not there in $Jx'y'z (documentation
|
||||
// notation failure--the single quote (any type) is not really in the
|
||||
// mangled string)
|
||||
// mangled string)
|
||||
// It also seems that the second, third, and fourth parameters CAN be
|
||||
// negative: $Jxabc, where x is some object, and a, b, and care some
|
||||
// signed numbers
|
||||
@@ -221,6 +218,65 @@ public class MDTemplateConstant extends MDParsableItem {
|
||||
}
|
||||
}
|
||||
|
||||
private String parseFloatingPointConstant() throws MDException {
|
||||
String str = "";
|
||||
MDSignedEncodedNumber a = new MDSignedEncodedNumber(dmang);
|
||||
a.parse();
|
||||
String aStr = a.toString();
|
||||
// 20140630: seems that '\'' is not there in $2a'b (documentation
|
||||
// notation failure--the single quote (any type) is not really in the
|
||||
// mangled string)
|
||||
MDSignedEncodedNumber b = new MDSignedEncodedNumber(dmang);
|
||||
b.parse();
|
||||
if (aStr.charAt(0) == '-') {
|
||||
str = "-";
|
||||
aStr = aStr.substring(1, aStr.length());
|
||||
}
|
||||
str += aStr.charAt(0) + ".";
|
||||
if (aStr.length() > 1) {
|
||||
str += aStr.substring(1, aStr.length());
|
||||
}
|
||||
str += "e" + b;
|
||||
return str;
|
||||
}
|
||||
|
||||
// Not sure that I like the name of this method, as I'm not sure what the full scope of
|
||||
// encodings/initializations are at this time.
|
||||
private String parseInitializedTemplateConstant() throws MDException {
|
||||
String str = "";
|
||||
// I don't know if we need to push and pop context before and after this
|
||||
// (to have correct back references if needed).
|
||||
MDDataType t = MDDataTypeParser.parseDataType(dmang, true);
|
||||
t.parse();
|
||||
|
||||
str += t.toString() + "{";
|
||||
|
||||
char code = dmang.peek();
|
||||
while (code != '@') {
|
||||
//From MDDataTypeParser:
|
||||
// MDParsableItem item = new MDObjectCPP(dmang);
|
||||
// dmang.pushContext();
|
||||
// item.parse();
|
||||
// dmang.popContext();
|
||||
|
||||
// I don't know if we need to push and pop context before and after this
|
||||
// (to have correct back references if needed).
|
||||
|
||||
//From MDObjectCpp
|
||||
//int RTTINum = qualifiedName.getRTTINumber();
|
||||
MDTypeInfo typeInfo = MDTypeInfoParser.parse(dmang, -1);
|
||||
//if (qualifiedName.isTypeCast()) {
|
||||
// typeInfo.setTypeCast();
|
||||
//}
|
||||
typeInfo.parse();
|
||||
|
||||
str += typeInfo.toString();
|
||||
}
|
||||
dmang.next(); // skip the '@' character
|
||||
str += "}";
|
||||
return str;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insert(StringBuilder builder) {
|
||||
dmang.insertString(builder, name);
|
||||
|
||||
@@ -3243,6 +3243,26 @@ public class MDMangBaseTest extends AbstractGenericTest {
|
||||
demangleAndTest();
|
||||
}
|
||||
|
||||
//=====================
|
||||
// $2 template constants
|
||||
//
|
||||
// We seem to have two different encodings for $2 template constant. An older form that
|
||||
// encodes floating point numbers that works in undname from vs2017 and a newer form that
|
||||
// encodes type constants with initializers that works in undname from vs2022. The 2017
|
||||
// mangled strings do not demangle under 2022 and the 2022 strings do not demangle under
|
||||
// 2017. I have not checked other VS versions. Probably no longer need to encode floating
|
||||
// point type the same way, as they could probably be encoded with the newer format, which
|
||||
// should offer a broader encoding scheme. We don't know if both encoding styles can
|
||||
// coexist or whether we need to offer different demangling versions (e.g., see MDMangVS2015).
|
||||
// We haven't pursued fleshing out the differences between versions, but if we did, then we
|
||||
// could offer the user the options of choosing or we could detect from PE header, PDB, or
|
||||
// other analysis. Probably best if we can make all coexist. (Note: we still have other
|
||||
// issues where LLVM or Clang don't adhere exactly to some MSFT encoding standards; this
|
||||
// was partially worked around, but is still a mess.)
|
||||
//
|
||||
// ALSO... gaining evidence that there are many more $ codes for template constants than
|
||||
// what we have implemented. Seems like it might be a lot of work to tackle all of them.
|
||||
|
||||
//manufactured symbol: $2 Blank (zero) exponent
|
||||
@Test
|
||||
public void testSpecialTemplateParameters_dollar2_blankzeroexp() throws Exception {
|
||||
@@ -3366,6 +3386,56 @@ public class MDMangBaseTest extends AbstractGenericTest {
|
||||
demangleAndTest();
|
||||
}
|
||||
|
||||
// Newer $2 template constant encodings below. See note at top of $2 section
|
||||
|
||||
// real symbol with $2 non-floating point template constant with initializers
|
||||
// From template_op_lit/tol64
|
||||
// mstruth here is from vs2022 undname
|
||||
@Category(MDMangFailingTestCategory.class)
|
||||
@Test
|
||||
public void testTemplateConstantParameterWithInitializers1() throws Exception {
|
||||
mangled =
|
||||
"??$?__K_x2@$2U?$DoubleString@$03@@3D0GB@@0GC@@0GD@@0GB@@0GC@@0GD@@0A@@@@@@YA?A_PXZ";
|
||||
msTruth =
|
||||
"auto __cdecl operator \"\" _x2<struct DoubleString<4>{char{97,98,99,97,98,99,0}}>(void)";
|
||||
mdTruth = msTruth;
|
||||
demangleAndTest16Bit();
|
||||
}
|
||||
|
||||
// This is fuzzed counterpoint to the real $2 template constant, above
|
||||
// mstruth here is from vs2022 undname
|
||||
@Category(MDMangFailingTestCategory.class)
|
||||
@Test
|
||||
public void testTemplateConstantParameterWithInitializers1_counterpoint1() throws Exception {
|
||||
mangled = "??$?M$2H@@@YA?AXXZ";
|
||||
msTruth = "void __cdecl operator<<int{}>(void)";
|
||||
mdTruth = msTruth;
|
||||
demangleAndTest16Bit();
|
||||
}
|
||||
|
||||
// This is fuzzed counterpoint to the real $2 template constant, above. This does not have $2
|
||||
// mstruth here is from both vs2022 and vs2017 undname
|
||||
@Test
|
||||
public void testTemplateConstantParameterWithInitializers1_counterpoint2() throws Exception {
|
||||
mangled = "??$?MH@@YAXXZ";
|
||||
msTruth = "void __cdecl operator<<int>(void)";
|
||||
mdTruth = msTruth;
|
||||
demangleAndTest16Bit();
|
||||
}
|
||||
|
||||
// This is fuzzed counterpoint to the real $2 template constant, above. This does not have $2
|
||||
// probably don't need since we just figured out ?A (we already process)
|
||||
// mstruth here is from both vs2022 and vs2017 undname
|
||||
@Test
|
||||
public void testTemplateConstantParameterWithInitializers1_counterpoint3() throws Exception {
|
||||
mangled = "??$?MH@@YA?AXXZ";
|
||||
msTruth = "void __cdecl operator<<int>(void)";
|
||||
mdTruth = msTruth;
|
||||
demangleAndTest16Bit();
|
||||
}
|
||||
|
||||
//=====================
|
||||
|
||||
//real symbol: $D
|
||||
@Test
|
||||
public void testSpecialTemplateParameters_dollarD() throws Exception {
|
||||
@@ -5050,6 +5120,22 @@ public class MDMangBaseTest extends AbstractGenericTest {
|
||||
demangleAndTest();
|
||||
}
|
||||
|
||||
//manufactured symbol
|
||||
// We have no real symbols and haven't been able to get undname to produce results,
|
||||
// which means that we might not have all the right pieces for a ??_W symbol to parse.
|
||||
// If we find/produce a symbol that undname works on, the we should delete and
|
||||
// replace this test and change the demangler to properly parse the symbol (which should
|
||||
// also cause this current test to fail).
|
||||
@Test
|
||||
public void testSpecialNames_W() throws Exception {
|
||||
mangled = "??_WAA@@QAAXXZ";
|
||||
msTruth = "";
|
||||
mdTruth = "public: void __cdecl AA::`omni callsig'(void)";
|
||||
demangleAndTest();
|
||||
}
|
||||
// ??_WAA@@QAAXXZ
|
||||
// public: void __cdecl AA::`omni callsig'(void)
|
||||
|
||||
//manufactured symbol
|
||||
@Test
|
||||
public void testSpecialNames_X() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user