[llvm] ede56e5 - [llvm-objcopy][MachO] Add support for --keep-undefined

Alexander Shaposhnikov via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 8 18:57:59 PST 2021


Author: Alexander Shaposhnikov
Date: 2021-03-08T18:57:25-08:00
New Revision: ede56e5127c9bd88b870f3300a4af6526c0dca86

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

LOG: [llvm-objcopy][MachO] Add support for --keep-undefined

This diff introduces --keep-undefined in llvm-objcopy/llvm-strip for Mach-O
which makes the tools preserve undefined symbols.

Test plan: make check-all

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

Added: 
    llvm/test/tools/llvm-objcopy/MachO/keep-undefined.test

Modified: 
    llvm/docs/CommandGuide/llvm-objcopy.rst
    llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
    llvm/tools/llvm-objcopy/CommonOpts.td
    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

Removed: 
    


################################################################################
diff  --git a/llvm/docs/CommandGuide/llvm-objcopy.rst b/llvm/docs/CommandGuide/llvm-objcopy.rst
index d4e05df03ee0..f50d338ae525 100644
--- a/llvm/docs/CommandGuide/llvm-objcopy.rst
+++ b/llvm/docs/CommandGuide/llvm-objcopy.rst
@@ -470,6 +470,13 @@ them.
 
  Mark all defined global symbols as weak in the output.
 
+MACH-O-SPECIFIC OPTIONS
+--------------------
+
+.. option:: --keep-undefined
+
+ Keep undefined symbols, even if they would otherwise be stripped.
+
 SUPPORTED FORMATS
 -----------------
 

diff  --git a/llvm/test/tools/llvm-objcopy/MachO/keep-undefined.test b/llvm/test/tools/llvm-objcopy/MachO/keep-undefined.test
new file mode 100644
index 000000000000..070797adcbf4
--- /dev/null
+++ b/llvm/test/tools/llvm-objcopy/MachO/keep-undefined.test
@@ -0,0 +1,105 @@
+## This test verifies that llvm-objcopy and llvm-strip do not remove
+## undefined symbols if --keep-undefined is specified.
+
+# RUN: yaml2obj %s -o %t
+# RUN: llvm-objcopy --strip-all --keep-undefined %t %t.stripped
+# RUN: llvm-readobj --symbols %t.stripped | FileCheck %s
+
+# RUN: llvm-strip --keep-undefined %t -o %t.stripped.2
+# RUN: cmp %t.stripped %t.stripped.2
+
+# CHECK:       Symbols [
+# CHECK-NEXT:    Symbol {
+# CHECK-NEXT:      Name: _u (1)
+# CHECK-NEXT:      Extern
+# CHECK-NEXT:      Type: Undef (0x0)
+# CHECK-NEXT:      Section:  (0x0)
+# CHECK-NEXT:      RefType: UndefinedNonLazy (0x0)
+# CHECK-NEXT:      Flags [ (0x220)
+# CHECK-NEXT:        AltEntry (0x200)
+# CHECK-NEXT:        NoDeadStrip (0x20)
+# CHECK-NEXT:      ]
+# CHECK-NEXT:      Value: 0x4
+# CHECK-NEXT:    }
+# CHECK-NEXT:  ]
+
+--- !mach-o
+FileHeader:
+  magic:           0xFEEDFACF
+  cputype:         0x1000007
+  cpusubtype:      0x3
+  filetype:        0x1
+  ncmds:           3
+  sizeofcmds:      256
+  flags:           0x2000
+  reserved:        0x0
+LoadCommands:
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         152
+    segname:         ''
+    vmaddr:          0
+    vmsize:          0
+    fileoff:         288
+    filesize:        0
+    maxprot:         7
+    initprot:        7
+    nsects:          1
+    flags:           0
+    Sections:
+      - sectname:        __text
+        segname:         __TEXT
+        addr:            0x0
+        size:            0
+        offset:          0x120
+        align:           0
+        reloff:          0x0
+        nreloc:          0
+        flags:           0x80000000
+        reserved1:       0x0
+        reserved2:       0x0
+        reserved3:       0x0
+        content:         ''
+  - cmd:             LC_SYMTAB
+    cmdsize:         24
+    symoff:          288
+    nsyms:           2
+    stroff:          320
+    strsize:         8
+  - cmd:             LC_DYSYMTAB
+    cmdsize:         80
+    ilocalsym:       0
+    nlocalsym:       1
+    iextdefsym:      1
+    nextdefsym:      0
+    iundefsym:       1
+    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:          4
+      n_type:          0xE
+      n_sect:          1
+      n_desc:          32
+      n_value:         0
+    - n_strx:          1
+      n_type:          0x1
+      n_sect:          0
+      n_desc:          544
+      n_value:         4
+  StringTable:
+    - ''
+    - _u
+    - _d
+    - ''
+...

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

diff  --git a/llvm/tools/llvm-objcopy/CommonOpts.td b/llvm/tools/llvm-objcopy/CommonOpts.td
index 0661b6b0f2d9..4222532a1a38 100644
--- a/llvm/tools/llvm-objcopy/CommonOpts.td
+++ b/llvm/tools/llvm-objcopy/CommonOpts.td
@@ -84,6 +84,9 @@ def K : JoinedOrSeparate<["-"], "K">,
 def keep_file_symbols : Flag<["--"], "keep-file-symbols">,
                         HelpText<"Do not remove file symbols">;
 
+def keep_undefined : Flag<["--"], "keep-undefined">,
+                        HelpText<"Do not remove undefined symbols">;
+
 def only_keep_debug
     : Flag<["--"], "only-keep-debug">,
       HelpText<

diff  --git a/llvm/tools/llvm-objcopy/CopyConfig.cpp b/llvm/tools/llvm-objcopy/CopyConfig.cpp
index d006c9ac93f7..569238a977e4 100644
--- a/llvm/tools/llvm-objcopy/CopyConfig.cpp
+++ b/llvm/tools/llvm-objcopy/CopyConfig.cpp
@@ -720,6 +720,7 @@ parseObjcopyOptions(ArrayRef<const char *> ArgsArr,
             : DiscardType::Locals;
   Config.OnlyKeepDebug = InputArgs.hasArg(OBJCOPY_only_keep_debug);
   Config.KeepFileSymbols = InputArgs.hasArg(OBJCOPY_keep_file_symbols);
+  Config.KeepUndefined = InputArgs.hasArg(OBJCOPY_keep_undefined);
   Config.DecompressDebugSections =
       InputArgs.hasArg(OBJCOPY_decompress_debug_sections);
   if (Config.DiscardMode == DiscardType::All) {
@@ -1097,6 +1098,7 @@ parseStripOptions(ArrayRef<const char *> ArgsArr,
   Config.StripSwiftSymbols = InputArgs.hasArg(STRIP_strip_swift_symbols);
   Config.OnlyKeepDebug = InputArgs.hasArg(STRIP_only_keep_debug);
   Config.KeepFileSymbols = InputArgs.hasArg(STRIP_keep_file_symbols);
+  Config.KeepUndefined = InputArgs.hasArg(STRIP_keep_undefined);
 
   for (auto Arg : InputArgs.filtered(STRIP_keep_section))
     if (Error E = Config.KeepSection.addMatcher(NameOrPattern::create(

diff  --git a/llvm/tools/llvm-objcopy/CopyConfig.h b/llvm/tools/llvm-objcopy/CopyConfig.h
index bc996cb6aea0..1b99e24137dd 100644
--- a/llvm/tools/llvm-objcopy/CopyConfig.h
+++ b/llvm/tools/llvm-objcopy/CopyConfig.h
@@ -215,6 +215,7 @@ struct CopyConfig {
   bool ExtractDWO = false;
   bool ExtractMainPartition = false;
   bool KeepFileSymbols = false;
+  bool KeepUndefined = false;
   bool LocalizeHidden = false;
   bool OnlyKeepDebug = false;
   bool PreserveDates = false;

diff  --git a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp b/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
index a05b1d44cae4..63c837d391a2 100644
--- a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
+++ b/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
@@ -532,7 +532,7 @@ 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)
+  if (Config.StripSwiftSymbols || Config.KeepUndefined)
     return createStringError(llvm::errc::invalid_argument,
                              "option not supported by llvm-objcopy for ELF");
   if (!Config.SplitDWO.empty())

diff  --git a/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp b/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp
index 1cda7bfb1b7a..45f5b372f95c 100644
--- a/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp
+++ b/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp
@@ -94,6 +94,8 @@ static void updateAndRemoveSymbols(const CopyConfig &Config, Object &Obj) {
   auto RemovePred = [Config, &Obj](const std::unique_ptr<SymbolEntry> &N) {
     if (N->Referenced)
       return false;
+    if (Config.KeepUndefined && N->isUndefinedSymbol())
+      return false;
     if (Config.StripAll)
       return true;
     if (Config.DiscardMode == DiscardType::All && !(N->n_type & MachO::N_EXT))


        


More information about the llvm-commits mailing list