[lld-macho] Ignore LLVM segments to prevent duplicate syms

There was an instance of a third-party archive containing multiple
_llvm symbols from different files that clashed with each other
producing duplicate symbols. Symbols under the LLVM segment
don't seem to be producing any meaningful value, so just ignore them.

Reviewed By: #lld-macho, int3

Differential Revision: https://reviews.llvm.org/D108016
This commit is contained in:
Vincent Lee
2021-08-11 22:08:56 -07:00
parent 6c0e6f91d7
commit 15dc93e61c
2 changed files with 58 additions and 4 deletions

View File

@@ -282,16 +282,24 @@ void ObjFile::parseSections(ArrayRef<Section> sections) {
} else {
auto *isec =
make<ConcatInputSection>(segname, name, this, data, align, flags);
if (!(isDebugSection(isec->getFlags()) &&
isec->getSegName() == segment_names::dwarf)) {
subsections.push_back({{0, isec}});
} else {
if (isDebugSection(isec->getFlags()) &&
isec->getSegName() == segment_names::dwarf) {
// Instead of emitting DWARF sections, we emit STABS symbols to the
// object files that contain them. We filter them out early to avoid
// parsing their relocations unnecessarily. But we must still push an
// empty map to ensure the indices line up for the remaining sections.
subsections.push_back({});
debugSections.push_back(isec);
} else if (isec->getSegName() == segment_names::llvm) {
// ld64 does not appear to emit contents from sections within the __LLVM
// segment. Symbols within those sections point to bitcode metadata
// instead of actual symbols. Global symbols within those sections could
// have the same name without causing duplicate symbol errors. Push an
// empty map to ensure indices line up for the remaining sections.
// TODO: Evaluate whether the bitcode metadata is needed.
subsections.push_back({});
} else {
subsections.push_back({{0, isec}});
}
}
}

View File

@@ -0,0 +1,46 @@
# REQUIRES: x86
# RUN: rm -rf %t; split-file %s %t
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/foo.s -o %t/foo.o
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/bar.s -o %t/bar.o
## "_llvm." symbols are not special. LLD would produce duplicate symbol errors
## if they were not within the LLVM segment.
## 1/ Test that LLD does not produce duplicate symbols errors when linking global symbols
## with the same name under the LLVM segment.
# RUN: %lld -dylib %t/foo.o %t/bar.o -o %t/libDuplicate.dylib
## 2/ Test that all sections within an LLVM segment are dropped.
# RUN: llvm-objdump --section-headers %t/libDuplicate.dylib | FileCheck %s
# CHECK-LABEL: Sections:
# CHECK-NEXT: Idx Name Size VMA Type
# CHECK-NEXT: 0 __text 00000000 {{[0-9a-f]+}} TEXT
## 3/ Test that linking global symbol that is not under the LLVM segment produces duplicate
## symbols
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin --defsym TEXT=0 %t/foo.s -o %t/foo.o
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin --defsym TEXT=0 %t/bar.s -o %t/bar.o
# RUN: not %lld -dylib %t/foo.o %t/bar.o -o %t/libDuplicate.dylib 2>&1 | FileCheck %s --check-prefix=DUP
# DUP: ld64.lld: error: duplicate symbol: _llvm.foo
#--- foo.s
.globl _llvm.foo
.ifdef TEXT
.section __TEXT,__cstring
.else
.section __LLVM,__bitcode
.endif
_llvm.foo:
.asciz "test"
#--- bar.s
.globl _llvm.foo
.ifdef TEXT
.section __TEXT,__cstring
.else
.section __LLVM,__bitcode
.endif
_llvm.foo:
.asciz "test"