diff --git a/llvm/lib/MC/WinCOFFObjectWriter.cpp b/llvm/lib/MC/WinCOFFObjectWriter.cpp --- a/llvm/lib/MC/WinCOFFObjectWriter.cpp +++ b/llvm/lib/MC/WinCOFFObjectWriter.cpp @@ -353,9 +353,10 @@ return nullptr; const MCSymbol &Aliasee = SymRef->getSymbol(); - if (!Aliasee.isUndefined()) + if (Aliasee.isUndefined() || Aliasee.isExternal()) + return GetOrCreateCOFFSymbol(&Aliasee); + else return nullptr; - return GetOrCreateCOFFSymbol(&Aliasee); } /// This function takes a symbol data object from the assembler diff --git a/llvm/test/MC/COFF/weak-alias-labels.s b/llvm/test/MC/COFF/weak-alias-labels.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/COFF/weak-alias-labels.s @@ -0,0 +1,122 @@ +// RUN: llvm-mc -filetype=obj -triple i686-pc-win32 %s | llvm-readobj --symbols - | FileCheck %s +// RUN: llvm-mc -filetype=obj -triple x86_64-pc-win32 %s | llvm-readobj --symbols - | FileCheck %s + +// When making weak references to labels/procedures, we reference them directly +// if they have global symbols; otherwise, we need to create a global symbol for +// the reference to resolve to. + + .text + + .globl proc1 +proc1: + ret + +proc2: + ret +// CHECK: Symbol { +// CHECK: Name: proc2 +// CHECK-NEXT: Value: [[PROC2_VALUE:[0-9]+]] +// CHECK-NEXT: Section: [[PROC2_SECTION:.*]] +// CHECK-NEXT: BaseType: Null +// CHECK-NEXT: ComplexType: Null +// CHECK-NEXT: StorageClass: Static +// CHECK-NEXT: AuxSymbolCount: 0 +// CHECK-NEXT: } + + .weak t1 +t1 = proc1 + +// CHECK: Symbol { +// CHECK: Name: t1 +// CHECK-NEXT: Value: 0 +// CHECK-NEXT: Section: IMAGE_SYM_UNDEFINED +// CHECK-NEXT: BaseType: Null +// CHECK-NEXT: ComplexType: Null +// CHECK-NEXT: StorageClass: WeakExternal +// CHECK-NEXT: AuxSymbolCount: 1 +// CHECK-NEXT: AuxWeakExternal { +// CHECK-NEXT: Linked: proc1 +// CHECK-NEXT: Search: Alias +// CHECK-NEXT: } +// CHECK-NEXT: } + + .weak t2 +t2 = proc2 + +// CHECK: Symbol { +// CHECK: Name: t2 +// CHECK-NEXT: Value: 0 +// CHECK-NEXT: Section: IMAGE_SYM_UNDEFINED +// CHECK-NEXT: BaseType: Null +// CHECK-NEXT: ComplexType: Null +// CHECK-NEXT: StorageClass: WeakExternal +// CHECK-NEXT: AuxSymbolCount: 1 +// CHECK-NEXT: AuxWeakExternal { +// CHECK-NEXT: Linked: .weak.t2.default +// CHECK-NEXT: Search: Alias +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK: Symbol { +// CHECK: Name: .weak.t2.default +// CHECK-NEXT: Value: [[PROC2_VALUE]] +// CHECK-NEXT: Section: [[PROC2_SECTION]] +// CHECK-NEXT: BaseType: Null +// CHECK-NEXT: ComplexType: Null +// CHECK-NEXT: StorageClass: External +// CHECK-NEXT: AuxSymbolCount: 0 +// CHECK-NEXT: } + + .weak t3 +t3 = foo + +// CHECK: Symbol { +// CHECK: Name: t3 +// CHECK-NEXT: Value: 0 +// CHECK-NEXT: Section: IMAGE_SYM_UNDEFINED +// CHECK-NEXT: BaseType: Null +// CHECK-NEXT: ComplexType: Null +// CHECK-NEXT: StorageClass: WeakExternal +// CHECK-NEXT: AuxSymbolCount: 1 +// CHECK-NEXT: AuxWeakExternal { +// CHECK-NEXT: Linked: foo +// CHECK-NEXT: Search: Alias +// CHECK-NEXT: } +// CHECK-NEXT: } + + .weak t4 +t4 = bar + + .globl bar +bar: + ret + +// CHECK: Symbol { +// CHECK: Name: t4 +// CHECK-NEXT: Value: 0 +// CHECK-NEXT: Section: IMAGE_SYM_UNDEFINED +// CHECK-NEXT: BaseType: Null +// CHECK-NEXT: ComplexType: Null +// CHECK-NEXT: StorageClass: WeakExternal +// CHECK-NEXT: AuxSymbolCount: 1 +// CHECK-NEXT: AuxWeakExternal { +// CHECK-NEXT: Linked: bar +// CHECK-NEXT: Search: Alias +// CHECK-NEXT: } +// CHECK-NEXT: } + + .weak t5 +t5 = t2 + +// CHECK: Symbol { +// CHECK: Name: t5 +// CHECK-NEXT: Value: 0 +// CHECK-NEXT: Section: IMAGE_SYM_UNDEFINED +// CHECK-NEXT: BaseType: Null +// CHECK-NEXT: ComplexType: Null +// CHECK-NEXT: StorageClass: WeakExternal +// CHECK-NEXT: AuxSymbolCount: 1 +// CHECK-NEXT: AuxWeakExternal { +// CHECK-NEXT: Linked: t2 +// CHECK-NEXT: Search: Alias +// CHECK-NEXT: } +// CHECK-NEXT: } diff --git a/llvm/test/MC/COFF/weak.s b/llvm/test/MC/COFF/weak.s --- a/llvm/test/MC/COFF/weak.s +++ b/llvm/test/MC/COFF/weak.s @@ -32,6 +32,11 @@ .weak _test_weak_alias _test_weak_alias=_main + .weak weakfunc + .globl weakfunc +weakfunc: + ret + // CHECK: Symbols [ // CHECK: Symbol { @@ -47,7 +52,7 @@ // CHECK: Symbol { // CHECK: Name: _test_weak // CHECK-NEXT: Value: 0 -// CHECK-NEXT: Section: IMAGE_SYM_UNDEFINED (0) +// CHECK-NEXT: Section: IMAGE_SYM_UNDEFINED // CHECK-NEXT: BaseType: Null // CHECK-NEXT: ComplexType: Null // CHECK-NEXT: StorageClass: WeakExternal @@ -61,7 +66,7 @@ // CHECK: Symbol { // CHECK: Name: .weak._test_weak.default._main // CHECK-NEXT: Value: 0 -// CHECK-NEXT: Section: IMAGE_SYM_ABSOLUTE (-1) +// CHECK-NEXT: Section: IMAGE_SYM_ABSOLUTE // CHECK-NEXT: BaseType: Null // CHECK-NEXT: ComplexType: Null // CHECK-NEXT: StorageClass: External @@ -71,23 +76,37 @@ // CHECK: Symbol { // CHECK: Name: _test_weak_alias // CHECK-NEXT: Value: 0 -// CHECK-NEXT: Section: IMAGE_SYM_UNDEFINED (0) +// CHECK-NEXT: Section: IMAGE_SYM_UNDEFINED // CHECK-NEXT: BaseType: Null // CHECK-NEXT: ComplexType: Null // CHECK-NEXT: StorageClass: WeakExternal // CHECK-NEXT: AuxSymbolCount: 1 // CHECK-NEXT: AuxWeakExternal { -// CHECK-NEXT: Linked: .weak._test_weak_alias.default -// CHECK-NEXT: Search: Alias +// CHECK-NEXT: Linked: _main +// CHECK-NEXT: Search: Alias // CHECK-NEXT: } // CHECK-NEXT: } // CHECK: Symbol { -// CHECK: Name: .weak._test_weak_alias.default._main -// CHECK-NEXT: Value: 0 -// CHECK-NEXT: Section: .text -// CHECK-NEXT: BaseType: Null -// CHECK-NEXT: ComplexType: Null -// CHECK-NEXT: StorageClass: External +// CHECK: Name: weakfunc +// CHECK-NEXT: Value: 0 +// CHECK-NEXT: Section: IMAGE_SYM_UNDEFINED +// CHECK-NEXT: BaseType: Null +// CHECK-NEXT: ComplexType: Null +// CHECK-NEXT: StorageClass: WeakExternal +// CHECK-NEXT: AuxSymbolCount: 1 +// CHECK-NEXT: AuxWeakExternal { +// CHECK-NEXT: Linked: .weak.weakfunc.default +// CHECK-NEXT: Search: Alias +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK: Symbol { +// CHECK: Name: .weak.weakfunc.default +// CHECK-NOT: Value: 0 +// CHECK-NOT: Symbol { +// CHECK: Section: .text +// CHECK-NEXT: BaseType: Null +// CHECK-NEXT: ComplexType: Null +// CHECK-NEXT: StorageClass: External // CHECK-NEXT: AuxSymbolCount: 0 // CHECK-NEXT: }