[lld] r292642 - Reduce code duplication when allocating program headers.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 20 12:41:19 PST 2017


Author: rafael
Date: Fri Jan 20 14:41:18 2017
New Revision: 292642

URL: http://llvm.org/viewvc/llvm-project?rev=292642&view=rev
Log:
Reduce code duplication when allocating program headers.

This will simplify a bug fix.

Modified:
    lld/trunk/ELF/LinkerScript.cpp
    lld/trunk/ELF/Writer.cpp
    lld/trunk/ELF/Writer.h

Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=292642&r1=292641&r2=292642&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Fri Jan 20 14:41:18 2017
@@ -733,17 +733,7 @@ void LinkerScript<ELFT>::assignAddresses
       Sec->Addr = 0;
   }
 
-  uintX_t HeaderSize = getHeaderSize();
-  // If the linker script doesn't have PHDRS, add ElfHeader and ProgramHeaders
-  // now that we know we have space.
-  if (HeaderSize <= MinVA && !hasPhdrsCommands())
-    allocateHeaders<ELFT>(Phdrs, *OutputSections);
-
-  // ELF and Program headers need to be right before the first section in
-  // memory. Set their addresses accordingly.
-  MinVA = alignDown(MinVA - HeaderSize, Config->MaxPageSize);
-  Out<ELFT>::ElfHeader->Addr = MinVA;
-  Out<ELFT>::ProgramHeaders->Addr = Out<ELFT>::ElfHeader->Size + MinVA;
+  allocateHeaders<ELFT>(Phdrs, *OutputSections, MinVA);
 }
 
 // Creates program headers as instructed by PHDRS linker script command.

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=292642&r1=292641&r2=292642&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Fri Jan 20 14:41:18 2017
@@ -1330,13 +1330,29 @@ template <class ELFT> void Writer<ELFT>:
 }
 
 template <class ELFT>
-void elf::allocateHeaders(MutableArrayRef<PhdrEntry> Phdrs,
-                          ArrayRef<OutputSectionBase *> OutputSections) {
+bool elf::allocateHeaders(MutableArrayRef<PhdrEntry> Phdrs,
+                          ArrayRef<OutputSectionBase *> OutputSections,
+                          uint64_t Min) {
   auto FirstPTLoad =
       std::find_if(Phdrs.begin(), Phdrs.end(),
                    [](const PhdrEntry &E) { return E.p_type == PT_LOAD; });
   if (FirstPTLoad == Phdrs.end())
-    return;
+    return false;
+
+  uint64_t HeaderSize = getHeaderSize<ELFT>();
+  if (HeaderSize > Min)
+    return false;
+  Min = alignDown(Min - HeaderSize, Config->MaxPageSize);
+
+  if (!ScriptConfig->HasSections)
+    Config->ImageBase = Min = std::min(Min, Config->ImageBase);
+
+  Out<ELFT>::ElfHeader->Addr = Min;
+  Out<ELFT>::ProgramHeaders->Addr = Min + Out<ELFT>::ElfHeader->Size;
+
+  if (Script<ELFT>::X->hasPhdrsCommands())
+    return true;
+
   if (FirstPTLoad->First)
     for (OutputSectionBase *Sec : OutputSections)
       if (Sec->FirstInPtLoad == FirstPTLoad->First)
@@ -1344,6 +1360,7 @@ void elf::allocateHeaders(MutableArrayRe
   FirstPTLoad->First = Out<ELFT>::ElfHeader;
   if (!FirstPTLoad->Last)
     FirstPTLoad->Last = Out<ELFT>::ProgramHeaders;
+  return true;
 }
 
 // We should set file offsets and VAs for elf header and program headers
@@ -1355,27 +1372,14 @@ template <class ELFT> void Writer<ELFT>:
   if (ScriptConfig->HasSections)
     return;
 
-  uintX_t HeaderSize = getHeaderSize<ELFT>();
   // When -T<section> option is specified, lower the base to make room for those
   // sections.
-  if (!Config->SectionStartMap.empty()) {
-    uint64_t Min = -1;
+  uint64_t Min = -1;
+  if (!Config->SectionStartMap.empty())
     for (const auto &P : Config->SectionStartMap)
       Min = std::min(Min, P.second);
-    if (HeaderSize < Min)
-      Min -= HeaderSize;
-    else
-      AllocateHeader = false;
-    if (Min < Config->ImageBase)
-      Config->ImageBase = alignDown(Min, Config->MaxPageSize);
-  }
-
-  if (AllocateHeader)
-    allocateHeaders<ELFT>(Phdrs, OutputSections);
 
-  uintX_t BaseVA = Config->ImageBase;
-  Out<ELFT>::ElfHeader->Addr = BaseVA;
-  Out<ELFT>::ProgramHeaders->Addr = BaseVA + Out<ELFT>::ElfHeader->Size;
+  AllocateHeader = allocateHeaders<ELFT>(Phdrs, OutputSections, Min);
 }
 
 // Assign VAs (addresses at run-time) to output sections.
@@ -1740,14 +1744,18 @@ template void elf::writeResult<ELF32BE>(
 template void elf::writeResult<ELF64LE>();
 template void elf::writeResult<ELF64BE>();
 
-template void elf::allocateHeaders<ELF32LE>(MutableArrayRef<PhdrEntry>,
-                                            ArrayRef<OutputSectionBase *>);
-template void elf::allocateHeaders<ELF32BE>(MutableArrayRef<PhdrEntry>,
-                                            ArrayRef<OutputSectionBase *>);
-template void elf::allocateHeaders<ELF64LE>(MutableArrayRef<PhdrEntry>,
-                                            ArrayRef<OutputSectionBase *>);
-template void elf::allocateHeaders<ELF64BE>(MutableArrayRef<PhdrEntry>,
-                                            ArrayRef<OutputSectionBase *>);
+template bool elf::allocateHeaders<ELF32LE>(MutableArrayRef<PhdrEntry>,
+                                            ArrayRef<OutputSectionBase *>,
+                                            uint64_t);
+template bool elf::allocateHeaders<ELF32BE>(MutableArrayRef<PhdrEntry>,
+                                            ArrayRef<OutputSectionBase *>,
+                                            uint64_t);
+template bool elf::allocateHeaders<ELF64LE>(MutableArrayRef<PhdrEntry>,
+                                            ArrayRef<OutputSectionBase *>,
+                                            uint64_t);
+template bool elf::allocateHeaders<ELF64BE>(MutableArrayRef<PhdrEntry>,
+                                            ArrayRef<OutputSectionBase *>,
+                                            uint64_t);
 
 template bool elf::isRelroSection<ELF32LE>(const OutputSectionBase *);
 template bool elf::isRelroSection<ELF32BE>(const OutputSectionBase *);

Modified: lld/trunk/ELF/Writer.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.h?rev=292642&r1=292641&r2=292642&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.h (original)
+++ lld/trunk/ELF/Writer.h Fri Jan 20 14:41:18 2017
@@ -50,8 +50,8 @@ struct PhdrEntry {
 llvm::StringRef getOutputSectionName(llvm::StringRef Name);
 
 template <class ELFT>
-void allocateHeaders(llvm::MutableArrayRef<PhdrEntry>,
-                     llvm::ArrayRef<OutputSectionBase *>);
+bool allocateHeaders(llvm::MutableArrayRef<PhdrEntry>,
+                     llvm::ArrayRef<OutputSectionBase *>, uint64_t Min);
 template <class ELFT> void reportDiscarded(InputSectionBase<ELFT> *IS);
 
 template <class ELFT> uint32_t getMipsEFlags();




More information about the llvm-commits mailing list