diff --git a/llvm/include/llvm/ObjCopy/MachO/MachOConfig.h b/llvm/include/llvm/ObjCopy/MachO/MachOConfig.h --- a/llvm/include/llvm/ObjCopy/MachO/MachOConfig.h +++ b/llvm/include/llvm/ObjCopy/MachO/MachOConfig.h @@ -32,6 +32,7 @@ // Boolean options bool StripSwiftSymbols = false; bool KeepUndefined = false; + bool RemoveCodesignLoadCommands = false; // install-name-tool's --delete_all_rpaths bool RemoveAllRpaths = false; diff --git a/llvm/lib/ObjCopy/MachO/MachOObjcopy.cpp b/llvm/lib/ObjCopy/MachO/MachOObjcopy.cpp --- a/llvm/lib/ObjCopy/MachO/MachOObjcopy.cpp +++ b/llvm/lib/ObjCopy/MachO/MachOObjcopy.cpp @@ -11,6 +11,7 @@ #include "MachOReader.h" #include "MachOWriter.h" #include "llvm/ADT/DenseSet.h" +#include "llvm/BinaryFormat/MachO.h" #include "llvm/ObjCopy/CommonConfig.h" #include "llvm/ObjCopy/MachO/MachOConfig.h" #include "llvm/ObjCopy/MultiFormatConfig.h" @@ -258,6 +259,16 @@ if (!MachOConfig.RPathToPrepend.empty()) Obj.updateLoadCommandIndexes(); + // Remove codesign load commands. + if (MachOConfig.RemoveCodesignLoadCommands) { + auto RemovePred = [](const LoadCommand &LC) { + return LC.MachOLoadCommand.load_command_data.cmd == + MachO::LC_CODE_SIGNATURE; + }; + if (Error E = Obj.removeLoadCommands(RemovePred)) + return E; + } + return Error::success(); } diff --git a/llvm/test/tools/llvm-objcopy/MachO/bitcode-strip-codesign.test b/llvm/test/tools/llvm-objcopy/MachO/bitcode-strip-codesign.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-objcopy/MachO/bitcode-strip-codesign.test @@ -0,0 +1,53 @@ +## Test codesign load commands are stripped by default. +# RUN: yaml2obj %s -o %t +# RUN: llvm-bitcode-strip -r %t -o %t2 +# RUN: llvm-otool -l %t2 | FileCheck --check-prefix=NOCODESIGN %s + +# NOCODESIGN-NOT: LC_CODE_SIGNATURE + +## Test codesign load commands are kept with -keep_cs. +# RUN: llvm-bitcode-strip -keep_cs -r %t -o %t3 +# RUN: llvm-otool -l %t3 | FileCheck --check-prefix=CODESIGN %s + +# CODESIGN: LC_CODE_SIGNATURE + +--- !mach-o +FileHeader: + magic: 0xFEEDFACF + cputype: 0x01000007 + cpusubtype: 0x00000003 + filetype: 0x00000001 + ncmds: 2 + sizeofcmds: 168 + flags: 0x00002000 + reserved: 0x00000000 +LoadCommands: + - cmd: LC_SEGMENT_64 + cmdsize: 152 + segname: __TEXT + vmaddr: 0 + vmsize: 4 + fileoff: 200 + filesize: 4 + maxprot: 7 + initprot: 7 + nsects: 1 + flags: 0 + Sections: + - sectname: __text + segname: __TEXT + addr: 0x0000000000000000 + content: 'AABBCCDD' + size: 4 + offset: 200 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x80000400 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - cmd: LC_CODE_SIGNATURE + cmdsize: 16 + dataoff: 0 + datasize: 0 diff --git a/llvm/tools/llvm-objcopy/BitcodeStripOpts.td b/llvm/tools/llvm-objcopy/BitcodeStripOpts.td --- a/llvm/tools/llvm-objcopy/BitcodeStripOpts.td +++ b/llvm/tools/llvm-objcopy/BitcodeStripOpts.td @@ -26,5 +26,8 @@ def remove : Flag<["-"], "r">, HelpText<"Remove the __LLVM bitcode segment entirely">; +def keep_codesign : Flag<["-"], "keep_cs">, + HelpText<"Preserve the codesign load commands in the output binary, even though the code signature is no longer valid">; + def output : JoinedOrSeparate<["-"], "o">, HelpText<"Write output to ">, MetaVarName<"">; diff --git a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp --- a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp +++ b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp @@ -1175,6 +1175,7 @@ DriverConfig DC; ConfigManager ConfigMgr; CommonConfig &Config = ConfigMgr.Common; + MachOConfig &MachOConfig = ConfigMgr.MachO; BitcodeStripOptTable T; unsigned MissingArgumentIndex, MissingArgumentCount; opt::InputArgList InputArgs = @@ -1223,6 +1224,11 @@ cantFail(Config.ToRemove.addMatcher(NameOrPattern::create( "__LLVM,__bundle", MatchStyle::Literal, ErrorCallback))); + // By default remove codesign load commands as they will be invalid after + // stripping. + MachOConfig.RemoveCodesignLoadCommands = + !InputArgs.hasArg(BITCODE_STRIP_keep_codesign); + DC.CopyConfigs.push_back(std::move(ConfigMgr)); return std::move(DC); }