[llvm] r340105 - [llvm-objcopy] Implement -G/--keep-global-symbol(s).

Jordan Rupprecht via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 17 15:34:48 PDT 2018


Author: rupprecht
Date: Fri Aug 17 15:34:48 2018
New Revision: 340105

URL: http://llvm.org/viewvc/llvm-project?rev=340105&view=rev
Log:
[llvm-objcopy] Implement -G/--keep-global-symbol(s).

Summary:
Port GNU Objcopy -G/--keep-global-symbol(s).

This is slightly different than the already-implemented --globalize-symbol, which marks a symbol as global when copying. When --keep-global-symbol (alias -G) is used, *only* those symbols marked will stay global, and all other globals are demoted to local. (Also note that it doesn't *promote* a symbol to global). Additionally, there is a pluralized version of the flag --keep-global-symbols, which effectively applies --keep-global-symbol for every non-comment in a file.

Reviewers: jakehehrlich, jhenderson, alexshap

Reviewed By: jhenderson

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D50589

Added:
    llvm/trunk/test/tools/llvm-objcopy/keep-global-symbols-mix-globalize.test
    llvm/trunk/test/tools/llvm-objcopy/keep-global-symbols.test
Modified:
    llvm/trunk/tools/llvm-objcopy/ObjcopyOpts.td
    llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp

Added: llvm/trunk/test/tools/llvm-objcopy/keep-global-symbols-mix-globalize.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/keep-global-symbols-mix-globalize.test?rev=340105&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/keep-global-symbols-mix-globalize.test (added)
+++ llvm/trunk/test/tools/llvm-objcopy/keep-global-symbols-mix-globalize.test Fri Aug 17 15:34:48 2018
@@ -0,0 +1,51 @@
+# RUN: yaml2obj %s > %t.o
+
+# Tests --keep-global-symbol when used in combination with --globalize-symbol on
+# a different symbol.
+
+# RUN: llvm-objcopy \
+# RUN:   --globalize-symbol Local1 \
+# RUN:   --keep-global-symbol Local2 \
+# RUN:   --globalize-symbol Weak1 \
+# RUN:   --keep-global-symbol Weak2 \
+# RUN:   --globalize-symbol Global1 \
+# RUN:   --keep-global-symbol Global2 \
+# RUN:   %t.o %t.2.o
+# RUN: llvm-readobj -elf-output-style=GNU -symbols %t.2.o | FileCheck %s
+
+!ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_X86_64
+Sections:
+  - Name:          .text
+    Type:          SHT_PROGBITS
+    Flags:         [ SHF_ALLOC, SHF_EXECINSTR ]
+Symbols:
+  Local:
+    - Name:        Local1
+      Section:     .text
+    - Name:        Local2
+      Section:     .text
+  Weak:
+    - Name:        Weak1
+      Section:     .text
+    - Name:        Weak2
+      Section:     .text
+  Global:
+    - Name:        Global1
+      Section:     .text
+    - Name:        Global2
+      Section:     .text
+
+# CHECK:      Symbol table '.symtab' contains 7 entries:
+# CHECK-NEXT:    Num: Value Size Type Bind Vis Ndx Name
+# CHECK-NEXT:      0: {{.*}}  LOCAL  {{.*}}
+# CHECK-NEXT:      1: {{.*}}  LOCAL  {{.*}} Local2
+# CHECK-NEXT:      2: {{.*}}  GLOBAL {{.*}} Local1
+# CHECK-NEXT:      3: {{.*}}  GLOBAL {{.*}} Global1
+# CHECK-NEXT:      4: {{.*}}  GLOBAL {{.*}} Global2
+# CHECK-NEXT:      5: {{.*}}  GLOBAL {{.*}} Weak1
+# CHECK-NEXT:      6: {{.*}}  WEAK   {{.*}} Weak2

Added: llvm/trunk/test/tools/llvm-objcopy/keep-global-symbols.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/keep-global-symbols.test?rev=340105&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/keep-global-symbols.test (added)
+++ llvm/trunk/test/tools/llvm-objcopy/keep-global-symbols.test Fri Aug 17 15:34:48 2018
@@ -0,0 +1,95 @@
+# RUN: yaml2obj %s > %t.o
+
+# Tests that only global symbols (via -G/--keep-global-symbols) are kept via
+# the several different variants of -G/--keep-global-symbol(s).
+#
+# Local1: Local because "-G Local1" doesn't make symbols global.
+# Local2: Global because of "--globalize-symbol Local2".
+# Weak1: Weak because "-G Weak1" doesn't make symbols global.
+# Weak2: Global because of "--globalize-symbol Weak2".
+# Weak3: Local because no -G flag covers it.
+# Global1: Global because of "-G Global1".
+# Global2: Global because of "--keep-global-symbol Global2".
+# Global3: Global because of "--keep-global-symbols %t-globals1.txt".
+# Global4: Global because of "--keep-global-symbols %t-globals2.txt".
+# Global5: Local, it appears in %t-globals2.txt but only in comments and as
+#     part of another symbol
+# Global6: Local, it appears in %t-globals2.txt but only part of another symbol
+# "Global5 Global6": Global, because it appears in %t-globals2.txt, but we only
+#     trim leading and trailing whitespace. We don't just take the first chunk
+#     that looks like a symbol.
+
+# RUN: echo Global2 > %t-globals1.txt
+# RUN: echo "  Global3  " > %t-globals2.txt
+# RUN: echo "Global4 # Global5" >> %t-globals2.txt
+# RUN: echo "  Global5 Global6  " >> %t-globals2.txt
+# RUN: echo "Unknown" >> %t-globals2.txt
+# RUN: echo "   " >> %t-globals2.txt
+# RUN: echo "# File with no symbols" > %t-globals3.txt
+
+# RUN: llvm-objcopy \
+# RUN:   -G Global1 \
+# RUN:   --keep-global-symbol Global2 \
+# RUN:   --keep-global-symbols %t-globals1.txt \
+# RUN:   --keep-global-symbols %t-globals2.txt \
+# RUN:   -G Local1 \
+# RUN:   --globalize-symbol Local2 \
+# RUN:   -G Weak1 \
+# RUN:   --globalize-symbol Weak2 \
+# RUN:   %t.o %t.2.o
+# RUN: llvm-readobj -elf-output-style=GNU -symbols %t.2.o | FileCheck %s
+
+!ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_X86_64
+Sections:
+  - Name:          .text
+    Type:          SHT_PROGBITS
+    Flags:         [ SHF_ALLOC, SHF_EXECINSTR ]
+Symbols:
+  Local:
+    - Name:        Local1
+      Section:     .text
+    - Name:        Local2
+      Section:     .text
+  Weak:
+    - Name:        Weak1
+      Section:     .text
+    - Name:        Weak2
+      Section:     .text
+    - Name:        Weak3
+      Section:     .text
+  Global:
+    - Name:        Global1
+      Section:     .text
+    - Name:        Global2
+      Section:     .text
+    - Name:        Global3
+      Section:     .text
+    - Name:        Global4
+      Section:     .text
+    - Name:        Global5
+      Section:     .text
+    - Name:        Global6
+      Section:     .text
+    - Name:        "Global5 Global6"
+      Section:     .text
+
+# CHECK:      Symbol table '.symtab' contains 13 entries:
+# CHECK-NEXT:    Num: Value Size Type Bind Vis Ndx Name
+# CHECK-NEXT:      0: {{.*}}  LOCAL  {{.*}}
+# CHECK-NEXT:      1: {{.*}}  LOCAL  {{.*}} Local1
+# CHECK-NEXT:      2: {{.*}}  LOCAL  {{.*}} Global5
+# CHECK-NEXT:      3: {{.*}}  LOCAL  {{.*}} Global6
+# CHECK-NEXT:      4: {{.*}}  LOCAL  {{.*}} Weak3
+# CHECK-NEXT:      5: {{.*}}  GLOBAL {{.*}} Local2
+# CHECK-NEXT:      6: {{.*}}  GLOBAL {{.*}} Global1
+# CHECK-NEXT:      7: {{.*}}  GLOBAL {{.*}} Global2
+# CHECK-NEXT:      8: {{.*}}  GLOBAL {{.*}} Global3
+# CHECK-NEXT:      9: {{.*}}  GLOBAL {{.*}} Global4
+# CHECK-NEXT:     10: {{.*}}  GLOBAL {{.*}} Global5 Global6
+# CHECK-NEXT:     11: {{.*}}  WEAK   {{.*}} Weak1
+# CHECK-NEXT:     12: {{.*}}  GLOBAL {{.*}} Weak2

Modified: llvm/trunk/tools/llvm-objcopy/ObjcopyOpts.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/ObjcopyOpts.td?rev=340105&r1=340104&r2=340105&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/ObjcopyOpts.td (original)
+++ llvm/trunk/tools/llvm-objcopy/ObjcopyOpts.td Fri Aug 17 15:34:48 2018
@@ -81,6 +81,24 @@ def L : JoinedOrSeparate<["-"], "L">,
 defm globalize_symbol : Eq<"globalize-symbol">,
                        MetaVarName<"symbol">,
                        HelpText<"Mark <symbol> as global">;
+
+defm keep_global_symbol
+    : Eq<"keep-global-symbol">,
+      MetaVarName<"symbol">,
+      HelpText<"Convert all symbols except <symbol> to local. May be repeated "
+               "to convert all except a set of symbols to local.">;
+def G : JoinedOrSeparate<[ "-" ], "G">, Alias<keep_global_symbol>;
+
+defm keep_global_symbols
+    : Eq<"keep-global-symbols">,
+      MetaVarName<"filename">,
+      HelpText<
+          "Reads a list of symbols from <filename> and runs as if "
+	  "--keep-global-symbol=<symbol> is set for each one. <filename> "
+	  "contains one symbol per line and may contain comments beginning "
+	  "with '#'. Leading and trailing whitespace is stripped from each "
+	  "line. May be repeated to read symbols from many files.">;
+
 defm weaken_symbol : Eq<"weaken-symbol">,
                        MetaVarName<"symbol">,
                        HelpText<"Mark <symbol> as weak">;

Modified: llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp?rev=340105&r1=340104&r2=340105&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp (original)
+++ llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp Fri Aug 17 15:34:48 2018
@@ -154,6 +154,7 @@ struct CopyConfig {
   std::vector<StringRef> SymbolsToRemove;
   std::vector<StringRef> SymbolsToWeaken;
   std::vector<StringRef> ToRemove;
+  std::vector<std::string> SymbolsToKeepGlobal;
 
   // Map options
   StringMap<SectionRename> SectionsToRename;
@@ -428,6 +429,20 @@ static void handleArgs(const CopyConfig
            is_contained(Config.SymbolsToLocalize, Sym.Name)))
         Sym.Binding = STB_LOCAL;
 
+      // Note: these two globalize flags have very similar names but different
+      // meanings:
+      //
+      // --globalize-symbol: promote a symbol to global
+      // --keep-global-symbol: all symbols except for these should be made local
+      //
+      // If --globalize-symbol is specified for a given symbol, it will be
+      // global in the output file even if it is not included via
+      // --keep-global-symbol. Because of that, make sure to check
+      // --globalize-symbol second.
+      if (!Config.SymbolsToKeepGlobal.empty() &&
+          !is_contained(Config.SymbolsToKeepGlobal, Sym.Name))
+        Sym.Binding = STB_LOCAL;
+
       if (!Config.SymbolsToGlobalize.empty() &&
           is_contained(Config.SymbolsToGlobalize, Sym.Name))
         Sym.Binding = STB_GLOBAL;
@@ -782,6 +797,23 @@ static void executeElfObjcopy(const Copy
   }
 }
 
+static void addGlobalSymbolsFromFile(std::vector<std::string> &Symbols,
+                                     StringRef Filename) {
+  SmallVector<StringRef, 16> Lines;
+  auto BufOrErr = MemoryBuffer::getFile(Filename);
+  if (!BufOrErr)
+    reportError(Filename, BufOrErr.getError());
+
+  BufOrErr.get()->getBuffer().split(Lines, '\n');
+  for (StringRef Line : Lines) {
+    // Ignore everything after '#', trim whitespace, and only add the symbol if
+    // it's not empty.
+    auto TrimmedLine = Line.split('#').first.trim();
+    if (!TrimmedLine.empty())
+      Symbols.push_back(TrimmedLine.str());
+  }
+}
+
 // ParseObjcopyOptions returns the config and sets the input arguments. If a
 // help flag is set then ParseObjcopyOptions will print the help messege and
 // exit.
@@ -870,6 +902,10 @@ static CopyConfig parseObjcopyOptions(Ar
   Config.KeepFileSymbols = InputArgs.hasArg(OBJCOPY_keep_file_symbols);
   for (auto Arg : InputArgs.filtered(OBJCOPY_localize_symbol))
     Config.SymbolsToLocalize.push_back(Arg->getValue());
+  for (auto Arg : InputArgs.filtered(OBJCOPY_keep_global_symbol))
+    Config.SymbolsToKeepGlobal.push_back(Arg->getValue());
+  for (auto Arg : InputArgs.filtered(OBJCOPY_keep_global_symbols))
+    addGlobalSymbolsFromFile(Config.SymbolsToKeepGlobal, Arg->getValue());
   for (auto Arg : InputArgs.filtered(OBJCOPY_globalize_symbol))
     Config.SymbolsToGlobalize.push_back(Arg->getValue());
   for (auto Arg : InputArgs.filtered(OBJCOPY_weaken_symbol))




More information about the llvm-commits mailing list