mirror of
https://github.com/morluto/rea
synced 2026-10-26 06:16:17 -04:00
@@ -20,6 +20,7 @@ interface ParsedSegment {
|
||||
}
|
||||
|
||||
interface ParsedLoadCommands {
|
||||
readonly cpuType: number | null;
|
||||
readonly commands: Array<{
|
||||
index: number;
|
||||
kind: string;
|
||||
@@ -135,7 +136,7 @@ export const parseOtoolLoadCommands = (raw: string) => {
|
||||
const header = parseHeader(output);
|
||||
if (header === undefined)
|
||||
throw new TypeError("otool output is missing the Mach header");
|
||||
const state = createLoadCommandState(header.flags);
|
||||
const state = createLoadCommandState(header.flags, header.cpuType);
|
||||
for (const block of output.split(/(?=^Load command \d+$)/mu))
|
||||
parseLoadCommand(block, state);
|
||||
validateLoadCommandFraming(header, state.commands);
|
||||
@@ -264,7 +265,9 @@ const validateLoadCommandFraming = (
|
||||
|
||||
const createLoadCommandState = (
|
||||
headerFlags: readonly string[] | undefined,
|
||||
cpuType: number | null,
|
||||
): ParsedLoadCommands => ({
|
||||
cpuType,
|
||||
commands: [],
|
||||
segments: [],
|
||||
dependencies: [],
|
||||
@@ -403,13 +406,33 @@ const collectBuild = (
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (kind.startsWith("LC_VERSION_MIN_"))
|
||||
if (kind.startsWith("LC_VERSION_MIN_")) {
|
||||
const platform = kind.slice("LC_VERSION_MIN_".length) || null;
|
||||
state.builds.push({
|
||||
platform: kind.slice("LC_VERSION_MIN_".length) || null,
|
||||
platform: legacySimulatorPlatform(platform, state.cpuType),
|
||||
minimum_os: stringField(fields, "version"),
|
||||
sdk: stringField(fields, "sdk"),
|
||||
tools: [],
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Apple dyld interprets legacy iOS/tvOS/watchOS minimum-version commands on
|
||||
// Intel slices as simulator platforms. Newer commands encode this directly.
|
||||
const legacySimulatorPlatform = (
|
||||
platform: string | null,
|
||||
cpuType: number | null,
|
||||
): string | null => {
|
||||
if (![7, 0x01000007].includes(cpuType ?? -1)) return platform;
|
||||
return (
|
||||
(
|
||||
{
|
||||
IPHONEOS: "IOSSIMULATOR",
|
||||
TVOS: "TVOSSIMULATOR",
|
||||
WATCHOS: "WATCHOSSIMULATOR",
|
||||
} as const
|
||||
)[platform as "IPHONEOS" | "TVOS" | "WATCHOS"] ?? platform
|
||||
);
|
||||
};
|
||||
|
||||
const collectDependency = (
|
||||
|
||||
@@ -267,3 +267,35 @@ Section
|
||||
const truncatedBytes = truncatedCount.replace("2 2 48", "2 1 32");
|
||||
expect(() => parseOtoolLoadCommands(truncatedBytes)).toThrow(/sizes/u);
|
||||
});
|
||||
|
||||
it.each([
|
||||
["LC_VERSION_MIN_IPHONEOS", "IOSSIMULATOR"],
|
||||
["LC_VERSION_MIN_TVOS", "TVOSSIMULATOR"],
|
||||
["LC_VERSION_MIN_WATCHOS", "WATCHOSSIMULATOR"],
|
||||
])("classifies legacy Intel simulator command %s", (command, platform) => {
|
||||
const text = [
|
||||
"Mach header",
|
||||
" magic cputype cpusubtype caps filetype ncmds sizeofcmds flags",
|
||||
" 0xfeedfacf 16777223 3 0x00 2 1 16 0x0",
|
||||
"Load command 0",
|
||||
` cmd ${command}`,
|
||||
" cmdsize 16",
|
||||
" version 12.0",
|
||||
" sdk 12.1",
|
||||
].join("\n");
|
||||
expect(parseOtoolLoadCommands(text).builds[0]?.platform).toBe(platform);
|
||||
});
|
||||
|
||||
it("keeps legacy device platforms on arm64 slices", () => {
|
||||
const text = [
|
||||
"Mach header",
|
||||
" magic cputype cpusubtype caps filetype ncmds sizeofcmds flags",
|
||||
" 0xfeedfacf 16777228 0 0x00 2 1 16 0x0",
|
||||
"Load command 0",
|
||||
" cmd LC_VERSION_MIN_IPHONEOS",
|
||||
" cmdsize 16",
|
||||
" version 12.0",
|
||||
" sdk 12.1",
|
||||
].join("\n");
|
||||
expect(parseOtoolLoadCommands(text).builds[0]?.platform).toBe("IPHONEOS");
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user