diff options
-rw-r--r-- | llvm/docs/CommandGuide/llvm-objcopy.rst | 5 | ||||
-rw-r--r-- | llvm/include/llvm/ObjCopy/CommonConfig.h | 1 | ||||
-rw-r--r-- | llvm/lib/ObjCopy/ConfigManager.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp | 5 | ||||
-rw-r--r-- | llvm/test/tools/llvm-objcopy/ELF/prefix-symbols-remove.test | 65 | ||||
-rw-r--r-- | llvm/tools/llvm-objcopy/ObjcopyOptions.cpp | 4 | ||||
-rw-r--r-- | llvm/tools/llvm-objcopy/ObjcopyOpts.td | 5 |
7 files changed, 89 insertions, 0 deletions
diff --git a/llvm/docs/CommandGuide/llvm-objcopy.rst b/llvm/docs/CommandGuide/llvm-objcopy.rst index 6e13cd9..42d11fa 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/include/llvm/ObjCopy/CommonConfig.h b/llvm/include/llvm/ObjCopy/CommonConfig.h index 386c20a..0d9320e 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 10ece49..e46b595 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 b6d77d1..36f7994 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 0000000..59bddb0 --- /dev/null +++ b/llvm/test/tools/llvm-objcopy/ELF/prefix-symbols-remove.test @@ -0,0 +1,65 @@ +# RUN: yaml2obj %s -o %t +# 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-symbol-prefix. +# 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=__1_ %t %t4 +# RUN: llvm-objcopy --prefix-symbols=__2_ %t %t5 +# RUN: llvm-objcopy --remove-symbol-prefix=__1_ --prefix-symbols=__2_ %t4 %t6 +# RUN: cmp %t5 %t6 + +## Show that the last --remove-symbol-prefix option wins. +# RUN: llvm-objcopy --remove-symbol-prefix=__pf_ --remove-symbol-prefix=__ %t %7 +# RUN: llvm-objcopy --remove-symbol-prefix=__ %t %8 +# RUN: cmp %7 %8 + +!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: Symbol table '.symtab' contains 7 entries: +# CHECK-NEXT: Name +# CHECK-NEXT: {{ $}} +# CHECK-NEXT: __pf_foo +# CHECK-NEXT: bar +# CHECK-NEXT: foobar +# CHECK-NEXT: foo__pf_bar1 +# CHECK-NEXT: foo__pf_bar2 +# CHECK-NEXT: undef diff --git a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp index f153071..394eaca 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_symbol_prefix); + 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 ead8cd2..bd041fa 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_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">; defm prefix_alloc_sections : Eq<"prefix-alloc-sections", "Add <prefix> to the start of every allocated section name">, |