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

Yi Kong via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 24 23:42:29 PST 2024


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

>From 5d6e4f0d4f0f61bca87c81a2795a595052a07955 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] 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/ELF/ELFObjcopy.cpp           |  4 +
 .../ELF/prefix-symbols-remove.test            | 78 +++++++++++++++++++
 llvm/tools/llvm-objcopy/ObjcopyOptions.cpp    |  8 ++
 llvm/tools/llvm-objcopy/ObjcopyOpts.td        |  5 ++
 5 files changed, 96 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 386c20aec184ded..0d9320ec2efd71b 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/ELF/ELFObjcopy.cpp b/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp
index b6d77d17bae36c5..a5ebc99b42ea84c 100644
--- a/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp
+++ b/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp
@@ -331,6 +331,10 @@ static Error updateAndRemoveSymbols(const CommonConfig &Config,
 
     if (!Config.SymbolsPrefix.empty() && Sym.Type != STT_SECTION)
       Sym.Name = (Config.SymbolsPrefix + Sym.Name).str();
+
+    if (!Config.SymbolsPrefixRemove.empty() && Sym.Type != STT_SECTION)
+      if (Sym.Name.rfind(Config.SymbolsPrefixRemove, 0) == 0)
+        Sym.Name = Sym.Name.substr(Config.SymbolsPrefixRemove.size());
   });
 
   // The purpose of this loop is to mark symbols referenced by sections
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 000000000000000..ad9b77d59f1b1cd
--- /dev/null
+++ b/llvm/test/tools/llvm-objcopy/ELF/prefix-symbols-remove.test
@@ -0,0 +1,78 @@
+# RUN: yaml2obj %s -o %t
+# RUN: llvm-objcopy --prefix-symbols-remove __pf_ %t %t2
+# RUN: llvm-readobj --symbols %t2 | 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 ]
+    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:     undef
+    Binding:  STB_GLOBAL
+
+# CHECK:  Symbols [
+# NEXT:        Symbol {
+# NEXT:          Name:
+# NEXT:          Value: 0x0
+# NEXT:          Size: 0
+# NEXT:          Binding: Local
+# NEXT:          Type: None
+# NEXT:          Other: 0
+# NEXT:          Section: Undefined
+# NEXT:        }
+# NEXT:        Symbol {
+# NEXT:          Name: foo
+# NEXT:          Value: 0x0
+# NEXT:          Size: 0
+# NEXT:          Binding: Local
+# NEXT:          Type: Section
+# NEXT:          Other: 0
+# NEXT:          Section: .text
+# NEXT:        }
+# NEXT:        Symbol {
+# NEXT:          Name: bar
+# NEXT:          Value: 0x0
+# NEXT:          Size: 0
+# NEXT:          Binding: Local
+# NEXT:          Type: File
+# NEXT:          Other: 0
+# NEXT:          Section: .text
+# NEXT:        }
+# NEXT:        Symbol {
+# NEXT:          Name: foobar
+# NEXT:          Value: 0x0
+# NEXT:          Size: 0
+# NEXT:          Binding: Global
+# NEXT:          Type: Function
+# NEXT:          Other: 0
+# NEXT:          Section: .text
+# NEXT:        }
+# NEXT:        Symbol {
+# NEXT:          Name: undef
+# NEXT:          Value: 0x0
+# NEXT:          Size: 0
+# NEXT:          Binding: Global
+# NEXT:          Type: None
+# NEXT:          Other: 0
+# NEXT:          Section: Undefined
+# NEXT:        }
+# NEXT:      ]
diff --git a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
index f15307181fad618..e3e28ae9f16e1a9 100644
--- a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
+++ b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
@@ -731,7 +731,15 @@ 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_prefix_symbols_remove);
+  if (!Config.SymbolsPrefix.empty() && !Config.SymbolsPrefixRemove.empty())
+    return createStringError(
+        errc::invalid_argument,
+        "--prefix-symbols and --prefix-symbols-remove are mutualy exclusive");
+
   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 ead8cd28d387791..6c64e5ecf52e4a7 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 prefix_symbols_remove
+    : Eq<"prefix-symbols-remove",
+         "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">,



More information about the llvm-commits mailing list