fix(native): inspect the selected universal Mach-O architecture (#601)

Signed-off-by: Rudy Celekli <47457359+rudycelekli@users.noreply.github.com>
This commit is contained in:
Rudy Mizrahi Celekli
2026-10-05 14:08:33 -04:00
committed by GitHub
parent 1b6f05470d
commit 2b7bb3bb6a
2 changed files with 70 additions and 2 deletions
+28 -2
View File
@@ -54,7 +54,11 @@ export const inspectNativeMacho = async (
for (const [tool, prefix] of REQUIRED_COMMANDS) {
const captured = await context.run(
tool,
[...prefix, context.target.path],
[
...prefix,
...selectedArchitectureArguments(tool, context.target),
context.target.path,
],
context.signal,
);
if (!captured.ok) return err(captured.error);
@@ -64,7 +68,11 @@ export const inspectNativeMacho = async (
const [tool, prefix] = OPTIONAL_VTOOL_COMMAND;
const optional = await context.run(
tool,
[...prefix, context.target.path],
[
...prefix,
...selectedArchitectureArguments(tool, context.target),
context.target.path,
],
context.signal,
);
if (optional.ok) captures.push(optional.value);
@@ -251,3 +259,21 @@ export const architectureLocations = (
}
return locations;
};
const selectedArchitectureArguments = (
tool: string,
target: BinaryTarget,
): string[] => {
if (
target.kind !== "executable" ||
target.availableArchitectures.length < 2 ||
tool === "file" ||
tool === "lipo"
)
return [];
const architecture =
target.architecture === "x86" ? "i386" : target.architecture;
return tool === "dwarfdump"
? [`--arch=${architecture}`]
: ["-arch", architecture];
};
@@ -0,0 +1,42 @@
import { expect, it } from "vitest";
import { inspectMachoSchema } from "../../../../src/domain/nativeInspection.js";
import { NativeMacOSProvider } from "../../../../src/native/NativeMacOSProvider.js";
import {
NativeFixtureRunner,
nativeFixture,
nativeMachoTarget,
} from "../../../fixtures/nativeCommands.js";
it("does not attribute the first universal slice's UUID and segments to the selected target", async () => {
const singleSlice = await nativeFixture("otool-load.txt");
const selected = new NativeFixtureRunner();
const universal = new NativeFixtureRunner({
"otool:-h": `${singleSlice}\n${singleSlice}`,
dwarfdump:
"UUID: AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA (x86_64) fixture\nUUID: 01234567-89AB-CDEF-0123-456789ABCDEF (arm64) fixture\n",
});
const client = new NativeMacOSProvider(
{
async run(tool, arguments_) {
const isSelected =
arguments_.includes("arm64") || arguments_.includes("--arch=arm64");
return (isSelected ? selected : universal).run(tool, arguments_);
},
},
"darwin",
).createClient(nativeMachoTarget("/owned/universal"));
const result = await client.execute("inspect_macho", {});
expect(result.ok).toBe(true);
if (!result.ok) return;
expect(result.value.result).toMatchObject({
uuid: "01234567-89AB-CDEF-0123-456789ABCDEF",
architectures: { total: 2 },
});
const normalized = inspectMachoSchema.parse(result.value.result);
expect(
normalized.segments.items.filter((segment) => segment.name === "__TEXT"),
).toHaveLength(1);
expect(JSON.stringify(normalized)).not.toContain(
"AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA",
);
});