[PATCH] D43999: [ELF] - Support moving location counter when MEMORY is used.

Rafael Avila de Espindola via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 2 11:06:02 PST 2018


This is awesome!

LGTM

Thanks,
Rafael

George Rimar via Phabricator <reviews at reviews.llvm.org> writes:

> grimar created this revision.
> grimar added reviewers: ruiu, rafael.
> Herald added subscribers: arichardson, emaste.
>
> We do not expand memory region correctly for following scripts:
>
>   .foo.1 : 
>    {
>      *(.foo.1)
>      . += 0x1000;
>    } > ram
>
> Patch generalizes expanding of output sections and memory
> regions in one place and fixes the issue.
>
>
> https://reviews.llvm.org/D43999
>
> Files:
>   ELF/LinkerScript.cpp
>   ELF/LinkerScript.h
>   test/ELF/linkerscript/memory-loc-counter.test
>
> Index: test/ELF/linkerscript/memory-loc-counter.test
> ===================================================================
> --- test/ELF/linkerscript/memory-loc-counter.test
> +++ test/ELF/linkerscript/memory-loc-counter.test
> @@ -0,0 +1,37 @@
> +# REQUIRES: x86
> +
> +# RUN: echo ".section .foo,\"a\"" > %t.s
> +# RUN: echo ".quad 1" >> %t.s
> +# RUN: echo ".section .bar,\"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: ld.lld -o %t %t.o --script %s
> +# RUN: llvm-readelf -sections -program-headers %t | FileCheck %s
> +
> +## Check that we can produce output without errors,
> +## and .foo section has proper size.
> +# CHECK:      Section Headers:
> +# CHECK-NEXT:   [Nr] Name Type     Address          Off    Size
> +# CHECK-NEXT:   [ 0]      NULL     0000000000000000 000000 000000
> +# CHECK-NEXT:   [ 1] .foo PROGBITS 0000000000001000 001000 000108
> +# CHECK-NEXT:   [ 2] .bar PROGBITS 0000000000001108 001108 000008
> +
> +## Check that load address is correct.
> +# CHECK:      Program Headers:
> +# CHECK-NEXT:   Type Offset   VirtAddr           PhysAddr           FileSiz  MemSiz
> +# CHECK-NEXT:   LOAD 0x001000 0x0000000000001000 0x0000000000002000 0x000110 0x000110
> +
> +MEMORY {
> +  ram (rwx)   : org = 0x1000, len = 0x200
> +  flash (rwx) : org = 0x2000, len = 0x200
> +}
> +SECTIONS {
> +  .foo : {
> +    *(.foo)
> +    . += 0x100;
> +  } > ram AT>flash
> +  .bar : {
> +    *(.bar)
> +  } > ram AT>flash
> +}
> Index: ELF/LinkerScript.h
> ===================================================================
> --- ELF/LinkerScript.h
> +++ ELF/LinkerScript.h
> @@ -215,6 +215,7 @@
>    void addSymbol(SymbolAssignment *Cmd);
>    void assignSymbol(SymbolAssignment *Cmd, bool InSec);
>    void setDot(Expr E, const Twine &Loc, bool InSec);
> +  void expandOutputSection(uint64_t Size);
>  
>    std::vector<InputSection *>
>    computeInputSections(const InputSectionDescription *);
> Index: ELF/LinkerScript.cpp
> ===================================================================
> --- ELF/LinkerScript.cpp
> +++ ELF/LinkerScript.cpp
> @@ -102,16 +102,36 @@
>    return CmdRef;
>  }
>  
> +// 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::expandOutputSection(uint64_t Size) {
> +  Ctx->OutSec->Size += Size;
> +  if (Ctx->MemRegion)
> +    expandMemoryRegion(Ctx->MemRegion, Size, Ctx->MemRegion->Name,
> +                       Ctx->OutSec->Name);
> +  // FIXME: check LMA region overflow too.
> +  if (Ctx->LMARegion)
> +    Ctx->LMARegion->CurPos += Size;
> +}
> +
>  void LinkerScript::setDot(Expr E, const Twine &Loc, bool InSec) {
>    uint64_t Val = E().getValue();
>    if (Val < Dot && InSec)
>      error(Loc + ": unable to move location counter backward for: " +
>            Ctx->OutSec->Name);
> -  Dot = Val;
>  
>    // Update to location counter means update to section size.
>    if (InSec)
> -    Ctx->OutSec->Size = Dot - Ctx->OutSec->Addr;
> +    expandOutputSection(Val - Dot);
> +  Dot = Val;
>  }
>  
>  // Used for handling linker symbol assignments, for both finalizing
> @@ -621,35 +641,15 @@
>    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);
>    S->OutSecOff = Pos - S->getSize() - Ctx->OutSec->Addr;
>  
>    // Update output section size after adding each section. This is so that
>    // SIZEOF works correctly in the case below:
>    // .foo { *(.aaa) a = SIZEOF(.foo); *(.bbb) }
> -  Ctx->OutSec->Size = Pos - Ctx->OutSec->Addr;
> -
> -  // If there is a memory region associated with this input section, then
> -  // place the section in that region and update the region index.
> -  if (Ctx->LMARegion)
> -    Ctx->LMARegion->CurPos += Pos - Before;
> -  // FIXME: should we also produce overflow errors for LMARegion?
> -
> -  if (Ctx->MemRegion)
> -    expandMemoryRegion(Ctx->MemRegion, Pos - Before, Ctx->MemRegion->Name,
> -                       Ctx->OutSec->Name);
> +  expandOutputSection(Pos - Before);
>  }
>  
>  void LinkerScript::switchTo(OutputSection *Sec) {
> @@ -739,12 +739,7 @@
>      if (auto *Cmd = dyn_cast<ByteCommand>(Base)) {
>        Cmd->Offset = Dot - Ctx->OutSec->Addr;
>        Dot += Cmd->Size;
> -      if (Ctx->MemRegion)
> -        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;
> +      expandOutputSection(Cmd->Size);
>        continue;
>      }
>  


More information about the llvm-commits mailing list