diff --git a/src/domain/binaryTarget.ts b/src/domain/binaryTarget.ts index 4361e344c..e2182bee0 100644 --- a/src/domain/binaryTarget.ts +++ b/src/domain/binaryTarget.ts @@ -88,7 +88,7 @@ const parseThinMachO = ( format: "mach-o", architecture, availableArchitectures: [architecture], - loaderArgs: ["-l", "Mach-O"], + loaderArgs: ["-l", "Mach-O", hopperArchitectureFlag(architecture)], }); }; @@ -124,19 +124,17 @@ const parseFatMachO = ( : undefined; if (preferred === undefined || !architectures.includes(preferred)) return err(`FAT binary has no host-compatible ${host} architecture`); - const flag = - preferred === "arm64" - ? "--aarch64" - : preferred === "x86_64" - ? "--x86_64" - : preferred === "arm" - ? "--arm" - : "--x86"; return ok({ format: "mach-o", architecture: preferred, availableArchitectures: architectures, - loaderArgs: ["-l", "FAT", flag, "-l", "Mach-O"], + loaderArgs: [ + "-l", + "FAT", + hopperArchitectureFlag(preferred), + "-l", + "Mach-O", + ], }); }; @@ -152,7 +150,7 @@ const parseElf = (bytes: Buffer): Result => { format: "elf", architecture, availableArchitectures: [architecture], - loaderArgs: ["-l", "ELF"], + loaderArgs: ["-l", "ELF", hopperArchitectureFlag(architecture)], }); }; @@ -170,7 +168,7 @@ const parsePe = (bytes: Buffer): Result => { format: "pe", architecture, availableArchitectures: [architecture], - loaderArgs: ["-l", "PE"], + loaderArgs: ["-l", "WinPE", hopperArchitectureFlag(architecture)], }); }; @@ -215,3 +213,16 @@ const peArchitecture = (machine: number): BinaryArchitecture | undefined => { } return undefined; }; + +const hopperArchitectureFlag = (architecture: BinaryArchitecture): string => { + switch (architecture) { + case "x86": + return "--intel-32"; + case "x86_64": + return "--intel-64"; + case "arm": + return "--armv7"; + case "arm64": + return "--aarch64"; + } +}; diff --git a/tests/binaryTarget.test.ts b/tests/binaryTarget.test.ts index ea4d34bd7..ad82098ee 100644 --- a/tests/binaryTarget.test.ts +++ b/tests/binaryTarget.test.ts @@ -33,9 +33,22 @@ describe("executable header parsing", () => { const arm = parseExecutableHeader(bytes, "arm64"); const intel = parseExecutableHeader(bytes, "x64"); expect(arm.ok && arm.value.loaderArgs).toContain("--aarch64"); - expect(intel.ok && intel.value.loaderArgs).toContain("--x86_64"); + expect(intel.ok && intel.value.loaderArgs).toContain("--intel-64"); }); + it.each([ + [thinMach(0xfeedfacf, 0x0100000c), ["-l", "Mach-O", "--aarch64"]], + [thinMach(0xcefaedfe, 0x01000007), ["-l", "Mach-O", "--intel-64"]], + [elf(2, 2, 183), ["-l", "ELF", "--aarch64"]], + [pe(0x8664), ["-l", "WinPE", "--intel-64"]], + ] as const)( + "emits a complete non-interactive Hopper selection", + (bytes, args) => { + const result = parseExecutableHeader(bytes, "arm64"); + expect(result.ok && result.value.loaderArgs).toEqual(args); + }, + ); + it("rejects FAT files without a host-compatible slice", () => { expect(parseExecutableHeader(fat([0x01000007]), "arm64")).toMatchObject({ ok: false,