[llvm] 842a8cc - [llvm-objcopy][MachO] Add support for removing Swift symbols

Alexander Shaposhnikov via llvm-commits llvm-commits at lists.llvm.org
Tue May 26 16:52:12 PDT 2020


Author: Alexander Shaposhnikov
Date: 2020-05-26T16:49:56-07:00
New Revision: 842a8cc10c4146cee6cedd94fbf556c94b8ec365

URL: https://github.com/llvm/llvm-project/commit/842a8cc10c4146cee6cedd94fbf556c94b8ec365
DIFF: https://github.com/llvm/llvm-project/commit/842a8cc10c4146cee6cedd94fbf556c94b8ec365.diff

LOG: [llvm-objcopy][MachO] Add support for removing Swift symbols

cctools strip has the option "-T" which removes Swift symbols.
This diff implements this option in llvm-strip for MachO.

Test plan: make check-all

Differential revision: https://reviews.llvm.org/D80099

Added: 
    llvm/test/tools/llvm-objcopy/MachO/remove-swift-symbols.test

Modified: 
    llvm/docs/CommandGuide/llvm-strip.rst
    llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
    llvm/tools/llvm-objcopy/CopyConfig.cpp
    llvm/tools/llvm-objcopy/CopyConfig.h
    llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
    llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp
    llvm/tools/llvm-objcopy/MachO/MachOReader.cpp
    llvm/tools/llvm-objcopy/MachO/MachOReader.h
    llvm/tools/llvm-objcopy/MachO/Object.h
    llvm/tools/llvm-objcopy/StripOpts.td

Removed: 
    


################################################################################
diff  --git a/llvm/docs/CommandGuide/llvm-strip.rst b/llvm/docs/CommandGuide/llvm-strip.rst
index 455dc07e9c5c..a40537bd51c1 100644
--- a/llvm/docs/CommandGuide/llvm-strip.rst
+++ b/llvm/docs/CommandGuide/llvm-strip.rst
@@ -181,6 +181,10 @@ them.
  segments. Note that many tools will not be able to use an object without
  section headers.
 
+.. option:: -T
+
+ Remove Swift symbols.
+
 EXIT STATUS
 -----------
 

diff  --git a/llvm/test/tools/llvm-objcopy/MachO/remove-swift-symbols.test b/llvm/test/tools/llvm-objcopy/MachO/remove-swift-symbols.test
new file mode 100644
index 000000000000..a47a2dfb9f37
--- /dev/null
+++ b/llvm/test/tools/llvm-objcopy/MachO/remove-swift-symbols.test
@@ -0,0 +1,221 @@
+## Verify that -T removes Swift symbols.
+# RUN: yaml2obj -D FLAGS=0x00200085 -D SEGMENT_NAME=__DATA \
+# RUN:  -D SECTION_NAME=__objc_imageinfo -D SECTION_SIZE=8 \
+# RUN:  -D SECTION_CONTENT=0000000040070105 %s -o %t1
+# RUN: llvm-strip -x -T %t1
+# RUN: llvm-readobj -symbols %t1 | FileCheck --check-prefix=NO-SWIFT-SYMBOLS %s
+
+# RUN: yaml2obj -D FLAGS=0x00200085 -D SEGMENT_NAME=__DATA_CONST \
+# RUN:  -D SECTION_NAME=__objc_imageinfo -D SECTION_SIZE=8 \
+# RUN:  -D SECTION_CONTENT=0000000040070105 %s -o %t2
+# RUN: llvm-strip -x -T %t2
+# RUN: llvm-readobj -symbols %t2 | FileCheck --check-prefix=NO-SWIFT-SYMBOLS %s
+
+# RUN: yaml2obj -D FLAGS=0x00200085 -D SEGMENT_NAME=__DATA_DIRTY \
+# RUN:  -D SECTION_NAME=__objc_imageinfo -D SECTION_SIZE=8 \
+# RUN:  -D SECTION_CONTENT=0000000040070105 %s -o %t3
+# RUN: llvm-strip -x -T %t3
+# RUN: llvm-readobj -symbols %t3 | FileCheck --check-prefix=NO-SWIFT-SYMBOLS %s
+
+# NO-SWIFT-SYMBOLS:      Symbols [
+# NO-SWIFT-SYMBOLS-NEXT:  Symbol {
+# NO-SWIFT-SYMBOLS-NEXT:    Name: _main (1)
+# NO-SWIFT-SYMBOLS-NEXT:    Extern
+# NO-SWIFT-SYMBOLS-NEXT:    Type: Section (0xE)
+# NO-SWIFT-SYMBOLS-NEXT:    Section: __text (0x1)
+# NO-SWIFT-SYMBOLS-NEXT:    RefType: UndefinedNonLazy (0x0)
+# NO-SWIFT-SYMBOLS-NEXT:    Flags [ (0x0)
+# NO-SWIFT-SYMBOLS-NEXT:    ]
+# NO-SWIFT-SYMBOLS-NEXT:    Value: 0x100000B70
+# NO-SWIFT-SYMBOLS-NEXT:  }
+# NO-SWIFT-SYMBOLS-NEXT: ]
+
+## Verify that -T does not remove (public) Swift symbols when the binary
+## does not contain __objc_imageinfo in one of the expected segments.
+
+# RUN: yaml2obj -D FLAGS=0x00200085 -D SEGMENT_NAME=__DATA \
+# RUN:  -D SECTION_NAME=__not_objc_imageinfo -D SECTION_SIZE=8 \
+# RUN:  -D SECTION_CONTENT=0000000040070105 %s -o %t4
+# RUN: llvm-strip -x -T %t4
+# RUN: llvm-readobj -symbols %t4 | FileCheck --check-prefix=SWIFT-SYMBOLS %s
+
+# RUN: yaml2obj -D FLAGS=0x00200085 -D SEGMENT_NAME=__NOT_DATA \
+# RUN:  -D SECTION_NAME=__objc_imageinfo -D SECTION_SIZE=8 \
+# RUN:  -D SECTION_CONTENT=0000000040070105 %s -o %t5
+# RUN: llvm-strip -x -T %t5
+# RUN: llvm-readobj -symbols %t5 | FileCheck --check-prefix=SWIFT-SYMBOLS %s
+
+## Verify that -T does not remove (public) Swift symbols when swift_version is zero.
+
+# RUN: yaml2obj -D FLAGS=0x00200085 -D SEGMENT_NAME=__DATA \
+# RUN:  -D SECTION_NAME=__objc_imageinfo -D SECTION_SIZE=8 \
+# RUN:  -D SECTION_CONTENT=0000000000000000 %s -o %t6
+# RUN: llvm-strip -x -T %t6
+# RUN: llvm-readobj -symbols %t6 | FileCheck --check-prefix=SWIFT-SYMBOLS %s
+
+## Verify that -T does not remove (public) Swift symbols when the binary
+## contains invalid (too small) __objc_imageinfo.
+
+# RUN: yaml2obj -D FLAGS=0x00200085 -D SEGMENT_NAME=__DATA \
+# RUN:  -D SECTION_NAME=__objc_imageinfo -D SECTION_SIZE=4 \
+# RUN:  -D SECTION_CONTENT=00000000 %s -o %t7
+# RUN: llvm-strip -x -T %t7
+# RUN: llvm-readobj -symbols %t7 | FileCheck --check-prefix=SWIFT-SYMBOLS %s
+
+## Verify that -T does not remove (public) Swift symbols
+## when the flag MH_DYLDLINK is not set.
+
+# RUN: yaml2obj -D FLAGS=0x00200000 -D SEGMENT_NAME=__DATA \
+# RUN:  -D SECTION_NAME=__objc_imageinfo -D SECTION_SIZE=8 \
+# RUN:  -D SECTION_CONTENT=0000000040070105 %s -o %t8
+# RUN: llvm-strip -x -T %t8
+# RUN: llvm-readobj -symbols %t8 | FileCheck --check-prefix=SWIFT-SYMBOLS %s
+
+# SWIFT-SYMBOLS:      Symbols [
+# SWIFT-SYMBOLS-NEXT:  Symbol {
+# SWIFT-SYMBOLS-NEXT:    Name: _$S1a13PublicSymbol1Sivp (26)
+# SWIFT-SYMBOLS-NEXT:    Extern
+# SWIFT-SYMBOLS-NEXT:    Type: Section (0xE)
+# SWIFT-SYMBOLS-NEXT:    Section: __text (0x1)
+# SWIFT-SYMBOLS-NEXT:    RefType: UndefinedNonLazy (0x0)
+# SWIFT-SYMBOLS-NEXT:    Flags [ (0x0)
+# SWIFT-SYMBOLS-NEXT:    ]
+# SWIFT-SYMBOLS-NEXT:    Value: 0x100001160
+# SWIFT-SYMBOLS-NEXT:  }
+# SWIFT-SYMBOLS-NEXT:  Symbol {
+# SWIFT-SYMBOLS-NEXT:    Name: _$s1a13PublicSymbol2Sivp (1)
+# SWIFT-SYMBOLS-NEXT:    Extern
+# SWIFT-SYMBOLS-NEXT:    Type: Section (0xE)
+# SWIFT-SYMBOLS-NEXT:    Section: __text (0x1)
+# SWIFT-SYMBOLS-NEXT:    RefType: UndefinedNonLazy (0x0)
+# SWIFT-SYMBOLS-NEXT:    Flags [ (0x0)
+# SWIFT-SYMBOLS-NEXT:    ]
+# SWIFT-SYMBOLS-NEXT:    Value: 0x100001168
+# SWIFT-SYMBOLS-NEXT:  }
+# SWIFT-SYMBOLS-NEXT:  Symbol {
+# SWIFT-SYMBOLS-NEXT:    Name: _main (51)
+# SWIFT-SYMBOLS-NEXT:    Extern
+# SWIFT-SYMBOLS-NEXT:    Type: Section (0xE)
+# SWIFT-SYMBOLS-NEXT:    Section: __text (0x1)
+# SWIFT-SYMBOLS-NEXT:    RefType: UndefinedNonLazy (0x0)
+# SWIFT-SYMBOLS-NEXT:    Flags [ (0x0)
+# SWIFT-SYMBOLS-NEXT:    ]
+# SWIFT-SYMBOLS-NEXT:    Value: 0x100000B70
+# SWIFT-SYMBOLS-NEXT:  }
+# SWIFT-SYMBOLS-NEXT: ]
+
+--- !mach-o
+FileHeader:
+  magic:           0xFEEDFACF
+  cputype:         0x01000007
+  cpusubtype:      0x80000003
+  filetype:        0x00000002
+  ncmds:           4
+  sizeofcmds:      400
+  flags:           [[FLAGS]]
+  reserved:        0x00000000
+LoadCommands:
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         152
+    segname:         __TEXT
+    vmaddr:          4294967296
+    vmsize:          4096
+    fileoff:         0
+    filesize:        4096
+    maxprot:         5
+    initprot:        5
+    nsects:          1
+    flags:           0
+    Sections:
+      - sectname:        __text
+        segname:         __TEXT
+        addr:            0x0000000100000B70
+        size:            845
+        offset:          0x00000B70
+        align:           4
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x80000400
+        reserved1:       0x00000000
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         152
+    segname:         [[SEGMENT_NAME]]
+    vmaddr:          4294971392
+    vmsize:          4096
+    fileoff:         4096
+    filesize:        4096
+    maxprot:         3
+    initprot:        3
+    nsects:          1
+    flags:           0
+    Sections:
+      - sectname:        [[SECTION_NAME]]
+        segname:         [[SEGMENT_NAME]]
+        addr:            0x0000000100001090
+        size:            [[SECTION_SIZE]]
+        offset:          0x00001090
+        align:           2
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x00000000
+        reserved1:       0x00000000
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+        content:         "[[SECTION_CONTENT]]"
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         72
+    segname:         __LINKEDIT
+    vmaddr:          4294975488
+    vmsize:          4096
+    fileoff:         8192
+    filesize:        188
+    maxprot:         1
+    initprot:        1
+    nsects:          0
+    flags:           0
+  - cmd:             LC_SYMTAB
+    cmdsize:         24
+    symoff:          8192
+    nsyms:           5
+    stroff:          8272
+    strsize:         108
+LinkEditData:
+  NameList:
+    - n_strx:          50
+      n_type:          0x1E
+      n_sect:          1
+      n_desc:          0
+      n_value:         4294971760
+    - n_strx:          1
+      n_type:          0x1E
+      n_sect:          1
+      n_desc:          0
+      n_value:         4294971768
+    - n_strx:          74
+      n_type:          0x0F
+      n_sect:          1
+      n_desc:          0
+      n_value:         4294971744
+    - n_strx:          25
+      n_type:          0x0F
+      n_sect:          1
+      n_desc:          0
+      n_value:         4294971752
+    - n_strx:          99
+      n_type:          0x0F
+      n_sect:          1
+      n_desc:          0
+      n_value:         4294970224
+  StringTable:
+    - ''
+    - '_$s1a12LocalSymbol2Sivp'
+    - '_$s1a13PublicSymbol2Sivp'
+    - '_$S1a12LocalSymbol1Sivp'
+    - '_$S1a13PublicSymbol1Sivp'
+    - _main
+    - ''
+    - ''
+    - ''
+...

diff  --git a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
index 2e363f26eacc..43ec2b1fa82f 100644
--- a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
+++ b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
@@ -251,7 +251,8 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) {
       !Config.SymbolsToKeepGlobal.empty() || !Config.SectionsToRename.empty() ||
       !Config.SetSectionAlignment.empty() || Config.ExtractDWO ||
       Config.LocalizeHidden || Config.PreserveDates || Config.StripDWO ||
-      Config.StripNonAlloc || Config.StripSections || Config.Weaken ||
+      Config.StripNonAlloc || Config.StripSections ||
+      Config.StripSwiftSymbols || Config.Weaken ||
       Config.DecompressDebugSections ||
       Config.DiscardMode == DiscardType::Locals ||
       !Config.SymbolsToAdd.empty() || Config.EntryExpr) {

diff  --git a/llvm/tools/llvm-objcopy/CopyConfig.cpp b/llvm/tools/llvm-objcopy/CopyConfig.cpp
index ff12e4bd89f3..1e151f01e01e 100644
--- a/llvm/tools/llvm-objcopy/CopyConfig.cpp
+++ b/llvm/tools/llvm-objcopy/CopyConfig.cpp
@@ -912,6 +912,7 @@ parseStripOptions(ArrayRef<const char *> ArgsArr,
   if (auto Arg = InputArgs.getLastArg(STRIP_strip_all, STRIP_no_strip_all))
     Config.StripAll = Arg->getOption().getID() == STRIP_strip_all;
   Config.StripAllGNU = InputArgs.hasArg(STRIP_strip_all_gnu);
+  Config.StripSwiftSymbols = InputArgs.hasArg(STRIP_strip_swift_symbols);
   Config.OnlyKeepDebug = InputArgs.hasArg(STRIP_only_keep_debug);
   Config.KeepFileSymbols = InputArgs.hasArg(STRIP_keep_file_symbols);
 

diff  --git a/llvm/tools/llvm-objcopy/CopyConfig.h b/llvm/tools/llvm-objcopy/CopyConfig.h
index be1dca46b968..acf783c7f278 100644
--- a/llvm/tools/llvm-objcopy/CopyConfig.h
+++ b/llvm/tools/llvm-objcopy/CopyConfig.h
@@ -219,6 +219,7 @@ struct CopyConfig {
   bool StripDebug = false;
   bool StripNonAlloc = false;
   bool StripSections = false;
+  bool StripSwiftSymbols = false;
   bool StripUnneeded = false;
   bool Weaken = false;
   bool DecompressDebugSections = false;

diff  --git a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp b/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
index f7332b7f66fe..8e14c887170d 100644
--- a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
+++ b/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
@@ -604,7 +604,9 @@ static Error replaceAndRemoveSections(const CopyConfig &Config, Object &Obj) {
 // system. The only priority is that keeps/copies overrule removes.
 static Error handleArgs(const CopyConfig &Config, Object &Obj,
                         const Reader &Reader, ElfType OutputElfType) {
-
+  if (Config.StripSwiftSymbols)
+    return createStringError(llvm::errc::invalid_argument,
+                             "option not supported by llvm-objcopy for ELF");
   if (!Config.SplitDWO.empty())
     if (Error E =
             splitDWOToFile(Config, Reader, Config.SplitDWO, OutputElfType))

diff  --git a/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp b/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp
index be44fdbe45f9..ae8889af8c42 100644
--- a/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp
+++ b/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp
@@ -65,13 +65,17 @@ static void updateAndRemoveSymbols(const CopyConfig &Config, Object &Obj) {
       Sym.Name = std::string(I->getValue());
   }
 
-  auto RemovePred = [Config](const std::unique_ptr<SymbolEntry> &N) {
+  auto RemovePred = [Config, &Obj](const std::unique_ptr<SymbolEntry> &N) {
     if (N->Referenced)
       return false;
     if (Config.StripAll)
       return true;
     if (Config.DiscardMode == DiscardType::All && !(N->n_type & MachO::N_EXT))
       return true;
+    // This behavior is consistent with cctools' strip.
+    if (Config.StripSwiftSymbols && (Obj.Header.Flags & MachO::MH_DYLDLINK) &&
+        Obj.SwiftVersion && *Obj.SwiftVersion && N->isSwiftSymbol())
+      return true;
     return false;
   };
 

diff  --git a/llvm/tools/llvm-objcopy/MachO/MachOReader.cpp b/llvm/tools/llvm-objcopy/MachO/MachOReader.cpp
index cf32f00f3615..39a8893c1eb1 100644
--- a/llvm/tools/llvm-objcopy/MachO/MachOReader.cpp
+++ b/llvm/tools/llvm-objcopy/MachO/MachOReader.cpp
@@ -283,6 +283,28 @@ void MachOReader::readIndirectSymbolTable(Object &O) const {
   }
 }
 
+void MachOReader::readSwiftVersion(Object &O) const {
+  struct ObjCImageInfo {
+    uint32_t Version;
+    uint32_t Flags;
+  } ImageInfo;
+
+  for (const LoadCommand &LC : O.LoadCommands)
+    for (const std::unique_ptr<Section> &Sec : LC.Sections)
+      if (Sec->Sectname == "__objc_imageinfo" &&
+          (Sec->Segname == "__DATA" || Sec->Segname == "__DATA_CONST" ||
+           Sec->Segname == "__DATA_DIRTY") &&
+          Sec->Content.size() >= sizeof(ObjCImageInfo)) {
+        memcpy(&ImageInfo, Sec->Content.data(), sizeof(ObjCImageInfo));
+        if (MachOObj.isLittleEndian() != sys::IsLittleEndianHost) {
+          sys::swapByteOrder(ImageInfo.Version);
+          sys::swapByteOrder(ImageInfo.Flags);
+        }
+        O.SwiftVersion = (ImageInfo.Flags >> 8) & 0xff;
+        return;
+      }
+}
+
 std::unique_ptr<Object> MachOReader::create() const {
   auto Obj = std::make_unique<Object>();
   readHeader(*Obj);
@@ -297,6 +319,7 @@ std::unique_ptr<Object> MachOReader::create() const {
   readDataInCodeData(*Obj);
   readFunctionStartsData(*Obj);
   readIndirectSymbolTable(*Obj);
+  readSwiftVersion(*Obj);
   return Obj;
 }
 

diff  --git a/llvm/tools/llvm-objcopy/MachO/MachOReader.h b/llvm/tools/llvm-objcopy/MachO/MachOReader.h
index 00c8f0d55f61..a369907147d6 100644
--- a/llvm/tools/llvm-objcopy/MachO/MachOReader.h
+++ b/llvm/tools/llvm-objcopy/MachO/MachOReader.h
@@ -39,6 +39,7 @@ class MachOReader : public Reader {
   void readDataInCodeData(Object &O) const;
   void readFunctionStartsData(Object &O) const;
   void readIndirectSymbolTable(Object &O) const;
+  void readSwiftVersion(Object &O) const;
 
 public:
   explicit MachOReader(const object::MachOObjectFile &Obj) : MachOObj(Obj) {}

diff  --git a/llvm/tools/llvm-objcopy/MachO/Object.h b/llvm/tools/llvm-objcopy/MachO/Object.h
index b0123732f80a..b9ecd1e7818f 100644
--- a/llvm/tools/llvm-objcopy/MachO/Object.h
+++ b/llvm/tools/llvm-objcopy/MachO/Object.h
@@ -115,6 +115,11 @@ struct SymbolEntry {
     return (n_type & MachO::N_TYPE) == MachO::N_UNDF;
   }
 
+  bool isSwiftSymbol() const {
+    return StringRef(Name).startswith("_$s") ||
+           StringRef(Name).startswith("_$S");
+  }
+
   Optional<uint32_t> section() const {
     return n_sect == MachO::NO_SECT ? None : Optional<uint32_t>(n_sect);
   }
@@ -298,6 +303,8 @@ struct Object {
   LinkData DataInCode;
   LinkData FunctionStarts;
 
+  Optional<uint32_t> SwiftVersion;
+
   /// The index of LC_SYMTAB load command if present.
   Optional<size_t> SymTabCommandIndex;
   /// The index of LC_DYLD_INFO or LC_DYLD_INFO_ONLY load command if present.

diff  --git a/llvm/tools/llvm-objcopy/StripOpts.td b/llvm/tools/llvm-objcopy/StripOpts.td
index cd02cffae673..001da23528d7 100644
--- a/llvm/tools/llvm-objcopy/StripOpts.td
+++ b/llvm/tools/llvm-objcopy/StripOpts.td
@@ -15,3 +15,6 @@ def d : Flag<["-"], "d">,
 def S : Flag<["-"], "S">,
         Alias<strip_debug>,
         HelpText<"Alias for --strip-debug">;
+
+def strip_swift_symbols : Flag<["-"], "T">,
+                          HelpText<"Remove Swift symbols">;


        


More information about the llvm-commits mailing list