From b3ba70f0067cdf2775b14ea0609b96c9ae8091e0 Mon Sep 17 00:00:00 2001 From: Martin Storsjo Date: Fri, 20 Jul 2018 20:48:29 +0000 Subject: [PATCH] [COFF] Adjust how we flag weak externals This fixes PR36096. Originally based on a patch by Martell Malone. Differential Revision: https://reviews.llvm.org/D44357 llvm-svn: 337613 --- include/llvm/Object/COFF.h | 8 +++ lib/Object/ArchiveWriter.cpp | 3 +- lib/Object/COFFObjectFile.cpp | 8 +-- test/tools/llvm-ar/coff-weak.yaml | 53 +++++++++++++++++++ test/tools/llvm-dlltool/coff-decorated.def | 2 +- test/tools/llvm-dlltool/coff-weak-exports.def | 8 +-- 6 files changed, 71 insertions(+), 11 deletions(-) create mode 100644 test/tools/llvm-ar/coff-weak.yaml diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h index df9bf607b12..6caadea0175 100644 --- a/include/llvm/Object/COFF.h +++ b/include/llvm/Object/COFF.h @@ -276,6 +276,7 @@ struct coff_symbol_generic { }; struct coff_aux_section_definition; +struct coff_aux_weak_external; class COFFSymbolRef { public: @@ -360,6 +361,13 @@ public: return getAux(); } + const coff_aux_weak_external *getWeakExternal() const { + if (!getNumberOfAuxSymbols() || + getStorageClass() != COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL) + return nullptr; + return getAux(); + } + bool isAbsolute() const { return getSectionNumber() == -1; } diff --git a/lib/Object/ArchiveWriter.cpp b/lib/Object/ArchiveWriter.cpp index c9796736896..ea17b2220a0 100644 --- a/lib/Object/ArchiveWriter.cpp +++ b/lib/Object/ArchiveWriter.cpp @@ -294,8 +294,7 @@ static bool isArchiveSymbol(const object::BasicSymbolRef &S) { return false; if (!(Symflags & object::SymbolRef::SF_Global)) return false; - if (Symflags & object::SymbolRef::SF_Undefined && - !(Symflags & object::SymbolRef::SF_Indirect)) + if (Symflags & object::SymbolRef::SF_Undefined) return false; return true; } diff --git a/lib/Object/COFFObjectFile.cpp b/lib/Object/COFFObjectFile.cpp index 26194888ac0..d72da3187e0 100644 --- a/lib/Object/COFFObjectFile.cpp +++ b/lib/Object/COFFObjectFile.cpp @@ -217,10 +217,10 @@ uint32_t COFFObjectFile::getSymbolFlags(DataRefImpl Ref) const { if (Symb.isExternal() || Symb.isWeakExternal()) Result |= SymbolRef::SF_Global; - if (Symb.isWeakExternal()) { + if (const coff_aux_weak_external *AWE = Symb.getWeakExternal()) { Result |= SymbolRef::SF_Weak; - // We use indirect to allow the archiver to write weak externs - Result |= SymbolRef::SF_Indirect; + if (AWE->Characteristics != COFF::IMAGE_WEAK_EXTERN_SEARCH_ALIAS) + Result |= SymbolRef::SF_Undefined; } if (Symb.getSectionNumber() == COFF::IMAGE_SYM_ABSOLUTE) @@ -235,7 +235,7 @@ uint32_t COFFObjectFile::getSymbolFlags(DataRefImpl Ref) const { if (Symb.isCommon()) Result |= SymbolRef::SF_Common; - if (Symb.isAnyUndefined()) + if (Symb.isUndefined()) Result |= SymbolRef::SF_Undefined; return Result; diff --git a/test/tools/llvm-ar/coff-weak.yaml b/test/tools/llvm-ar/coff-weak.yaml new file mode 100644 index 00000000000..c66271dc8a7 --- /dev/null +++ b/test/tools/llvm-ar/coff-weak.yaml @@ -0,0 +1,53 @@ +# RUN: yaml2obj %s -o %t.obj +# +# RUN: rm -f %t.ar +# RUN: llvm-ar crs %t.a %t.obj +# RUN: llvm-nm -print-armap %t.a | FileCheck %s + +# CHECK: Archive map +# CHECK-NEXT: WeakSearchAlias in coff-weak.yaml.tmp.obj +# CHECK-EMPTY: + +--- !COFF +header: + Machine: IMAGE_FILE_MACHINE_UNKNOWN + Characteristics: [ ] +sections: + - Name: .drectve + Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] + SectionData: '' +symbols: + - Name: NormalUndefined + Value: 0 + SectionNumber: 0 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: WeakSearchAlias + Value: 0 + SectionNumber: 0 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_WEAK_EXTERNAL + WeakExternal: + TagIndex: 0 + Characteristics: IMAGE_WEAK_EXTERN_SEARCH_ALIAS + - Name: WeakSearchLibrary + Value: 0 + SectionNumber: 0 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_WEAK_EXTERNAL + WeakExternal: + TagIndex: 0 + Characteristics: IMAGE_WEAK_EXTERN_SEARCH_LIBRARY + - Name: WeakSearchNolibrary + Value: 0 + SectionNumber: 0 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_WEAK_EXTERNAL + WeakExternal: + TagIndex: 0 + Characteristics: IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY +... diff --git a/test/tools/llvm-dlltool/coff-decorated.def b/test/tools/llvm-dlltool/coff-decorated.def index d6496b098f9..3885abca836 100644 --- a/test/tools/llvm-dlltool/coff-decorated.def +++ b/test/tools/llvm-dlltool/coff-decorated.def @@ -22,5 +22,5 @@ StdcallAlias@4==StdcallFunction@4 ; CHECK: Name type: name ; CHECK: Symbol: __imp_??_7exception@@6B@ ; CHECK: Symbol: ??_7exception@@6B@ -; CHECK-NM: w _StdcallAlias@4 +; CHECK-NM: W _StdcallAlias@4 ; CHECK-NM: U _StdcallFunction@4 diff --git a/test/tools/llvm-dlltool/coff-weak-exports.def b/test/tools/llvm-dlltool/coff-weak-exports.def index 693a03a445a..dbc59be8ae1 100644 --- a/test/tools/llvm-dlltool/coff-weak-exports.def +++ b/test/tools/llvm-dlltool/coff-weak-exports.def @@ -15,14 +15,14 @@ ImpLibName2 = Implementation2 == AltTestFunction2 ImpLibName3 = kernel32.Sleep ; CHECK: U AltTestFunction -; CHECK-NEXT: w TestFunction +; CHECK-NEXT: W TestFunction ; CHECK: U __imp_AltTestFunction -; CHECK-NEXT: w __imp_TestFunction +; CHECK-NEXT: W __imp_TestFunction ; CHECK: T ImpLibName ; CHECK-NEXT: T __imp_ImpLibName ; CHECK: U AltTestFunction2 -; CHECK-NEXT: w ImpLibName2 +; CHECK-NEXT: W ImpLibName2 ; CHECK: U __imp_AltTestFunction2 -; CHECK-NEXT: w __imp_ImpLibName2 +; CHECK-NEXT: W __imp_ImpLibName2 ; CHECK: T ImpLibName3 ; CHECK-NEXT: T __imp_ImpLibName3