fix(native): name numeric Mach-O build-version platforms and tools (#2065)
Squash merge of https://github.com/morluto/rea/pull/2065. Co-authored-by: TonyWu <2038838159@qq.com>
This commit is contained in:
parent
168bfe5060
commit
77e71d55ec
|
|
@ -63,6 +63,56 @@ const DYLIB_FIELDS = [
|
|||
const DYLIB_ENCODING_FIELDS = ["time stamp", "options"];
|
||||
const EMPTY_VALUE_FIELDS = new Set(["options", "segname", "sectname"]);
|
||||
|
||||
/**
|
||||
* Non-verbose otool prints LC_BUILD_VERSION platform and tool codes as
|
||||
* numbers. Name the codes declared in the SDK's <mach-o/loader.h>, without
|
||||
* the PLATFORM_/TOOL_ prefix, so build metadata uses the same symbolic style
|
||||
* as LC_VERSION_MIN_* platforms. Unknown codes keep their printed value.
|
||||
*/
|
||||
const BUILD_PLATFORM_NAMES: ReadonlyMap<string, string> = new Map([
|
||||
["1", "MACOS"],
|
||||
["2", "IOS"],
|
||||
["3", "TVOS"],
|
||||
["4", "WATCHOS"],
|
||||
["5", "BRIDGEOS"],
|
||||
["6", "MACCATALYST"],
|
||||
["7", "IOSSIMULATOR"],
|
||||
["8", "TVOSSIMULATOR"],
|
||||
["9", "WATCHOSSIMULATOR"],
|
||||
["10", "DRIVERKIT"],
|
||||
["11", "VISIONOS"],
|
||||
["12", "VISIONOSSIMULATOR"],
|
||||
["13", "FIRMWARE"],
|
||||
["14", "SEPOS"],
|
||||
["15", "MACOS_EXCLAVECORE"],
|
||||
["16", "MACOS_EXCLAVEKIT"],
|
||||
["17", "IOS_EXCLAVECORE"],
|
||||
["18", "IOS_EXCLAVEKIT"],
|
||||
["19", "TVOS_EXCLAVECORE"],
|
||||
["20", "TVOS_EXCLAVEKIT"],
|
||||
["21", "WATCHOS_EXCLAVECORE"],
|
||||
["22", "WATCHOS_EXCLAVEKIT"],
|
||||
["23", "VISIONOS_EXCLAVECORE"],
|
||||
["24", "VISIONOS_EXCLAVEKIT"],
|
||||
]);
|
||||
const BUILD_TOOL_NAMES: ReadonlyMap<string, string> = new Map([
|
||||
["1", "CLANG"],
|
||||
["2", "SWIFT"],
|
||||
["3", "LD"],
|
||||
["4", "LLD"],
|
||||
["1024", "METAL"],
|
||||
["1025", "AIRLLD"],
|
||||
["1026", "AIRNT"],
|
||||
["1027", "AIRNT_PLUGIN"],
|
||||
["1028", "AIRPACK"],
|
||||
["1031", "GPUARCHIVER"],
|
||||
["1032", "METAL_FRAMEWORK"],
|
||||
]);
|
||||
const buildCodeName = (
|
||||
names: ReadonlyMap<string, string>,
|
||||
value: string | null,
|
||||
): string | null => (value === null ? null : (names.get(value) ?? value));
|
||||
|
||||
/**
|
||||
* otool emits LF, but a capture replayed from another host or toolchain can
|
||||
* carry CRLF. The section/command boundaries below match a bare `\n`, so a
|
||||
|
|
@ -295,7 +345,10 @@ const collectBuild = (
|
|||
if (numberField(fields, "ntools") !== tools.length)
|
||||
throw new TypeError("otool build-tool count does not match ntools");
|
||||
state.builds.push({
|
||||
platform: stringField(fields, "platform"),
|
||||
platform: buildCodeName(
|
||||
BUILD_PLATFORM_NAMES,
|
||||
stringField(fields, "platform"),
|
||||
),
|
||||
minimum_os: stringField(fields, "minos"),
|
||||
sdk: stringField(fields, "sdk"),
|
||||
tools,
|
||||
|
|
@ -434,7 +487,7 @@ const parseBuildTools = (
|
|||
const tool = /^tool\s+(.+)$/u.exec(lines[index] ?? "")?.[1];
|
||||
const version = /^version\s+(.+)$/u.exec(lines[index + 1] ?? "")?.[1];
|
||||
if (tool !== undefined && version !== undefined)
|
||||
tools.push({ name: tool, version });
|
||||
tools.push({ name: BUILD_TOOL_NAMES.get(tool) ?? tool, version });
|
||||
}
|
||||
return tools;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -229,6 +229,62 @@ it("normalizes legacy version-minimum commands into build metadata", () => {
|
|||
]);
|
||||
});
|
||||
|
||||
it("names numeric build-version platforms and tools", () => {
|
||||
const load = parseOtoolLoadCommands(
|
||||
withOtoolMachHeader(
|
||||
[
|
||||
"Load command 0",
|
||||
" cmd LC_BUILD_VERSION",
|
||||
" cmdsize 48",
|
||||
" platform 1",
|
||||
" minos 11.0",
|
||||
" sdk 26.5",
|
||||
" ntools 2",
|
||||
" tool 3",
|
||||
" version 1267.0",
|
||||
" tool 1029",
|
||||
" version 1.0",
|
||||
"Load command 1",
|
||||
" cmd LC_BUILD_VERSION",
|
||||
" cmdsize 24",
|
||||
" platform 99",
|
||||
" minos 1.0",
|
||||
" sdk 1.0",
|
||||
" ntools 0",
|
||||
"Load command 2",
|
||||
" cmd LC_BUILD_VERSION",
|
||||
" cmdsize 32",
|
||||
" platform MACCATALYST",
|
||||
" minos 14.0",
|
||||
" sdk 14.2",
|
||||
" ntools 1",
|
||||
" tool SWIFT",
|
||||
" version 5.9",
|
||||
"",
|
||||
].join("\n"),
|
||||
),
|
||||
);
|
||||
expect(load.builds).toEqual([
|
||||
{
|
||||
platform: "MACOS",
|
||||
minimum_os: "11.0",
|
||||
sdk: "26.5",
|
||||
tools: [
|
||||
{ name: "LD", version: "1267.0" },
|
||||
{ name: "1029", version: "1.0" },
|
||||
],
|
||||
},
|
||||
{ platform: "99", minimum_os: "1.0", sdk: "1.0", tools: [] },
|
||||
{
|
||||
platform: "MACCATALYST",
|
||||
minimum_os: "14.0",
|
||||
sdk: "14.2",
|
||||
tools: [{ name: "SWIFT", version: "5.9" }],
|
||||
},
|
||||
]);
|
||||
expect(load.commands[0]?.fields.platform).toBe(1);
|
||||
});
|
||||
|
||||
it("does not classify LC_LOAD_DYLINKER as a dylib dependency", async () => {
|
||||
const load = parseOtoolLoadCommands(
|
||||
await nativeFixture("native-macho-header/otool-header-load.txt"),
|
||||
|
|
@ -273,3 +329,78 @@ it("limits thread-state entrypoints instead of reporting none silently", async (
|
|||
"Thread-state entrypoints (LC_UNIXTHREAD/LC_THREAD) are retained as raw load commands; file offsets are not derived.",
|
||||
);
|
||||
});
|
||||
|
||||
it.each([
|
||||
["1", "MACOS"],
|
||||
["2", "IOS"],
|
||||
["3", "TVOS"],
|
||||
["4", "WATCHOS"],
|
||||
["5", "BRIDGEOS"],
|
||||
["6", "MACCATALYST"],
|
||||
["7", "IOSSIMULATOR"],
|
||||
["8", "TVOSSIMULATOR"],
|
||||
["9", "WATCHOSSIMULATOR"],
|
||||
["10", "DRIVERKIT"],
|
||||
["11", "VISIONOS"],
|
||||
["12", "VISIONOSSIMULATOR"],
|
||||
["13", "FIRMWARE"],
|
||||
["14", "SEPOS"],
|
||||
["15", "MACOS_EXCLAVECORE"],
|
||||
["16", "MACOS_EXCLAVEKIT"],
|
||||
["17", "IOS_EXCLAVECORE"],
|
||||
["18", "IOS_EXCLAVEKIT"],
|
||||
["19", "TVOS_EXCLAVECORE"],
|
||||
["20", "TVOS_EXCLAVEKIT"],
|
||||
["21", "WATCHOS_EXCLAVECORE"],
|
||||
["22", "WATCHOS_EXCLAVEKIT"],
|
||||
["23", "VISIONOS_EXCLAVECORE"],
|
||||
["24", "VISIONOS_EXCLAVEKIT"],
|
||||
] as const)("names build platform %s as %s", (code, name) => {
|
||||
const load = parseOtoolLoadCommands(
|
||||
withOtoolMachHeader(
|
||||
[
|
||||
"Load command 0",
|
||||
"cmd LC_BUILD_VERSION",
|
||||
"cmdsize 24",
|
||||
`platform ${code}`,
|
||||
"minos 1.0",
|
||||
"sdk 1.0",
|
||||
"ntools 0",
|
||||
"",
|
||||
].join("\n"),
|
||||
),
|
||||
);
|
||||
expect(load.builds[0]?.platform).toBe(name);
|
||||
});
|
||||
|
||||
it.each([
|
||||
["1", "CLANG"],
|
||||
["2", "SWIFT"],
|
||||
["3", "LD"],
|
||||
["4", "LLD"],
|
||||
["1024", "METAL"],
|
||||
["1025", "AIRLLD"],
|
||||
["1026", "AIRNT"],
|
||||
["1027", "AIRNT_PLUGIN"],
|
||||
["1028", "AIRPACK"],
|
||||
["1031", "GPUARCHIVER"],
|
||||
["1032", "METAL_FRAMEWORK"],
|
||||
] as const)("names build tool %s as %s", (code, name) => {
|
||||
const load = parseOtoolLoadCommands(
|
||||
withOtoolMachHeader(
|
||||
[
|
||||
"Load command 0",
|
||||
"cmd LC_BUILD_VERSION",
|
||||
"cmdsize 32",
|
||||
"platform 1",
|
||||
"minos 1.0",
|
||||
"sdk 1.0",
|
||||
"ntools 1",
|
||||
`tool ${code}`,
|
||||
"version 1.0",
|
||||
"",
|
||||
].join("\n"),
|
||||
),
|
||||
);
|
||||
expect(load.builds[0]?.tools).toEqual([{ name, version: "1.0" }]);
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue