From 3e6833b4b236e46ccf304a7b118615036d7c582b Mon Sep 17 00:00:00 2001 From: George Rimar Date: Fri, 19 Aug 2016 15:46:28 +0000 Subject: [PATCH] [ELF] - Fix for PR28976 - Corrupted section contents when using linker scripts This is fix for PR28976. Problem was that in scanRelocs, we computed relocation offset too early for case when linkerscript was used. Patch fixes the issue delaying the calculation. Differential revision: https://reviews.llvm.org/D23655 llvm-svn: 279264 --- lld/ELF/InputSection.cpp | 2 +- lld/ELF/OutputSections.cpp | 2 +- lld/ELF/Relocations.cpp | 2 +- .../Inputs/linkerscript-merge-sections-reloc.s | 3 +++ .../ELF/linkerscript/linkerscript-merge-sections-reloc.s | 16 ++++++++++++++++ 5 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 lld/test/ELF/linkerscript/Inputs/linkerscript-merge-sections-reloc.s create mode 100644 lld/test/ELF/linkerscript/linkerscript-merge-sections-reloc.s diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index 191832e..a699044 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -351,7 +351,7 @@ void InputSectionBase::relocate(uint8_t *Buf, uint8_t *BufEnd) { const unsigned Bits = sizeof(uintX_t) * 8; for (const Relocation &Rel : Relocations) { - uintX_t Offset = Rel.Offset; + uintX_t Offset = getOffset(Rel.Offset); uint8_t *BufLoc = Buf + Offset; uint32_t Type = Rel.Type; uintX_t A = Rel.Addend; diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index 02539f5..2631ccc 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -1274,7 +1274,7 @@ template typename ELFT::uint DynamicReloc::getOffset() const { if (OutputSec) return OutputSec->getVA() + OffsetInSec; - return InputSec->OutSec->getVA() + OffsetInSec; + return InputSec->OutSec->getVA() + InputSec->getOffset(OffsetInSec); } template diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index dca84e1..0f03857 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -566,7 +566,7 @@ static void scanRelocs(InputSectionBase &C, ArrayRef Rels) { continue; Offset = PieceI->OutputOff + RI.r_offset - PieceI->InputOff; } else { - Offset = C.getOffset(RI.r_offset); + Offset = RI.r_offset; } // This relocation does not require got entry, but it is relative to got and diff --git a/lld/test/ELF/linkerscript/Inputs/linkerscript-merge-sections-reloc.s b/lld/test/ELF/linkerscript/Inputs/linkerscript-merge-sections-reloc.s new file mode 100644 index 0000000..07e599b --- /dev/null +++ b/lld/test/ELF/linkerscript/Inputs/linkerscript-merge-sections-reloc.s @@ -0,0 +1,3 @@ +.globl _start +_start: + .quad 0x11223344 diff --git a/lld/test/ELF/linkerscript/linkerscript-merge-sections-reloc.s b/lld/test/ELF/linkerscript/linkerscript-merge-sections-reloc.s new file mode 100644 index 0000000..9d8089a --- /dev/null +++ b/lld/test/ELF/linkerscript/linkerscript-merge-sections-reloc.s @@ -0,0 +1,16 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/linkerscript-merge-sections-reloc.s -o %t1.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t2.o +# RUN: echo "SECTIONS {}" > %t.script +# RUN: ld.lld -o %t --script %t.script %t1.o %t2.o +# RUN: llvm-objdump -s %t | FileCheck %s + +## Check that sections content is not corrupted. +# CHECK: Contents of section .text: +# CHECK-NEXT: 44332211 00000000 44332211 00000000 +# CHECK-NEXT: f0ffffff ffffffff + +.globl _start +_foo: + .quad 0x11223344 + .quad _start - . -- 2.7.4