mirror of
https://github.com/morluto/rea
synced 2026-10-28 15:07:26 -04:00
fix(native): share Swift mangling recognition across metadata
Use one upstream Swift mangling prefix owner for demangler status and metadata projection/counts. Keep visible legacy class names and nominal-category decoding semantics distinct. Validation: metadata prefix, negative symbol and partial decode regressions pass; existing Mach-O controls pass. Based on #3157. Co-authored-by: 吴佳浩 <wujiahao@supremind.com>
This commit is contained in:
@@ -38,4 +38,40 @@ describe("ObjC/Swift metadata", () => {
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("projects every accepted Swift mangling prefix and counts it", () => {
|
||||
const names = [
|
||||
"$s5Store7launchyyF",
|
||||
"_$s5Store7launchyyF",
|
||||
"$S5Store7launchyyF",
|
||||
"_$S5Store7launchyyF",
|
||||
"_T05Store7launchyyF",
|
||||
"@__swiftmacro_5Store7launchfMf_",
|
||||
"$e5Store7launchyyF",
|
||||
"_$e5Store7launchyyF",
|
||||
"_TtC5Store11StoreHandle",
|
||||
"_Tprintf",
|
||||
];
|
||||
const result = inspectNativeDispatchMetadata(
|
||||
names.map((name, index) => ({
|
||||
address: `ram:0x${(0x1000 + index * 0x100).toString(16)}`,
|
||||
name,
|
||||
})),
|
||||
names.length,
|
||||
);
|
||||
|
||||
expect(result.swift_symbols.map((entry) => entry.mangled_name)).toEqual(
|
||||
names.slice(0, -1),
|
||||
);
|
||||
expect(
|
||||
result.swift_symbols.every((entry) => entry.decode.status === "partial"),
|
||||
).toBe(true);
|
||||
expect(result.coverage).toContainEqual(
|
||||
expect.objectContaining({
|
||||
facet: "swift_declarations",
|
||||
examined: 9,
|
||||
decoded: 0,
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { z } from "zod";
|
||||
import { providerSchema } from "../evidence.js";
|
||||
import { isSwiftMangledSymbolName } from "../swiftSymbolClassification.js";
|
||||
|
||||
import {
|
||||
compareUnicodeCodePoints,
|
||||
@@ -368,7 +369,7 @@ export const inspectNativeDispatchMetadata = (
|
||||
classNames.add(methodMatch[2]);
|
||||
}
|
||||
|
||||
if (/^(?:_?\$s|_Tt)/u.test(entry.name))
|
||||
if (isSwiftMangledSymbolName(entry.name) || entry.name.startsWith("_Tt"))
|
||||
swiftSymbols.push({
|
||||
mangled_name: entry.name,
|
||||
address: entry.address,
|
||||
|
||||
@@ -55,6 +55,26 @@ export const classifySwiftSymbol = (
|
||||
return { category };
|
||||
};
|
||||
|
||||
/**
|
||||
* Prefixes accepted by Swift's demangler as manglings. This is deliberately
|
||||
* narrower than visible Swift runtime class names (`_Tt…`): those names are
|
||||
* useful metadata symbols but are not themselves demangler manglings.
|
||||
*/
|
||||
const SWIFT_MANGLING_PREFIXES = [
|
||||
"_T0",
|
||||
"$S",
|
||||
"_$S",
|
||||
"$s",
|
||||
"_$s",
|
||||
"@__swiftmacro_",
|
||||
"$e",
|
||||
"_$e",
|
||||
] as const;
|
||||
|
||||
/** Recognize names the Swift demangler accepts as mangled symbols. */
|
||||
export const isSwiftMangledSymbolName = (name: string): boolean =>
|
||||
SWIFT_MANGLING_PREFIXES.some((prefix) => name.startsWith(prefix));
|
||||
|
||||
const identifierEnd = (
|
||||
mangling: string,
|
||||
offset: number,
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import { isSwiftMangledSymbolName } from "../../domain/swiftSymbolClassification.js";
|
||||
|
||||
const resultSchema = z.object({
|
||||
input: z.string(),
|
||||
output: z.string(),
|
||||
@@ -8,22 +10,6 @@ const resultSchema = z.object({
|
||||
|
||||
export type DemangledSymbol = z.infer<typeof resultSchema>;
|
||||
|
||||
/**
|
||||
* Prefixes the Swift demangler accepts as mangled names (Swift 4, 4.x, 5+,
|
||||
* macro file names and Embedded Swift). Legacy `_T` is omitted because it is
|
||||
* also an ordinary C symbol spelling such as `_Tprintf`.
|
||||
*/
|
||||
const SWIFT_MANGLING_PREFIXES = [
|
||||
"_T0",
|
||||
"$S",
|
||||
"_$S",
|
||||
"$s",
|
||||
"_$s",
|
||||
"@__swiftmacro_",
|
||||
"$e",
|
||||
"_$e",
|
||||
] as const;
|
||||
|
||||
/**
|
||||
* Preserve input ordering while parsing `swift-demangle --compact` lines.
|
||||
* The demangler ends each record with LF, so a carriage return belongs to the
|
||||
@@ -49,7 +35,7 @@ export const parseDemangledSymbols = (
|
||||
output: value,
|
||||
status:
|
||||
value === input
|
||||
? SWIFT_MANGLING_PREFIXES.some((prefix) => input.startsWith(prefix))
|
||||
? isSwiftMangledSymbolName(input)
|
||||
? "invalid"
|
||||
: "unchanged"
|
||||
: "demangled",
|
||||
|
||||
Reference in New Issue
Block a user