From 97785af4644957a90e7ce238a7983d2cffd73d25 Mon Sep 17 00:00:00 2001 From: George Rimar Date: Fri, 2 Mar 2018 08:11:58 +0000 Subject: [PATCH] [ELF] - Report error when memory region is overflowed by data commands. LLD can not catch a memory area overflow when using a data command. If we have the script below: .foo : { *(.foo) BYTE(0x1) } > ram where BYTE overflows the ram region, we do not report it currently. Patch fixes that. Differential revision: https://reviews.llvm.org/D43948 llvm-svn: 326545 --- lld/ELF/LinkerScript.cpp | 27 ++++++++++--------- .../linkerscript/memory-data-commands.test | 22 +++++++++++++++ 2 files changed, 37 insertions(+), 12 deletions(-) create mode 100644 lld/test/ELF/linkerscript/memory-data-commands.test diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index f1a6d6381f16..f99d55d3541f 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -621,6 +621,16 @@ uint64_t LinkerScript::advance(uint64_t Size, unsigned Alignment) { return End; } +// Expands the memory region by the specified size. +static void expandMemoryRegion(MemoryRegion *MemRegion, uint64_t Size, + StringRef RegionName, StringRef SecName) { + MemRegion->CurPos += Size; + uint64_t NewSize = MemRegion->CurPos - MemRegion->Origin; + if (NewSize > MemRegion->Length) + error("section '" + SecName + "' will not fit in region '" + RegionName + + "': overflowed by " + Twine(NewSize - MemRegion->Length) + " bytes"); +} + void LinkerScript::output(InputSection *S) { uint64_t Before = advance(0, 1); uint64_t Pos = advance(S->getSize(), S->Alignment); @@ -637,17 +647,9 @@ void LinkerScript::output(InputSection *S) { Ctx->LMARegion->CurPos += Pos - Before; // FIXME: should we also produce overflow errors for LMARegion? - if (Ctx->MemRegion) { - uint64_t &CurOffset = Ctx->MemRegion->CurPos; - CurOffset += Pos - Before; - uint64_t CurSize = CurOffset - Ctx->MemRegion->Origin; - if (CurSize > Ctx->MemRegion->Length) { - uint64_t OverflowAmt = CurSize - Ctx->MemRegion->Length; - error("section '" + Ctx->OutSec->Name + "' will not fit in region '" + - Ctx->MemRegion->Name + "': overflowed by " + Twine(OverflowAmt) + - " bytes"); - } - } + if (Ctx->MemRegion) + expandMemoryRegion(Ctx->MemRegion, Pos - Before, Ctx->MemRegion->Name, + Ctx->OutSec->Name); } void LinkerScript::switchTo(OutputSection *Sec) { @@ -738,7 +740,8 @@ void LinkerScript::assignOffsets(OutputSection *Sec) { Cmd->Offset = Dot - Ctx->OutSec->Addr; Dot += Cmd->Size; if (Ctx->MemRegion) - Ctx->MemRegion->CurPos += Cmd->Size; + expandMemoryRegion(Ctx->MemRegion, Cmd->Size, Ctx->MemRegion->Name, + Ctx->OutSec->Name); if (Ctx->LMARegion) Ctx->LMARegion->CurPos += Cmd->Size; Ctx->OutSec->Size = Dot - Ctx->OutSec->Addr; diff --git a/lld/test/ELF/linkerscript/memory-data-commands.test b/lld/test/ELF/linkerscript/memory-data-commands.test new file mode 100644 index 000000000000..2762ec9e985f --- /dev/null +++ b/lld/test/ELF/linkerscript/memory-data-commands.test @@ -0,0 +1,22 @@ +# REQUIRES: x86 + +# RUN: echo ".section .foo,\"a\"" > %t.s +# RUN: echo ".quad 1" >> %t.s +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %t.s -o %t.o + +# RUN: not ld.lld -o %t %t.o --script %s 2>&1 | FileCheck %s + +# Check we are able to catch 'ram' overflow caused by BYTE command. +# CHECK: error: section '.foo' will not fit in region 'ram': overflowed by 1 bytes + +MEMORY { + text (rwx): org = 0x0, len = 0x1000 + ram (rwx): org = 0x1000, len = 8 +} +SECTIONS { + .text : { *(.text) } > text + .foo : { + *(.foo) + BYTE(0x1) + } > ram +}