Index: test/tools/llvm-objcopy/COFF/Inputs/discard-locals.yaml =================================================================== --- /dev/null +++ test/tools/llvm-objcopy/COFF/Inputs/discard-locals.yaml @@ -0,0 +1,45 @@ +--- !COFF +header: + Machine: IMAGE_FILE_MACHINE_AMD64 + Characteristics: [ ] +sections: + - Name: .text + Characteristics: [ ] + Alignment: 4 + SectionData: E800000000C3C3C3 + Relocations: + - VirtualAddress: 1 + SymbolName: local_referenced + Type: IMAGE_REL_AMD64_REL32 +symbols: + - Name: external + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: external_undefined + 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 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + - Name: local_referenced + Value: 7 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + - Name: local_undefined_unreferenced + Value: 0 + SectionNumber: 0 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC +... Index: test/tools/llvm-objcopy/COFF/discard-all.test =================================================================== --- /dev/null +++ test/tools/llvm-objcopy/COFF/discard-all.test @@ -0,0 +1,25 @@ +RUN: yaml2obj %p/Inputs/discard-locals.yaml > %t.in.o + +RUN: llvm-objdump -t %t.in.o | FileCheck %s --check-prefixes=SYMBOLS,SYMBOLS-PRE + +RUN: llvm-objcopy --discard-all %t.in.o %t.out.o +RUN: llvm-objdump -t %t.out.o | FileCheck %s --check-prefixes=SYMBOLS + +RUN: llvm-objcopy -x %t.in.o %t.out-x.o +RUN: cmp %t.out.o %t.out-x.o + +RUN: cp %t.in.o %t.strip-x.o +RUN: llvm-strip -x %t.strip-x.o +RUN: cmp %t.out.o %t.strip-x.o + +RUN: cp %t.in.o %t.strip-discard-all.o +RUN: llvm-strip --discard-all %t.strip-discard-all.o +RUN: cmp %t.out.o %t.strip-discard-all.o + +SYMBOLS: SYMBOL TABLE: +SYMBOLS-NEXT: external +SYMBOLS-NEXT: external_undefined +SYMBOLS-PRE-NEXT: local_unreferenced +SYMBOLS-NEXT: local_referenced +SYMBOLS-NEXT: local_undefined_unreferenced +SYMBOLS-EMPTY: Index: test/tools/llvm-objcopy/COFF/strip-unneeded.test =================================================================== --- /dev/null +++ test/tools/llvm-objcopy/COFF/strip-unneeded.test @@ -0,0 +1,14 @@ +RUN: yaml2obj %p/Inputs/discard-locals.yaml > %t.in.o + +RUN: llvm-objdump -t %t.in.o | FileCheck %s --check-prefixes=SYMBOLS,SYMBOLS-PRE + +RUN: llvm-objcopy --strip-unneeded %t.in.o %t.out.o +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: local_unreferenced +SYMBOLS-NEXT: local_referenced +SYMBOLS-PRE-NEXT: local_undefined_unreferenced +SYMBOLS-EMPTY: Index: tools/llvm-objcopy/COFF/COFFObjcopy.cpp =================================================================== --- tools/llvm-objcopy/COFF/COFFObjcopy.cpp +++ tools/llvm-objcopy/COFF/COFFObjcopy.cpp @@ -29,7 +29,8 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) { // If we need to do per-symbol removals, initialize the Referenced field. - if (!Config.SymbolsToRemove.empty()) + if (Config.StripUnneeded || Config.DiscardAll || + !Config.SymbolsToRemove.empty()) if (Error E = Obj.markSymbols()) return E; @@ -46,6 +47,16 @@ return true; } + if (!Sym.Referenced && Sym.Sym.StorageClass == IMAGE_SYM_CLASS_STATIC) { + if (Config.StripUnneeded) + 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) + return true; + } + return false; }); return Error::success();