[PATCH] D23165: [ELF, Drawt] - Linkerscript: implement SIZEOF_HEADERS

George Rimar via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 4 08:29:10 PDT 2016


grimar created this revision.
grimar added reviewers: ruiu, rafael, davide.
grimar added subscribers: llvm-commits, grimar, evgeny777.
Herald added a subscriber: emaste.

SIZEOF_HEADERS is a feature used in FreeBsd script,
there is a discussion on PR28688 page about it.

It seems that for BSD script at least this implementation should be enough and
I found that I see no reasons why we can not implement it that simple.

We are calculating amount of headers before assignAddresses() call. And we need
this constant only during assign addresses, so headers amount will not change after createPhdrs() anymore.
What I am missing ?

There is no testcases as it is draft patch. If it is generally fine, I`ll add them.


https://reviews.llvm.org/D23165

Files:
  ELF/LinkerScript.cpp
  ELF/LinkerScript.h

Index: ELF/LinkerScript.h
===================================================================
--- ELF/LinkerScript.h
+++ ELF/LinkerScript.h
@@ -123,6 +123,8 @@
 
   bool HasContents = false;
 
+  bool ManualHeadersSize = false;
+
   llvm::BumpPtrAllocator Alloc;
 
   // List of section patterns specified with KEEP commands. They will
@@ -150,6 +152,7 @@
   void addScriptedSymbols();
   bool hasPhdrsCommands();
   uintX_t getOutputSectionSize(StringRef Name);
+  uintX_t getSizeOfHeaders();
 
 private:
   std::vector<std::pair<StringRef, const InputSectionDescription *>>
Index: ELF/LinkerScript.cpp
===================================================================
--- ELF/LinkerScript.cpp
+++ ELF/LinkerScript.cpp
@@ -239,7 +239,7 @@
   }
 
   // Assign addresses as instructed by linker script SECTIONS sub-commands.
-  Dot = Out<ELFT>::ElfHeader->getSize() + Out<ELFT>::ProgramHeaders->getSize();
+  Dot = Opt.ManualHeadersSize ? 0 : getSizeOfHeaders();
   uintX_t MinVA = std::numeric_limits<uintX_t>::max();
   uintX_t ThreadBssOffset = 0;
 
@@ -431,6 +431,11 @@
   return 0;
 }
 
+template <class ELFT>
+typename ELFT::uint LinkerScript<ELFT>::getSizeOfHeaders() {
+  return Out<ELFT>::ElfHeader->getSize() + Out<ELFT>::ProgramHeaders->getSize();
+}
+
 // Returns indices of ELF headers containing specific section, identified
 // by Name. Each index is a zero based number of ELF header listed within
 // PHDRS {} script block.
@@ -933,6 +938,22 @@
   return 0;
 }
 
+static uint64_t getSizeOfHeaders() {
+  switch (Config->EKind) {
+  case ELF32LEKind:
+    return Script<ELF32LE>::X->getSizeOfHeaders();
+  case ELF32BEKind:
+    return Script<ELF32BE>::X->getSizeOfHeaders();
+  case ELF64LEKind:
+    return Script<ELF64LE>::X->getSizeOfHeaders();
+  case ELF64BEKind:
+    return Script<ELF64BE>::X->getSizeOfHeaders();
+  default:
+    llvm_unreachable("unsupported target");
+  }
+  return 0;
+}
+
 SymbolAssignment *ScriptParser::readAssignment(StringRef Name) {
   StringRef Op = next();
   assert(Op == "=" || Op == "+=");
@@ -1047,6 +1068,10 @@
     expect(")");
     return [=](uint64_t Dot) { return getSectionSize(Name); };
   }
+  if (Tok == "SIZEOF_HEADERS") {
+    Opt.ManualHeadersSize = true;
+    return [=](uint64_t Dot) { return getSizeOfHeaders(); };
+  }
 
   // Parse a symbol name or a number literal.
   uint64_t V = 0;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D23165.66809.patch
Type: text/x-patch
Size: 2427 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160804/642a0ec0/attachment.bin>


More information about the llvm-commits mailing list