diff --git a/llvm/docs/CommandGuide/llvm-objcopy.rst b/llvm/docs/CommandGuide/llvm-objcopy.rst --- a/llvm/docs/CommandGuide/llvm-objcopy.rst +++ b/llvm/docs/CommandGuide/llvm-objcopy.rst @@ -81,6 +81,9 @@ Remove the specified section from the output. Can be specified multiple times to remove multiple sections simultaneously. + For MachO objects, ``
`` must be formatted as + ``,
``. + .. option:: --strip-all-gnu Remove all symbols, debug sections and relocations from the output. This option diff --git a/llvm/test/tools/llvm-objcopy/MachO/remove-section.test b/llvm/test/tools/llvm-objcopy/MachO/remove-section.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-objcopy/MachO/remove-section.test @@ -0,0 +1,132 @@ +## Show that if --remove-section is given, llvm-objcopy removes sections +## specified by the option. + +# RUN: yaml2obj %s > %t + +## Error case: Invalid section name. +# RUN: not llvm-objcopy --remove-section __text %t %t2 2>&1 \ +# RUN: | FileCheck %s -DINPUT=%t --check-prefix=BAD-SECTION-NAME +# BAD-SECTION-NAME: error: '[[INPUT]]': invalid section name '__text' (should be formatted as ',
') + +## Remove only __TEXT,__text section. +# RUN: llvm-objcopy --remove-section __TEXT,__text %t %t2 +# RUN: llvm-readobj --sections --section-data %t2 \ +# RUN: | FileCheck %s --check-prefixes=COMMON,REMOVE-TEXT-ONLY + +## Remove multiple sections. +# RUN: llvm-objcopy --remove-section __TEXT,__text --remove-section __DATA,__data %t %t3 +# RUN: llvm-readobj --sections --section-data %t3 \ +# RUN: | FileCheck %s --check-prefixes=COMMON,REMOVE-TEXT-AND-DATA + +# COMMON: Sections [ +# REMOVE-TEXT-ONLY-NEXT: Section { +# REMOVE-TEXT-ONLY-NEXT: Index: 0 +# REMOVE-TEXT-ONLY-NEXT: Name: __data (5F 5F 64 61 74 61 00 00 00 00 00 00 00 00 00 00) +# REMOVE-TEXT-ONLY-NEXT: Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00) +# REMOVE-TEXT-ONLY-NEXT: Address: 0x4 +# REMOVE-TEXT-ONLY-NEXT: Size: 0x4 +# REMOVE-TEXT-ONLY-NEXT: Offset: 264 +# REMOVE-TEXT-ONLY-NEXT: Alignment: 0 +# REMOVE-TEXT-ONLY-NEXT: RelocationOffset: 0x0 +# REMOVE-TEXT-ONLY-NEXT: RelocationCount: 0 +# REMOVE-TEXT-ONLY-NEXT: Type: Regular (0x0) +# REMOVE-TEXT-ONLY-NEXT: Attributes [ (0x0) +# REMOVE-TEXT-ONLY-NEXT: ] +# REMOVE-TEXT-ONLY-NEXT: Reserved1: 0x0 +# REMOVE-TEXT-ONLY-NEXT: Reserved2: 0x0 +# REMOVE-TEXT-ONLY-NEXT: Reserved3: 0x0 +# REMOVE-TEXT-ONLY-NEXT: SectionData ( +# REMOVE-TEXT-ONLY-NEXT: 0000: DDAADDAA |....| +# REMOVE-TEXT-ONLY-NEXT: ) +# REMOVE-TEXT-ONLY-NEXT: } +# COMMON-NEXT: Section { +# REMOVE-TEXT-ONLY-NEXT: Index: 1 +# REMOVE-TEXT-AND-DATA-NEXT: Index: 0 +# COMMON-NEXT: Name: __const (5F 5F 63 6F 6E 73 74 00 00 00 00 00 00 00 00 00) +# COMMON-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00) +# COMMON-NEXT: Address: 0x8 +# COMMON-NEXT: Size: 0x4 +# REMOVE-TEXT-ONLY-NEXT: Offset: 268 +# REMOVE-TEXT-AND-DATA-NEXT: Offset: 184 +# COMMON-NEXT: Alignment: 0 +# COMMON-NEXT: RelocationOffset: 0x0 +# COMMON-NEXT: RelocationCount: 0 +# COMMON-NEXT: Type: Regular (0x0) +# COMMON-NEXT: Attributes [ (0x0) +# COMMON-NEXT: ] +# COMMON-NEXT: Reserved1: 0x0 +# COMMON-NEXT: Reserved2: 0x0 +# COMMON-NEXT: Reserved3: 0x0 +# COMMON-NEXT: SectionData ( +# COMMON-NEXT: 0000: EEFFEEFF |....| +# COMMON-NEXT: ) +# COMMON-NEXT: } +# COMMON-NEXT: ] + +## Keep all sections if the specified section name is not present in the +## input. The output file should be the same as the input. +# RUN: llvm-objcopy --remove-section __TEXT,__foo %t %t4 +# RUN: cmp %t %t4 + +--- !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: __const + segname: __TEXT + 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/MachO/MachOObjcopy.cpp b/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp --- a/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp +++ b/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp @@ -23,6 +23,12 @@ static void removeSections(const CopyConfig &Config, Object &Obj) { SectionPred RemovePred = [](const Section &) { return false; }; + if (!Config.ToRemove.empty()) { + RemovePred = [&Config, RemovePred](const Section &Sec) { + return is_contained(Config.ToRemove, Sec.CannonicalName); + }; + } + if (Config.StripAll) { // Remove all debug sections. RemovePred = [RemovePred](const Section &Sec) { @@ -69,6 +75,12 @@ return E; } + if (!Config.ToRemove.empty()) { + for (const NameOrRegex &NR : Config.ToRemove) + if (Error E = NR.isMachOCannonicalName()) + return E; + } + return Error::success(); } @@ -83,14 +95,13 @@ !Config.SymbolsToKeepGlobal.empty() || !Config.SectionsToRename.empty() || !Config.SymbolsToRename.empty() || !Config.UnneededSymbolsToRemove.empty() || - !Config.SetSectionFlags.empty() || !Config.ToRemove.empty() || - Config.ExtractDWO || Config.KeepFileSymbols || Config.LocalizeHidden || - Config.PreserveDates || Config.StripAllGNU || Config.StripDWO || - Config.StripNonAlloc || Config.StripSections || Config.Weaken || - Config.DecompressDebugSections || Config.StripDebug || - Config.StripNonAlloc || Config.StripSections || Config.StripUnneeded || - Config.DiscardMode != DiscardType::None || !Config.SymbolsToAdd.empty() || - Config.EntryExpr) { + !Config.SetSectionFlags.empty() || Config.ExtractDWO || + Config.KeepFileSymbols || Config.LocalizeHidden || Config.PreserveDates || + Config.StripAllGNU || Config.StripDWO || Config.StripNonAlloc || + Config.StripSections || Config.Weaken || Config.DecompressDebugSections || + Config.StripDebug || Config.StripNonAlloc || Config.StripSections || + Config.StripUnneeded || Config.DiscardMode != DiscardType::None || + !Config.SymbolsToAdd.empty() || Config.EntryExpr) { return createStringError(llvm::errc::invalid_argument, "option not supported by llvm-objcopy for MachO"); }