[lld] r302007 - [ELF] Fix problems with fabricateDefaultCommands() and --section-start

Peter Smith via llvm-commits llvm-commits at lists.llvm.org
Wed May 3 01:44:50 PDT 2017


Author: psmith
Date: Wed May  3 03:44:50 2017
New Revision: 302007

URL: http://llvm.org/viewvc/llvm-project?rev=302007&view=rev
Log:
[ELF] Fix problems with fabricateDefaultCommands() and --section-start

The --section-start <name>=<address> needs to be translated into equivalent
linker script commands. There are a couple of problems with the existing
implementation:
- The --section-start with the lowest address is assumed to be at the start
of the map. This assumption is incorrect, we have to iterate through the
SectionStartMap to find the lowest address.
- The addresses in --section-start were being over-aligned when the
sections were marked as PageAlign. This is inconsistent with the use of
SectionStartMap in fixHeaders(), and can cause problems when the PageAlign
causes an "unable to move location counter backward" error when the
--section-start with PageAlign is aligned to an address higher than the next
--section-start. The ld.bfd and ld.gold seem to be more consistent with this
approach but this is not a well specified area.
    
This change fixes the problems above and also corrects a typo in which
fabricateDefaultCommands() is called with the wrong parameter, it should be
called with AllocateHeader not Config->MaxPageSize.

Differential Revision: https://reviews.llvm.org/D32749


Added:
    lld/trunk/test/ELF/sectionstart-noallochdr.s
Modified:
    lld/trunk/ELF/LinkerScript.cpp
    lld/trunk/ELF/Writer.cpp

Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=302007&r1=302006&r2=302007&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Wed May  3 03:44:50 2017
@@ -428,13 +428,12 @@ void LinkerScript::fabricateDefaultComma
   if (AllocateHeader)
     StartAddr += elf::getHeaderSize();
 
-  // The Sections with -T<section> are sorted in order of ascending address
-  // we must use this if it is lower than StartAddr as calls to setDot() must
-  // be monotonically increasing
-  if (!Config->SectionStartMap.empty()) {
-    uint64_t LowestSecStart = Config->SectionStartMap.begin()->second;
-    StartAddr = std::min(StartAddr, LowestSecStart);
-  }
+  // The Sections with -T<section> have been sorted in order of ascending
+  // address. We must lower StartAddr if the lowest -T<section address> as
+  // calls to setDot() must be monotonically increasing.
+  for (auto& KV : Config->SectionStartMap)
+    StartAddr = std::min(StartAddr, KV.second);
+
   Commands.push_back(
       make<SymbolAssignment>(".", [=] { return StartAddr; }, ""));
 
@@ -444,17 +443,19 @@ void LinkerScript::fabricateDefaultComma
     if (!(Sec->Flags & SHF_ALLOC))
       continue;
 
+    auto *OSCmd = make<OutputSectionCommand>(Sec->Name);
+    OSCmd->Sec = Sec;
+
+    // Prefer user supplied address over additional alignment constraint
     auto I = Config->SectionStartMap.find(Sec->Name);
     if (I != Config->SectionStartMap.end())
       Commands.push_back(
           make<SymbolAssignment>(".", [=] { return I->second; }, ""));
-
-    auto *OSCmd = make<OutputSectionCommand>(Sec->Name);
-    OSCmd->Sec = Sec;
-    if (Sec->PageAlign)
+    else if (Sec->PageAlign)
       OSCmd->AddrExpr = [=] {
         return alignTo(Script->getDot(), Config->MaxPageSize);
       };
+
     Commands.push_back(OSCmd);
     if (Sec->Sections.size()) {
       auto *ISD = make<InputSectionDescription>("");

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=302007&r1=302006&r2=302007&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Wed May  3 03:44:50 2017
@@ -252,7 +252,7 @@ template <class ELFT> void Writer<ELFT>:
   } else {
     if (!Script->Opt.HasSections) {
       fixSectionAlignments();
-      Script->fabricateDefaultCommands(Config->MaxPageSize);
+      Script->fabricateDefaultCommands(AllocateHeader);
     }
     Script->synchronize();
     Script->assignAddresses(Phdrs);

Added: lld/trunk/test/ELF/sectionstart-noallochdr.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/sectionstart-noallochdr.s?rev=302007&view=auto
==============================================================================
--- lld/trunk/test/ELF/sectionstart-noallochdr.s (added)
+++ lld/trunk/test/ELF/sectionstart-noallochdr.s Wed May  3 03:44:50 2017
@@ -0,0 +1,23 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: ld.lld %t.o --section-start .data=0x20 \
+# RUN: --section-start .bss=0x30 --section-start .text=0x10 -o %t1
+# RUN: llvm-objdump -section-headers %t1 | FileCheck %s
+
+# CHECK:      Sections:
+# CHECK-NEXT:  Idx Name          Size      Address          Type
+# CHECK-NEXT:    0               00000000 0000000000000000
+# CHECK-NEXT:    1 .text         00000001 0000000000000010 TEXT DATA
+# CHECK-NEXT:    2 .data         00000004 0000000000000020 DATA
+# CHECK-NEXT:    3 .bss          00000004 0000000000000030 BSS
+
+.text
+.globl _start
+_start:
+ nop
+
+.data
+.long 0
+
+.bss
+.zero 4




More information about the llvm-commits mailing list