[lld] r284786 - Move code from InputFile to ELFCreator to decouple the two files.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 20 14:57:06 PDT 2016


Author: ruiu
Date: Thu Oct 20 16:57:06 2016
New Revision: 284786

URL: http://llvm.org/viewvc/llvm-project?rev=284786&view=rev
Log:
Move code from InputFile to ELFCreator to decouple the two files.

Now that only one non-member function is exported from ELFCreator.h.
All the details are handled internally in ELFCreator.cpp file.

Modified:
    lld/trunk/ELF/ELFCreator.cpp
    lld/trunk/ELF/ELFCreator.h
    lld/trunk/ELF/InputFiles.cpp
    lld/trunk/ELF/InputFiles.h

Modified: lld/trunk/ELF/ELFCreator.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/ELFCreator.cpp?rev=284786&r1=284785&r2=284786&view=diff
==============================================================================
--- lld/trunk/ELF/ELFCreator.cpp (original)
+++ lld/trunk/ELF/ELFCreator.cpp Thu Oct 20 16:57:06 2016
@@ -13,6 +13,10 @@
 //===----------------------------------------------------------------------===//
 
 #include "ELFCreator.h"
+#include "Config.h"
+#include "llvm/MC/StringTableBuilder.h"
+#include "llvm/Object/ELFTypes.h"
+#include "llvm/Support/StringSaver.h"
 
 using namespace llvm;
 using namespace llvm::ELF;
@@ -21,13 +25,45 @@ using namespace llvm::object;
 using namespace lld;
 using namespace lld::elf;
 
+namespace {
+template <class ELFT> class ELFCreator {
+  typedef typename ELFT::uint uintX_t;
+  typedef typename ELFT::Ehdr Elf_Ehdr;
+  typedef typename ELFT::Shdr Elf_Shdr;
+  typedef typename ELFT::Sym Elf_Sym;
+
+public:
+  struct Section {
+    Elf_Shdr *Header;
+    size_t Index;
+  };
+
+  ELFCreator(std::uint16_t Type, std::uint16_t Machine);
+  Section addSection(StringRef Name);
+  Elf_Sym *addSymbol(StringRef Name);
+  size_t layout();
+  void writeTo(uint8_t *Out);
+
+private:
+  Elf_Ehdr Header = {};
+  std::vector<Elf_Shdr *> Sections;
+  std::vector<Elf_Sym *> Symbols;
+  StringTableBuilder ShStrTabBuilder{StringTableBuilder::ELF};
+  StringTableBuilder StrTabBuilder{StringTableBuilder::ELF};
+  BumpPtrAllocator Alloc;
+  StringSaver Saver{Alloc};
+  Elf_Shdr *ShStrTab;
+  Elf_Shdr *StrTab;
+  Elf_Shdr *SymTab;
+};
+}
+
 template <class ELFT>
 ELFCreator<ELFT>::ELFCreator(std::uint16_t Type, std::uint16_t Machine) {
   std::memcpy(Header.e_ident, "\177ELF", 4);
   Header.e_ident[EI_CLASS] = ELFT::Is64Bits ? ELFCLASS64 : ELFCLASS32;
-  Header.e_ident[EI_DATA] = ELFT::TargetEndianness == llvm::support::little
-                                ? ELFDATA2LSB
-                                : ELFDATA2MSB;
+  Header.e_ident[EI_DATA] =
+      ELFT::TargetEndianness == support::little ? ELFDATA2LSB : ELFDATA2MSB;
   Header.e_ident[EI_VERSION] = EV_CURRENT;
   Header.e_type = Type;
   Header.e_machine = Machine;
@@ -111,7 +147,50 @@ template <class ELFT> void ELFCreator<EL
     *Shdr++ = *S;
 }
 
-template class elf::ELFCreator<ELF32LE>;
-template class elf::ELFCreator<ELF32BE>;
-template class elf::ELFCreator<ELF64LE>;
-template class elf::ELFCreator<ELF64BE>;
+template <class ELFT>
+std::vector<uint8_t> elf::wrapBinaryWithElfHeader(ArrayRef<uint8_t> Blob,
+                                                  std::string Filename) {
+  typedef typename ELFT::uint uintX_t;
+  typedef typename ELFT::Sym Elf_Sym;
+
+  // Fill the ELF file header.
+  ELFCreator<ELFT> File(ET_REL, Config->EMachine);
+  auto Sec = File.addSection(".data");
+  Sec.Header->sh_flags = SHF_ALLOC;
+  Sec.Header->sh_size = Blob.size();
+  Sec.Header->sh_type = SHT_PROGBITS;
+  Sec.Header->sh_addralign = 8;
+
+  // Replace non-alphanumeric characters with '_'.
+  std::transform(Filename.begin(), Filename.end(), Filename.begin(),
+                 [](char C) { return isalnum(C) ? C : '_'; });
+
+  // Add _start, _end and _size symbols.
+  auto AddSym = [&](std::string Name, uintX_t SecIdx, uintX_t Value) {
+    Elf_Sym *Sym = File.addSymbol("_binary_" + Filename + Name);
+    Sym->setBindingAndType(STB_GLOBAL, STT_OBJECT);
+    Sym->st_shndx = SecIdx;
+    Sym->st_value = Value;
+  };
+  AddSym("_start", Sec.Index, 0);
+  AddSym("_end", Sec.Index, Blob.size());
+  AddSym("_size", SHN_ABS, Blob.size());
+
+  // Fix the ELF file layout and write it down to a uint8_t vector.
+  size_t Size = File.layout();
+  std::vector<uint8_t> Ret(Size);
+  File.writeTo(Ret.data());
+
+  // Fill .data section with actual data.
+  memcpy(Ret.data() + Sec.Header->sh_offset, Blob.data(), Blob.size());
+  return Ret;
+}
+
+template std::vector<uint8_t>
+    elf::wrapBinaryWithElfHeader<ELF32LE>(ArrayRef<uint8_t>, std::string);
+template std::vector<uint8_t>
+    elf::wrapBinaryWithElfHeader<ELF32BE>(ArrayRef<uint8_t>, std::string);
+template std::vector<uint8_t>
+    elf::wrapBinaryWithElfHeader<ELF64LE>(ArrayRef<uint8_t>, std::string);
+template std::vector<uint8_t>
+    elf::wrapBinaryWithElfHeader<ELF64BE>(ArrayRef<uint8_t>, std::string);

Modified: lld/trunk/ELF/ELFCreator.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/ELFCreator.h?rev=284786&r1=284785&r2=284786&view=diff
==============================================================================
--- lld/trunk/ELF/ELFCreator.h (original)
+++ lld/trunk/ELF/ELFCreator.h Thu Oct 20 16:57:06 2016
@@ -12,43 +12,14 @@
 
 #include "lld/Core/LLVM.h"
 
-#include "llvm/MC/StringTableBuilder.h"
-#include "llvm/Object/ELFTypes.h"
-#include "llvm/Support/StringSaver.h"
-
 namespace lld {
 namespace elf {
 
-template <class ELFT> class ELFCreator {
-  typedef typename ELFT::uint uintX_t;
-  typedef typename ELFT::Ehdr Elf_Ehdr;
-  typedef typename ELFT::Shdr Elf_Shdr;
-  typedef typename ELFT::Sym Elf_Sym;
-
-public:
-  struct Section {
-    Elf_Shdr *Header;
-    size_t Index;
-  };
-
-  ELFCreator(std::uint16_t Type, std::uint16_t Machine);
-  Section addSection(StringRef Name);
-  Elf_Sym *addSymbol(StringRef Name);
-  size_t layout();
-  void writeTo(uint8_t *Out);
-
-private:
-  Elf_Ehdr Header = {};
-  std::vector<Elf_Shdr *> Sections;
-  std::vector<Elf_Sym *> Symbols;
-  llvm::StringTableBuilder ShStrTabBuilder{llvm::StringTableBuilder::ELF};
-  llvm::StringTableBuilder StrTabBuilder{llvm::StringTableBuilder::ELF};
-  llvm::BumpPtrAllocator Alloc;
-  llvm::StringSaver Saver{Alloc};
-  Elf_Shdr *ShStrTab;
-  Elf_Shdr *StrTab;
-  Elf_Shdr *SymTab;
-};
+// Wraps a given binary blob with an ELF header so that the blob
+// can be linked as an ELF file. Used for "--format binary".
+template <class ELFT>
+std::vector<uint8_t> wrapBinaryWithElfHeader(ArrayRef<uint8_t> Data,
+                                             std::string Filename);
 }
 }
 

Modified: lld/trunk/ELF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=284786&r1=284785&r2=284786&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.cpp (original)
+++ lld/trunk/ELF/InputFiles.cpp Thu Oct 20 16:57:06 2016
@@ -781,44 +781,12 @@ static InputFile *createELFFile(MemoryBu
 // Wraps a binary blob with an ELF header and footer
 // so that we can link it as a regular ELF file.
 template <class ELFT> InputFile *BinaryFile::createELF() {
-  typedef typename ELFT::uint uintX_t;
-  typedef typename ELFT::Sym Elf_Sym;
+  ArrayRef<uint8_t> Blob((uint8_t *)MB.getBufferStart(), MB.getBufferSize());
+  StringRef Filename = MB.getBufferIdentifier();
+  Buffer = wrapBinaryWithElfHeader<ELFT>(Blob, Filename);
 
-  // Fill the ELF file header.
-  ELFCreator<ELFT> File(ET_REL, Config->EMachine);
-  auto DataSec = File.addSection(".data");
-  DataSec.Header->sh_flags = SHF_ALLOC;
-  DataSec.Header->sh_size = MB.getBufferSize();
-  DataSec.Header->sh_type = SHT_PROGBITS;
-  DataSec.Header->sh_addralign = 8;
-
-  // Replace non-alphanumeric characters with '_'.
-  std::string Filepath = MB.getBufferIdentifier();
-  std::transform(Filepath.begin(), Filepath.end(), Filepath.begin(),
-                 [](char C) { return isalnum(C) ? C : '_'; });
-
-  // Add _start, _end and _size symbols.
-  auto AddSym = [&](std::string Name, uintX_t SecIdx, uintX_t Value) {
-    Elf_Sym *Sym = File.addSymbol("_binary_" + Filepath + Name);
-    Sym->setBindingAndType(STB_GLOBAL, STT_OBJECT);
-    Sym->st_shndx = SecIdx;
-    Sym->st_value = Value;
-  };
-  AddSym("_start", DataSec.Index, 0);
-  AddSym("_end", DataSec.Index, MB.getBufferSize());
-  AddSym("_size", SHN_ABS, MB.getBufferSize());
-
-  // Fix the ELF file layout and write it down to ELFData uint8_t vector.
-  size_t Size = File.layout();
-  ELFData.resize(Size);
-  File.writeTo(ELFData.data());
-
-  // Fill .data section with actual data.
-  memcpy(ELFData.data() + DataSec.Header->sh_offset, MB.getBufferStart(),
-         MB.getBufferSize());
-
-  return createELFFile<ObjectFile>(MemoryBufferRef(
-      StringRef((char *)ELFData.data(), Size), MB.getBufferIdentifier()));
+  return createELFFile<ObjectFile>(
+      MemoryBufferRef(toStringRef(Buffer), Filename));
 }
 
 static bool isBitcode(MemoryBufferRef MB) {

Modified: lld/trunk/ELF/InputFiles.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.h?rev=284786&r1=284785&r2=284786&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.h (original)
+++ lld/trunk/ELF/InputFiles.h Thu Oct 20 16:57:06 2016
@@ -326,7 +326,7 @@ public:
   template <class ELFT> InputFile *createELF();
 
 private:
-  std::vector<uint8_t> ELFData;
+  std::vector<uint8_t> Buffer;
 };
 
 InputFile *createObjectFile(MemoryBufferRef MB, StringRef ArchiveName = "",




More information about the llvm-commits mailing list