From 5f86a063375f85b41105aaa88087c57da49982b1 Mon Sep 17 00:00:00 2001 From: Eugene Leviant Date: Fri, 8 Feb 2019 10:33:16 +0000 Subject: [PATCH] [llvm-objcopy] Add --redefine-syms Differential revision: https://reviews.llvm.org/D57738 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@353509 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/tools/llvm-objcopy/ELF/redefine-symbol.test | 19 ++++++++++++++ tools/llvm-objcopy/CopyConfig.cpp | 32 ++++++++++++++++++++++++ tools/llvm-objcopy/ObjcopyOpts.td | 10 ++++++++ tools/llvm-objcopy/llvm-objcopy.cpp | 10 +++++--- tools/llvm-objcopy/llvm-objcopy.h | 2 ++ 5 files changed, 69 insertions(+), 4 deletions(-) diff --git a/test/tools/llvm-objcopy/ELF/redefine-symbol.test b/test/tools/llvm-objcopy/ELF/redefine-symbol.test index c56621a79d8..b8e6066c3f0 100644 --- a/test/tools/llvm-objcopy/ELF/redefine-symbol.test +++ b/test/tools/llvm-objcopy/ELF/redefine-symbol.test @@ -3,6 +3,16 @@ # RUN: llvm-readobj --symbols %t2 | FileCheck %s # RUN: not llvm-objcopy --redefine-sym barbar %t %t2 2>&1 | FileCheck %s --check-prefix=BAD-FORMAT # RUN: not llvm-objcopy --redefine-sym foo=f1 --redefine-sym foo=f2 %t %t2 2>&1 | FileCheck %s --check-prefix=MULTIPLE-REDEFINITION +# RUN: echo " foo oof #rename foo " > %t.rename.txt +# RUN: echo "empty" >> %t.rename.txt +# RUN: not llvm-objcopy --redefine-syms %t.rename.txt %t %t3 2>&1 | FileCheck %s --check-prefix=MISSING-SYM-NAME +# RUN: not llvm-objcopy --redefine-syms %t.rename-none.txt %t %t-none 2>&1 | FileCheck %s --check-prefix=NO-FILE +# RUN: cmp %t2 %t3 +# RUN: echo " bar rab #rename bar " > %t.rename2.txt +# RUN: echo " foo oof #rename foo " > %t.rename3.txt +# RUN: echo " empty ytpme #rename empty " >> %t.rename3.txt +# RUN: llvm-objcopy --redefine-syms %t.rename2.txt --redefine-syms %t.rename3.txt %t %t4 +# RUN: llvm-readobj --symbols %t4 | FileCheck %s --check-prefix=MULTIPLE-FILES !ELF FileHeader: @@ -79,3 +89,12 @@ Symbols: #BAD-FORMAT: Bad format for --redefine-sym #MULTIPLE-REDEFINITION: Multiple redefinition of symbol foo +#MISSING-SYM-NAME: error: {{.*}}.rename.txt:2: missing new symbol name +#NO-FILE: error: '{{.*}}.rename-none.txt': {{[Nn]}}o such file or directory + +#MULTIPLE-FILES: Name: oof +#MULTIPLE-FILES-NEXT: Value: 0x1004 +#MULTIPLE-FILES: Name: rab +#MULTIPLE-FILES-NEXT: Value: 0x2000 +#MULTIPLE-FILES: Name: ytpme +#MULTIPLE-FILES-NEXT: Value: 0x1008 diff --git a/tools/llvm-objcopy/CopyConfig.cpp b/tools/llvm-objcopy/CopyConfig.cpp index d013ee4f35d..3a0e01caf22 100644 --- a/tools/llvm-objcopy/CopyConfig.cpp +++ b/tools/llvm-objcopy/CopyConfig.cpp @@ -18,6 +18,7 @@ #include "llvm/Option/ArgList.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Compression.h" +#include "llvm/Support/Errc.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/StringSaver.h" #include @@ -255,6 +256,32 @@ NameOrRegex::NameOrRegex(StringRef Pattern, bool IsRegex) { ("^" + Pattern.ltrim('^').rtrim('$') + "$").toStringRef(Data)); } +static Error addSymbolsToRenameFromFile(StringMap &SymbolsToRename, + BumpPtrAllocator &Alloc, + StringRef Filename) { + StringSaver Saver(Alloc); + SmallVector Lines; + auto BufOrErr = MemoryBuffer::getFile(Filename); + if (!BufOrErr) + return createError(Filename, BufOrErr.getError()); + + BufOrErr.get()->getBuffer().split(Lines, '\n'); + size_t NumLines = Lines.size(); + for (size_t LineNo = 0; LineNo < NumLines; ++LineNo) { + StringRef TrimmedLine = Lines[LineNo].split('#').first.trim(); + if (TrimmedLine.empty()) + continue; + + std::pair Pair = Saver.save(TrimmedLine).split(' '); + StringRef NewName = Pair.second.trim(); + if (NewName.empty()) + return createStringError(errc::invalid_argument, + "%s:%zu: missing new symbol name", + Filename.str().c_str(), LineNo + 1); + SymbolsToRename.insert({Pair.first, NewName}); + } + return Error::success(); +} // ParseObjcopyOptions returns the config and sets the input arguments. If a // help flag is set then ParseObjcopyOptions will print the help messege and // exit. @@ -358,6 +385,11 @@ DriverConfig parseObjcopyOptions(ArrayRef ArgsArr) { error("Multiple redefinition of symbol " + Old2New.first); } + for (auto Arg : InputArgs.filtered(OBJCOPY_redefine_symbols)) + if (Error E = addSymbolsToRenameFromFile(Config.SymbolsToRename, DC.Alloc, + Arg->getValue())) + error(std::move(E)); + for (auto Arg : InputArgs.filtered(OBJCOPY_rename_section)) { SectionRename SR = parseRenameSectionValue(StringRef(Arg->getValue())); if (!Config.SectionsToRename.try_emplace(SR.OriginalName, SR).second) diff --git a/tools/llvm-objcopy/ObjcopyOpts.td b/tools/llvm-objcopy/ObjcopyOpts.td index bc1ac7869de..ccfc5420360 100644 --- a/tools/llvm-objcopy/ObjcopyOpts.td +++ b/tools/llvm-objcopy/ObjcopyOpts.td @@ -76,6 +76,16 @@ defm rename_section defm redefine_symbol : Eq<"redefine-sym", "Change the name of a symbol old to new">, MetaVarName<"old=new">; +defm redefine_symbols + : Eq<"redefine-syms", + "Reads a list of symbol pairs from and runs as if " + "--redefine-sym== is set for each one. " + "contains two symbols per line separated with whitespace and may " + "contain comments beginning with '#'. Leading and trailing " + "whitespace is stripped from each line. May be repeated to read " + "symbols from many files.">, + MetaVarName<"filename">; + defm keep_section : Eq<"keep-section", "Keep
">, MetaVarName<"section">; defm only_section : Eq<"only-section", "Remove all but
">, diff --git a/tools/llvm-objcopy/llvm-objcopy.cpp b/tools/llvm-objcopy/llvm-objcopy.cpp index d8dea16c062..72774ec6f3c 100644 --- a/tools/llvm-objcopy/llvm-objcopy.cpp +++ b/tools/llvm-objcopy/llvm-objcopy.cpp @@ -52,6 +52,11 @@ namespace objcopy { // The name this program was invoked as. StringRef ToolName; +Error createError(StringRef File, std::error_code EC) { + assert(EC); + return createFileError(File, make_error(EC)); +} + LLVM_ATTRIBUTE_NORETURN void error(Twine Message) { WithColor::error(errs(), ToolName) << Message << ".\n"; errs().flush(); @@ -69,10 +74,7 @@ LLVM_ATTRIBUTE_NORETURN void error(Error E) { } LLVM_ATTRIBUTE_NORETURN void reportError(StringRef File, std::error_code EC) { - assert(EC); - WithColor::error(errs(), ToolName) - << "'" << File << "': " << EC.message() << ".\n"; - exit(1); + error(createError(File, EC)); } LLVM_ATTRIBUTE_NORETURN void reportError(StringRef File, Error E) { diff --git a/tools/llvm-objcopy/llvm-objcopy.h b/tools/llvm-objcopy/llvm-objcopy.h index 18a789ca1f8..4783e7804b5 100644 --- a/tools/llvm-objcopy/llvm-objcopy.h +++ b/tools/llvm-objcopy/llvm-objcopy.h @@ -18,6 +18,8 @@ namespace llvm { namespace objcopy { +Error createError(StringRef File, std::error_code EC); + LLVM_ATTRIBUTE_NORETURN extern void error(Twine Message); LLVM_ATTRIBUTE_NORETURN extern void error(Error E); LLVM_ATTRIBUTE_NORETURN extern void reportError(StringRef File, Error E); -- 2.11.0