diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -838,6 +838,16 @@ if (!target) return nullptr; + // ELF spec allows mergeable sections with relocations, but they are + // rare, and it is in practice hard to merge such sections by contents, + // because applying relocations at end of linking changes section + // contents. So, we simply handle such sections as non-mergeable ones. + // Degrading like this is acceptable because section merging is optional. + if (auto *ms = dyn_cast(target)) { + target = toRegularSection(ms); + this->sections[sec.sh_info] = target; + } + // This section contains relocation information. // If -r is given, we do not interpret or apply relocation // but just copy relocation sections to output. @@ -856,16 +866,6 @@ fatal(toString(this) + ": multiple relocation sections to one section are not supported"); - // ELF spec allows mergeable sections with relocations, but they are - // rare, and it is in practice hard to merge such sections by contents, - // because applying relocations at end of linking changes section - // contents. So, we simply handle such sections as non-mergeable ones. - // Degrading like this is acceptable because section merging is optional. - if (auto *ms = dyn_cast(target)) { - target = toRegularSection(ms); - this->sections[sec.sh_info] = target; - } - if (sec.sh_type == SHT_RELA) { ArrayRef rels = CHECK(getObj().relas(&sec), this); target->firstRelocation = rels.begin(); diff --git a/lld/test/ELF/merge-relocatable.s b/lld/test/ELF/merge-relocatable.s new file mode 100644 --- /dev/null +++ b/lld/test/ELF/merge-relocatable.s @@ -0,0 +1,23 @@ +# REQUIRES: x86 + +## Test that we keep a SHT_REL[A] section which relocates a SHF_MERGE section +## in -r mode. The relocated SHF_MERGE section is handled as non-mergeable. + +# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o +# RUN: ld.lld -r %t.o -o %t +# RUN: llvm-readobj -S %t | FileCheck %s + +# CHECK: Name: .rodata.cst8 +# CHECK-NOT: } +# CHECK: Size: 16 +# CHECK: Name: .rela.rodata.cst8 +# CHECK-NOT: } +# CHECK: Size: 48 + +foo: + +.section .rodata.cst8,"aM",@progbits,8,unique,0 +.quad foo + +.section .rodata.cst8,"aM",@progbits,8,unique,1 +.quad foo