diff options
author | Jez Ng <jezng@fb.com> | 2020-09-24 15:00:56 -0700 |
---|---|---|
committer | Jez Ng <jezng@fb.com> | 2020-09-24 15:00:56 -0700 |
commit | 5213576fa25e6deb7c649032b2893726de2f8b6c (patch) | |
tree | 45dfa62bf47c3fb1a6acfaba8b030255c5570b1b /lld | |
parent | c32e69b2ce7abfb151a87ba363ac9e25abf7d417 (diff) | |
download | llvm-5213576fa25e6deb7c649032b2893726de2f8b6c.zip llvm-5213576fa25e6deb7c649032b2893726de2f8b6c.tar.gz llvm-5213576fa25e6deb7c649032b2893726de2f8b6c.tar.bz2 |
[lld-macho][re-land] Implement and test resolution of common symbols
Earlier build break fixed in c32e69b2ce7abfb151a87ba363ac9e25abf7d417.
This reverts commit c367f93e8539c4d0bcdc86ad7ea7923e06231a93.
Diffstat (limited to 'lld')
-rw-r--r-- | lld/MachO/SymbolTable.cpp | 5 | ||||
-rw-r--r-- | lld/test/MachO/common-symbol-resolution.s | 113 | ||||
-rw-r--r-- | lld/test/MachO/nonweak-definition-override.s | 18 |
3 files changed, 134 insertions, 2 deletions
diff --git a/lld/MachO/SymbolTable.cpp b/lld/MachO/SymbolTable.cpp index 6719981..0aa8828 100644 --- a/lld/MachO/SymbolTable.cpp +++ b/lld/MachO/SymbolTable.cpp @@ -84,10 +84,11 @@ Symbol *SymbolTable::addCommon(StringRef name, InputFile *file, uint64_t size, if (auto *common = dyn_cast<CommonSymbol>(s)) { if (size < common->size) return s; - } else if (!isa<Undefined>(s)) { - error("TODO: implement common symbol resolution with other symbol kinds"); + } else if (isa<Defined>(s)) { return s; } + // Common symbols take priority over all non-Defined symbols, so in case of + // a name conflict, we fall through to the replaceSymbol() call below. } replaceSymbol<CommonSymbol>(s, name, file, size, align); diff --git a/lld/test/MachO/common-symbol-resolution.s b/lld/test/MachO/common-symbol-resolution.s new file mode 100644 index 0000000..6cefe30 --- /dev/null +++ b/lld/test/MachO/common-symbol-resolution.s @@ -0,0 +1,113 @@ +# REQUIRES: x86 +# RUN: split-file %s %t + +# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/common.s -o %t/common.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/weak-common.s -o %t/weak-common.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/defined.s -o %t/defined.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/weak-defined.s -o %t/weak-defined.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/libfoo.s -o %t/libfoo.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/test.s -o %t/test.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/calls-foo.s -o %t/calls-foo.o + +# RUN: lld -flavor darwinnew -syslibroot %S/Inputs/MacOSX.sdk -lSystem -order_file %t/order -dylib %t/libfoo.o -o %t/libfoo.dylib + +# RUN: rm -f %t/defined.a %t/weak-defined-and-common.a +# RUN: llvm-ar rcs %t/defined.a %t/defined.o +# RUN: llvm-ar rcs %t/weak-defined-and-common.a %t/weak-defined.o %t/common.o + +## The weak attribute appears to have no effect on common symbols. Given two +## common symbols of the same name, we always pick the one with the larger size, +## regardless of whether it is weak. Moreover, the resolved symbol in the output +## file will always be non-weak, even if the winning input symbol definition was +## weak. +# RUN: lld -flavor darwinnew -syslibroot %S/Inputs/MacOSX.sdk -lSystem -order_file %t/order %t/common.o %t/weak-common.o %t/test.o -o %t/test +# RUN: llvm-objdump --syms %t/test | FileCheck %s --check-prefix=LARGER-COMMON +# RUN: lld -flavor darwinnew -syslibroot %S/Inputs/MacOSX.sdk -lSystem -order_file %t/order %t/weak-common.o %t/common.o %t/test.o -o %t/test +# RUN: llvm-objdump --syms %t/test | FileCheck %s --check-prefix=LARGER-COMMON + +## Defined symbols are the only ones that take precedence over common symbols. +# RUN: lld -flavor darwinnew -syslibroot %S/Inputs/MacOSX.sdk -lSystem -order_file %t/order %t/defined.o %t/common.o %t/test.o -o %t/test +# RUN: llvm-objdump --syms %t/test | FileCheck %s --check-prefix=DEFINED +# RUN: lld -flavor darwinnew -syslibroot %S/Inputs/MacOSX.sdk -lSystem -order_file %t/order %t/common.o %t/defined.o %t/test.o -o %t/test +# RUN: llvm-objdump --syms %t/test | FileCheck %s --check-prefix=DEFINED + +# RUN: lld -flavor darwinnew -syslibroot %S/Inputs/MacOSX.sdk -lSystem -order_file %t/order %t/weak-defined.o %t/common.o %t/test.o -o %t/test +# RUN: llvm-objdump --syms %t/test | FileCheck %s --check-prefix=WEAK-DEFINED +# RUN: lld -flavor darwinnew -syslibroot %S/Inputs/MacOSX.sdk -lSystem -order_file %t/order %t/common.o %t/weak-defined.o %t/test.o -o %t/test +# RUN: llvm-objdump --syms %t/test | FileCheck %s --check-prefix=WEAK-DEFINED + +## Common symbols take precedence over archive symbols. +# RUN: lld -flavor darwinnew -syslibroot %S/Inputs/MacOSX.sdk -lSystem -order_file %t/order %t/defined.a %t/weak-common.o %t/test.o -o %t/test +# RUN: llvm-objdump --syms %t/test | FileCheck %s --check-prefix=LARGER-COMMON +# RUN: lld -flavor darwinnew -syslibroot %S/Inputs/MacOSX.sdk -lSystem -order_file %t/order %t/weak-common.o %t/defined.a %t/test.o -o %t/test +# RUN: llvm-objdump --syms %t/test | FileCheck %s --check-prefix=LARGER-COMMON + +## If an archive has both a common and a defined symbol, the defined one should +## win. +# RUN: lld -flavor darwinnew -syslibroot %S/Inputs/MacOSX.sdk -lSystem -order_file %t/order %t/weak-defined-and-common.a %t/calls-foo.o -o %t/calls-foo +# RUN: llvm-objdump --syms %t/calls-foo | FileCheck %s --check-prefix=WEAK-DEFINED +# RUN: lld -flavor darwinnew -syslibroot %S/Inputs/MacOSX.sdk -lSystem -order_file %t/order %t/calls-foo.o %t/weak-defined-and-common.a -o %t/calls-foo +# RUN: llvm-objdump --syms %t/calls-foo | FileCheck %s --check-prefix=WEAK-DEFINED + +## Common symbols take precedence over dylib symbols. +# RUN: lld -flavor darwinnew -syslibroot %S/Inputs/MacOSX.sdk -lSystem -order_file %t/order %t/libfoo.dylib %t/weak-common.o %t/test.o -o %t/test +# RUN: llvm-objdump --syms %t/test | FileCheck %s --check-prefix=LARGER-COMMON +# RUN: lld -flavor darwinnew -syslibroot %S/Inputs/MacOSX.sdk -lSystem -order_file %t/order %t/weak-common.o %t/libfoo.dylib %t/test.o -o %t/test +# RUN: llvm-objdump --syms %t/test | FileCheck %s --check-prefix=LARGER-COMMON + +# LARGER-COMMON-LABEL: SYMBOL TABLE: +# LARGER-COMMON-DAG: [[#%x, FOO_ADDR:]] g O __DATA,__common _foo +# LARGER-COMMON-DAG: [[#FOO_ADDR + 2]] g O __DATA,__common _foo_end + +# DEFINED-LABEL: SYMBOL TABLE: +# DEFINED: g F __TEXT,__text _foo + +# WEAK-DEFINED-LABEL: SYMBOL TABLE: +# WEAK-DEFINED: w F __TEXT,__text _foo + +#--- order +## %t/order is important as we determine the size of a given symbol via the +## address of the next symbol. +_foo +_foo_end + +#--- common.s +.comm _foo, 1 + +.globl _bar +_bar: + +#--- weak-common.s +.weak_definition _foo +.comm _foo, 2 + +#--- defined.s +.globl _foo +_foo: + .quad 0x1234 + +#--- weak-defined.s +.globl _foo +.weak_definition _foo +_foo: + .quad 0x1234 + +#--- libfoo.s +.globl _foo +_foo: + .quad 0x1234 + +#--- test.s +.comm _foo_end, 1 + +.globl _main +_main: + ret + +#--- calls-foo.s +.comm _foo_end, 1 + +.globl _main +_main: + callq _foo + ret diff --git a/lld/test/MachO/nonweak-definition-override.s b/lld/test/MachO/nonweak-definition-override.s index d5c94d4..c531d2b 100644 --- a/lld/test/MachO/nonweak-definition-override.s +++ b/lld/test/MachO/nonweak-definition-override.s @@ -3,6 +3,7 @@ # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/libfoo.s -o %t/libfoo.o # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/nonweakdef.s -o %t/nonweakdef.o # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/weakdef.s -o %t/weakdef.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/common.s -o %t/common.o # RUN: lld -flavor darwinnew -syslibroot %S/Inputs/MacOSX.sdk -dylib %t/libfoo.o -o %t/libfoo.dylib ## Check that non-weak defined symbols override weak dylib symbols. @@ -30,6 +31,14 @@ # NO-WEAK-OVERRIDE-NEXT: segment section address type addend symbol # NO-WEAK-OVERRIDE-EMPTY: +## Check that common symbols take precedence over weak dylib symbols, but do not +## generate an overridding weak binding. +# RUN: lld -flavor darwinnew -syslibroot %S/Inputs/MacOSX.sdk -L%t -lfoo %t/common.o -o %t/common -lSystem +# RUN: llvm-objdump --macho --weak-bind %t/common | FileCheck %s --check-prefix=NO-WEAK-OVERRIDE +# RUN: llvm-objdump --syms %t/common | FileCheck %s --check-prefix=COMMON +# COMMON-DAG: g O __DATA,__common _nonweak_in_dylib +# COMMON-DAG: g O __DATA,__common _weak_in_dylib + #--- libfoo.s .globl _weak_in_dylib, _nonweak_in_dylib @@ -58,3 +67,12 @@ _nonweak_in_dylib: _main: ret + +#--- common.s + +.globl _main +.comm _weak_in_dylib, 1 +.comm _nonweak_in_dylib, 1 + +_main: + ret |