[PATCH] D32749: [LLD][ELF] Fix problems with fabricateDefaultCommands() and --section-start

Peter Smith via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue May 2 07:16:33 PDT 2017


peter.smith created this revision.

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 section with PageAlign is aligned to an address higher than the next --section-start without PageAlign. The ld.bfd and ld.gold seem to be more consistent with this interpretation 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.

The problems were found while investigating dmikulin's comments in https://reviews.llvm.org/D31888 , however I don't think that these changes are directly related.


https://reviews.llvm.org/D32749

Files:
  ELF/LinkerScript.cpp
  ELF/Writer.cpp
  test/ELF/sectionstart-noallochdr.s


Index: test/ELF/sectionstart-noallochdr.s
===================================================================
--- /dev/null
+++ test/ELF/sectionstart-noallochdr.s
@@ -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
Index: ELF/Writer.cpp
===================================================================
--- ELF/Writer.cpp
+++ ELF/Writer.cpp
@@ -252,7 +252,7 @@
   } else {
     if (!Script->Opt.HasSections) {
       fixSectionAlignments();
-      Script->fabricateDefaultCommands(Config->MaxPageSize);
+      Script->fabricateDefaultCommands(AllocateHeader);
     }
     Script->synchronize();
     Script->assignAddresses(Phdrs);
Index: ELF/LinkerScript.cpp
===================================================================
--- ELF/LinkerScript.cpp
+++ ELF/LinkerScript.cpp
@@ -431,10 +431,10 @@
   // 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);
-  }
+  if (!Config->SectionStartMap.empty())
+    for (auto& KV : Config->SectionStartMap)
+      StartAddr = std::min(StartAddr, KV.second);
+
   Commands.push_back(
       make<SymbolAssignment>(".", [=] { return StartAddr; }, ""));
 
@@ -444,17 +444,19 @@
     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>("");


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D32749.97445.patch
Type: text/x-patch
Size: 2843 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170502/bed37e79/attachment.bin>


More information about the llvm-commits mailing list