[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