[lld] r287445 - Change filler type from ArrayRef<uint8_t> to uint32_t.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Sat Nov 19 10:05:57 PST 2016


Author: ruiu
Date: Sat Nov 19 12:05:56 2016
New Revision: 287445

URL: http://llvm.org/viewvc/llvm-project?rev=287445&view=rev
Log:
Change filler type from ArrayRef<uint8_t> to uint32_t.

Filler expressions in linker script "=fillexp" are always handled
as 32-bit integers. Thus the new type is more natural.

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

Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=287445&r1=287444&r2=287445&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Sat Nov 19 12:05:56 2016
@@ -787,12 +787,12 @@ template <class ELFT> bool LinkerScript<
 }
 
 template <class ELFT>
-ArrayRef<uint8_t> LinkerScript<ELFT>::getFiller(StringRef Name) {
+uint32_t LinkerScript<ELFT>::getFiller(StringRef Name) {
   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands)
     if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()))
       if (Cmd->Name == Name)
         return Cmd->Filler;
-  return {};
+  return 0;
 }
 
 template <class ELFT>
@@ -981,9 +981,9 @@ private:
 
   SymbolAssignment *readAssignment(StringRef Name);
   BytesDataCommand *readBytesDataCommand(StringRef Tok);
-  std::vector<uint8_t> readFill();
+  uint32_t readFill();
   OutputSectionCommand *readOutputSectionDescription(StringRef OutSec);
-  std::vector<uint8_t> readOutputSectionFiller(StringRef Tok);
+  uint32_t readOutputSectionFiller(StringRef Tok);
   std::vector<StringRef> readOutputSectionPhdrs();
   InputSectionDescription *readInputSectionDescription(StringRef Tok);
   StringMatcher readFilePatterns();
@@ -1387,9 +1387,9 @@ Expr ScriptParser::readAssert() {
 // alias for =fillexp section attribute, which is different from
 // what GNU linkers do.
 // https://sourceware.org/binutils/docs/ld/Output-Section-Data.html
-std::vector<uint8_t> ScriptParser::readFill() {
+uint32_t ScriptParser::readFill() {
   expect("(");
-  std::vector<uint8_t> V = readOutputSectionFiller(next());
+  uint32_t V = readOutputSectionFiller(next());
   expect(")");
   expect(";");
   return V;
@@ -1452,13 +1452,12 @@ ScriptParser::readOutputSectionDescripti
 // hexstrings as blobs of arbitrary sizes, while ld.gold handles them
 // as 32-bit big-endian values. We will do the same as ld.gold does
 // because it's simpler than what ld.bfd does.
-std::vector<uint8_t> ScriptParser::readOutputSectionFiller(StringRef Tok) {
+uint32_t ScriptParser::readOutputSectionFiller(StringRef Tok) {
   uint32_t V;
-  if (Tok.getAsInteger(0, V)) {
-    setError("invalid filler expression: " + Tok);
-    return {};
-  }
-  return {uint8_t(V >> 24), uint8_t(V >> 16), uint8_t(V >> 8), uint8_t(V)};
+  if (!Tok.getAsInteger(0, V))
+    return V;
+  setError("invalid filler expression: " + Tok);
+  return 0;
 }
 
 SymbolAssignment *ScriptParser::readProvideHidden(bool Provide, bool Hidden) {

Modified: lld/trunk/ELF/LinkerScript.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.h?rev=287445&r1=287444&r2=287445&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.h (original)
+++ lld/trunk/ELF/LinkerScript.h Sat Nov 19 12:05:56 2016
@@ -122,7 +122,7 @@ struct OutputSectionCommand : BaseComman
   Expr SubalignExpr;
   std::vector<std::unique_ptr<BaseCommand>> Commands;
   std::vector<StringRef> Phdrs;
-  std::vector<uint8_t> Filler;
+  uint32_t Filler = 0;
   ConstraintKind Constraint = ConstraintKind::NoConstraint;
 };
 
@@ -232,7 +232,7 @@ public:
   std::vector<PhdrEntry<ELFT>> createPhdrs();
   bool ignoreInterpSection();
 
-  ArrayRef<uint8_t> getFiller(StringRef Name);
+  uint32_t getFiller(StringRef Name);
   void writeDataBytes(StringRef Name, uint8_t *Buf);
   bool hasLMA(StringRef Name);
   bool shouldKeep(InputSectionBase<ELFT> *S);

Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=287445&r1=287444&r2=287445&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Sat Nov 19 12:05:56 2016
@@ -329,22 +329,27 @@ template <class ELFT> void OutputSection
   std::stable_sort(Sections.begin(), Sections.end(), compCtors<ELFT>);
 }
 
-static void fill(uint8_t *Buf, size_t Size, ArrayRef<uint8_t> A) {
+// Fill [Buf, Buf + Size) with Filler. Filler is written in big
+// endian order. This is used for linker script "=fillexp" command.
+void fill(uint8_t *Buf, size_t Size, uint32_t Filler) {
+  uint8_t V[4];
+  write32be(V, Filler);
   size_t I = 0;
-  for (; I + A.size() < Size; I += A.size())
-    memcpy(Buf + I, A.data(), A.size());
-  memcpy(Buf + I, A.data(), Size - I);
+  for (; I + 4 < Size; I += 4)
+    memcpy(Buf + I, V, 4);
+  memcpy(Buf + I, V, Size - I);
 }
 
 template <class ELFT> void OutputSection<ELFT>::writeTo(uint8_t *Buf) {
-  ArrayRef<uint8_t> Filler = Script<ELFT>::X->getFiller(this->Name);
-  if (!Filler.empty())
+  if (uint32_t Filler = Script<ELFT>::X->getFiller(this->Name))
     fill(Buf, this->Size, Filler);
+
   auto Fn = [=](InputSection<ELFT> *IS) { IS->writeTo(Buf); };
   if (Config->Threads)
     parallel_for_each(Sections.begin(), Sections.end(), Fn);
   else
     std::for_each(Sections.begin(), Sections.end(), Fn);
+
   // Linker scripts may have BYTE()-family commands with which you
   // can write arbitrary bytes to the output. Process them if any.
   Script<ELFT>::X->writeDataBytes(this->Name, Buf);




More information about the llvm-commits mailing list