[PATCH] D43284: [ELF] Simplify handling of AT section attribute.

Igor Kudrin via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 14 05:06:38 PST 2018


ikudrin created this revision.
ikudrin added reviewers: rafael, ruiu.
ikudrin added a project: lld.
Herald added subscribers: arichardson, emaste.

The patch is going to replace the implementation from r323625.

The original implementation adds a section with AT attribute into the same load segment
as a previous section if that segment does not contain a section with a customized LMA.
After that, this attribute affects not only this and following sections, as required by specs,
but also previous sections in that segment.

I believe that a better way is to just start a new segment if we encounter a section
with AT attribute, with the only exception for the very first section, because we have added
header sections in the first load segment. It looks like GNU ld does the same.


Repository:
  rLLD LLVM Linker

https://reviews.llvm.org/D43284

Files:
  ELF/Writer.cpp
  ELF/Writer.h
  test/ELF/linkerscript/at5.s


Index: test/ELF/linkerscript/at5.s
===================================================================
--- /dev/null
+++ test/ELF/linkerscript/at5.s
@@ -0,0 +1,36 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+# RUN: echo "SECTIONS { \
+# RUN:  . = 0x1000; \
+# RUN:  .aaa : { *(.aaa) } \
+# RUN:  .bbb : AT(0x2008) { *(.bbb) } \
+# RUN:  .ccc : { *(.ccc) } \
+# RUN: }" > %t.script
+# RUN: ld.lld %t --script %t.script -o %t2
+# RUN: llvm-readobj -program-headers %t2 | tee %t2.log | FileCheck %s
+
+# CHECK:        Type: PT_LOAD
+# CHECK-NEXT:     Offset: 0x1000
+# CHECK-NEXT:     VirtualAddress: 0x1000
+# CHECK-NEXT:     PhysicalAddress: 0x1000
+# CHECK-NEXT:     FileSize: 8
+# CHECK-NEXT:     MemSize: 8
+# CHECK:        Type: PT_LOAD
+# CHECK-NEXT:     Offset: 0x1008
+# CHECK-NEXT:     VirtualAddress: 0x1008
+# CHECK-NEXT:     PhysicalAddress: 0x2008
+# CHECK-NEXT:     FileSize: 17
+# CHECK-NEXT:     MemSize: 17
+
+.global _start
+_start:
+ nop
+
+.section .aaa, "a"
+.quad 0
+
+.section .bbb, "a"
+.quad 0
+
+.section .ccc, "a"
+.quad 0
Index: ELF/Writer.h
===================================================================
--- ELF/Writer.h
+++ ELF/Writer.h
@@ -45,11 +45,6 @@
   OutputSection *LastSec = nullptr;
   bool HasLMA = false;
 
-  // True if one of the sections in this program header has a LMA specified via
-  // linker script: AT(addr). We never allow 2 or more sections with LMA in the
-  // same program header.
-  bool ASectionHasLMA = false;
-
   uint64_t LMAOffset = 0;
 };
 
Index: ELF/Writer.cpp
===================================================================
--- ELF/Writer.cpp
+++ ELF/Writer.cpp
@@ -821,8 +821,6 @@
   p_align = std::max(p_align, Sec->Alignment);
   if (p_type == PT_LOAD)
     Sec->PtLoad = this;
-  if (Sec->LMAExpr)
-    ASectionHasLMA = true;
 }
 
 // The beginning and the ending of .rel[a].plt section are marked
@@ -1654,6 +1652,7 @@
   Load->add(Out::ElfHeader);
   Load->add(Out::ProgramHeaders);
 
+  bool FirstLoadSection = true;
   for (OutputSection *Sec : OutputSections) {
     if (!(Sec->Flags & SHF_ALLOC))
       break;
@@ -1666,14 +1665,15 @@
     // different flags or is loaded at a discontiguous address using AT linker
     // script command.
     uint64_t NewFlags = computeFlags(Sec->getPhdrFlags());
-    if ((Sec->LMAExpr && Load->ASectionHasLMA) ||
+    if ((Sec->LMAExpr && !FirstLoadSection) ||
         Sec->MemRegion != Load->FirstSec->MemRegion || Flags != NewFlags) {
 
       Load = AddHdr(PT_LOAD, NewFlags);
       Flags = NewFlags;
     }
 
     Load->add(Sec);
+    FirstLoadSection = false;
   }
 
   // Add a TLS segment if any.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D43284.134198.patch
Type: text/x-patch
Size: 2671 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180214/6b182f12/attachment.bin>


More information about the llvm-commits mailing list