mirror of
https://github.com/morluto/rea
synced 2026-10-28 06:46:47 -04:00
96fc84f1fb
* fix(native): select one slice when universal Mach-O slices share a CPU type On macOS 27 most system binaries are universal files whose slices share CPU_TYPE_ARM64: arm64e + arm64e.x1 (Calculator, TextEdit), x86_64 + arm64e + arm64e.x1 (/bin/ls), or arm64 + arm64e.x1 (ShortcutDroplet). Target admission names slices by CPU family, so these targets have availableArchitectures ["arm64"] while the file holds two arm64 slices. inspect_macho read that family count as a slice count and ran otool, nm, dyld_info, dwarfdump and vtool without -arch. ShortcutDroplet failed with "Malformed otool load-command output" (40 load commands against ncmds 20). Calculator reported both slices' imports (4138 instead of 2069), nm's "(for architecture ...)" header lines as exports, and no selected slice. selectArchitecture now also filters when lipo lists more than one slice. Its preference is unchanged: the family name, then arm64e, then the first arm64e.<variant>. inspect_native_dispatch_metadata matched FAT slices by CPU type only and refused /bin/ls and TextEdit as "Ambiguous FAT architecture slice". selectMachoSlice now ranks slices of the requested CPU type by base subtype in the same order: arm64 (0, then 1) or x86_64 (3), then arm64e (2), then other variants such as arm64e.x1 in FAT table order. It reports ambiguity only when the top-ranked slices share a subtype. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(native): share Mach-O slice preference across inspections * chore: preserve upstream process capture test during merge --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
55 lines
1.7 KiB
TypeScript
55 lines
1.7 KiB
TypeScript
interface MachoArchitecturePolicy {
|
|
readonly cpuType: number;
|
|
readonly subtypes: readonly {
|
|
readonly subtype: number;
|
|
readonly name: string;
|
|
}[];
|
|
readonly variantName?: RegExp;
|
|
}
|
|
|
|
/** One preference order for FAT subtype identities and Apple tool slice names. */
|
|
export const MACHO_ARCHITECTURE_POLICIES: Readonly<
|
|
Record<string, MachoArchitecturePolicy>
|
|
> = {
|
|
x86: { cpuType: 7, subtypes: [{ subtype: 3, name: "i386" }] },
|
|
x86_64: {
|
|
cpuType: 0x01000007,
|
|
subtypes: [{ subtype: 3, name: "x86_64" }],
|
|
},
|
|
arm: { cpuType: 12, subtypes: [], variantName: /^arm$/u },
|
|
arm64: {
|
|
cpuType: 0x0100000c,
|
|
subtypes: [
|
|
{ subtype: 0, name: "arm64" },
|
|
{ subtype: 2, name: "arm64e" },
|
|
{ subtype: 1, name: "arm64v8" },
|
|
],
|
|
variantName: /^arm64e\.[A-Za-z0-9_]+$/u,
|
|
},
|
|
};
|
|
|
|
/** High subtype bits carry capabilities, such as the arm64e PAC ABI version. */
|
|
export const baseMachoCpuSubtype = (subtype: number): number =>
|
|
subtype & 0x00ffffff;
|
|
|
|
/** Unlisted subtypes follow the preferred slices in FAT table order. */
|
|
export const machoSubtypeRank = (
|
|
policy: MachoArchitecturePolicy,
|
|
subtype: number,
|
|
): number => {
|
|
const rank = policy.subtypes.findIndex(
|
|
(candidate) => candidate.subtype === baseMachoCpuSubtype(subtype),
|
|
);
|
|
return rank < 0 ? policy.subtypes.length : rank;
|
|
};
|
|
|
|
/** Select a tool spelling using the same preference order as FAT selection. */
|
|
export const selectMachoArchitectureName = (
|
|
policy: MachoArchitecturePolicy,
|
|
available: readonly string[],
|
|
): string | undefined => {
|
|
for (const { name } of policy.subtypes)
|
|
if (available.includes(name)) return name;
|
|
return available.find((name) => policy.variantName?.test(name));
|
|
};
|