Index: lld/trunk/ELF/InputSection.cpp =================================================================== --- lld/trunk/ELF/InputSection.cpp +++ lld/trunk/ELF/InputSection.cpp @@ -411,7 +411,8 @@ } if (Config->IsRela) { - P->r_addend += Sym.getVA() - Section->getOutputSection()->Addr; + P->r_addend = + Sym.getVA(getAddend(Rel)) - Section->getOutputSection()->Addr; } else if (Config->Relocatable) { const uint8_t *BufLoc = Sec->Data.begin() + Rel.r_offset; Sec->Relocations.push_back({R_ABS, Type, Rel.r_offset, Index: lld/trunk/ELF/Writer.cpp =================================================================== --- lld/trunk/ELF/Writer.cpp +++ lld/trunk/ELF/Writer.cpp @@ -473,8 +473,10 @@ } template void Writer::addSectionSymbols() { - // Create one STT_SECTION symbol for each output section we might - // have a relocation with. + // Create a section symbol for each output section so that we can represent + // relocations that point to the section. If we know that no relocation is + // referring to a section (that happens if the section is a synthetic one), we + // don't create a section symbol for that section. for (BaseCommand *Base : Script->SectionCommands) { auto *Sec = dyn_cast(Base); if (!Sec) @@ -487,8 +489,15 @@ if (I == Sec->SectionCommands.end()) continue; InputSection *IS = cast(*I)->Sections[0]; - if (isa(IS) || IS->Type == SHT_REL || - IS->Type == SHT_RELA) + + // Relocations are not using REL[A] section symbols. + if (IS->Type == SHT_REL || IS->Type == SHT_RELA) + continue; + + // Unlike other synthetic sections, mergeable output sections contain data + // copied from input sections, and there may be a relocation pointing to its + // contents if -emit-reloc is given. + if (isa(IS) && !(IS->Flags & SHF_MERGE)) continue; auto *Sym = make("", /*IsLocal=*/true, /*StOther=*/0, STT_SECTION, Index: lld/trunk/test/ELF/emit-relocs-mergeable-i386.s =================================================================== --- lld/trunk/test/ELF/emit-relocs-mergeable-i386.s +++ lld/trunk/test/ELF/emit-relocs-mergeable-i386.s @@ -0,0 +1,66 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t1 +# RUN: ld.lld --emit-relocs %t1 -o %t2 +# RUN: llvm-readobj -sections -section-data %t2 | FileCheck %s + +## Check lf we produce proper relocations when doing merging of SHF_MERGE sections. + +## Check addends of relocations are: 0x0, 0x8, 0x8, 0x4 +# CHECK: Section { +# CHECK: Index: +# CHECK: Name: .foo +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: SHF_EXECINSTR +# CHECK-NEXT: ] +# CHECK-NEXT: Address: +# CHECK-NEXT: Offset: +# CHECK-NEXT: Size: +# CHECK-NEXT: Link: +# CHECK-NEXT: Info: +# CHECK-NEXT: AddressAlignment: +# CHECK-NEXT: EntrySize: +# CHECK-NEXT: SectionData ( +# CHECK-NEXT: 0000: 00000000 08000000 08000000 04000000 +# CHECK-NEXT: ) +# CHECK-NEXT: } + +## Check that offsets for AAA is 0x0, for BBB is 0x8 and CCC has offset 0x4. +# CHECK: Section { +# CHECK: Index: +# CHECK: Name: .strings +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_MERGE +# CHECK-NEXT: SHF_STRINGS +# CHECK-NEXT: ] +# CHECK-NEXT: Address: +# CHECK-NEXT: Offset: +# CHECK-NEXT: Size: +# CHECK-NEXT: Link: +# CHECK-NEXT: Info: +# CHECK-NEXT: AddressAlignment: +# CHECK-NEXT: EntrySize: +# CHECK-NEXT: SectionData ( +# CHECK-NEXT: |AAA.CCC.BBB.| +# CHECK-NEXT: ) +# CHECK-NEXT: } + +.section .strings,"MS",@progbits,1,unique,10 +.Linfo_string0: + .asciz "AAA" +.Linfo_string1: + .asciz "BBB" + +.section .strings,"MS",@progbits,1,unique,20 +.Linfo_string2: + .asciz "BBB" +.Linfo_string3: + .asciz "CCC" + +.section .foo,"ax",@progbits +.long .Linfo_string0 +.long .Linfo_string1 +.long .Linfo_string2 +.long .Linfo_string3 Index: lld/trunk/test/ELF/emit-relocs-mergeable.s =================================================================== --- lld/trunk/test/ELF/emit-relocs-mergeable.s +++ lld/trunk/test/ELF/emit-relocs-mergeable.s @@ -0,0 +1,53 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1 +# RUN: ld.lld --emit-relocs %t1 -o %t2 +# RUN: llvm-readobj -sections -section-data -r %t2 | FileCheck %s + +## Check if we produce proper relocations when doing merging of SHF_MERGE sections. + +# CHECK: Section { +# CHECK: Index: +# CHECK: Name: .strings +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_MERGE +# CHECK-NEXT: SHF_STRINGS +# CHECK-NEXT: ] +# CHECK-NEXT: Address: +# CHECK-NEXT: Offset: +# CHECK-NEXT: Size: 12 +# CHECK-NEXT: Link: +# CHECK-NEXT: Info: +# CHECK-NEXT: AddressAlignment: +# CHECK-NEXT: EntrySize: +# CHECK-NEXT: SectionData ( +# CHECK-NEXT: 0000: 41414100 43434300 42424200 |AAA.CCC.BBB.| +# CHECK-NEXT: ) +# CHECK-NEXT: } + +# CHECK: Relocations [ +# CHECK-NEXT: Section {{.*}} .rela.foo { +# CHECK-NEXT: 0x201000 R_X86_64_64 .strings 0x0 +# CHECK-NEXT: 0x201008 R_X86_64_64 .strings 0x8 +# CHECK-NEXT: 0x201010 R_X86_64_64 .strings 0x8 +# CHECK-NEXT: 0x201018 R_X86_64_64 .strings 0x4 +# CHECK-NEXT: } +# CHECK-NEXT: ] + +.section .strings,"MS",@progbits,1,unique,10 +.Linfo_string0: + .asciz "AAA" +.Linfo_string1: + .asciz "BBB" + +.section .strings,"MS",@progbits,1,unique,20 +.Linfo_string2: + .asciz "BBB" +.Linfo_string3: + .asciz "CCC" + +.section .foo,"ax",@progbits +.quad .Linfo_string0 +.quad .Linfo_string1 +.quad .Linfo_string2 +.quad .Linfo_string3 Index: lld/trunk/test/ELF/emit-relocs.s =================================================================== --- lld/trunk/test/ELF/emit-relocs.s +++ lld/trunk/test/ELF/emit-relocs.s @@ -64,6 +64,15 @@ # CHECK-NEXT: Section: .text # CHECK-NEXT: } # CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: +# CHECK-NEXT: Value: 0x0 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Local +# CHECK-NEXT: Type: Section +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: .comment +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { # CHECK-NEXT: Name: fn # CHECK-NEXT: Value: 0x201000 # CHECK-NEXT: Size: 0