From: George Rimar Date: Fri, 24 May 2019 15:04:50 +0000 (+0000) Subject: [llvm-objcopy] - Strip undefined symbols if they are no longer referenced following... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=67b61d3101c52d53d7f324163e489e60994066e8;p=llvm [llvm-objcopy] - Strip undefined symbols if they are no longer referenced following --only-section This is https://bugs.llvm.org/show_bug.cgi?id=40004. In this patch I teach llvm-objcopy to remove undefined symbols if them are not used anymore after applying -j/--only-section option. Differential revision: https://reviews.llvm.org/D62317 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@361642 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/test/tools/llvm-objcopy/ELF/only-section-strip-undefined.test b/test/tools/llvm-objcopy/ELF/only-section-strip-undefined.test new file mode 100644 index 00000000000..c9d21ac8b2e --- /dev/null +++ b/test/tools/llvm-objcopy/ELF/only-section-strip-undefined.test @@ -0,0 +1,60 @@ +## Here we want to check that llvm-objcopy removes an undefined symbol +## if all references to it have been stripped. + +# RUN: yaml2obj --docnum=1 %s -o %t.o +# RUN: llvm-objcopy -j .other.section %t.o %t2.o +# RUN: llvm-readobj --symbols %t2.o | FileCheck %s --implicit-check-not=bar + +# RUN: llvm-objcopy -j .text -j .rela.text1 %t.o %t2.o +# RUN: llvm-readobj --symbols %t2.o | FileCheck %s --check-prefix=BAR + +# BAR: bar + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .text + Type: SHT_PROGBITS + - Name: .rela.text1 + Type: SHT_RELA + Relocations: + - Offset: 0x0000000000000001 + Symbol: bar + Type: R_X86_64_32 + - Name: .rela.text2 + Type: SHT_RELA + Relocations: + - Offset: 0x0000000000000001 + Symbol: bar + Type: R_X86_64_32 + - Name: .other.section + Type: SHT_PROGBITS +Symbols: + - Name: bar + Binding: STB_GLOBAL +... + +## Check we remove unreferenced undefined symbols, even if +## they weren't previously referenced. This follows GNU. + +# RUN: yaml2obj --docnum=2 %s -o %t.o +# RUN: llvm-objcopy -j .keep_me %t.o %t2.o +# RUN: llvm-readobj --symbols %t2.o | FileCheck %s --implicit-check-not=bar + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .keep_me + Type: SHT_PROGBITS +Symbols: + - Name: bar + Binding: STB_GLOBAL +... diff --git a/tools/llvm-objcopy/ELF/ELFObjcopy.cpp b/tools/llvm-objcopy/ELF/ELFObjcopy.cpp index b2e750d15f0..be25bd5ee43 100644 --- a/tools/llvm-objcopy/ELF/ELFObjcopy.cpp +++ b/tools/llvm-objcopy/ELF/ELFObjcopy.cpp @@ -387,7 +387,8 @@ static Error updateAndRemoveSymbols(const CopyConfig &Config, Object &Obj) { // The purpose of this loop is to mark symbols referenced by sections // (like GroupSection or RelocationSection). This way, we know which // symbols are still 'needed' and which are not. - if (Config.StripUnneeded || !Config.UnneededSymbolsToRemove.empty()) { + if (Config.StripUnneeded || !Config.UnneededSymbolsToRemove.empty() || + !Config.OnlySection.empty()) { for (auto &Section : Obj.sections()) Section.markSymbols(); } @@ -415,6 +416,11 @@ static Error updateAndRemoveSymbols(const CopyConfig &Config, Object &Obj) { isUnneededSymbol(Sym)) return true; + // We want to remove undefined symbols if all references have been stripped. + if (!Config.OnlySection.empty() && !Sym.Referenced && + Sym.getShndx() == SHN_UNDEF) + return true; + return false; };