Skip to content

Commit

Permalink
lld: elf: Fix sections with explict addresses in regions
Browse files Browse the repository at this point in the history
Patch by Gabriel Smith.

The address for a section would be evaluated before the region was
switched to. Because of this, the position within the region would not
be updated. After the region is swapped to the dot would be set to the
out of date position within the region, undoing the section address
evaluation.

To fix this, the region is swapped to before the section's address is
evaluated. As part of the fallout of this, expandMemoryRegions needed
to be gated in setDot on the condition that the evaluated address is
less than the dot. This is for the case where sections are not listed
from lowest address to highest address.

Finally, a test for the case where sections are listed "out of order"
was added.

Differential Revision: https://reviews.llvm.org/D60744

llvm-svn: 358638
  • Loading branch information
rui314 committed Apr 18, 2019
1 parent 9266337 commit 14ef9b3
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 3 deletions.
7 changes: 4 additions & 3 deletions lld/ELF/LinkerScript.cpp
Expand Up @@ -135,7 +135,7 @@ void LinkerScript::setDot(Expr E, const Twine &Loc, bool InSec) {
// Update to location counter means update to section size.
if (InSec)
expandOutputSection(Val - Dot);
else
else if (Val > Dot)
expandMemoryRegions(Val - Dot);

Dot = Val;
Expand Down Expand Up @@ -760,14 +760,15 @@ static OutputSection *findFirstSection(PhdrEntry *Load) {
void LinkerScript::assignOffsets(OutputSection *Sec) {
if (!(Sec->Flags & SHF_ALLOC))
Dot = 0;
else if (Sec->AddrExpr)
setDot(Sec->AddrExpr, Sec->Location, false);

Ctx->MemRegion = Sec->MemRegion;
Ctx->LMARegion = Sec->LMARegion;
if (Ctx->MemRegion)
Dot = Ctx->MemRegion->CurPos;

if ((Sec->Flags & SHF_ALLOC) && Sec->AddrExpr)
setDot(Sec->AddrExpr, Sec->Location, false);

switchTo(Sec);

if (Sec->LMAExpr)
Expand Down
22 changes: 22 additions & 0 deletions lld/test/ELF/linkerscript/out-of-order-section-in-region.s
@@ -0,0 +1,22 @@
# REQUIRES: x86
# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
# RUN: echo "MEMORY { \
# RUN: REGION (rwx) : ORIGIN = 0x1000, LENGTH = 0x100 \
# RUN: } \
# RUN: \
# RUN: SECTIONS { \
# RUN: .aaa ORIGIN(REGION) + 0x8 : { *(.aaa) } > REGION \
# RUN: _stext = .; \
# RUN: .bbb ORIGIN(REGION) : { *(.bbb) } > REGION \
# RUN: . = _stext; \
# RUN: }" > %t.script
# RUN: ld.lld %t --script %t.script -o %t2
# RUN: llvm-objdump -section-headers %t2 | FileCheck %s
# CHECK: .aaa 00000008 0000000000001008 DATA
# CHECK: .bbb 00000008 0000000000001000 DATA

.section .aaa, "a"
.quad 0

.section .bbb, "a"
.quad 0

0 comments on commit 14ef9b3

Please sign in to comment.