fix(macos): add LC_BUILD_VERSION + codesign diagnostics
Modern macOS binaries require LC_BUILD_VERSION to declare platform and minimum OS version. Without it, the kernel may reject the binary. - Add LC_BUILD_VERSION (platform=macOS, minos=11.0, sdk=14.0) to both MachOWriter (x64) and MachOWriterArm64 (arm64) - ncmds 9→10, sizeofcmds += 24 - Add codesign -dv / codesign --verify / spctl / otool -l diagnostics to macOS workflow smoke test to identify why binaries get Killed:9
这个提交包含在:
@@ -93,26 +93,30 @@ jobs:
|
|||||||
|
|
||||||
- name: Smoke test — compile hello.pe
|
- name: Smoke test — compile hello.pe
|
||||||
env:
|
env:
|
||||||
# arm64 构建用 --arch arm 产出 arm64 Mach-O;x64 用默认 AMD64。
|
|
||||||
# x64 产物在 macos-14 (arm64) 上经 Rosetta 2 运行。
|
|
||||||
ARCH_FLAG: ${{ matrix.arch == 'arm64' && '--arch arm' || '' }}
|
ARCH_FLAG: ${{ matrix.arch == 'arm64' && '--arch arm' || '' }}
|
||||||
run: |
|
run: |
|
||||||
BIN="staging/paze-${{ steps.meta.outputs.version }}-macos-${{ matrix.arch }}/bin"
|
BIN="staging/paze-${{ steps.meta.outputs.version }}-macos-${{ matrix.arch }}/bin"
|
||||||
if [ -f "$BIN/paze" ]; then
|
PAZE="$BIN/paze"
|
||||||
"$BIN/paze" tests/hello.pe --target macos $ARCH_FLAG -o /tmp/hello.macos
|
if [ -f "$BIN/paze.dll" ] && [ ! -f "$PAZE" ]; then PAZE="dotnet $BIN/paze.dll"; fi
|
||||||
file /tmp/hello.macos
|
if [ -z "$PAZE" ] || [ ! -f "$BIN/paze" ]; then
|
||||||
chmod +x /tmp/hello.macos
|
echo "WARN: paze binary not found, listing bin/:"; ls -la "$BIN"; exit 0
|
||||||
# macOS 上执行编译产物(Mach-O 原生可执行;x64 经 Rosetta 2)
|
|
||||||
/tmp/hello.macos || true
|
|
||||||
elif [ -f "$BIN/paze.dll" ]; then
|
|
||||||
dotnet "$BIN/paze.dll" tests/hello.pe --target macos $ARCH_FLAG -o /tmp/hello.macos
|
|
||||||
file /tmp/hello.macos
|
|
||||||
chmod +x /tmp/hello.macos
|
|
||||||
/tmp/hello.macos || true
|
|
||||||
else
|
|
||||||
echo "WARN: paze binary not found, listing bin/:"
|
|
||||||
ls -la "$BIN"
|
|
||||||
fi
|
fi
|
||||||
|
$PAZE tests/hello.pe --target macos $ARCH_FLAG -o /tmp/hello.macos
|
||||||
|
file /tmp/hello.macos
|
||||||
|
chmod +x /tmp/hello.macos
|
||||||
|
# 诊断代码签名
|
||||||
|
echo "=== codesign display ==="
|
||||||
|
codesign -dv --verbose=4 /tmp/hello.macos 2>&1 || true
|
||||||
|
echo "=== codesign verify ==="
|
||||||
|
codesign --verify --deep --strict /tmp/hello.macos 2>&1 && echo "SIGNATURE OK" || echo "SIGNATURE FAILED"
|
||||||
|
echo "=== spctl assessment ==="
|
||||||
|
spctl --assess --type execute /tmp/hello.macos 2>&1 || true
|
||||||
|
echo "=== try run ==="
|
||||||
|
/tmp/hello.macos 2>&1; echo "exit code: $?"
|
||||||
|
|
||||||
|
- name: Dump Mach-O load commands
|
||||||
|
run: |
|
||||||
|
otool -l /tmp/hello.macos 2>&1 | head -120 || true
|
||||||
|
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ public sealed class MachOWriter : IExecutableWriter
|
|||||||
private const uint LC_DYSYMTAB = 0x0B;
|
private const uint LC_DYSYMTAB = 0x0B;
|
||||||
private const uint LC_MAIN = 0x80000028;
|
private const uint LC_MAIN = 0x80000028;
|
||||||
private const uint LC_CODE_SIGNATURE = 0x1D;
|
private const uint LC_CODE_SIGNATURE = 0x1D;
|
||||||
|
private const uint LC_BUILD_VERSION = 0x32;
|
||||||
private const int VM_PROT_READ = 1, VM_PROT_WRITE = 2, VM_PROT_EXECUTE = 4;
|
private const int VM_PROT_READ = 1, VM_PROT_WRITE = 2, VM_PROT_EXECUTE = 4;
|
||||||
private const int S_NON_LAZY_SYMBOL_POINTERS = 0x06;
|
private const int S_NON_LAZY_SYMBOL_POINTERS = 0x06;
|
||||||
// nlist n_type
|
// nlist n_type
|
||||||
@@ -160,8 +161,9 @@ public sealed class MachOWriter : IExecutableWriter
|
|||||||
int lcSymtab = 24;
|
int lcSymtab = 24;
|
||||||
int lcDysymtab = 80;
|
int lcDysymtab = 80;
|
||||||
int lcCodeSig = 16; // linkedit_data_command(cmd+cmdsize+dataoff+datasize)
|
int lcCodeSig = 16; // linkedit_data_command(cmd+cmdsize+dataoff+datasize)
|
||||||
int sizeofcmds = segTextCmd + segDataCmd + segLinkCmd + lcDylinker + lcDylib + lcMain + lcSymtab + lcDysymtab + lcCodeSig;
|
int lcBuildVer = 24; // build_version_command(cmd+cmdsize+platform+minos+sdk+ntools)
|
||||||
int ncmds = 9;
|
int sizeofcmds = segTextCmd + segDataCmd + segLinkCmd + lcDylinker + lcDylib + lcMain + lcSymtab + lcDysymtab + lcCodeSig + lcBuildVer;
|
||||||
|
int ncmds = 10;
|
||||||
|
|
||||||
int headerSize = 32;
|
int headerSize = 32;
|
||||||
int textFileOff = headerSize + sizeofcmds; // __text 文件偏移
|
int textFileOff = headerSize + sizeofcmds; // __text 文件偏移
|
||||||
@@ -331,6 +333,14 @@ public sealed class MachOWriter : IExecutableWriter
|
|||||||
Write32At(f2, 0); Write32At(f2, 0); // extreloff, nextrel
|
Write32At(f2, 0); Write32At(f2, 0); // extreloff, nextrel
|
||||||
Write32At(f2, 0); Write32At(f2, 0); // locreloff, nlocrel
|
Write32At(f2, 0); Write32At(f2, 0); // locreloff, nlocrel
|
||||||
|
|
||||||
|
// ---- LC_BUILD_VERSION ----
|
||||||
|
Write32At(f2, LC_BUILD_VERSION);
|
||||||
|
Write32At(f2, 24); // cmdsize
|
||||||
|
Write32At(f2, 1); // platform = PLATFORM_MACOS
|
||||||
|
Write32At(f2, 0x000B0000); // minos = macOS 11.0.0
|
||||||
|
Write32At(f2, 0x000E0000); // sdk = macOS 14.0.0
|
||||||
|
Write32At(f2, 0); // ntools = 0
|
||||||
|
|
||||||
// ---- LC_CODE_SIGNATURE ----
|
// ---- LC_CODE_SIGNATURE ----
|
||||||
Write32At(f2, LC_CODE_SIGNATURE);
|
Write32At(f2, LC_CODE_SIGNATURE);
|
||||||
Write32At(f2, 16); // cmdsize (linkedit_data_command)
|
Write32At(f2, 16); // cmdsize (linkedit_data_command)
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ public sealed class MachOWriterArm64 : IExecutableWriter
|
|||||||
private const uint LC_DYSYMTAB = 0x0B;
|
private const uint LC_DYSYMTAB = 0x0B;
|
||||||
private const uint LC_MAIN = 0x80000028;
|
private const uint LC_MAIN = 0x80000028;
|
||||||
private const uint LC_CODE_SIGNATURE = 0x1D;
|
private const uint LC_CODE_SIGNATURE = 0x1D;
|
||||||
|
private const uint LC_BUILD_VERSION = 0x32;
|
||||||
private const int VM_PROT_READ = 1, VM_PROT_WRITE = 2, VM_PROT_EXECUTE = 4;
|
private const int VM_PROT_READ = 1, VM_PROT_WRITE = 2, VM_PROT_EXECUTE = 4;
|
||||||
private const int S_NON_LAZY_SYMBOL_POINTERS = 0x06;
|
private const int S_NON_LAZY_SYMBOL_POINTERS = 0x06;
|
||||||
private const byte N_EXT = 0x01, N_SECT = 0x0e;
|
private const byte N_EXT = 0x01, N_SECT = 0x0e;
|
||||||
@@ -139,8 +140,9 @@ public sealed class MachOWriterArm64 : IExecutableWriter
|
|||||||
int lcSymtab = 24;
|
int lcSymtab = 24;
|
||||||
int lcDysymtab = 80;
|
int lcDysymtab = 80;
|
||||||
int lcCodeSig = 16; // linkedit_data_command(cmd+cmdsize+dataoff+datasize)
|
int lcCodeSig = 16; // linkedit_data_command(cmd+cmdsize+dataoff+datasize)
|
||||||
int sizeofcmds = segTextCmd + segDataCmd + segLinkCmd + lcDylinker + lcDylib + lcMain + lcSymtab + lcDysymtab + lcCodeSig;
|
int lcBuildVer = 24; // build_version_command(cmd+cmdsize+platform+minos+sdk+ntools)
|
||||||
int ncmds = 9;
|
int sizeofcmds = segTextCmd + segDataCmd + segLinkCmd + lcDylinker + lcDylib + lcMain + lcSymtab + lcDysymtab + lcCodeSig + lcBuildVer;
|
||||||
|
int ncmds = 10;
|
||||||
|
|
||||||
int headerSize = 32;
|
int headerSize = 32;
|
||||||
int textFileOff = headerSize + sizeofcmds;
|
int textFileOff = headerSize + sizeofcmds;
|
||||||
@@ -329,6 +331,14 @@ public sealed class MachOWriterArm64 : IExecutableWriter
|
|||||||
Write32At(f2, 0); Write32At(f2, 0);
|
Write32At(f2, 0); Write32At(f2, 0);
|
||||||
Write32At(f2, 0); Write32At(f2, 0);
|
Write32At(f2, 0); Write32At(f2, 0);
|
||||||
|
|
||||||
|
// ---- LC_BUILD_VERSION ----
|
||||||
|
Write32At(f2, LC_BUILD_VERSION);
|
||||||
|
Write32At(f2, 24); // cmdsize
|
||||||
|
Write32At(f2, 1); // platform = PLATFORM_MACOS
|
||||||
|
Write32At(f2, 0x000B0000); // minos = macOS 11.0.0
|
||||||
|
Write32At(f2, 0x000E0000); // sdk = macOS 14.0.0
|
||||||
|
Write32At(f2, 0); // ntools = 0
|
||||||
|
|
||||||
// ---- LC_CODE_SIGNATURE ----
|
// ---- LC_CODE_SIGNATURE ----
|
||||||
Write32At(f2, LC_CODE_SIGNATURE);
|
Write32At(f2, LC_CODE_SIGNATURE);
|
||||||
Write32At(f2, 16); // cmdsize (linkedit_data_command)
|
Write32At(f2, 16); // cmdsize (linkedit_data_command)
|
||||||
|
|||||||
在新工单中引用
屏蔽一个用户