summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/Object/COFF.h8
-rw-r--r--llvm/lib/Object/ArchiveWriter.cpp3
-rw-r--r--llvm/lib/Object/COFFObjectFile.cpp8
-rw-r--r--llvm/test/tools/llvm-ar/coff-weak.yaml53
-rw-r--r--llvm/test/tools/llvm-dlltool/coff-decorated.def2
-rw-r--r--llvm/test/tools/llvm-dlltool/coff-weak-exports.def8
6 files changed, 71 insertions, 11 deletions
diff --git a/llvm/include/llvm/Object/COFF.h b/llvm/include/llvm/Object/COFF.h
index df9bf607b12..6caadea0175 100644
--- a/llvm/include/llvm/Object/COFF.h
+++ b/llvm/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<coff_aux_section_definition>();
}
+ const coff_aux_weak_external *getWeakExternal() const {
+ if (!getNumberOfAuxSymbols() ||
+ getStorageClass() != COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL)
+ return nullptr;
+ return getAux<coff_aux_weak_external>();
+ }
+
bool isAbsolute() const {
return getSectionNumber() == -1;
}
diff --git a/llvm/lib/Object/ArchiveWriter.cpp b/llvm/lib/Object/ArchiveWriter.cpp
index c9796736896..ea17b2220a0 100644
--- a/llvm/lib/Object/ArchiveWriter.cpp
+++ b/llvm/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/llvm/lib/Object/COFFObjectFile.cpp b/llvm/lib/Object/COFFObjectFile.cpp
index 26194888ac0..d72da3187e0 100644
--- a/llvm/lib/Object/COFFObjectFile.cpp
+++ b/llvm/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/llvm/test/tools/llvm-ar/coff-weak.yaml b/llvm/test/tools/llvm-ar/coff-weak.yaml
new file mode 100644
index 00000000000..c66271dc8a7
--- /dev/null
+++ b/llvm/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/llvm/test/tools/llvm-dlltool/coff-decorated.def b/llvm/test/tools/llvm-dlltool/coff-decorated.def
index d6496b098f9..3885abca836 100644
--- a/llvm/test/tools/llvm-dlltool/coff-decorated.def
+++ b/llvm/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/llvm/test/tools/llvm-dlltool/coff-weak-exports.def b/llvm/test/tools/llvm-dlltool/coff-weak-exports.def
index 693a03a445a..dbc59be8ae1 100644
--- a/llvm/test/tools/llvm-dlltool/coff-weak-exports.def
+++ b/llvm/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
OpenPOWER on IntegriCloud