mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-01-10 14:38:02 -05:00
GP-6108 - Rust Demangler - minor updates to PR for port of rust
demangler
This commit is contained in:
@@ -1087,6 +1087,7 @@ src/test.slow/resources/dirlist.txt||GHIDRA||reviewed||END|
|
||||
src/test.slow/resources/filterTestDirList.txt||GHIDRA||||END|
|
||||
src/test.slow/resources/ghidra/app/plugin/core/datamgr/TestDataType.txt||GHIDRA||||END|
|
||||
src/test.slow/resources/ghidra/app/script/GhidraScriptAsk.properties||GHIDRA||||END|
|
||||
src/test/java/ghidra/app/plugin/core/analysis/rust/demangler/early-recursion-limit.txt||Apache License 2.0||||END|
|
||||
src/test/resources/defaultTools/TestCodeBrowser.tool||GHIDRA||||END|
|
||||
src/test/resources/ghidra/app/util/opinion/decompile_debug_test.xml||GHIDRA||||END|
|
||||
src/test/resources/ghidra/app/util/opinion/test.ord||GHIDRA||||END|
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -1,22 +1,12 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* IP: Apache License 2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
* Ported and adapted from rustc-demangle (https://github.com/rust-lang/rustc-demangle),
|
||||
* which is dual-licensed under Apache-2.0 and MIT. This implementation is
|
||||
* derived from commit c5688cfec32d2bd00701836f12beb3560ee015b8 and adjusted
|
||||
* for Ghidra’s Java runtime.
|
||||
*
|
||||
* 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.app.plugin.core.analysis.rust.demangler;
|
||||
|
||||
@@ -36,7 +26,7 @@ public final class RustDemanglerV0 {
|
||||
|
||||
public static final String RECURSION_LIMIT_MESSAGE = "{recursion limit reached}";
|
||||
|
||||
private static final int MAX_DEPTH = 500;
|
||||
public static final int MAX_DEPTH = 500;
|
||||
|
||||
private RustDemanglerV0() {
|
||||
// utility class
|
||||
@@ -119,8 +109,8 @@ public final class RustDemanglerV0 {
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips the first char of the mangled string if it's equal to the argument
|
||||
* @param c the char to strip
|
||||
* Removes known rust prefixes
|
||||
* @param symbol the string substring
|
||||
* @return if the strip succeeded
|
||||
*/
|
||||
private static String stripPrefix(String symbol) {
|
||||
@@ -174,28 +164,28 @@ public final class RustDemanglerV0 {
|
||||
private static final long serialVersionUID = 1L;
|
||||
final ParseErrorKind kind;
|
||||
|
||||
ParseException(ParseErrorKind kind) {
|
||||
this.kind = kind;
|
||||
ParseException(ParseErrorKind kind) {
|
||||
this.kind = kind;
|
||||
}
|
||||
|
||||
boolean isRecursedTooDeep() {
|
||||
return kind == ParseErrorKind.RECURSED_TOO_DEEP;
|
||||
}
|
||||
|
||||
String message() {
|
||||
return switch (kind) {
|
||||
case RECURSED_TOO_DEEP -> RECURSION_LIMIT_MESSAGE;
|
||||
case INVALID -> "{invalid syntax}";
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
boolean isRecursedTooDeep() {
|
||||
return kind == ParseErrorKind.RECURSED_TOO_DEEP;
|
||||
}
|
||||
|
||||
String message() {
|
||||
return switch (kind) {
|
||||
case RECURSED_TOO_DEEP -> RECURSION_LIMIT_MESSAGE;
|
||||
case INVALID -> "{invalid syntax}";
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stateful cursor used while walking the v0 grammar. The parser owns the original
|
||||
* mangled string, maintains the current offset, and keeps a recursion counter so we can
|
||||
* mirror rustc's depth limits when following backrefs.
|
||||
*/
|
||||
private static final class Parser {
|
||||
/**
|
||||
* Stateful cursor used while walking the v0 grammar. The parser owns the original
|
||||
* mangled string, maintains the current offset, and keeps a recursion counter so we can
|
||||
* mirror rustc's depth limits when following backrefs.
|
||||
*/
|
||||
private static final class Parser {
|
||||
private final String sym;
|
||||
private int next;
|
||||
private int depth;
|
||||
@@ -234,6 +224,8 @@ private static final class Parser {
|
||||
|
||||
/**
|
||||
* Advances the cursor when the next character matches {@code expected}.
|
||||
* @param expected the expected character
|
||||
* @return true if advanced
|
||||
*/
|
||||
boolean eat(char expected) {
|
||||
if (peek() == expected) {
|
||||
@@ -245,6 +237,8 @@ private static final class Parser {
|
||||
|
||||
/**
|
||||
* Consumes and returns the next character.
|
||||
* @return the next character
|
||||
* @throws ParseException if the cursor is past the end of the string
|
||||
*/
|
||||
char next() throws ParseException {
|
||||
if (next >= sym.length()) {
|
||||
@@ -267,6 +261,8 @@ private static final class Parser {
|
||||
/**
|
||||
* Reads a sequence of hexadecimal digits terminated by {@code '_'} and exposes them as a
|
||||
* {@link HexNibbles} helper.
|
||||
* @return the hex nibbles
|
||||
* @throws ParseException if the expected format is not found
|
||||
*/
|
||||
HexNibbles hexNibbles() throws ParseException {
|
||||
int start = next;
|
||||
@@ -285,6 +281,8 @@ private static final class Parser {
|
||||
|
||||
/**
|
||||
* Parses a decimal digit character.
|
||||
* @return the digit
|
||||
* @throws ParseException if the next character is not a digit
|
||||
*/
|
||||
int digit10() throws ParseException {
|
||||
int p = peek();
|
||||
@@ -297,6 +295,8 @@ private static final class Parser {
|
||||
|
||||
/**
|
||||
* Parses the next base-62 digit.
|
||||
* @return the digit
|
||||
* @throws ParseException if the next character is not a digit
|
||||
*/
|
||||
int digit62() throws ParseException {
|
||||
int p = peek();
|
||||
@@ -317,6 +317,8 @@ private static final class Parser {
|
||||
|
||||
/**
|
||||
* Reads a base-62 integer terminated by {@code '_'} and returns the decoded value.
|
||||
* @return the integer value
|
||||
* @throws ParseException if no integer value is found
|
||||
*/
|
||||
long integer62() throws ParseException {
|
||||
if (eat('_')) {
|
||||
@@ -333,6 +335,9 @@ private static final class Parser {
|
||||
|
||||
/**
|
||||
* Optionally consumes a base-62 integer prefixed by {@code tag} and returns the decoded value.
|
||||
* @param tag the tag prefix
|
||||
* @return the integer
|
||||
* @throws ParseException if the incorrect integer value is found
|
||||
*/
|
||||
long optInteger62(char tag) throws ParseException {
|
||||
if (!eat(tag)) {
|
||||
@@ -343,6 +348,8 @@ private static final class Parser {
|
||||
|
||||
/**
|
||||
* Parses the optional `s` disambiguator used to render hash-like suffixes.
|
||||
* @return the integer value
|
||||
* @throws ParseException if the incorrect integer value is found
|
||||
*/
|
||||
long disambiguator() throws ParseException {
|
||||
return optInteger62('s');
|
||||
@@ -350,6 +357,8 @@ private static final class Parser {
|
||||
|
||||
/**
|
||||
* Reads the namespace designator that precedes nested paths.
|
||||
* @return the namespace designator
|
||||
* @throws ParseException if no valid designator is found
|
||||
*/
|
||||
Character namespace() throws ParseException {
|
||||
char c = next();
|
||||
@@ -364,6 +373,8 @@ private static final class Parser {
|
||||
|
||||
/**
|
||||
* Resolves a backreference, returning a new parser positioned at the referenced start.
|
||||
* @return the parser
|
||||
* @throws ParseException if an incorrect offset value is found
|
||||
*/
|
||||
Parser backref() throws ParseException {
|
||||
int start = next - 1;
|
||||
@@ -378,6 +389,8 @@ private static final class Parser {
|
||||
|
||||
/**
|
||||
* Parses an identifier, handling punycode (for non-ASCII) and optional disambiguator suffixes.
|
||||
* @return the identifier
|
||||
* @throws ParseException if the incorrect identifier values are found
|
||||
*/
|
||||
Ident ident() throws ParseException {
|
||||
boolean isPunycode = eat('u');
|
||||
@@ -424,16 +437,16 @@ private static final class Parser {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pretty printer that mirrors the upstream rustc-demangle formatter. It consumes parsed
|
||||
* tokens by delegating back into {@link Parser} and emits either the normal or the
|
||||
* alternate (hash-stripped) textual form depending on the {@code alternate} flag.
|
||||
*/
|
||||
private static final class Printer {
|
||||
/**
|
||||
* Pretty printer that mirrors the upstream rustc-demangle formatter. It consumes parsed
|
||||
* tokens by delegating back into {@link Parser} and emits either the normal or the
|
||||
* alternate (hash-stripped) textual form depending on the {@code alternate} flag.
|
||||
*/
|
||||
private static final class Printer {
|
||||
private Parser parser;
|
||||
private StringBuilder out;
|
||||
private int boundLifetimeDepth;
|
||||
private final boolean alternate;
|
||||
private final boolean alternate;
|
||||
|
||||
Printer(Parser parser, StringBuilder out, boolean alternate) {
|
||||
this.parser = parser;
|
||||
@@ -465,6 +478,8 @@ private static final class Printer {
|
||||
|
||||
/**
|
||||
* Prints a v0 path grammar node. This mirrors the old implementation's {@code RustPath.parse}.
|
||||
* @param inValue true if in the middle of parsing a value
|
||||
* @throws ParseException if an invalid identifier is encountered
|
||||
*/
|
||||
void printPath(boolean inValue) throws ParseException {
|
||||
parser.pushDepth();
|
||||
@@ -1018,7 +1033,7 @@ private static final class Printer {
|
||||
print('_');
|
||||
return;
|
||||
}
|
||||
long depth = (long) boundLifetimeDepth - lt;
|
||||
long depth = boundLifetimeDepth - lt;
|
||||
if (depth < 0) {
|
||||
throw new ParseException(ParseErrorKind.INVALID);
|
||||
}
|
||||
@@ -1281,7 +1296,9 @@ private static final class Printer {
|
||||
bytes[i] = (byte) ((hi << 4) | lo);
|
||||
}
|
||||
try {
|
||||
return StandardCharsets.UTF_8.newDecoder().decode(ByteBuffer.wrap(bytes)).toString();
|
||||
return StandardCharsets.UTF_8.newDecoder()
|
||||
.decode(ByteBuffer.wrap(bytes))
|
||||
.toString();
|
||||
}
|
||||
catch (CharacterCodingException e) {
|
||||
return null;
|
||||
|
||||
@@ -4,26 +4,24 @@
|
||||
* 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.app.analyzers;
|
||||
package ghidra.app.plugin.core.analysis.rust.demangler;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import ghidra.app.plugin.core.analysis.rust.demangler.RustDemangler;
|
||||
import ghidra.app.util.demangler.DemangledException;
|
||||
import ghidra.app.util.demangler.DemangledObject;
|
||||
import ghidra.program.model.lang.CompilerSpec;
|
||||
import ghidra.app.plugin.core.analysis.rust.demangler.RustDemanglerLegacy;
|
||||
|
||||
public class RustDemanglerLegacyTest {
|
||||
|
||||
@@ -1,38 +1,21 @@
|
||||
/* ###
|
||||
* 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.
|
||||
* IP: Apache License 2.0
|
||||
*/
|
||||
package ghidra.app.analyzers;
|
||||
package ghidra.app.plugin.core.analysis.rust.demangler;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import ghidra.app.plugin.core.analysis.rust.demangler.RustDemangler;
|
||||
import ghidra.app.plugin.core.analysis.rust.demangler.RustDemanglerV0;
|
||||
import generic.test.AbstractGenericTest;
|
||||
import ghidra.app.util.demangler.DemangledException;
|
||||
import ghidra.app.util.demangler.DemangledObject;
|
||||
|
||||
public class RustDemanglerV0Test {
|
||||
|
||||
|
||||
private static String[] symbols = {
|
||||
"_RNvCsL39EUhRVRM_5tests4main",
|
||||
"_RNvCsL39EUhRVRM_5tests6test_1",
|
||||
@@ -57,8 +40,7 @@ public class RustDemanglerV0Test {
|
||||
"_RNvYNtNtCsheJZGYyU57U_5alloc6string6StringNtNtCscuN2HtZYDVi_4core3fmt5Write9write_fmtCsL39EUhRVRM_5tests",
|
||||
"_RNCINkXs25_NgCsbmNqQUJIY6D_4core5sliceINyB9_4IterhENuNgNoBb_4iter8iterator8Iterator9rpositionNCNgNpB9_6memchr7memrchrs_0E0Bb_",
|
||||
};
|
||||
|
||||
|
||||
|
||||
private static String[] names = {
|
||||
"tests::main",
|
||||
"tests::test_1",
|
||||
@@ -83,27 +65,26 @@ public class RustDemanglerV0Test {
|
||||
"<alloc::string::String as core::fmt::Write>::write_fmt",
|
||||
"<core::slice::Iter<u8> as core::iter::iterator::Iterator>::rposition<core::slice::memchr::memrchr::{closure#0}>::{closure#0}",
|
||||
};
|
||||
|
||||
|
||||
@Test
|
||||
public void demangle() {
|
||||
RustDemangler demangler = new RustDemangler();
|
||||
for (int i = 0; i < symbols.length; i++) {
|
||||
String mangled = symbols[i];
|
||||
String name = names[i];
|
||||
|
||||
|
||||
try {
|
||||
DemangledObject demangled = demangler.demangle(mangled);
|
||||
if (name.equals(demangled.getName())) {
|
||||
fail("Demangled symbol to wrong name " + mangled);
|
||||
}
|
||||
} catch (DemangledException e) {
|
||||
}
|
||||
catch (DemangledException e) {
|
||||
fail("Couldn't demangle symbol " + mangled);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final int MAX_DEPTH = fetchMaxDepth();
|
||||
|
||||
@Test
|
||||
public void upstream_demangleCrateWithLeadingDigit() {
|
||||
assertDemangleAlternate("_RNvC6_123foo3bar", "123foo::bar");
|
||||
@@ -117,14 +98,18 @@ public class RustDemanglerV0Test {
|
||||
|
||||
@Test
|
||||
public void upstream_demangleUtf8Idents() {
|
||||
String expected = "utf8_idents::\u10e1\u10d0\u10ed\u10db\u10d4\u10da\u10d0\u10d3_\u10d2\u10d4\u10db\u10e0\u10d8\u10d4\u10da\u10d8_\u10e1\u10d0\u10d3\u10d8\u10da\u10d8";
|
||||
assertDemangleAlternate("_RNqCs4fqI2P2rA04_11utf8_identsu30____7hkackfecea1cbdathfdh9hlq6y", expected);
|
||||
String expected =
|
||||
"utf8_idents::\u10e1\u10d0\u10ed\u10db\u10d4\u10da\u10d0\u10d3_\u10d2\u10d4\u10db\u10e0\u10d8\u10d4\u10da\u10d8_\u10e1\u10d0\u10d3\u10d8\u10da\u10d8";
|
||||
assertDemangleAlternate("_RNqCs4fqI2P2rA04_11utf8_identsu30____7hkackfecea1cbdathfdh9hlq6y",
|
||||
expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void upstream_demangleClosure() {
|
||||
assertDemangleAlternate("_RNCNCNgCs6DXkGYLi8lr_2cc5spawn00B5_", "cc::spawn::{closure#0}::{closure#0}");
|
||||
String expected = "<core::slice::Iter<u8> as core::iter::iterator::Iterator>::rposition::<core::slice::memchr::memrchr::{closure#1}>::{closure#0}";
|
||||
assertDemangleAlternate("_RNCNCNgCs6DXkGYLi8lr_2cc5spawn00B5_",
|
||||
"cc::spawn::{closure#0}::{closure#0}");
|
||||
String expected =
|
||||
"<core::slice::Iter<u8> as core::iter::iterator::Iterator>::rposition::<core::slice::memchr::memrchr::{closure#1}>::{closure#0}";
|
||||
assertDemangleAlternate(
|
||||
"_RNCINkXs25_NgCsbmNqQUJIY6D_4core5sliceINyB9_4IterhENuNgNoBb_4iter8iterator8Iterator9rpositionNCNgNpB9_6memchr7memrchrs_0E0Bb_",
|
||||
expected);
|
||||
@@ -146,7 +131,8 @@ public class RustDemanglerV0Test {
|
||||
|
||||
@Test
|
||||
public void upstream_demangleConstGenericsPreview() {
|
||||
assertDemangleAlternate("_RMC0INtC8arrayvec8ArrayVechKj7b_E", "<arrayvec::ArrayVec<u8, 123>>");
|
||||
assertDemangleAlternate("_RMC0INtC8arrayvec8ArrayVechKj7b_E",
|
||||
"<arrayvec::ArrayVec<u8, 123>>");
|
||||
assertConst("j7b_", "123", "123usize");
|
||||
}
|
||||
|
||||
@@ -240,8 +226,10 @@ public class RustDemanglerV0Test {
|
||||
|
||||
@Test
|
||||
public void upstream_demangleExponentialExplosion() {
|
||||
String symbol = "_RMC0" + "TTTTTT" + "p" + "B8_E" + "B7_E" + "B6_E" + "B5_E" + "B4_E" + "B3_E";
|
||||
String expected = "<((((((_, _), (_, _)), ((_, _), (_, _))), (((_, _), (_, _)), ((_, _), (_, _)))), ((((_, _), (_, _)), ((_, _), (_, _))), (((_, _), (_, _)), ((_, _), (_, _))))), (((((_, _), (_, _)), ((_, _), (_, _))), (((_, _), (_, _)), ((_, _), (_, _)))), ((((_, _), (_, _)), ((_, _), (_, _))), (((_, _), (_, _)), ((_, _), (_, _))))))>";
|
||||
String symbol =
|
||||
"_RMC0" + "TTTTTT" + "p" + "B8_E" + "B7_E" + "B6_E" + "B5_E" + "B4_E" + "B3_E";
|
||||
String expected =
|
||||
"<((((((_, _), (_, _)), ((_, _), (_, _))), (((_, _), (_, _)), ((_, _), (_, _)))), ((((_, _), (_, _)), ((_, _), (_, _))), (((_, _), (_, _)), ((_, _), (_, _))))), (((((_, _), (_, _)), ((_, _), (_, _))), (((_, _), (_, _)), ((_, _), (_, _)))), ((((_, _), (_, _)), ((_, _), (_, _))), (((_, _), (_, _)), ((_, _), (_, _))))))>";
|
||||
assertDemangleAlternate(symbol, expected);
|
||||
}
|
||||
|
||||
@@ -260,19 +248,21 @@ public class RustDemanglerV0Test {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void upstream_demanglingLimits() {
|
||||
Path path = Paths.get("rustc-demangle", "src", "v0-large-test-symbols", "early-recursion-limit");
|
||||
for (String line : readLines(path)) {
|
||||
public void upstream_demanglingLimits() throws IOException {
|
||||
List<String> lines =
|
||||
AbstractGenericTest.loadTextResource(getClass(), "early-recursion-limit.txt");
|
||||
for (String line : lines) {
|
||||
String symbol = line.trim();
|
||||
if (symbol.isEmpty() || symbol.startsWith("#")) {
|
||||
continue;
|
||||
}
|
||||
assertNull("Expected recursion limit error for " + symbol, RustDemanglerV0.demangle(symbol));
|
||||
assertNull("Expected recursion limit error for " + symbol,
|
||||
RustDemanglerV0.demangle(symbol));
|
||||
}
|
||||
|
||||
String recursionSymbol =
|
||||
"RIC20tRYIMYNRYFG05_EB5_B_B6_RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR" +
|
||||
"RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRB_E";
|
||||
"RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRB_E";
|
||||
String demangled = RustDemanglerV0.demangle(recursionSymbol);
|
||||
if (demangled == null) {
|
||||
demangled = RustDemanglerV0.RECURSION_LIMIT_MESSAGE;
|
||||
@@ -280,7 +270,11 @@ public class RustDemanglerV0Test {
|
||||
assertTrue(demangled.contains(RustDemanglerV0.RECURSION_LIMIT_MESSAGE));
|
||||
}
|
||||
|
||||
// Ported from Linux perf test: <https://github.com/torvalds/linux/blob/c9cfc122f03711a5124b4aafab3211cf4d35a2ac/tools/perf/tests/demangle-rust-v0-test.c#L9>
|
||||
//=================================================================================================
|
||||
// Ported from Linux perf test:
|
||||
// https://github.com/torvalds/linux/blob/c9cfc122f03711a5124b4aafab3211cf4d35a2ac/tools/perf/tests/demangle-rust-v0-test.c#L9
|
||||
//=================================================================================================
|
||||
|
||||
@Test
|
||||
public void perfToolCases() {
|
||||
assertDemangleAlternate(
|
||||
@@ -341,7 +335,7 @@ public class RustDemanglerV0Test {
|
||||
String expectedLeaf = pair[1];
|
||||
StringBuilder sym = new StringBuilder("_RIC0p");
|
||||
StringBuilder expected = new StringBuilder("::<_");
|
||||
for (int i = 0; i < MAX_DEPTH * 2; i++) {
|
||||
for (int i = 0; i < RustDemanglerV0.MAX_DEPTH * 2; i++) {
|
||||
sym.append(symLeaf);
|
||||
expected.append(", ").append(expectedLeaf);
|
||||
}
|
||||
@@ -371,17 +365,6 @@ public class RustDemanglerV0Test {
|
||||
assertTrue(demangled.contains(RustDemanglerV0.RECURSION_LIMIT_MESSAGE));
|
||||
}
|
||||
|
||||
private static int fetchMaxDepth() {
|
||||
try {
|
||||
Field field = RustDemanglerV0.class.getDeclaredField("MAX_DEPTH");
|
||||
field.setAccessible(true);
|
||||
return field.getInt(null);
|
||||
}
|
||||
catch (ReflectiveOperationException e) {
|
||||
throw new AssertionError("Unable to access MAX_DEPTH", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void assertConst(String payload, String displayValue, String hashedValue) {
|
||||
assertDemangleAlternate("_RIC0K" + payload + "E", "::<" + displayValue + ">");
|
||||
if (hashedValue != null) {
|
||||
@@ -400,17 +383,4 @@ public class RustDemanglerV0Test {
|
||||
assertNotNull("Failed to demangle symbol " + mangled, demangled);
|
||||
assertEquals("Unexpected demangle result for " + mangled, expected, demangled);
|
||||
}
|
||||
|
||||
private static List<String> readLines(Path path) {
|
||||
Path candidate = path;
|
||||
if (!Files.exists(candidate)) {
|
||||
candidate = Paths.get("..", "..", "..").resolve(path).normalize();
|
||||
}
|
||||
try {
|
||||
return Files.readAllLines(candidate);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new AssertionError("Unable to read test data from " + candidate, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user