From 7c395d1b358a949e4cc8f69762dff5bfa244ca70 Mon Sep 17 00:00:00 2001 From: Martin Storsjo Date: Mon, 14 Jan 2019 18:56:47 +0000 Subject: [PATCH] [llvm-objcopy] [COFF] Remove unreferenced undefined externals with --strip-unneeded. Differential Revision: https://reviews.llvm.org/D56660 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351099 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../llvm-objcopy/COFF/Inputs/discard-locals.yaml | 11 ++++++++++- test/tools/llvm-objcopy/COFF/discard-all.test | 1 + test/tools/llvm-objcopy/COFF/strip-unneeded.test | 1 + tools/llvm-objcopy/COFF/COFFObjcopy.cpp | 12 +++++++++--- 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/test/tools/llvm-objcopy/COFF/Inputs/discard-locals.yaml b/test/tools/llvm-objcopy/COFF/Inputs/discard-locals.yaml index 0a8def855ee..8b34e8fffed 100644 --- a/test/tools/llvm-objcopy/COFF/Inputs/discard-locals.yaml +++ b/test/tools/llvm-objcopy/COFF/Inputs/discard-locals.yaml @@ -6,11 +6,14 @@ sections: - Name: .text Characteristics: [ ] Alignment: 4 - SectionData: E800000000C3C3C3 + SectionData: E800000000E800000000C3C3C3 Relocations: - VirtualAddress: 1 SymbolName: local_referenced Type: IMAGE_REL_AMD64_REL32 + - VirtualAddress: 5 + SymbolName: external_undefined + Type: IMAGE_REL_AMD64_REL32 symbols: - Name: external Value: 0 @@ -24,6 +27,12 @@ symbols: SimpleType: IMAGE_SYM_TYPE_NULL ComplexType: IMAGE_SYM_DTYPE_NULL StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: external_undefined_unreferenced + Value: 0 + SectionNumber: 0 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_EXTERNAL - Name: local_unreferenced Value: 6 SectionNumber: 1 diff --git a/test/tools/llvm-objcopy/COFF/discard-all.test b/test/tools/llvm-objcopy/COFF/discard-all.test index 2ea4f444509..5d7d5cef2f3 100644 --- a/test/tools/llvm-objcopy/COFF/discard-all.test +++ b/test/tools/llvm-objcopy/COFF/discard-all.test @@ -19,6 +19,7 @@ RUN: cmp %t.out.o %t.strip-discard-all.o SYMBOLS: SYMBOL TABLE: SYMBOLS-NEXT: external SYMBOLS-NEXT: external_undefined +SYMBOLS-NEXT: external_undefined_unreferenced SYMBOLS-PRE-NEXT: local_unreferenced SYMBOLS-NEXT: local_referenced SYMBOLS-NEXT: local_undefined_unreferenced diff --git a/test/tools/llvm-objcopy/COFF/strip-unneeded.test b/test/tools/llvm-objcopy/COFF/strip-unneeded.test index bbecb15e3e4..569bc8aed2f 100644 --- a/test/tools/llvm-objcopy/COFF/strip-unneeded.test +++ b/test/tools/llvm-objcopy/COFF/strip-unneeded.test @@ -8,6 +8,7 @@ RUN: llvm-objdump -t %t.out.o | FileCheck %s --check-prefix=SYMBOLS SYMBOLS: SYMBOL TABLE: SYMBOLS-NEXT: external SYMBOLS-NEXT: external_undefined +SYMBOLS-PRE-NEXT: external_undefined_unreferenced SYMBOLS-PRE-NEXT: local_unreferenced SYMBOLS-NEXT: local_referenced SYMBOLS-PRE-NEXT: local_undefined_unreferenced diff --git a/tools/llvm-objcopy/COFF/COFFObjcopy.cpp b/tools/llvm-objcopy/COFF/COFFObjcopy.cpp index d48bd0267fa..ea46b841bcf 100644 --- a/tools/llvm-objcopy/COFF/COFFObjcopy.cpp +++ b/tools/llvm-objcopy/COFF/COFFObjcopy.cpp @@ -47,13 +47,19 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) { return true; } - if (!Sym.Referenced && Sym.Sym.StorageClass == IMAGE_SYM_CLASS_STATIC) { - if (Config.StripUnneeded) + if (!Sym.Referenced) { + // With --strip-unneeded, GNU objcopy removes all unreferenced local + // symbols, and any unreferenced undefined external. + if (Config.StripUnneeded && + (Sym.Sym.StorageClass == IMAGE_SYM_CLASS_STATIC || + Sym.Sym.SectionNumber == 0)) return true; + // GNU objcopy keeps referenced local symbols and external symbols // if --discard-all is set, similar to what --strip-unneeded does, // but undefined local symbols are kept when --discard-all is set. - if (Config.DiscardAll && Sym.Sym.SectionNumber != 0) + if (Config.DiscardAll && Sym.Sym.StorageClass == IMAGE_SYM_CLASS_STATIC && + Sym.Sym.SectionNumber != 0) return true; } -- 2.40.0