From ee29e42b3341e6d14bb55f9ad532941343a89a2f Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Tue, 14 Feb 2017 20:14:03 +0000 Subject: [PATCH] Relax the restriction on what relocations can be in a non-alloc section. The main thing that they can't have is relocations that require the creation of gots or plt. For now also accept R_PC. Found while linking seabios. llvm-svn: 295102 --- lld/ELF/InputSection.cpp | 5 +++-- lld/test/ELF/i386-reloc-non-alloc.s | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 lld/test/ELF/i386-reloc-non-alloc.s diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index 9b21a3271902..40f95daaf3d1 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -452,7 +452,8 @@ void InputSection::relocateNonAlloc(uint8_t *Buf, ArrayRef Rels) { Addend += Target->getImplicitAddend(BufLoc, Type); SymbolBody &Sym = this->File->getRelocTargetSym(Rel); - if (Target->getRelExpr(Type, Sym) != R_ABS) { + RelExpr E = Target->getRelExpr(Type, Sym); + if (E != R_ABS && E != R_PC) { error(this->getLocation(Offset) + ": has non-ABS reloc"); return; } @@ -461,7 +462,7 @@ void InputSection::relocateNonAlloc(uint8_t *Buf, ArrayRef Rels) { uint64_t SymVA = 0; if (!Sym.isTls() || Out::TlsPhdr) SymVA = SignExtend64( - getRelocTargetVA(Type, Addend, AddrLoc, Sym, R_ABS)); + getRelocTargetVA(Type, Addend, AddrLoc, Sym, E)); Target->relocateOne(BufLoc, Type, SymVA); } } diff --git a/lld/test/ELF/i386-reloc-non-alloc.s b/lld/test/ELF/i386-reloc-non-alloc.s new file mode 100644 index 000000000000..98612fe57f74 --- /dev/null +++ b/lld/test/ELF/i386-reloc-non-alloc.s @@ -0,0 +1,18 @@ +// REQUIRES: x86 + +// RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t.o +// RUN: ld.lld -shared %t.o -o %t.so +// RUN: llvm-objdump -s %t.so | FileCheck %s + +// CHECK: Contents of section .text: +// CHECK-NEXT: 1000 00000000 00000000 + +// CHECK: Contents of section .bar: +// CHECK-NEXT: 0000 00100000 fc0f0000 + +foo: +.quad 0 + +.section .bar +.long foo - . +.long foo - .