diff --git a/llvm/docs/CommandGuide/llvm-objcopy.rst b/llvm/docs/CommandGuide/llvm-objcopy.rst --- a/llvm/docs/CommandGuide/llvm-objcopy.rst +++ b/llvm/docs/CommandGuide/llvm-objcopy.rst @@ -84,6 +84,19 @@ For MachO objects, ``
`` must be formatted as ``,
``. +.. option:: --redefine-sym = + + Rename symbols called ```` to ```` in the output. Can be specified + multiple times to rename multiple symbols. + +.. option:: --redefine-syms + + Rename symbols in the output as described in the file ````. In the + file, each line represents a single symbol to rename, with the old name and new + name separated by whitespace. Leading and trailing whitespace is ignored, as is + anything following a '#'. Can be specified multiple times to read names from + multiple files. + .. option:: --regex If specified, symbol and section names specified by other switches are treated @@ -378,19 +391,6 @@ Preserve access and modification timestamps in the output. -.. option:: --redefine-sym = - - Rename symbols called ```` to ```` in the output. Can be specified - multiple times to rename multiple symbols. - -.. option:: --redefine-syms - - Rename symbols in the output as described in the file ````. In the - file, each line represents a single symbol to rename, with the old name and new - name separated by an equals sign. Leading and trailing whitespace is ignored, - as is anything following a '#'. Can be specified multiple times to read names - from multiple files. - .. option:: --rename-section =[,,...] Rename sections called ```` to ```` in the output, and apply any diff --git a/llvm/test/tools/llvm-objcopy/COFF/redefine-symbol.test b/llvm/test/tools/llvm-objcopy/COFF/redefine-symbol.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-objcopy/COFF/redefine-symbol.test @@ -0,0 +1,69 @@ +# RUN: yaml2obj %s -o %t + +## A non-existent symbol does not error. +# RUN: llvm-objcopy --redefine-sym func=cnuf1234 --redefine-sym foo=ba --redefine-sym=notexist= %t %t2 2>&1 | count 0 +# RUN: llvm-readobj --symbols %t2 | FileCheck %s + +# RUN: echo 'func cnuf1234 #rename func' > %t.rename.txt +# RUN: echo ' foo ba ' >> %t.rename.txt +# RUN: echo 'notexist notexist' >> %t.rename.txt +# RUN: llvm-objcopy --redefine-syms %t.rename.txt %t %t3 2>&1 | count 0 +# RUN: cmp %t2 %t3 + +# CHECK: Symbol { +# CHECK: Symbol { +# CHECK: Symbol { +# CHECK-NEXT: Name: cnuf1234 +# CHECK-NEXT: Value: 0 +# CHECK-NEXT: Section: .text (1) +# CHECK-NEXT: BaseType: Null (0x0) +# CHECK-NEXT: ComplexType: Function (0x2) +# CHECK-NEXT: StorageClass: External (0x2) +# CHECK-NEXT: AuxSymbolCount: 0 +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: ba +# CHECK-NEXT: Value: 0 +# CHECK-NEXT: Section: .rdata (2) +# CHECK-NEXT: BaseType: Null (0x0) +# CHECK-NEXT: ComplexType: Null (0x0) +# CHECK-NEXT: StorageClass: External (0x2) +# CHECK-NEXT: AuxSymbolCount: 0 +# CHECK-NEXT: } + +--- !COFF +header: + Machine: IMAGE_FILE_MACHINE_AMD64 + Characteristics: [ ] +sections: + - Name: .text + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + - Name: .rdata + Characteristics: [ ] + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] +symbols: + - Name: .text + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + - Name: .rdata + Value: 0 + SectionNumber: 2 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + - Name: func + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: foo + Value: 0 + SectionNumber: 2 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_EXTERNAL +... diff --git a/llvm/test/tools/llvm-objcopy/ELF/redefine-symbol.test b/llvm/test/tools/llvm-objcopy/ELF/redefine-symbol.test --- a/llvm/test/tools/llvm-objcopy/ELF/redefine-symbol.test +++ b/llvm/test/tools/llvm-objcopy/ELF/redefine-symbol.test @@ -1,16 +1,10 @@ # RUN: yaml2obj %s > %t # RUN: llvm-objcopy --redefine-sym foo=oof --redefine-sym empty= %t %t2 # 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: 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: echo " bar rab #rename bar " > %t.rename1.txt +# RUN: echo "foo oof #rename foo " > %t.rename2.txt +# RUN: echo " empty ytpme #rename empty " >> %t.rename2.txt +# RUN: llvm-objcopy --redefine-syms %t.rename1.txt --redefine-syms %t.rename2.txt %t %t4 # RUN: llvm-readobj --symbols %t4 | FileCheck %s --check-prefix=MULTIPLE-FILES !ELF @@ -88,11 +82,6 @@ #CHECK-NEXT: Section: .text #CHECK-NEXT: } -#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 diff --git a/llvm/test/tools/llvm-objcopy/redefine-symbols.test b/llvm/test/tools/llvm-objcopy/redefine-symbols.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-objcopy/redefine-symbols.test @@ -0,0 +1,33 @@ +## Test common parsing errors general to all supported binary formats. + +# RUN: yaml2obj %s > %t + +# RUN: not llvm-objcopy --redefine-sym bar %t /dev/null 2>&1 | FileCheck %s --check-prefix=BAD-FORMAT +# BAD-FORMAT: bad format for --redefine-sym + +# RUN: not llvm-objcopy --redefine-sym foo=f1 --redefine-sym foo=f2 %t /dev/null 2>&1 | FileCheck %s --check-prefix=MULTIPLE-REDEFINITION +# MULTIPLE-REDEFINITION: multiple redefinition of symbol 'foo' + +# RUN: echo ' foo oof #rename foo ' > %t.rename.txt +# RUN: echo 'bar' >> %t.rename.txt +# RUN: not llvm-objcopy --redefine-syms %t.rename.txt %t /dev/null 2>&1 | FileCheck %s --check-prefix=MISSING-SYM-NAME +# MISSING-SYM-NAME: error: {{.*}}.rename.txt:2: missing new symbol name + +# RUN: not llvm-objcopy --redefine-syms %t.rename-none.txt %t /dev/null 2>&1 | FileCheck %s --check-prefix=NO-FILE +# NO-FILE: error: '{{.*}}.rename-none.txt': {{[Nn]}}o such file or directory + +!ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] +Symbols: + - Name: foo + Section: .text + - Name: bar + Section: .text diff --git a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp --- a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp +++ b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp @@ -131,6 +131,12 @@ if (Error E = Obj.markSymbols()) return E; + for (Symbol &Sym : Obj.getMutableSymbols()) { + auto I = Config.SymbolsToRename.find(Sym.Name); + if (I != Config.SymbolsToRename.end()) + Sym.Name = I->getValue(); + } + // Actually do removals of symbols. Obj.removeSymbols([&](const Symbol &Sym) { // For StripAll, all relocations have been stripped and we remove all @@ -200,10 +206,9 @@ !Config.SymbolsToLocalize.empty() || !Config.SymbolsToWeaken.empty() || !Config.SymbolsToKeepGlobal.empty() || !Config.SectionsToRename.empty() || !Config.SetSectionAlignment.empty() || !Config.SetSectionFlags.empty() || - !Config.SymbolsToRename.empty() || Config.ExtractDWO || - Config.KeepFileSymbols || Config.LocalizeHidden || Config.PreserveDates || - Config.StripDWO || Config.StripNonAlloc || Config.StripSections || - Config.Weaken || Config.DecompressDebugSections || + Config.ExtractDWO || Config.KeepFileSymbols || Config.LocalizeHidden || + Config.PreserveDates || Config.StripDWO || Config.StripNonAlloc || + Config.StripSections || Config.Weaken || Config.DecompressDebugSections || Config.DiscardMode == DiscardType::Locals || !Config.SymbolsToAdd.empty() || Config.EntryExpr) { return createStringError(llvm::errc::invalid_argument,