Index: lld/trunk/ELF/Writer.cpp =================================================================== --- lld/trunk/ELF/Writer.cpp +++ lld/trunk/ELF/Writer.cpp @@ -263,6 +263,7 @@ public: typedef typename OutputSectionBase::uintX_t uintX_t; typedef typename ELFFile::Elf_Shdr Elf_Shdr; + typedef typename ELFFile::Elf_Sym Elf_Sym; typedef typename ELFFile::Elf_Rel Elf_Rel; typedef typename ELFFile::Elf_Rela Elf_Rela; OutputSection(const PltSection &PltSec, const GotSection &GotSec, @@ -734,6 +735,21 @@ } template +static typename ELFFile::uintX_t +getLocalSymVA(const typename ELFFile::Elf_Sym *Sym, + const ObjectFile &File) { + uint32_t SecIndex = Sym->st_shndx; + + if (SecIndex == SHN_XINDEX) + SecIndex = File.getObj()->getExtendedSymbolTableIndex( + Sym, File.getSymbolTable(), File.getSymbolTableShndx()); + ArrayRef *> Chunks = File.getChunks(); + InputSection *Section = Chunks[SecIndex]; + OutputSection *Out = Section->getOutputSection(); + return Out->getVA() + Section->getOutputSectionOff() + Sym->st_value; +} + +template void OutputSection::relocateOne(uint8_t *Buf, const Elf_Rel &Rel, uint32_t Type, uintX_t BaseAddr, uintX_t SymVA) { @@ -789,42 +805,51 @@ bool IsMips64EL = File.getObj()->isMips64EL(); for (const RelType &RI : Rels) { uint32_t SymIndex = RI.getSymbol(IsMips64EL); - const SymbolBody *Body = File.getSymbolBody(SymIndex); - if (!Body) - continue; - uint32_t Type = RI.getType(IsMips64EL); uintX_t SymVA; - switch (Body->kind()) { - case SymbolBody::DefinedRegularKind: - SymVA = getSymVA(cast>(Body)); - break; - case SymbolBody::DefinedAbsoluteKind: - SymVA = cast>(Body)->Sym.st_value; - break; - case SymbolBody::DefinedCommonKind: { - auto *DC = cast>(Body); - SymVA = DC->OutputSec->getVA() + DC->OffsetInBSS; - break; - } - case SymbolBody::SharedKind: - if (relocNeedsPLT(Type)) { - SymVA = PltSec.getEntryAddr(*Body); - Type = R_X86_64_PC32; - } else if (relocNeedsGOT(Type)) { - SymVA = GotSec.getEntryAddr(*Body); - Type = R_X86_64_PC32; - } else { + // Handle relocations for local symbols -- they never get + // resolved so we don't allocate a SymbolBody. + const Elf_Shdr *SymTab = File.getSymbolTable(); + if (SymIndex < SymTab->sh_info) { + const Elf_Sym *Sym = File.getObj()->getRelocationSymbol(&RI, SymTab); + if (!Sym) + continue; + SymVA = getLocalSymVA(Sym, File); + } else { + const SymbolBody *Body = File.getSymbolBody(SymIndex); + if (!Body) continue; + switch (Body->kind()) { + case SymbolBody::DefinedRegularKind: + SymVA = getSymVA(cast>(Body)); + break; + case SymbolBody::DefinedAbsoluteKind: + SymVA = cast>(Body)->Sym.st_value; + break; + case SymbolBody::DefinedCommonKind: { + auto *DC = cast>(Body); + SymVA = DC->OutputSec->getVA() + DC->OffsetInBSS; + break; + } + case SymbolBody::SharedKind: + if (relocNeedsPLT(Type)) { + SymVA = PltSec.getEntryAddr(*Body); + Type = R_X86_64_PC32; + } else if (relocNeedsGOT(Type)) { + SymVA = GotSec.getEntryAddr(*Body); + Type = R_X86_64_PC32; + } else { + continue; + } + break; + case SymbolBody::UndefinedKind: + assert(Body->isWeak() && "Undefined symbol reached writer"); + SymVA = 0; + break; + case SymbolBody::LazyKind: + llvm_unreachable("Lazy symbol reached writer"); } - break; - case SymbolBody::UndefinedKind: - assert(Body->isWeak() && "Undefined symbol reached writer"); - SymVA = 0; - break; - case SymbolBody::LazyKind: - llvm_unreachable("Lazy symbol reached writer"); } relocateOne(Buf, RI, Type, BaseAddr, SymVA); Index: lld/trunk/test/elf2/relocation-local.s =================================================================== --- lld/trunk/test/elf2/relocation-local.s +++ lld/trunk/test/elf2/relocation-local.s @@ -0,0 +1,38 @@ +// Test that relocation of local symbols is working. +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t +// RUN: lld -flavor gnu2 %t -o %t2 +// RUN: llvm-objdump -s -d %t2 | FileCheck %s +// REQUIRES: x86 + + +.global _start +_start: + call lulz + +.zero 4 +lulz: + +.section .text2,"ax",@progbits +R_X86_64_32: + movl $R_X86_64_32, %edx + +// FIXME: this would be far more self evident if llvm-objdump printed +// constants in hex. +// CHECK: Disassembly of section .text2: +// CHECK-NEXT: R_X86_64_32: +// CHECK-NEXT: 1100c: {{.*}} movl $69644, %edx + +.section .R_X86_64_32S,"ax",@progbits +R_X86_64_32S: + movq lulz - 0x100000, %rdx + +// CHECK: Disassembly of section .R_X86_64_32S: +// CHECK-NEXT: R_X86_64_32S: +// CHECK-NEXT: {{.*}}: {{.*}} movq -978935, %rdx + +.section .R_X86_64_64,"a",@progbits +R_X86_64_64: + .quad R_X86_64_64 + +// CHECK: Contents of section .R_X86_64_64: +// CHECK-NEXT: 12000 00200100 00000000