Index: ELF/CMakeLists.txt =================================================================== --- ELF/CMakeLists.txt +++ ELF/CMakeLists.txt @@ -6,7 +6,6 @@ Driver.cpp DriverUtils.cpp EhFrame.cpp - ELFCreator.cpp Error.cpp GdbIndex.cpp ICF.cpp Index: ELF/Config.h =================================================================== --- ELF/Config.h +++ ELF/Config.h @@ -70,6 +70,7 @@ // Most fields are initialized by the driver. struct Configuration { InputFile *FirstElf = nullptr; + uint8_t OSABI = 0; llvm::StringMap SectionStartMap; llvm::StringRef DynamicLinker; llvm::StringRef Entry; Index: ELF/ELFCreator.h =================================================================== --- ELF/ELFCreator.h +++ /dev/null @@ -1,28 +0,0 @@ -//===- ELFCreator.h ---------------------------------------------*- C++ -*-===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLD_ELF_ELF_CREATOR_H -#define LLD_ELF_ELF_CREATOR_H - -#include "lld/Core/LLVM.h" -#include -#include - -namespace lld { -namespace elf { - -// 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 -std::vector wrapBinaryWithElfHeader(llvm::ArrayRef Data, - std::string Filename); -} -} - -#endif Index: ELF/ELFCreator.cpp =================================================================== --- ELF/ELFCreator.cpp +++ /dev/null @@ -1,178 +0,0 @@ -//===- ELFCreator.cpp -----------------------------------------------------===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains a class to create an ELF file in memory. This is -// supposed to be used for "-format binary" option. -// -//===----------------------------------------------------------------------===// - -#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; -using namespace llvm::object; - -using namespace lld; -using namespace lld::elf; - -namespace { -template 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); - void addSymbol(StringRef Name, uintX_t SecIdx, uintX_t Value); - size_t layout(); - void writeTo(uint8_t *Out); - -private: - Elf_Ehdr Header = {}; - std::vector Sections; - std::vector Symbols; - StringTableBuilder StrTabBuilder{StringTableBuilder::ELF}; - BumpPtrAllocator Alloc; - StringSaver Saver{Alloc}; - Elf_Shdr *StrTab; - Elf_Shdr *SymTab; -}; -} - -template -ELFCreator::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 == support::little ? ELFDATA2LSB : ELFDATA2MSB; - Header.e_ident[EI_VERSION] = EV_CURRENT; - Header.e_type = Type; - Header.e_machine = Machine; - Header.e_version = EV_CURRENT; - Header.e_ehsize = sizeof(Elf_Ehdr); - Header.e_shentsize = sizeof(Elf_Shdr); - Header.e_shstrndx = 1; - - StrTab = addSection(".strtab").Header; - StrTab->sh_type = SHT_STRTAB; - StrTab->sh_addralign = 1; - - SymTab = addSection(".symtab").Header; - SymTab->sh_type = SHT_SYMTAB; - SymTab->sh_link = 1; - SymTab->sh_info = 1; - SymTab->sh_addralign = sizeof(uintX_t); - SymTab->sh_entsize = sizeof(Elf_Sym); -} - -template -typename ELFCreator::Section -ELFCreator::addSection(StringRef Name) { - auto *Shdr = new (Alloc) Elf_Shdr{}; - Shdr->sh_name = StrTabBuilder.add(Saver.save(Name)); - Sections.push_back(Shdr); - return {Shdr, Sections.size()}; -} - -template -void ELFCreator::addSymbol(StringRef Name, uintX_t SecIdx, - uintX_t Value) { - auto *Sym = new (Alloc) Elf_Sym{}; - Sym->st_name = StrTabBuilder.add(Saver.save(Name)); - Sym->setBindingAndType(STB_GLOBAL, STT_OBJECT); - Sym->st_shndx = SecIdx; - Sym->st_value = Value; - Symbols.push_back(Sym); -} - -template size_t ELFCreator::layout() { - StrTabBuilder.finalizeInOrder(); - StrTab->sh_size = StrTabBuilder.getSize(); - SymTab->sh_size = (Symbols.size() + 1) * sizeof(Elf_Sym); - - uintX_t Offset = sizeof(Elf_Ehdr); - for (Elf_Shdr *Sec : Sections) { - Offset = alignTo(Offset, Sec->sh_addralign); - Sec->sh_offset = Offset; - Offset += Sec->sh_size; - } - - Offset = alignTo(Offset, sizeof(uintX_t)); - Header.e_shoff = Offset; - Offset += (Sections.size() + 1) * sizeof(Elf_Shdr); - Header.e_shnum = Sections.size() + 1; - return Offset; -} - -template void ELFCreator::writeTo(uint8_t *Out) { - std::memcpy(Out, &Header, sizeof(Elf_Ehdr)); - StrTabBuilder.write(Out + StrTab->sh_offset); - - Elf_Sym *Sym = reinterpret_cast(Out + SymTab->sh_offset); - // Skip null. - ++Sym; - for (Elf_Sym *S : Symbols) - *Sym++ = *S; - - Elf_Shdr *Shdr = reinterpret_cast(Out + Header.e_shoff); - // Skip null. - ++Shdr; - for (Elf_Shdr *S : Sections) - *Shdr++ = *S; -} - -template -std::vector elf::wrapBinaryWithElfHeader(ArrayRef Blob, - std::string Filename) { - // Fill the ELF file header. - ELFCreator File(ET_REL, Config->EMachine); - typename ELFCreator::Section 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. - File.addSymbol("_binary_" + Filename + "_start", Sec.Index, 0); - File.addSymbol("_binary_" + Filename + "_end", Sec.Index, Blob.size()); - File.addSymbol("_binary_" + Filename + "_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 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 - elf::wrapBinaryWithElfHeader(ArrayRef, std::string); -template std::vector - elf::wrapBinaryWithElfHeader(ArrayRef, std::string); -template std::vector - elf::wrapBinaryWithElfHeader(ArrayRef, std::string); -template std::vector - elf::wrapBinaryWithElfHeader(ArrayRef, std::string); Index: ELF/InputFiles.h =================================================================== --- ELF/InputFiles.h +++ ELF/InputFiles.h @@ -352,11 +352,13 @@ public: explicit BinaryFile(MemoryBufferRef M) : InputFile(BinaryKind, M) {} static bool classof(const InputFile *F) { return F->kind() == BinaryKind; } - template InputFile *createELF(); + template void parse(); + ArrayRef getSections() const { return Sections; } private: - std::vector Buffer; llvm::BumpPtrAllocator Alloc; + llvm::StringSaver Saver{Alloc}; + std::vector Sections; }; InputFile *createObjectFile(llvm::BumpPtrAllocator &Alloc, MemoryBufferRef MB, Index: ELF/InputFiles.cpp =================================================================== --- ELF/InputFiles.cpp +++ ELF/InputFiles.cpp @@ -9,7 +9,6 @@ #include "InputFiles.h" #include "Driver.h" -#include "ELFCreator.h" #include "Error.h" #include "InputSection.h" #include "LinkerScript.h" @@ -792,6 +791,16 @@ createBitcodeSymbol(KeptComdats, ObjSym, Saver, this)); } +template +static T *createELFFileAux(BumpPtrAllocator &Alloc, MemoryBufferRef MB) { + T *Obj = new T(Alloc, MB); + if (!Config->FirstElf) { + Config->FirstElf = Obj; + Config->OSABI = Obj->getOSABI(); + } + return Obj; +} + template