diff --git a/llvm/lib/ObjCopy/MachO/MachOObject.cpp b/llvm/lib/ObjCopy/MachO/MachOObject.cpp --- a/llvm/lib/ObjCopy/MachO/MachOObject.cpp +++ b/llvm/lib/ObjCopy/MachO/MachOObject.cpp @@ -8,6 +8,7 @@ #include "MachOObject.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/BinaryFormat/MachO.h" #include using namespace llvm; diff --git a/llvm/test/tools/llvm-objcopy/MachO/bitcode-strip.test b/llvm/test/tools/llvm-objcopy/MachO/bitcode-strip.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-objcopy/MachO/bitcode-strip.test @@ -0,0 +1,109 @@ +## Show that if --remove-section is given, llvm-objcopy removes sections +## specified by the option. + +# RUN: yaml2obj %s -o %t + +# RUN: llvm-bitcode-strip -r %t -o %t2 +# RUN: llvm-readobj --sections %t2 | FileCheck %s + +# CHECK:Sections [ +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: 0 +# CHECK-NEXT: Name: __text (5F 5F 74 65 78 74 00 00 00 00 00 00 00 00 00 00) +# CHECK-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00) +# CHECK-NEXT: Address: 0x0 +# CHECK-NEXT: Size: 0x4 +# CHECK-NEXT: Offset: 264 +# CHECK-NEXT: Alignment: 0 +# CHECK-NEXT: RelocationOffset: 0x0 +# CHECK-NEXT: RelocationCount: 0 +# CHECK-NEXT: Type: Regular (0x0) +# CHECK-NEXT: Attributes [ (0x800004) +# CHECK-NEXT: PureInstructions (0x800000) +# CHECK-NEXT: SomeInstructions (0x4) +# CHECK-NEXT: ] +# CHECK-NEXT: Reserved1: 0x0 +# CHECK-NEXT: Reserved2: 0x0 +# CHECK-NEXT: Reserved3: 0x0 +# CHECK-NEXT: } +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: 1 +# CHECK-NEXT: Name: __data (5F 5F 64 61 74 61 00 00 00 00 00 00 00 00 00 00) +# CHECK-NEXT: Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00) +# CHECK-NEXT: Address: 0x4 +# CHECK-NEXT: Size: 0x4 +# CHECK-NEXT: Offset: 268 +# CHECK-NEXT: Alignment: 0 +# CHECK-NEXT: RelocationOffset: 0x0 +# CHECK-NEXT: RelocationCount: 0 +# CHECK-NEXT: Type: Regular (0x0) +# CHECK-NEXT: Attributes [ (0x0) +# CHECK-NEXT: ] +# CHECK-NEXT: Reserved1: 0x0 +# CHECK-NEXT: Reserved2: 0x0 +# CHECK-NEXT: Reserved3: 0x0 +# CHECK-NEXT: } +# CHECK-NEXT:] + +--- !mach-o +FileHeader: + magic: 0xFEEDFACF + cputype: 0x01000007 + cpusubtype: 0x00000003 + filetype: 0x00000001 + ncmds: 1 + sizeofcmds: 312 + flags: 0x00002000 + reserved: 0x00000000 +LoadCommands: + - cmd: LC_SEGMENT_64 + cmdsize: 312 + segname: '' + vmaddr: 0 + vmsize: 12 + fileoff: 344 + filesize: 12 + maxprot: 7 + initprot: 7 + nsects: 3 + flags: 0 + Sections: + - sectname: __text + segname: __TEXT + addr: 0x0000000000000000 + content: 'AABBCCDD' + size: 4 + offset: 344 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x80000400 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __data + segname: __DATA + addr: 0x0000000000000004 + content: 'DDAADDAA' + size: 4 + offset: 348 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __bundle + segname: __LLVM + addr: 0x0000000000000008 + content: 'EEFFEEFF' + size: 4 + offset: 352 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 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 @@ -22,3 +22,9 @@ def V : Flag<["-"], "V">, Alias, HelpText<"Alias for --version">; + +def remove : Flag<["-"], "r">, + HelpText<"Remove the __LLVM bitcode segment entirely.">; + +def output : JoinedOrSeparate<["-"], "o">, HelpText<"Write output to ">, + MetaVarName<"">; diff --git a/llvm/tools/llvm-objcopy/ObjcopyOptions.h b/llvm/tools/llvm-objcopy/ObjcopyOptions.h --- a/llvm/tools/llvm-objcopy/ObjcopyOptions.h +++ b/llvm/tools/llvm-objcopy/ObjcopyOptions.h @@ -41,7 +41,9 @@ // ParseBitcodeStripOptions returns the config and sets the input arguments. // If a help flag is set then ParseBitcodeStripOptions will print the help // messege and exit. -Expected parseBitcodeStripOptions(ArrayRef ArgsArr); +Expected +parseBitcodeStripOptions(ArrayRef ArgsArr, + llvm::function_ref ErrorCallback); // ParseStripOptions returns the config and sets the input arguments. If a // help flag is set then ParseStripOptions will print the help messege and 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 @@ -12,6 +12,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSet.h" #include "llvm/BinaryFormat/COFF.h" +#include "llvm/ObjCopy/CommonConfig.h" #include "llvm/ObjCopy/ConfigManager.h" #include "llvm/Option/Arg.h" #include "llvm/Option/ArgList.h" @@ -1169,7 +1170,8 @@ } Expected -objcopy::parseBitcodeStripOptions(ArrayRef ArgsArr) { +objcopy::parseBitcodeStripOptions(ArrayRef ArgsArr, + function_ref ErrorCallback) { DriverConfig DC; ConfigManager ConfigMgr; CommonConfig &Config = ConfigMgr.Common; @@ -1207,7 +1209,24 @@ "llvm-bitcode-strip expects a single input file"); assert(!Positional.empty()); Config.InputFilename = Positional[0]; - Config.OutputFilename = Positional[0]; + + if (!InputArgs.hasArg(BITCODE_STRIP_output)) { + return createStringError( + errc::invalid_argument, + "llvm-bitcode-strip expects a single output path specified with -o"); + } + Config.OutputFilename = InputArgs.getLastArgValue(BITCODE_STRIP_output); + + if (!InputArgs.hasArg(BITCODE_STRIP_remove)) { + return createStringError(errc::invalid_argument, + "llvm-bitcode-strip has no action specified"); + } + + // We only support -r for now, which removes all bitcode sections + if (Error E = Config.ToRemove.addMatcher(NameOrPattern::create( + "__LLVM,__bundle", MatchStyle::Literal, ErrorCallback))) { + return std::move(E); + } DC.CopyConfigs.push_back(std::move(ConfigMgr)); return std::move(DC); diff --git a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp --- a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp +++ b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp @@ -86,7 +86,7 @@ }; if (Is("bitcode-strip") || Is("bitcode_strip")) - return parseBitcodeStripOptions(Args); + return parseBitcodeStripOptions(Args, reportWarning); else if (Is("strip")) return parseStripOptions(Args, reportWarning); else if (Is("install-name-tool") || Is("install_name_tool"))