[lld] r281024 - Linker script: implement AT [ (address) ] for PHDR

Eugene Leviant via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 9 02:46:19 PDT 2016


Author: evgeny777
Date: Fri Sep  9 04:46:16 2016
New Revision: 281024

URL: http://llvm.org/viewvc/llvm-project?rev=281024&view=rev
Log:
Linker script: implement AT [ (address) ] for PHDR

Differential revision: https://reviews.llvm.org/D24340

Modified:
    lld/trunk/ELF/LinkerScript.cpp
    lld/trunk/ELF/LinkerScript.h
    lld/trunk/ELF/Writer.cpp
    lld/trunk/ELF/Writer.h
    lld/trunk/test/ELF/linkerscript/phdrs.s

Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=281024&r1=281023&r2=281024&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Fri Sep  9 04:46:16 2016
@@ -463,6 +463,11 @@ std::vector<PhdrEntry<ELFT>> LinkerScrip
       Phdr.add(Out<ELFT>::ElfHeader);
     if (Cmd.HasPhdrs)
       Phdr.add(Out<ELFT>::ProgramHeaders);
+
+    if (Cmd.LMAExpr) {
+      Phdr.H.p_paddr = Cmd.LMAExpr(0);
+      Phdr.HasLMA = true;
+    }
   }
 
   // Add output sections to program headers.
@@ -860,7 +865,8 @@ void ScriptParser::readPhdrs() {
   expect("{");
   while (!Error && !skip("}")) {
     StringRef Tok = next();
-    Opt.PhdrsCommands.push_back({Tok, PT_NULL, false, false, UINT_MAX});
+    Opt.PhdrsCommands.push_back(
+        {Tok, PT_NULL, false, false, UINT_MAX, nullptr});
     PhdrsCommand &PhdrCmd = Opt.PhdrsCommands.back();
 
     PhdrCmd.Type = readPhdrType();
@@ -872,6 +878,8 @@ void ScriptParser::readPhdrs() {
         PhdrCmd.HasFilehdr = true;
       else if (Tok == "PHDRS")
         PhdrCmd.HasPhdrs = true;
+      else if (Tok == "AT")
+        PhdrCmd.LMAExpr = readParenExpr();
       else if (Tok == "FLAGS") {
         expect("(");
         // Passing 0 for the value of dot is a bit of a hack. It means that

Modified: lld/trunk/ELF/LinkerScript.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.h?rev=281024&r1=281023&r2=281024&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.h (original)
+++ lld/trunk/ELF/LinkerScript.h Fri Sep  9 04:46:16 2016
@@ -121,6 +121,7 @@ struct PhdrsCommand {
   bool HasFilehdr;
   bool HasPhdrs;
   unsigned Flags;
+  Expr LMAExpr;
 };
 
 class LinkerScriptBase {

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=281024&r1=281023&r2=281024&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Fri Sep  9 04:46:16 2016
@@ -1168,10 +1168,14 @@ template <class ELFT> void Writer<ELFT>:
     else if (H.p_type == PT_GNU_RELRO)
       H.p_align = 1;
 
-    H.p_paddr = H.p_vaddr;
-    if (H.p_type == PT_LOAD && First)
-      if (Expr LmaExpr = Script<ELFT>::X->getLma(First->getName()))
-        H.p_paddr = LmaExpr(H.p_vaddr);
+    if (!P.HasLMA) {
+    // The p_paddr field can be set using linker script AT command.
+    // By default, it is the same value as p_vaddr.
+      H.p_paddr = H.p_vaddr;
+      if (H.p_type == PT_LOAD && First)
+        if (Expr LmaExpr = Script<ELFT>::X->getLma(First->getName()))
+          H.p_paddr = LmaExpr(H.p_vaddr);
+    }
 
     // The TLS pointer goes after PT_TLS. At least glibc will align it,
     // so round up the size to make sure the offsets are correct.

Modified: lld/trunk/ELF/Writer.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.h?rev=281024&r1=281023&r2=281024&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.h (original)
+++ lld/trunk/ELF/Writer.h Fri Sep  9 04:46:16 2016
@@ -38,6 +38,7 @@ struct PhdrEntry {
   typename ELFT::Phdr H = {};
   OutputSectionBase<ELFT> *First = nullptr;
   OutputSectionBase<ELFT> *Last = nullptr;
+  bool HasLMA = false;
 };
 
 template <class ELFT>

Modified: lld/trunk/test/ELF/linkerscript/phdrs.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/phdrs.s?rev=281024&r1=281023&r2=281024&view=diff
==============================================================================
--- lld/trunk/test/ELF/linkerscript/phdrs.s (original)
+++ lld/trunk/test/ELF/linkerscript/phdrs.s Fri Sep  9 04:46:16 2016
@@ -6,9 +6,19 @@
 # RUN:           .text : {*(.text*)} :all \
 # RUN:           .foo : {*(.foo.*)} :all \
 # RUN:           .data : {*(.data.*)} :all}" > %t.script
-
 # RUN: ld.lld -o %t1 --script %t.script %t
 # RUN: llvm-readobj -program-headers %t1 | FileCheck %s
+
+## Check the AT(expr)
+# RUN: echo "PHDRS {all PT_LOAD FILEHDR PHDRS AT(0x500 + 0x500) ;} \
+# RUN:       SECTIONS { \
+# RUN:           . = 0x10000200; \
+# RUN:           .text : {*(.text*)} :all \
+# RUN:           .foo : {*(.foo.*)} :all \
+# RUN:           .data : {*(.data.*)} :all}" > %t.script
+# RUN: ld.lld -o %t1 --script %t.script %t
+# RUN: llvm-readobj -program-headers %t1 | FileCheck --check-prefix=AT %s
+
 # CHECK:     ProgramHeaders [
 # CHECK-NEXT:  ProgramHeader {
 # CHECK-NEXT:    Type: PT_LOAD (0x1)
@@ -23,6 +33,20 @@
 # CHECK-NEXT:      PF_X (0x1)
 # CHECK-NEXT:    ]
 
+# AT:       ProgramHeaders [
+# AT-NEXT:    ProgramHeader {
+# AT-NEXT:      Type: PT_LOAD (0x1)
+# AT-NEXT:      Offset: 0x0
+# AT-NEXT:      VirtualAddress: 0x10000000
+# AT-NEXT:      PhysicalAddress: 0xA00
+# AT-NEXT:      FileSize: 521
+# AT-NEXT:      MemSize: 521
+# AT-NEXT:      Flags [ (0x7)
+# AT-NEXT:        PF_R (0x4)
+# AT-NEXT:        PF_W (0x2)
+# AT-NEXT:        PF_X (0x1)
+# AT-NEXT:      ]
+
 .global _start
 _start:
  nop




More information about the llvm-commits mailing list