[PATCH] D22961: [ELF] - Linkerscript: restrict moving location counter backwards.

George Rimar via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 29 06:36:44 PDT 2016


grimar created this revision.
grimar added reviewers: ruiu, rafael.
grimar added subscribers: llvm-commits, grimar, davide, evgeny777.

According to documentation, 
"The location counter may not be moved backwards inside an output section, and may not be moved backwards outside of an output section if so doing creates areas with overlapping LMAs."

Currently we do not perform any overlaping checks and can produce broken binary if location counter was moved backward.
Also probably there is no reasons to support that checks at all. I suggest just to restrict moving location counter backwards in all cases.
Since we did not implement LC inside output sections yet,  this patch implements that check for "outside of an output section" case.

https://reviews.llvm.org/D22961

Files:
  ELF/LinkerScript.cpp
  test/ELF/linkerscript/linkerscript-locationcounter-backward.s

Index: test/ELF/linkerscript/linkerscript-locationcounter-backward.s
===================================================================
--- test/ELF/linkerscript/linkerscript-locationcounter-backward.s
+++ test/ELF/linkerscript/linkerscript-locationcounter-backward.s
@@ -0,0 +1,11 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+
+# RUN: echo "SECTIONS { \
+# RUN:  . = 0x10000; \
+# RUN:  . = . - 1; \
+# RUN: }" > %t.script
+# RUN: not ld.lld -shared %t --script %t.script -o %t2 2>&1 | \
+# RUN:  FileCheck --check-prefix=ERR %s
+# ERR: location counter may not be moved backwards
+
Index: ELF/LinkerScript.cpp
===================================================================
--- ELF/LinkerScript.cpp
+++ ELF/LinkerScript.cpp
@@ -192,6 +192,13 @@
   return Sections;
 }
 
+static uint64_t safeAssign(Expr Expr, uint64_t Dot) {
+  uint64_t Val = Expr(Dot);
+  if (Val < Dot)
+    error("location counter may not be moved backwards");
+  return Val;
+}
+
 template <class ELFT>
 void LinkerScript<ELFT>::assignAddresses(
     ArrayRef<OutputSectionBase<ELFT> *> Sections) {
@@ -213,11 +220,10 @@
 
   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) {
     if (auto *Cmd = dyn_cast<SymbolAssignment>(Base.get())) {
-      if (Cmd->Name == ".") {
-        Dot = Cmd->Expression(Dot);
-      } else if (Cmd->Sym) {
+      if (Cmd->Name == ".")
+        Dot = safeAssign(Cmd->Expression, Dot);
+      else if (Cmd->Sym)
         cast<DefinedRegular<ELFT>>(Cmd->Sym)->Value = Cmd->Expression(Dot);
-      }
       continue;
     }
 
@@ -230,7 +236,7 @@
         continue;
 
       if (Cmd->AddrExpr)
-        Dot = Cmd->AddrExpr(Dot);
+        Dot = safeAssign(Cmd->AddrExpr, Dot);
 
       if (Cmd->AlignExpr)
         Sec->updateAlignment(Cmd->AlignExpr(Dot));


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D22961.66116.patch
Type: text/x-patch
Size: 1865 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160729/e0bfda73/attachment.bin>


More information about the llvm-commits mailing list