[PATCH] D25774: [ELF] Linkerscript: don't add program headers to segment when we have PHDRS directive but don't have FILEHDR and PHDRS attributes for segment

Eugene Leviant via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 19 08:22:12 PDT 2016


evgeny777 created this revision.
evgeny777 added reviewers: ruiu, rafael.
evgeny777 added subscribers: ikudrin, grimar, llvm-commits.
evgeny777 set the repository for this revision to rL LLVM.
evgeny777 added a project: lld.

Linker shouldn't include program headers in PT_LOAD in the following case:

- PHDRS directive exists
- PT_LOAD segment doesn't contain PHDRS and/or FILEHDR attribute

Below is an example of such script:

  PHDRS { 
    hdr PT_PHDR FILEHDR PHDRS;
    all PT_LOAD; 
  }
  SECTIONS { 
     . = 0x10000;
     .text : { *(.text) } : all
    /* other sections go here */
  }

Current revision will detect that there is a place to put ELF and program headers and will do this even though 'all' segment doesn't
have PHDRS and FILEHDR attributes.

To make this patch as simple as possible, both FILEHDR and PHDRS attributes are required to put ELF and program headers to PT_LOAD.
GNU gold has the same requirement.


Repository:
  rL LLVM

https://reviews.llvm.org/D25774

Files:
  ELF/LinkerScript.cpp
  test/ELF/linkerscript/phdrs.s


Index: test/ELF/linkerscript/phdrs.s
===================================================================
--- test/ELF/linkerscript/phdrs.s
+++ test/ELF/linkerscript/phdrs.s
@@ -9,6 +9,17 @@
 # RUN: ld.lld -o %t1 --script %t.script %t
 # RUN: llvm-readobj -program-headers %t1 | FileCheck %s
 
+## Check that program headers are not written, unless we explicitly tell
+## lld to do this.
+# RUN: echo "PHDRS {all PT_LOAD;} \
+# RUN:       SECTIONS { \
+# RUN:           . = 0x10000200; \
+# RUN:           /DISCARD/ : {*(.text*)}  \
+# RUN:           .foo : {*(.foo.*)} :all \
+# RUN:       }" > %t.script
+# RUN: ld.lld -o %t1 --script %t.script %t
+# RUN: llvm-readobj -program-headers %t1 | FileCheck --check-prefix=NOPHDR %s
+
 ## Check the AT(expr)
 # RUN: echo "PHDRS {all PT_LOAD FILEHDR PHDRS AT(0x500 + 0x500) ;} \
 # RUN:       SECTIONS { \
@@ -33,6 +44,22 @@
 # CHECK-NEXT:      PF_X (0x1)
 # CHECK-NEXT:    ]
 
+# NOPHDR:     ProgramHeaders [
+# NOPHDR-NEXT:  ProgramHeader {
+# NOPHDR-NEXT:    Type: PT_LOAD (0x1)
+# NOPHDR-NEXT:    Offset: 0x200
+# NOPHDR-NEXT:    VirtualAddress: 0x10000200
+# NOPHDR-NEXT:    PhysicalAddress: 0x10000200
+# NOPHDR-NEXT:    FileSize: 8
+# NOPHDR-NEXT:    MemSize: 8
+# NOPHDR-NEXT:    Flags [ (0x6)
+# NOPHDR-NEXT:      PF_R (0x4)
+# NOPHDR-NEXT:      PF_W (0x2)
+# NOPHDR-NEXT:    ]
+# NOPHDR-NEXT:    Alignment: 4096
+# NOPHDR-NEXT:  }
+# NOPHDR-NEXT: ]
+
 # AT:       ProgramHeaders [
 # AT-NEXT:    ProgramHeader {
 # AT-NEXT:      Type: PT_LOAD (0x1)
Index: ELF/LinkerScript.cpp
===================================================================
--- ELF/LinkerScript.cpp
+++ ELF/LinkerScript.cpp
@@ -652,7 +652,16 @@
       std::find_if(Phdrs.begin(), Phdrs.end(), [](const PhdrEntry<ELFT> &E) {
         return E.H.p_type == PT_LOAD;
       });
+
   if (HeaderSize <= MinVA && FirstPTLoad != Phdrs.end()) {
+    // If linker script specifies program headers and first PT_LOAD doesn't 
+    // both PHDRS and FILEHDR attributes then do nothing
+    if (!Opt.PhdrsCommands.empty()) {
+      size_t SegNum = std::distance(Phdrs.begin(), FirstPTLoad);
+      if (!Opt.PhdrsCommands[SegNum].HasPhdrs ||
+          !Opt.PhdrsCommands[SegNum].HasFilehdr)
+        return;
+    }
     // ELF and Program headers need to be right before the first section in
     // memory. Set their addresses accordingly.
     MinVA = alignDown(MinVA - HeaderSize, Target->PageSize);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D25774.75156.patch
Type: text/x-patch
Size: 2414 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20161019/b0016113/attachment-0001.bin>


More information about the llvm-commits mailing list