[PATCH] D33629: [ELF] Use late evaluation for ALIGN in expression

Rafael Avila de Espindola via llvm-commits llvm-commits at lists.llvm.org
Mon May 29 10:28:02 PDT 2017


LGTM

Petr Hosek via Phabricator via llvm-commits
<llvm-commits at lists.llvm.org> writes:

> phosek created this revision.
> phosek added a project: lld.
> Herald added a subscriber: emaste.
>
> While the following expression is handled fine:
>
>   PROVIDE_HIDDEN(newsym = oldsym + address);
>
> The following expression triggers an error because the expression
> is evaluated as absolute:
>
>   PROVIDE_HIDDEN(newsym = ALIGN(oldsym, CONSTANT(MAXPAGESIZE)) + address);
>
> To avoid this error, we use late evaluation for ALIGN by making the
> alignment an attribute of the expression itself.
>
>
> Repository:
>   rL LLVM
>
> https://reviews.llvm.org/D33629
>
> Files:
>   ELF/LinkerScript.cpp
>   ELF/LinkerScript.h
>   ELF/ScriptParser.cpp
>   test/ELF/linkerscript/align.s
>   test/ELF/linkerscript/symbol-reserved.s
>
>
> Index: test/ELF/linkerscript/symbol-reserved.s
> ===================================================================
> --- test/ELF/linkerscript/symbol-reserved.s
> +++ test/ELF/linkerscript/symbol-reserved.s
> @@ -11,6 +11,12 @@
>  
>  # SHARED: 0000000000000005 .dynsym 00000000 .hidden newsym
>  
> +# RUN: echo "PROVIDE_HIDDEN(newsym = ALIGN(__ehdr_start, CONSTANT(MAXPAGESIZE)) + 5);" > %t.script
> +# RUN: ld.lld -o %t1 %t.script %t
> +# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=ALIGNED %s
> +
> +# ALIGNED: 0000000000200005 .text 00000000 .hidden newsym
> +
>  .global _start
>  _start:
>    lea newsym(%rip),%rax
> Index: test/ELF/linkerscript/align.s
> ===================================================================
> --- test/ELF/linkerscript/align.s
> +++ test/ELF/linkerscript/align.s
> @@ -64,7 +64,7 @@
>  # SYMBOLS-NEXT: 0000000000010000         *ABS*           00000000 __code_base__
>  # SYMBOLS-NEXT: 0000000000001000         *ABS*           00000000 VAR
>  # SYMBOLS-NEXT: 0000000000011000         .bbb            00000000 __start_bbb
> -# SYMBOLS-NEXT: 0000000000012000         *ABS*           00000000 __end_bbb
> +# SYMBOLS-NEXT: 0000000000012000         .bbb            00000000 __end_bbb
>  
>  .global _start
>  _start:
> Index: ELF/ScriptParser.cpp
> ===================================================================
> --- ELF/ScriptParser.cpp
> +++ ELF/ScriptParser.cpp
> @@ -859,7 +859,11 @@
>      expect(",");
>      Expr E2 = readExpr();
>      expect(")");
> -    return [=] { return alignTo(E().getValue(), E2().getValue()); };
> +    return [=] {
> +      ExprValue V = E();
> +      V.Align = E2().getValue();
> +      return V;
> +    };
>    }
>    if (Tok == "ALIGNOF") {
>      StringRef Name = readParenLiteral();
> Index: ELF/LinkerScript.h
> ===================================================================
> --- ELF/LinkerScript.h
> +++ ELF/LinkerScript.h
> @@ -41,9 +41,12 @@
>    SectionBase *Sec;
>    uint64_t Val;
>    bool ForceAbsolute;
> +  uint64_t Align;
>  
> +  ExprValue(SectionBase *Sec, bool ForceAbsolute, uint64_t Val, uint64_t Align)
> +      : Sec(Sec), Val(Val), ForceAbsolute(ForceAbsolute), Align(Align) {}
>    ExprValue(SectionBase *Sec, bool ForceAbsolute, uint64_t Val)
> -      : Sec(Sec), Val(Val), ForceAbsolute(ForceAbsolute) {}
> +      : Sec(Sec), Val(Val), ForceAbsolute(ForceAbsolute), Align(1) {}
>    ExprValue(SectionBase *Sec, uint64_t Val) : ExprValue(Sec, false, Val) {}
>    ExprValue(uint64_t Val) : ExprValue(nullptr, Val) {}
>    bool isAbsolute() const { return ForceAbsolute || Sec == nullptr; }
> Index: ELF/LinkerScript.cpp
> ===================================================================
> --- ELF/LinkerScript.cpp
> +++ ELF/LinkerScript.cpp
> @@ -52,11 +52,12 @@
>  uint64_t ExprValue::getValue() const {
>    if (Sec) {
>      if (Sec->getOutputSection())
> -      return Sec->getOffset(Val) + Sec->getOutputSection()->Addr;
> +      return alignTo(Sec->getOffset(Val) + Sec->getOutputSection()->Addr,
> +                     Align);
>      error("unable to evaluate expression: input section " + Sec->Name +
>            " has no output section assigned");
>    }
> -  return Val;
> +  return alignTo(Val, Align);
>  }
>  
>  uint64_t ExprValue::getSecAddr() const {
> @@ -143,7 +144,7 @@
>    } else {
>      Sym->Section = V.Sec;
>      if (Sym->Section->Flags & SHF_ALLOC)
> -      Sym->Value = V.Val;
> +      Sym->Value = alignTo(V.Val, V.Align);
>      else
>        Sym->Value = V.getValue();
>    }
>
>
> Index: test/ELF/linkerscript/symbol-reserved.s
> ===================================================================
> --- test/ELF/linkerscript/symbol-reserved.s
> +++ test/ELF/linkerscript/symbol-reserved.s
> @@ -11,6 +11,12 @@
>  
>  # SHARED: 0000000000000005 .dynsym 00000000 .hidden newsym
>  
> +# RUN: echo "PROVIDE_HIDDEN(newsym = ALIGN(__ehdr_start, CONSTANT(MAXPAGESIZE)) + 5);" > %t.script
> +# RUN: ld.lld -o %t1 %t.script %t
> +# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=ALIGNED %s
> +
> +# ALIGNED: 0000000000200005 .text 00000000 .hidden newsym
> +
>  .global _start
>  _start:
>    lea newsym(%rip),%rax
> Index: test/ELF/linkerscript/align.s
> ===================================================================
> --- test/ELF/linkerscript/align.s
> +++ test/ELF/linkerscript/align.s
> @@ -64,7 +64,7 @@
>  # SYMBOLS-NEXT: 0000000000010000         *ABS*           00000000 __code_base__
>  # SYMBOLS-NEXT: 0000000000001000         *ABS*           00000000 VAR
>  # SYMBOLS-NEXT: 0000000000011000         .bbb            00000000 __start_bbb
> -# SYMBOLS-NEXT: 0000000000012000         *ABS*           00000000 __end_bbb
> +# SYMBOLS-NEXT: 0000000000012000         .bbb            00000000 __end_bbb
>  
>  .global _start
>  _start:
> Index: ELF/ScriptParser.cpp
> ===================================================================
> --- ELF/ScriptParser.cpp
> +++ ELF/ScriptParser.cpp
> @@ -859,7 +859,11 @@
>      expect(",");
>      Expr E2 = readExpr();
>      expect(")");
> -    return [=] { return alignTo(E().getValue(), E2().getValue()); };
> +    return [=] {
> +      ExprValue V = E();
> +      V.Align = E2().getValue();
> +      return V;
> +    };
>    }
>    if (Tok == "ALIGNOF") {
>      StringRef Name = readParenLiteral();
> Index: ELF/LinkerScript.h
> ===================================================================
> --- ELF/LinkerScript.h
> +++ ELF/LinkerScript.h
> @@ -41,9 +41,12 @@
>    SectionBase *Sec;
>    uint64_t Val;
>    bool ForceAbsolute;
> +  uint64_t Align;
>  
> +  ExprValue(SectionBase *Sec, bool ForceAbsolute, uint64_t Val, uint64_t Align)
> +      : Sec(Sec), Val(Val), ForceAbsolute(ForceAbsolute), Align(Align) {}
>    ExprValue(SectionBase *Sec, bool ForceAbsolute, uint64_t Val)
> -      : Sec(Sec), Val(Val), ForceAbsolute(ForceAbsolute) {}
> +      : Sec(Sec), Val(Val), ForceAbsolute(ForceAbsolute), Align(1) {}
>    ExprValue(SectionBase *Sec, uint64_t Val) : ExprValue(Sec, false, Val) {}
>    ExprValue(uint64_t Val) : ExprValue(nullptr, Val) {}
>    bool isAbsolute() const { return ForceAbsolute || Sec == nullptr; }
> Index: ELF/LinkerScript.cpp
> ===================================================================
> --- ELF/LinkerScript.cpp
> +++ ELF/LinkerScript.cpp
> @@ -52,11 +52,12 @@
>  uint64_t ExprValue::getValue() const {
>    if (Sec) {
>      if (Sec->getOutputSection())
> -      return Sec->getOffset(Val) + Sec->getOutputSection()->Addr;
> +      return alignTo(Sec->getOffset(Val) + Sec->getOutputSection()->Addr,
> +                     Align);
>      error("unable to evaluate expression: input section " + Sec->Name +
>            " has no output section assigned");
>    }
> -  return Val;
> +  return alignTo(Val, Align);
>  }
>  
>  uint64_t ExprValue::getSecAddr() const {
> @@ -143,7 +144,7 @@
>    } else {
>      Sym->Section = V.Sec;
>      if (Sym->Section->Flags & SHF_ALLOC)
> -      Sym->Value = V.Val;
> +      Sym->Value = alignTo(V.Val, V.Align);
>      else
>        Sym->Value = V.getValue();
>    }
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits


More information about the llvm-commits mailing list