Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -200,6 +200,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 GotSection &GotSec, StringRef Name, @@ -724,24 +725,39 @@ 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; - if (auto *DR = dyn_cast>(Body)) { - SymVA = getSymVA(DR); - } else if (auto *DA = dyn_cast>(Body)) { - SymVA = DA->Sym.st_value; - } else if (auto *S = dyn_cast>(Body)) { - if (!relocNeedsGOT(Type)) + + // Handle relocations for local symbols -- they never get + // resolved so we don't allocate a SymbolBody for them. + const Elf_Shdr *SymTab = File.getSymbolTable(); + if (SymIndex < SymTab->sh_info) { + const Elf_Sym *Sym = File.getObj()->getRelocationSymbol(&RI, SymTab); + ArrayRef *> Chunks = File.getChunks(); + SectionChunk *Section = Chunks[SymIndex]; + if (!Section) continue; - SymVA = GotSec.getEntryAddr(*S); - Type = R_X86_64_PC32; - } else { - // Skip unsupported for now. - continue; + OutputSection *Out = Section->getOutputSection(); + SymVA = Out->getVA() + Section->getOutputSectionOff() + Sym->st_value; + } + else { + const SymbolBody *Body = File.getSymbolBody(SymIndex); + if (!Body) + continue; + + if (auto *DR = dyn_cast>(Body)) { + SymVA = getSymVA(DR); + } else if (auto *DA = dyn_cast>(Body)) { + SymVA = DA->Sym.st_value; + } else if (auto *S = dyn_cast>(Body)) { + if (!relocNeedsGOT(Type)) + continue; + SymVA = GotSec.getEntryAddr(*S); + Type = R_X86_64_PC32; + } else { + // Skip unsupported for now. + continue; + } } relocateOne(Buf, RI, Type, BaseAddr, SymVA); Index: test/elf2/relocation-local.s =================================================================== --- test/elf2/relocation-local.s +++ test/elf2/relocation-local.s @@ -0,0 +1,41 @@ +// 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 + + +.section .text,"ax",@progbits,unique,1 +.global _start +_start: + call lulz + +.section .text,"ax",@progbits,unique,2 +.zero 4 +lulz: + nop + +.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 $0, %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 -978940, %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 05100100 00000000