diff --git a/llvm/test/tools/llvm-objcopy/COFF/Inputs/discard-locals.yaml b/llvm/test/tools/llvm-objcopy/COFF/Inputs/discard-locals.yaml index 0a8def855ee8..8b34e8fffed0 100644 --- a/llvm/test/tools/llvm-objcopy/COFF/Inputs/discard-locals.yaml +++ b/llvm/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/llvm/test/tools/llvm-objcopy/COFF/discard-all.test b/llvm/test/tools/llvm-objcopy/COFF/discard-all.test index 2ea4f444509b..5d7d5cef2f36 100644 --- a/llvm/test/tools/llvm-objcopy/COFF/discard-all.test +++ b/llvm/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/llvm/test/tools/llvm-objcopy/COFF/strip-unneeded.test b/llvm/test/tools/llvm-objcopy/COFF/strip-unneeded.test index bbecb15e3e4d..569bc8aed2f3 100644 --- a/llvm/test/tools/llvm-objcopy/COFF/strip-unneeded.test +++ b/llvm/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/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp index d48bd0267fae..ea46b841bcff 100644 --- a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp +++ b/llvm/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; }