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 @@ -91,8 +91,8 @@ For ELF objects, remove from the output all symbols and non-alloc sections not within segments, except for .gnu.warning sections and the section name table. - For COFF objects, remove all symbols, debug sections, and relocations from the - output. + For COFF and Mach-O objects, remove all symbols, debug sections, and + relocations from the output. .. option:: --strip-debug, -g diff --git a/llvm/test/tools/llvm-objcopy/MachO/Inputs/strip-all-with-dwarf.yaml b/llvm/test/tools/llvm-objcopy/MachO/Inputs/strip-all-with-dwarf.yaml new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-objcopy/MachO/Inputs/strip-all-with-dwarf.yaml @@ -0,0 +1,448 @@ +--- !mach-o +FileHeader: + magic: 0xFEEDFACF + cputype: 0x01000007 + cpusubtype: 0x00000003 + filetype: 0x00000001 + ncmds: 4 + sizeofcmds: 1240 + flags: 0x00002000 + reserved: 0x00000000 +LoadCommands: + - cmd: LC_SEGMENT_64 + cmdsize: 1112 + segname: '' + vmaddr: 0 + vmsize: 798 + fileoff: 1272 + filesize: 798 + maxprot: 7 + initprot: 7 + nsects: 13 + flags: 0 + Sections: + - sectname: __text + segname: __TEXT + addr: 0x0000000000000000 + size: 36 + offset: 0x000004F8 + align: 4 + reloff: 0x00000818 + nreloc: 2 + flags: 0x80000400 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __data + segname: __DATA + addr: 0x0000000000000024 + size: 4 + offset: 0x0000051C + align: 2 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __debug_str + segname: __DWARF + addr: 0x0000000000000028 + size: 117 + offset: 0x00000520 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x02000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __debug_abbrev + segname: __DWARF + addr: 0x000000000000009D + size: 84 + offset: 0x00000595 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x02000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __debug_info + segname: __DWARF + addr: 0x00000000000000F1 + size: 117 + offset: 0x000005E9 + align: 0 + reloff: 0x00000828 + nreloc: 4 + flags: 0x02000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __debug_macinfo + segname: __DWARF + addr: 0x0000000000000166 + size: 1 + offset: 0x0000065E + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x02000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __apple_names + segname: __DWARF + addr: 0x0000000000000167 + size: 116 + offset: 0x0000065F + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x02000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __apple_objc + segname: __DWARF + addr: 0x00000000000001DB + size: 36 + offset: 0x000006D3 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x02000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __apple_namespac + segname: __DWARF + addr: 0x00000000000001FF + size: 36 + offset: 0x000006F7 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x02000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __apple_types + segname: __DWARF + addr: 0x0000000000000223 + size: 71 + offset: 0x0000071B + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x02000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __compact_unwind + segname: __LD + addr: 0x0000000000000270 + size: 32 + offset: 0x00000768 + align: 3 + reloff: 0x00000848 + nreloc: 1 + flags: 0x02000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __eh_frame + segname: __TEXT + addr: 0x0000000000000290 + size: 64 + offset: 0x00000788 + align: 3 + reloff: 0x00000000 + nreloc: 0 + flags: 0x6800000B + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __debug_line + segname: __DWARF + addr: 0x00000000000002D0 + size: 78 + offset: 0x000007C8 + align: 0 + reloff: 0x00000850 + nreloc: 1 + flags: 0x02000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - cmd: LC_BUILD_VERSION + cmdsize: 24 + platform: 1 + minos: 658944 + sdk: 0 + ntools: 0 + - cmd: LC_SYMTAB + cmdsize: 24 + symoff: 2136 + nsyms: 3 + stroff: 2184 + strsize: 20 + - cmd: LC_DYSYMTAB + cmdsize: 80 + ilocalsym: 0 + nlocalsym: 1 + iextdefsym: 1 + nextdefsym: 1 + iundefsym: 2 + nundefsym: 1 + tocoff: 0 + ntoc: 0 + modtaboff: 0 + nmodtab: 0 + extrefsymoff: 0 + nextrefsyms: 0 + indirectsymoff: 0 + nindirectsyms: 0 + extreloff: 0 + nextrel: 0 + locreloff: 0 + nlocrel: 0 +LinkEditData: + NameList: + - n_strx: 1 + n_type: 0x0E + n_sect: 2 + n_desc: 0 + n_value: 36 + - n_strx: 11 + n_type: 0x0F + n_sect: 1 + n_desc: 0 + n_value: 0 + - n_strx: 6 + n_type: 0x01 + n_sect: 0 + n_desc: 512 + n_value: 4 + StringTable: + - '' + - _bar + - _foo + - _main + - '' + - '' + - '' +DWARF: + debug_str: + - 'Apple LLVM version 10.0.1 (clang-1001.0.46.4)' + - strip-test.c + - '/Users/seiya/dev/llvm-project/llvm/build' + - foo + - int + - bar + - main + debug_abbrev: + - Code: 0x00000001 + Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_producer + Form: DW_FORM_strp + - Attribute: DW_AT_language + Form: DW_FORM_data2 + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Attribute: DW_AT_stmt_list + Form: DW_FORM_sec_offset + - Attribute: DW_AT_comp_dir + Form: DW_FORM_strp + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - Attribute: DW_AT_high_pc + Form: DW_FORM_data4 + - Code: 0x00000002 + Tag: DW_TAG_variable + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Attribute: DW_AT_type + Form: DW_FORM_ref4 + - Attribute: DW_AT_external + Form: DW_FORM_flag_present + - Attribute: DW_AT_decl_file + Form: DW_FORM_data1 + - Attribute: DW_AT_decl_line + Form: DW_FORM_data1 + - Attribute: DW_AT_location + Form: DW_FORM_exprloc + - Code: 0x00000003 + Tag: DW_TAG_base_type + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Attribute: DW_AT_encoding + Form: DW_FORM_data1 + - Attribute: DW_AT_byte_size + Form: DW_FORM_data1 + - Code: 0x00000004 + Tag: DW_TAG_variable + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Attribute: DW_AT_type + Form: DW_FORM_ref4 + - Attribute: DW_AT_decl_file + Form: DW_FORM_data1 + - Attribute: DW_AT_decl_line + Form: DW_FORM_data1 + - Attribute: DW_AT_location + Form: DW_FORM_exprloc + - Code: 0x00000005 + Tag: DW_TAG_subprogram + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - Attribute: DW_AT_high_pc + Form: DW_FORM_data4 + - Attribute: DW_AT_frame_base + Form: DW_FORM_exprloc + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Attribute: DW_AT_decl_file + Form: DW_FORM_data1 + - Attribute: DW_AT_decl_line + Form: DW_FORM_data1 + - Attribute: DW_AT_type + Form: DW_FORM_ref4 + - Attribute: DW_AT_external + Form: DW_FORM_flag_present + debug_info: + - Length: + TotalLength: 113 + Version: 4 + AbbrOffset: 0 + AddrSize: 8 + Entries: + - AbbrCode: 0x00000001 + Values: + - Value: 0x0000000000000000 + - Value: 0x000000000000000C + - Value: 0x000000000000002E + - Value: 0x0000000000000000 + - Value: 0x000000000000003B + - Value: 0x0000000000000000 + - Value: 0x0000000000000024 + - AbbrCode: 0x00000002 + Values: + - Value: 0x0000000000000064 + - Value: 0x000000000000003F + - Value: 0x0000000000000001 + - Value: 0x0000000000000001 + - Value: 0x0000000000000001 + - Value: 0x0000000000000009 + BlockData: + - 0x03 + - 0x00 + - 0x00 + - 0x00 + - 0x00 + - 0x00 + - 0x00 + - 0x00 + - 0x00 + - AbbrCode: 0x00000003 + Values: + - Value: 0x0000000000000068 + - Value: 0x0000000000000005 + - Value: 0x0000000000000004 + - AbbrCode: 0x00000004 + Values: + - Value: 0x000000000000006C + - Value: 0x000000000000003F + - Value: 0x0000000000000001 + - Value: 0x0000000000000002 + - Value: 0x0000000000000009 + BlockData: + - 0x03 + - 0x24 + - 0x00 + - 0x00 + - 0x00 + - 0x00 + - 0x00 + - 0x00 + - 0x00 + - AbbrCode: 0x00000005 + Values: + - Value: 0x0000000000000000 + - Value: 0x0000000000000024 + - Value: 0x0000000000000001 + BlockData: + - 0x56 + - Value: 0x0000000000000070 + - Value: 0x0000000000000001 + - Value: 0x0000000000000003 + - Value: 0x000000000000003F + - Value: 0x0000000000000001 + - AbbrCode: 0x00000000 + Values: [] + debug_line: + - Length: + TotalLength: 74 + Version: 4 + PrologueLength: 36 + MinInstLength: 1 + MaxOpsPerInst: 1 + DefaultIsStmt: 1 + LineBase: 251 + LineRange: 14 + OpcodeBase: 13 + StandardOpcodeLengths: [ 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 ] + IncludeDirs: [] + Files: + - Name: strip-test.c + DirIdx: 0 + ModTime: 0 + Length: 0 + Opcodes: + - Opcode: DW_LNS_extended_op + ExtLen: 9 + SubOpcode: DW_LNE_set_address + Data: 0 + - Opcode: 0x14 + Data: 0 + - Opcode: DW_LNS_set_column + Data: 7 + - Opcode: DW_LNS_set_prologue_end + Data: 7 + - Opcode: DW_LNS_const_add_pc + Data: 7 + - Opcode: 0x21 + Data: 7 + - Opcode: DW_LNS_set_column + Data: 10 + - Opcode: 0x67 + Data: 10 + - Opcode: DW_LNS_set_column + Data: 14 + - Opcode: DW_LNS_negate_stmt + Data: 14 + - Opcode: 0x2E + Data: 14 + - Opcode: DW_LNS_set_column + Data: 3 + - Opcode: 0x66 + Data: 3 + - Opcode: DW_LNS_advance_pc + Data: 4 + - Opcode: DW_LNS_extended_op + ExtLen: 1 + SubOpcode: DW_LNE_end_sequence + Data: 4 +... diff --git a/llvm/test/tools/llvm-objcopy/MachO/Inputs/strip-all.yaml b/llvm/test/tools/llvm-objcopy/MachO/Inputs/strip-all.yaml new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-objcopy/MachO/Inputs/strip-all.yaml @@ -0,0 +1,320 @@ +--- !mach-o +FileHeader: + magic: 0xFEEDFACF + cputype: 0x01000007 + cpusubtype: 0x80000003 + filetype: 0x00000002 + ncmds: 15 + sizeofcmds: 976 + flags: 0x00200085 + reserved: 0x00000000 +LoadCommands: + - cmd: LC_SEGMENT_64 + cmdsize: 72 + segname: __PAGEZERO + vmaddr: 0 + vmsize: 4294967296 + fileoff: 0 + filesize: 0 + maxprot: 0 + initprot: 0 + nsects: 0 + flags: 0 + - cmd: LC_SEGMENT_64 + cmdsize: 232 + segname: __TEXT + vmaddr: 4294967296 + vmsize: 4096 + fileoff: 0 + filesize: 4096 + maxprot: 7 + initprot: 5 + nsects: 2 + flags: 0 + Sections: + - sectname: __text + segname: __TEXT + addr: 0x0000000100000F90 + size: 36 + offset: 0x00000F90 + align: 4 + reloff: 0x00000000 + nreloc: 0 + flags: 0x80000400 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __unwind_info + segname: __TEXT + addr: 0x0000000100000FB4 + size: 72 + offset: 0x00000FB4 + align: 2 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - cmd: LC_SEGMENT_64 + cmdsize: 232 + segname: __DATA + vmaddr: 4294971392 + vmsize: 4096 + fileoff: 4096 + filesize: 4096 + maxprot: 7 + initprot: 3 + nsects: 2 + flags: 0 + Sections: + - sectname: __data + segname: __DATA + addr: 0x0000000100001000 + size: 4 + offset: 0x00001000 + align: 2 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __common + segname: __DATA + addr: 0x0000000100001004 + size: 4 + offset: 0x00000000 + align: 2 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000001 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - cmd: LC_SEGMENT_64 + cmdsize: 72 + segname: __LINKEDIT + vmaddr: 4294975488 + vmsize: 4096 + fileoff: 8192 + filesize: 496 + maxprot: 7 + initprot: 1 + nsects: 0 + flags: 0 + - cmd: LC_DYLD_INFO_ONLY + cmdsize: 48 + rebase_off: 0 + rebase_size: 0 + bind_off: 0 + bind_size: 0 + weak_bind_off: 0 + weak_bind_size: 0 + lazy_bind_off: 0 + lazy_bind_size: 0 + export_off: 8192 + export_size: 56 + - cmd: LC_SYMTAB + cmdsize: 24 + symoff: 8256 + nsyms: 15 + stroff: 8496 + strsize: 192 + - cmd: LC_DYSYMTAB + cmdsize: 80 + ilocalsym: 0 + nlocalsym: 11 + iextdefsym: 11 + nextdefsym: 3 + iundefsym: 14 + nundefsym: 1 + tocoff: 0 + ntoc: 0 + modtaboff: 0 + nmodtab: 0 + extrefsymoff: 0 + nextrefsyms: 0 + indirectsymoff: 0 + nindirectsyms: 0 + extreloff: 0 + nextrel: 0 + locreloff: 0 + nlocrel: 0 + - cmd: LC_LOAD_DYLINKER + cmdsize: 32 + name: 12 + PayloadString: '/usr/lib/dyld' + ZeroPadBytes: 7 + - cmd: LC_UUID + cmdsize: 24 + uuid: 56D84164-1DA8-393B-8589-BC4C6B56168E + - cmd: LC_BUILD_VERSION + cmdsize: 32 + platform: 1 + minos: 658944 + sdk: 658944 + ntools: 1 + Tools: + - tool: 3 + version: 29491968 + - cmd: LC_SOURCE_VERSION + cmdsize: 16 + version: 0 + - cmd: LC_MAIN + cmdsize: 24 + entryoff: 3984 + stacksize: 0 + - cmd: LC_LOAD_DYLIB + cmdsize: 56 + dylib: + name: 24 + timestamp: 2 + current_version: 82115073 + compatibility_version: 65536 + PayloadString: '/usr/lib/libSystem.B.dylib' + ZeroPadBytes: 6 + - cmd: LC_FUNCTION_STARTS + cmdsize: 16 + dataoff: 8248 + datasize: 8 + - cmd: LC_DATA_IN_CODE + cmdsize: 16 + dataoff: 8256 + datasize: 0 +LinkEditData: + ExportTrie: + TerminalSize: 0 + NodeOffset: 0 + Name: '' + Flags: 0x0000000000000000 + Address: 0x0000000000000000 + Other: 0x0000000000000000 + ImportName: '' + Children: + - TerminalSize: 0 + NodeOffset: 5 + Name: _ + Flags: 0x0000000000000000 + Address: 0x0000000000000000 + Other: 0x0000000000000000 + ImportName: '' + Children: + - TerminalSize: 2 + NodeOffset: 38 + Name: _mh_execute_header + Flags: 0x0000000000000000 + Address: 0x0000000000000000 + Other: 0x0000000000000000 + ImportName: '' + - TerminalSize: 3 + NodeOffset: 42 + Name: main + Flags: 0x0000000000000000 + Address: 0x0000000000000F90 + Other: 0x0000000000000000 + ImportName: '' + - TerminalSize: 3 + NodeOffset: 47 + Name: foo + Flags: 0x0000000000000000 + Address: 0x0000000000001004 + Other: 0x0000000000000000 + ImportName: '' + NameList: + - n_strx: 50 + n_type: 0x64 + n_sect: 0 + n_desc: 0 + n_value: 0 + - n_strx: 92 + n_type: 0x64 + n_sect: 0 + n_desc: 0 + n_value: 0 + - n_strx: 100 + n_type: 0x66 + n_sect: 3 + n_desc: 1 + n_value: 1564714240 + - n_strx: 1 + n_type: 0x2E + n_sect: 1 + n_desc: 0 + n_value: 4294971280 + - n_strx: 164 + n_type: 0x24 + n_sect: 1 + n_desc: 0 + n_value: 4294971280 + - n_strx: 1 + n_type: 0x24 + n_sect: 0 + n_desc: 0 + n_value: 36 + - n_strx: 1 + n_type: 0x4E + n_sect: 1 + n_desc: 0 + n_value: 36 + - n_strx: 170 + n_type: 0x26 + n_sect: 3 + n_desc: 0 + n_value: 4294971392 + - n_strx: 175 + n_type: 0x20 + n_sect: 0 + n_desc: 0 + n_value: 0 + - n_strx: 1 + n_type: 0x64 + n_sect: 1 + n_desc: 0 + n_value: 0 + - n_strx: 180 + n_type: 0x0E + n_sect: 3 + n_desc: 0 + n_value: 4294971392 + - n_strx: 2 + n_type: 0x0F + n_sect: 1 + n_desc: 16 + n_value: 4294967296 + - n_strx: 22 + n_type: 0x0F + n_sect: 4 + n_desc: 0 + n_value: 4294971396 + - n_strx: 27 + n_type: 0x0F + n_sect: 1 + n_desc: 0 + n_value: 4294971280 + - n_strx: 33 + n_type: 0x01 + n_sect: 0 + n_desc: 256 + n_value: 0 + StringTable: + - ' ' + - __mh_execute_header + - _foo + - _main + - dyld_stub_binder + - '/Users/anonymous/llvm-project/llvm/build/' + - strip.c + - '/var/folders/g7/l0p5czpd2jz6w0gswg6cwgjc0000gn/T/strip-95c4bf.o' + - _main + - _bar + - _foo + - _bar + - '' + - '' + - '' + - '' + - '' + - '' + - '' +... diff --git a/llvm/test/tools/llvm-objcopy/MachO/strip-all.test b/llvm/test/tools/llvm-objcopy/MachO/strip-all.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-objcopy/MachO/strip-all.test @@ -0,0 +1,43 @@ +## Show that llvm-objcopy/llvm-strip removes all symbols and debug sections. + +# RUN: yaml2obj %p/Inputs/strip-all.yaml > %t.exec +# RUN: yaml2obj %p/Inputs/strip-all-with-dwarf.yaml > %t.dwarf + +# RUN: llvm-objcopy --strip-all %t.exec %t.exec.stripped +# RUN: llvm-readobj --sections --relocations --symbols %t.exec.stripped \ +# RUN: | FileCheck --check-prefixes=COMMON,EXEC %s + +# RUN: llvm-objcopy --strip-all %t.dwarf %t.dwarf.stripped +# RUN: llvm-readobj --sections --relocations --symbols %t.dwarf.stripped \ +# RUN: | FileCheck --check-prefixes=COMMON,DWARF %s + +## The output of "llvm-strip" should be identical with that of +## "llvm-strip --strip-all" and "llvm-objcopy --strip-all". +# RUN: llvm-strip %t.exec -o %t2 +# RUN: llvm-strip --strip-all %t.exec -o %t3 +# cmp %t2 %t.exec.stripped +# cmp %t3 %t.exec.stripped + +# RUN: llvm-strip %t.dwarf -o %t4 +# RUN: llvm-strip --strip-all %t.dwarf -o %t5 +# cmp %t4 %t.dwarf.stripped +# cmp %t5 %t.dwarf.stripped + +## Make sure that debug sections are removed. +# DWARF: Sections [ +# DWARF-NOT: Name: __debug_str +# DWARF-NOT: Name: __debug_abbrev +# DWARF-NOT: Name: __debug_info +# DWARF-NOT: Name: __debug_macinfo +# DWARF-NOT: Name: __apple_names +# DWARF-NOT: Name: __apple_objc +# DWARF-NOT: Name: __apple_namespac +# DWARF-NOT: Name: __apple_types +# DWARF-NOT: Name: __debug_line +# DWARF: ] + +## Make sure that all relocations and symbols are removed. +# COMMON: Relocations [ +# COMMON-NEXT: ] +# COMMON: Symbols [ +# COMMON-NEXT: ] 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,16 @@ static void removeSections(const CopyConfig &Config, Object &Obj) { SectionPred RemovePred = [](const Section &) { return false; }; + if (Config.StripAll) { + // Remove all debug sections. + RemovePred = [RemovePred](const Section &Sec) { + if (Sec.Segname == "__DWARF") + return true; + + return RemovePred(Sec); + }; + } + if (!Config.OnlySection.empty()) { RemovePred = [&Config, RemovePred](const Section &Sec) { return !is_contained(Config.OnlySection, Sec.CannonicalName); @@ -32,6 +42,23 @@ return Obj.removeSections(RemovePred); } +static void markSymbols(const CopyConfig &Config, Object &Obj) { + // Symbols referenced from the indirect symbol table must not be removed. + for (IndirectSymbolEntry &ISE : Obj.IndirectSymTable.Symbols) + if (ISE.Symbol) + (*ISE.Symbol)->Referenced = true; +} + +static void removeSymbols(const CopyConfig &Config, Object &Obj) { + auto RemovePred = [Config](const std::unique_ptr &N) { + if (N->Referenced) + return false; + return Config.StripAll; + }; + + Obj.SymTable.removeSymbols(RemovePred); +} + static Error validateOptions(const CopyConfig &Config) { // TODO: Support section renaming in GNU objcopy for compatibility (see // http://lists.llvm.org/pipermail/llvm-dev/2019-May/132570.html). @@ -58,11 +85,12 @@ !Config.UnneededSymbolsToRemove.empty() || !Config.SetSectionFlags.empty() || !Config.ToRemove.empty() || Config.ExtractDWO || Config.KeepFileSymbols || Config.LocalizeHidden || - Config.PreserveDates || 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.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"); } @@ -71,6 +99,18 @@ return E; removeSections(Config, Obj); + + // Mark symbols to determine which symbols are still needed. + if (Config.StripAll) + markSymbols(Config, Obj); + + removeSymbols(Config, Obj); + + if (Config.StripAll) + for (LoadCommand &LC : Obj.LoadCommands) + for (Section &Sec : LC.Sections) + Sec.Relocations.clear(); + return Error::success(); } diff --git a/llvm/tools/llvm-objcopy/MachO/Object.h b/llvm/tools/llvm-objcopy/MachO/Object.h --- a/llvm/tools/llvm-objcopy/MachO/Object.h +++ b/llvm/tools/llvm-objcopy/MachO/Object.h @@ -87,6 +87,7 @@ // nlist. struct SymbolEntry { std::string Name; + bool Referenced = false; uint32_t Index; uint8_t n_type; uint8_t n_sect; @@ -110,16 +111,19 @@ std::vector> Symbols; const SymbolEntry *getSymbolByIndex(uint32_t Index) const; + SymbolEntry *getSymbolByIndex(uint32_t Index); + void removeSymbols( + function_ref &)> ToRemove); }; struct IndirectSymbolEntry { uint32_t OriginalIndex; /// The Symbol referenced by this entry. It's None if the index is /// INDIRECT_SYMBOL_LOCAL or INDIRECT_SYMBOL_ABS. - Optional Symbol; + Optional Symbol; IndirectSymbolEntry(uint32_t OriginalIndex, - Optional Symbol) + Optional Symbol) : OriginalIndex(OriginalIndex), Symbol(Symbol) {} }; diff --git a/llvm/tools/llvm-objcopy/MachO/Object.cpp b/llvm/tools/llvm-objcopy/MachO/Object.cpp --- a/llvm/tools/llvm-objcopy/MachO/Object.cpp +++ b/llvm/tools/llvm-objcopy/MachO/Object.cpp @@ -10,6 +10,18 @@ return Symbols[Index].get(); } +SymbolEntry *SymbolTable::getSymbolByIndex(uint32_t Index) { + return const_cast( + static_cast(this)->getSymbolByIndex(Index)); +} + +void SymbolTable::removeSymbols( + function_ref &)> ToRemove) { + Symbols.erase( + std::remove_if(std::begin(Symbols), std::end(Symbols), ToRemove), + std::end(Symbols)); +} + void Object::removeSections(function_ref ToRemove) { for (LoadCommand &LC : LoadCommands) LC.Sections.erase(std::remove_if(std::begin(LC.Sections),