[llvm] Add functionality to llvm-objcopy to remove prefixes (PR #79415)

Yi Kong via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 2 02:59:25 PST 2024


https://github.com/kongy updated https://github.com/llvm/llvm-project/pull/79415

>From c176f9b6eef393291d2dc075b011309ff1be9408 Mon Sep 17 00:00:00 2001
From: Yi Kong <yikong at google.com>
Date: Thu, 25 Jan 2024 14:20:44 +0900
Subject: [PATCH 1/3] Add functionality to llvm-objcopy to remove prefixes

llvm-objcopy has functionality to add prefixes to symbols
(--prefix-symbols). This adds an inverse action to undo the modification
and return to the original.
---
 llvm/include/llvm/ObjCopy/CommonConfig.h      |   1 +
 llvm/lib/ObjCopy/ConfigManager.cpp            |   4 +
 llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp           |   5 +
 .../ELF/prefix-symbols-remove.test            | 115 ++++++++++++++++++
 llvm/tools/llvm-objcopy/ObjcopyOptions.cpp    |   4 +
 llvm/tools/llvm-objcopy/ObjcopyOpts.td        |   5 +
 6 files changed, 134 insertions(+)
 create mode 100644 llvm/test/tools/llvm-objcopy/ELF/prefix-symbols-remove.test

diff --git a/llvm/include/llvm/ObjCopy/CommonConfig.h b/llvm/include/llvm/ObjCopy/CommonConfig.h
index 386c20aec184d..0d9320ec2efd7 100644
--- a/llvm/include/llvm/ObjCopy/CommonConfig.h
+++ b/llvm/include/llvm/ObjCopy/CommonConfig.h
@@ -218,6 +218,7 @@ struct CommonConfig {
   uint64_t PadTo = 0;
   StringRef SplitDWO;
   StringRef SymbolsPrefix;
+  StringRef SymbolsPrefixRemove;
   StringRef AllocSectionsPrefix;
   DiscardType DiscardMode = DiscardType::None;
 
diff --git a/llvm/lib/ObjCopy/ConfigManager.cpp b/llvm/lib/ObjCopy/ConfigManager.cpp
index 10ece49028f21..e46b595a56dc4 100644
--- a/llvm/lib/ObjCopy/ConfigManager.cpp
+++ b/llvm/lib/ObjCopy/ConfigManager.cpp
@@ -15,6 +15,7 @@ namespace objcopy {
 
 Expected<const COFFConfig &> ConfigManager::getCOFFConfig() const {
   if (!Common.SplitDWO.empty() || !Common.SymbolsPrefix.empty() ||
+      !Common.SymbolsPrefixRemove.empty() ||
       !Common.AllocSectionsPrefix.empty() || !Common.KeepSection.empty() ||
       !Common.SymbolsToGlobalize.empty() || !Common.SymbolsToKeep.empty() ||
       !Common.SymbolsToLocalize.empty() || !Common.SymbolsToWeaken.empty() ||
@@ -33,6 +34,7 @@ Expected<const COFFConfig &> ConfigManager::getCOFFConfig() const {
 
 Expected<const MachOConfig &> ConfigManager::getMachOConfig() const {
   if (!Common.SplitDWO.empty() || !Common.SymbolsPrefix.empty() ||
+      !Common.SymbolsPrefixRemove.empty() ||
       !Common.AllocSectionsPrefix.empty() || !Common.KeepSection.empty() ||
       !Common.SymbolsToGlobalize.empty() || !Common.SymbolsToKeep.empty() ||
       !Common.SymbolsToLocalize.empty() ||
@@ -54,6 +56,7 @@ Expected<const MachOConfig &> ConfigManager::getMachOConfig() const {
 Expected<const WasmConfig &> ConfigManager::getWasmConfig() const {
   if (!Common.AddGnuDebugLink.empty() || Common.ExtractPartition ||
       !Common.SplitDWO.empty() || !Common.SymbolsPrefix.empty() ||
+      !Common.SymbolsPrefixRemove.empty() ||
       !Common.AllocSectionsPrefix.empty() ||
       Common.DiscardMode != DiscardType::None || !Common.SymbolsToAdd.empty() ||
       !Common.SymbolsToGlobalize.empty() || !Common.SymbolsToLocalize.empty() ||
@@ -74,6 +77,7 @@ Expected<const WasmConfig &> ConfigManager::getWasmConfig() const {
 Expected<const XCOFFConfig &> ConfigManager::getXCOFFConfig() const {
   if (!Common.AddGnuDebugLink.empty() || Common.ExtractPartition ||
       !Common.SplitDWO.empty() || !Common.SymbolsPrefix.empty() ||
+      !Common.SymbolsPrefixRemove.empty() ||
       !Common.AllocSectionsPrefix.empty() ||
       Common.DiscardMode != DiscardType::None || !Common.AddSection.empty() ||
       !Common.DumpSection.empty() || !Common.SymbolsToAdd.empty() ||
diff --git a/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp b/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp
index b6d77d17bae36..36f799446a04f 100644
--- a/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp
+++ b/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp
@@ -329,6 +329,11 @@ static Error updateAndRemoveSymbols(const CommonConfig &Config,
     if (I != Config.SymbolsToRename.end())
       Sym.Name = std::string(I->getValue());
 
+    if (!Config.SymbolsPrefixRemove.empty() && Sym.Type != STT_SECTION)
+      if (Sym.Name.compare(0, Config.SymbolsPrefixRemove.size(),
+                           Config.SymbolsPrefixRemove) == 0)
+        Sym.Name = Sym.Name.substr(Config.SymbolsPrefixRemove.size());
+
     if (!Config.SymbolsPrefix.empty() && Sym.Type != STT_SECTION)
       Sym.Name = (Config.SymbolsPrefix + Sym.Name).str();
   });
diff --git a/llvm/test/tools/llvm-objcopy/ELF/prefix-symbols-remove.test b/llvm/test/tools/llvm-objcopy/ELF/prefix-symbols-remove.test
new file mode 100644
index 0000000000000..402404c8d6e68
--- /dev/null
+++ b/llvm/test/tools/llvm-objcopy/ELF/prefix-symbols-remove.test
@@ -0,0 +1,115 @@
+# RUN: yaml2obj %s -o %t
+# RUN: llvm-objcopy --remove-prefix-symbols __pf_ %t %t2
+# RUN: llvm-readobj --symbols %t2 | FileCheck %s
+
+## Show that an empty string is permitted as the argument to
+## --remove-prefix-symbols.
+# RUN: llvm-objcopy --remove-prefix-symbols= %t2 %t3
+# RUN: cmp %t2 %t3
+
+## When both options are present, llvm-objcopy should remove
+## prefixes first, before adding prefixes.
+# RUN: llvm-objcopy --prefix-symbols=AAA --remove-prefix-symbols=AAA %t %t4
+# RUN: llvm-objcopy --prefix-symbols=AAA %t %t5
+# RUN: cmp %t4 %t5
+
+!ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_X86_64
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    Address:         0x1000
+    AddressAlign:    0x0000000000000010
+    Size:            64
+Symbols:
+  - Name:     __pf_foo
+    Type:     STT_SECTION
+    Section:  .text
+  - Name:     __pf_bar
+    Type:     STT_FILE
+    Section:  .text
+  - Name:     foobar
+    Type:     STT_FUNC
+    Section:  .text
+    Binding:  STB_GLOBAL
+  - Name:     foo__pf_bar1
+    Type:     STT_FUNC
+    Section:  .text
+    Binding:  STB_GLOBAL
+  - Name:     __pf_foo__pf_bar2
+    Type:     STT_FUNC
+    Section:  .text
+    Binding:  STB_GLOBAL
+  - Name:     undef
+    Binding:  STB_GLOBAL
+
+# CHECK: Symbols [
+# CHECK-NEXT:  Symbol {
+# CHECK-NEXT:    Name:
+# CHECK-NEXT:    Value: 0x0
+# CHECK-NEXT:    Size: 0
+# CHECK-NEXT:    Binding: Local
+# CHECK-NEXT:    Type: None
+# CHECK-NEXT:    Other: 0
+# CHECK-NEXT:    Section: Undefined
+# CHECK-NEXT:  }
+# CHECK-NEXT:  Symbol {
+# CHECK-NEXT:    Name: __pf_foo
+# CHECK-NEXT:    Value: 0x0
+# CHECK-NEXT:    Size: 0
+# CHECK-NEXT:    Binding: Local
+# CHECK-NEXT:    Type: Section
+# CHECK-NEXT:    Other: 0
+# CHECK-NEXT:    Section: .text
+# CHECK-NEXT:  }
+# CHECK-NEXT:  Symbol {
+# CHECK-NEXT:    Name: bar
+# CHECK-NEXT:    Value: 0x0
+# CHECK-NEXT:    Size: 0
+# CHECK-NEXT:    Binding: Local
+# CHECK-NEXT:    Type: File
+# CHECK-NEXT:    Other: 0
+# CHECK-NEXT:    Section: .text
+# CHECK-NEXT:  }
+# CHECK-NEXT:  Symbol {
+# CHECK-NEXT:    Name: foobar
+# CHECK-NEXT:    Value: 0x0
+# CHECK-NEXT:    Size: 0
+# CHECK-NEXT:    Binding: Global
+# CHECK-NEXT:    Type: Function
+# CHECK-NEXT:    Other: 0
+# CHECK-NEXT:    Section: .text
+# CHECK-NEXT:  }
+# CHECK-NEXT:  Symbol {
+# CHECK-NEXT:    Name: foo__pf_bar1
+# CHECK-NEXT:    Value: 0x0
+# CHECK-NEXT:    Size: 0
+# CHECK-NEXT:    Binding: Global
+# CHECK-NEXT:    Type: Function
+# CHECK-NEXT:    Other: 0
+# CHECK-NEXT:    Section: .text
+# CHECK-NEXT:  }
+# CHECK-NEXT:  Symbol {
+# CHECK-NEXT:    Name: foo__pf_bar2
+# CHECK-NEXT:    Value: 0x0
+# CHECK-NEXT:    Size: 0
+# CHECK-NEXT:    Binding: Global
+# CHECK-NEXT:    Type: Function
+# CHECK-NEXT:    Other: 0
+# CHECK-NEXT:    Section: .text
+# CHECK-NEXT:  }
+# CHECK-NEXT:  Symbol {
+# CHECK-NEXT:    Name: undef
+# CHECK-NEXT:    Value: 0x0
+# CHECK-NEXT:    Size: 0
+# CHECK-NEXT:    Binding: Global
+# CHECK-NEXT:    Type: None
+# CHECK-NEXT:    Other: 0
+# CHECK-NEXT:    Section: Undefined
+# CHECK-NEXT:  }
+# CHECK-NEXT:]
diff --git a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
index f15307181fad6..6fcb5e6cdd5da 100644
--- a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
+++ b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
@@ -731,7 +731,11 @@ objcopy::parseObjcopyOptions(ArrayRef<const char *> RawArgsArr,
         llvm::crc32(arrayRefFromStringRef(Debug->getBuffer()));
   }
   Config.SplitDWO = InputArgs.getLastArgValue(OBJCOPY_split_dwo);
+
   Config.SymbolsPrefix = InputArgs.getLastArgValue(OBJCOPY_prefix_symbols);
+  Config.SymbolsPrefixRemove =
+      InputArgs.getLastArgValue(OBJCOPY_remove_prefix_symbols);
+
   Config.AllocSectionsPrefix =
       InputArgs.getLastArgValue(OBJCOPY_prefix_alloc_sections);
   if (auto Arg = InputArgs.getLastArg(OBJCOPY_extract_partition))
diff --git a/llvm/tools/llvm-objcopy/ObjcopyOpts.td b/llvm/tools/llvm-objcopy/ObjcopyOpts.td
index ead8cd28d3877..5fe583cf2b402 100644
--- a/llvm/tools/llvm-objcopy/ObjcopyOpts.td
+++ b/llvm/tools/llvm-objcopy/ObjcopyOpts.td
@@ -203,6 +203,11 @@ defm dump_section
 defm prefix_symbols
     : Eq<"prefix-symbols", "Add <prefix> to the start of every symbol name">,
       MetaVarName<"prefix">;
+defm remove_prefix_symbols
+    : Eq<"remove-prefix-symbols",
+         "Remove <prefix> from the start of every symbol name. No-op for symbols that do not start "
+         "with <prefix>">,
+      MetaVarName<"prefix">;
 
 defm prefix_alloc_sections
     : Eq<"prefix-alloc-sections", "Add <prefix> to the start of every allocated section name">,

>From ec9d7dda2bd09754b0d6e3ae71b7069ec222b8f4 Mon Sep 17 00:00:00 2001
From: Yi Kong <yikong at google.com>
Date: Thu, 1 Feb 2024 14:24:27 +0900
Subject: [PATCH 2/3] Address review comments

---
 .../ELF/prefix-symbols-remove.test            | 84 ++++---------------
 llvm/tools/llvm-objcopy/ObjcopyOptions.cpp    |  2 +-
 llvm/tools/llvm-objcopy/ObjcopyOpts.td        |  4 +-
 3 files changed, 17 insertions(+), 73 deletions(-)

diff --git a/llvm/test/tools/llvm-objcopy/ELF/prefix-symbols-remove.test b/llvm/test/tools/llvm-objcopy/ELF/prefix-symbols-remove.test
index 402404c8d6e68..0cf39bbb693aa 100644
--- a/llvm/test/tools/llvm-objcopy/ELF/prefix-symbols-remove.test
+++ b/llvm/test/tools/llvm-objcopy/ELF/prefix-symbols-remove.test
@@ -1,16 +1,16 @@
 # RUN: yaml2obj %s -o %t
-# RUN: llvm-objcopy --remove-prefix-symbols __pf_ %t %t2
-# RUN: llvm-readobj --symbols %t2 | FileCheck %s
+# RUN: llvm-objcopy --remove-symbol-prefix __pf_ %t %t2
+# RUN: llvm-readelf --symbols %t2 | FileCheck %s
 
 ## Show that an empty string is permitted as the argument to
 ## --remove-prefix-symbols.
-# RUN: llvm-objcopy --remove-prefix-symbols= %t2 %t3
+# RUN: llvm-objcopy --remove-symbol-prefix= %t2 %t3
 # RUN: cmp %t2 %t3
 
 ## When both options are present, llvm-objcopy should remove
 ## prefixes first, before adding prefixes.
-# RUN: llvm-objcopy --prefix-symbols=AAA --remove-prefix-symbols=AAA %t %t4
-# RUN: llvm-objcopy --prefix-symbols=AAA %t %t5
+# RUN: llvm-objcopy --remove-symbol-prefix=AAA --remove-symbol-prefix=AAA %t %t4
+# RUN: llvm-objcopy --remove-symbol-prefix=AAA %t %t5
 # RUN: cmp %t4 %t5
 
 !ELF
@@ -48,68 +48,12 @@ Symbols:
   - Name:     undef
     Binding:  STB_GLOBAL
 
-# CHECK: Symbols [
-# CHECK-NEXT:  Symbol {
-# CHECK-NEXT:    Name:
-# CHECK-NEXT:    Value: 0x0
-# CHECK-NEXT:    Size: 0
-# CHECK-NEXT:    Binding: Local
-# CHECK-NEXT:    Type: None
-# CHECK-NEXT:    Other: 0
-# CHECK-NEXT:    Section: Undefined
-# CHECK-NEXT:  }
-# CHECK-NEXT:  Symbol {
-# CHECK-NEXT:    Name: __pf_foo
-# CHECK-NEXT:    Value: 0x0
-# CHECK-NEXT:    Size: 0
-# CHECK-NEXT:    Binding: Local
-# CHECK-NEXT:    Type: Section
-# CHECK-NEXT:    Other: 0
-# CHECK-NEXT:    Section: .text
-# CHECK-NEXT:  }
-# CHECK-NEXT:  Symbol {
-# CHECK-NEXT:    Name: bar
-# CHECK-NEXT:    Value: 0x0
-# CHECK-NEXT:    Size: 0
-# CHECK-NEXT:    Binding: Local
-# CHECK-NEXT:    Type: File
-# CHECK-NEXT:    Other: 0
-# CHECK-NEXT:    Section: .text
-# CHECK-NEXT:  }
-# CHECK-NEXT:  Symbol {
-# CHECK-NEXT:    Name: foobar
-# CHECK-NEXT:    Value: 0x0
-# CHECK-NEXT:    Size: 0
-# CHECK-NEXT:    Binding: Global
-# CHECK-NEXT:    Type: Function
-# CHECK-NEXT:    Other: 0
-# CHECK-NEXT:    Section: .text
-# CHECK-NEXT:  }
-# CHECK-NEXT:  Symbol {
-# CHECK-NEXT:    Name: foo__pf_bar1
-# CHECK-NEXT:    Value: 0x0
-# CHECK-NEXT:    Size: 0
-# CHECK-NEXT:    Binding: Global
-# CHECK-NEXT:    Type: Function
-# CHECK-NEXT:    Other: 0
-# CHECK-NEXT:    Section: .text
-# CHECK-NEXT:  }
-# CHECK-NEXT:  Symbol {
-# CHECK-NEXT:    Name: foo__pf_bar2
-# CHECK-NEXT:    Value: 0x0
-# CHECK-NEXT:    Size: 0
-# CHECK-NEXT:    Binding: Global
-# CHECK-NEXT:    Type: Function
-# CHECK-NEXT:    Other: 0
-# CHECK-NEXT:    Section: .text
-# CHECK-NEXT:  }
-# CHECK-NEXT:  Symbol {
-# CHECK-NEXT:    Name: undef
-# CHECK-NEXT:    Value: 0x0
-# CHECK-NEXT:    Size: 0
-# CHECK-NEXT:    Binding: Global
-# CHECK-NEXT:    Type: None
-# CHECK-NEXT:    Other: 0
-# CHECK-NEXT:    Section: Undefined
-# CHECK-NEXT:  }
-# CHECK-NEXT:]
+# CHECK:      Symbol table '.symtab' contains [[#]] entries:
+# CHECK-NEXT:  Num: Value Size Type Bind Vis Ndx Name
+# CHECK-NEXT:   0: [[#]] 0 NOTYPE  LOCAL  {{.*}}
+# CHECK-NEXT:   1: [[#]] 0 SECTION LOCAL  {{.*}} __pf_foo
+# CHECK-NEXT:   2: [[#]] 0 FILE    LOCAL  {{.*}} bar
+# CHECK-NEXT:   3: [[#]] 0 FUNC    GLOBAL {{.*}} foobar
+# CHECK-NEXT:   4: [[#]] 0 FUNC    GLOBAL {{.*}} foo__pf_bar1
+# CHECK-NEXT:   5: [[#]] 0 FUNC    GLOBAL {{.*}} foo__pf_bar2
+# CHECK-NEXT:   6: [[#]] 0 NOTYPE  GLOBAL {{.*}} undef
diff --git a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
index 6fcb5e6cdd5da..394eacacb57e5 100644
--- a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
+++ b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
@@ -734,7 +734,7 @@ objcopy::parseObjcopyOptions(ArrayRef<const char *> RawArgsArr,
 
   Config.SymbolsPrefix = InputArgs.getLastArgValue(OBJCOPY_prefix_symbols);
   Config.SymbolsPrefixRemove =
-      InputArgs.getLastArgValue(OBJCOPY_remove_prefix_symbols);
+      InputArgs.getLastArgValue(OBJCOPY_remove_symbol_prefix);
 
   Config.AllocSectionsPrefix =
       InputArgs.getLastArgValue(OBJCOPY_prefix_alloc_sections);
diff --git a/llvm/tools/llvm-objcopy/ObjcopyOpts.td b/llvm/tools/llvm-objcopy/ObjcopyOpts.td
index 5fe583cf2b402..bd041fabbdd7a 100644
--- a/llvm/tools/llvm-objcopy/ObjcopyOpts.td
+++ b/llvm/tools/llvm-objcopy/ObjcopyOpts.td
@@ -203,8 +203,8 @@ defm dump_section
 defm prefix_symbols
     : Eq<"prefix-symbols", "Add <prefix> to the start of every symbol name">,
       MetaVarName<"prefix">;
-defm remove_prefix_symbols
-    : Eq<"remove-prefix-symbols",
+defm remove_symbol_prefix
+    : Eq<"remove-symbol-prefix",
          "Remove <prefix> from the start of every symbol name. No-op for symbols that do not start "
          "with <prefix>">,
       MetaVarName<"prefix">;

>From 8566506d4faf44a66e7b6eec733677de78a3e083 Mon Sep 17 00:00:00 2001
From: Yi Kong <yikong at google.com>
Date: Fri, 2 Feb 2024 19:57:45 +0900
Subject: [PATCH 3/3] Add entry in llvm-objcopy.rst

---
 llvm/docs/CommandGuide/llvm-objcopy.rst                  | 5 +++++
 .../tools/llvm-objcopy/ELF/prefix-symbols-remove.test    | 9 +++++++--
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/llvm/docs/CommandGuide/llvm-objcopy.rst b/llvm/docs/CommandGuide/llvm-objcopy.rst
index 6e13cd94b92fd..84b6a607343e5 100644
--- a/llvm/docs/CommandGuide/llvm-objcopy.rst
+++ b/llvm/docs/CommandGuide/llvm-objcopy.rst
@@ -117,6 +117,11 @@ multiple file formats.
  If specified, symbol and section names specified by other switches are treated
  as extended POSIX regular expression patterns.
 
+.. option:: --remove-symbol-prefix <prefix>
+
+Remove <prefix> from the start of every symbol name. No-op for symbols that do
+not start with <prefix>.
+
 .. option:: --remove-section <section>, -R
 
  Remove the specified section from the output. Can be specified multiple times
diff --git a/llvm/test/tools/llvm-objcopy/ELF/prefix-symbols-remove.test b/llvm/test/tools/llvm-objcopy/ELF/prefix-symbols-remove.test
index 0cf39bbb693aa..4e588b39c153b 100644
--- a/llvm/test/tools/llvm-objcopy/ELF/prefix-symbols-remove.test
+++ b/llvm/test/tools/llvm-objcopy/ELF/prefix-symbols-remove.test
@@ -9,10 +9,15 @@
 
 ## When both options are present, llvm-objcopy should remove
 ## prefixes first, before adding prefixes.
-# RUN: llvm-objcopy --remove-symbol-prefix=AAA --remove-symbol-prefix=AAA %t %t4
-# RUN: llvm-objcopy --remove-symbol-prefix=AAA %t %t5
+# RUN: llvm-objcopy --remove-symbol-prefix=AAA --prefix-symbols=AAA %t %t4
+# RUN: llvm-objcopy --prefix-symbols=AAA %t %t5
 # RUN: cmp %t4 %t5
 
+## Show that the last --remove-symbol-prefix option wins.
+# RUN: llvm-objcopy --remove-symbol-prefix=__pf_ --remove-symbol-prefix=__ %t %6
+# RUN: llvm-objcopy --remove-symbol-prefix=__ %t %7
+# RUN: cmp %6 %7
+
 !ELF
 FileHeader:
   Class:           ELFCLASS64



More information about the llvm-commits mailing list