[lld] r285322 - Don't create a dummy ELF to process a binary file.
Rafael Espindola via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 27 10:45:41 PDT 2016
Author: rafael
Date: Thu Oct 27 12:45:40 2016
New Revision: 285322
URL: http://llvm.org/viewvc/llvm-project?rev=285322&view=rev
Log:
Don't create a dummy ELF to process a binary file.
Now that it is easy to create input section and symbols, this is
simple.
Removed:
lld/trunk/ELF/ELFCreator.cpp
lld/trunk/ELF/ELFCreator.h
Modified:
lld/trunk/ELF/CMakeLists.txt
lld/trunk/ELF/InputFiles.cpp
lld/trunk/ELF/InputFiles.h
lld/trunk/ELF/InputSection.cpp
lld/trunk/ELF/InputSection.h
lld/trunk/ELF/LinkerScript.cpp
lld/trunk/ELF/SymbolTable.cpp
lld/trunk/ELF/SymbolTable.h
lld/trunk/ELF/Writer.cpp
Modified: lld/trunk/ELF/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/CMakeLists.txt?rev=285322&r1=285321&r2=285322&view=diff
==============================================================================
--- lld/trunk/ELF/CMakeLists.txt (original)
+++ lld/trunk/ELF/CMakeLists.txt Thu Oct 27 12:45:40 2016
@@ -6,7 +6,6 @@ add_lld_library(lldELF
Driver.cpp
DriverUtils.cpp
EhFrame.cpp
- ELFCreator.cpp
Error.cpp
GdbIndex.cpp
ICF.cpp
Removed: lld/trunk/ELF/ELFCreator.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/ELFCreator.cpp?rev=285321&view=auto
==============================================================================
--- lld/trunk/ELF/ELFCreator.cpp (original)
+++ lld/trunk/ELF/ELFCreator.cpp (removed)
@@ -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 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);
- void addSymbol(StringRef Name, uintX_t SecIdx, uintX_t Value);
- size_t layout();
- void writeTo(uint8_t *Out);
-
-private:
- Elf_Ehdr Header = {};
- std::vector<Elf_Shdr *> Sections;
- std::vector<Elf_Sym *> Symbols;
- StringTableBuilder StrTabBuilder{StringTableBuilder::ELF};
- BumpPtrAllocator Alloc;
- StringSaver Saver{Alloc};
- 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 == 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 <class ELFT>
-typename ELFCreator<ELFT>::Section
-ELFCreator<ELFT>::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 <class ELFT>
-void ELFCreator<ELFT>::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 <class ELFT> size_t ELFCreator<ELFT>::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 <class ELFT> void ELFCreator<ELFT>::writeTo(uint8_t *Out) {
- std::memcpy(Out, &Header, sizeof(Elf_Ehdr));
- StrTabBuilder.write(Out + StrTab->sh_offset);
-
- Elf_Sym *Sym = reinterpret_cast<Elf_Sym *>(Out + SymTab->sh_offset);
- // Skip null.
- ++Sym;
- for (Elf_Sym *S : Symbols)
- *Sym++ = *S;
-
- Elf_Shdr *Shdr = reinterpret_cast<Elf_Shdr *>(Out + Header.e_shoff);
- // Skip null.
- ++Shdr;
- for (Elf_Shdr *S : Sections)
- *Shdr++ = *S;
-}
-
-template <class ELFT>
-std::vector<uint8_t> elf::wrapBinaryWithElfHeader(ArrayRef<uint8_t> Blob,
- std::string Filename) {
- // Fill the ELF file header.
- ELFCreator<ELFT> File(ET_REL, Config->EMachine);
- typename ELFCreator<ELFT>::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<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);
Removed: lld/trunk/ELF/ELFCreator.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/ELFCreator.h?rev=285321&view=auto
==============================================================================
--- lld/trunk/ELF/ELFCreator.h (original)
+++ lld/trunk/ELF/ELFCreator.h (removed)
@@ -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 <string>
-#include <vector>
-
-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 <class ELFT>
-std::vector<uint8_t> wrapBinaryWithElfHeader(llvm::ArrayRef<uint8_t> Data,
- std::string Filename);
-}
-}
-
-#endif
Modified: lld/trunk/ELF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=285322&r1=285321&r2=285322&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.cpp (original)
+++ lld/trunk/ELF/InputFiles.cpp Thu Oct 27 12:45:40 2016
@@ -9,7 +9,6 @@
#include "InputFiles.h"
#include "Driver.h"
-#include "ELFCreator.h"
#include "Error.h"
#include "InputSection.h"
#include "LinkerScript.h"
@@ -822,15 +821,29 @@ static InputFile *createELFFile(BumpPtrA
return Obj;
}
-// 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() {
- ArrayRef<uint8_t> Blob((uint8_t *)MB.getBufferStart(), MB.getBufferSize());
- StringRef Filename = MB.getBufferIdentifier();
- Buffer = wrapBinaryWithElfHeader<ELFT>(Blob, Filename);
-
- return createELFFile<ObjectFile>(
- Alloc, MemoryBufferRef(toStringRef(Buffer), Filename));
+template <class ELFT> void BinaryFile::parse() {
+ StringRef Buf = MB.getBuffer();
+ ArrayRef<uint8_t> Data =
+ makeArrayRef<uint8_t>((const uint8_t *)Buf.data(), Buf.size());
+
+ std::string Filename = MB.getBufferIdentifier();
+ std::transform(Filename.begin(), Filename.end(), Filename.begin(),
+ [](char C) { return isalnum(C) ? C : '_'; });
+ Filename = "_binary_" + Filename;
+ StringRef StartName = Saver.save(Twine(Filename) + "_start");
+ StringRef EndName = Saver.save(Twine(Filename) + "_end");
+ StringRef SizeName = Saver.save(Twine(Filename) + "_size");
+
+ auto *Section =
+ new InputSection<ELFT>(SHF_ALLOC, SHT_PROGBITS, 8, Data, ".data");
+ Sections.push_back(Section);
+
+ elf::Symtab<ELFT>::X->addRegular(StartName, STV_DEFAULT, Section, STB_GLOBAL,
+ STT_OBJECT, 0);
+ elf::Symtab<ELFT>::X->addRegular(EndName, STV_DEFAULT, Section, STB_GLOBAL,
+ STT_OBJECT, Data.size());
+ elf::Symtab<ELFT>::X->addRegular(SizeName, STV_DEFAULT, nullptr, STB_GLOBAL,
+ STT_OBJECT, Data.size());
}
static bool isBitcode(MemoryBufferRef MB) {
@@ -942,10 +955,10 @@ template class elf::SharedFile<ELF32BE>;
template class elf::SharedFile<ELF64LE>;
template class elf::SharedFile<ELF64BE>;
-template InputFile *BinaryFile::createELF<ELF32LE>();
-template InputFile *BinaryFile::createELF<ELF32BE>();
-template InputFile *BinaryFile::createELF<ELF64LE>();
-template InputFile *BinaryFile::createELF<ELF64BE>();
+template void BinaryFile::parse<ELF32LE>();
+template void BinaryFile::parse<ELF32BE>();
+template void BinaryFile::parse<ELF64LE>();
+template void BinaryFile::parse<ELF64BE>();
template class elf::DIHelper<ELF32LE>;
template class elf::DIHelper<ELF32BE>;
Modified: lld/trunk/ELF/InputFiles.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.h?rev=285322&r1=285321&r2=285322&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.h (original)
+++ lld/trunk/ELF/InputFiles.h Thu Oct 27 12:45:40 2016
@@ -361,11 +361,13 @@ class BinaryFile : public InputFile {
public:
explicit BinaryFile(MemoryBufferRef M) : InputFile(BinaryKind, M) {}
static bool classof(const InputFile *F) { return F->kind() == BinaryKind; }
- template <class ELFT> InputFile *createELF();
+ template <class ELFT> void parse();
+ ArrayRef<InputSectionData *> getSections() const { return Sections; }
private:
- std::vector<uint8_t> Buffer;
llvm::BumpPtrAllocator Alloc;
+ llvm::StringSaver Saver{Alloc};
+ std::vector<InputSectionData *> Sections;
};
InputFile *createObjectFile(llvm::BumpPtrAllocator &Alloc, MemoryBufferRef MB,
Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=285322&r1=285321&r2=285322&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Thu Oct 27 12:45:40 2016
@@ -189,10 +189,11 @@ InputSectionBase<ELFT> *InputSectionBase
template <class ELFT>
InputSection<ELFT>::InputSection(uintX_t Flags, uint32_t Type,
- uintX_t Addralign, ArrayRef<uint8_t> Data)
+ uintX_t Addralign, ArrayRef<uint8_t> Data,
+ StringRef Name)
: InputSectionBase<ELFT>(nullptr, Flags, Type,
/*Entsize*/ 0, /*Link*/ 0, /*Info*/ 0, Addralign,
- Data, "", Base::Regular) {}
+ Data, Name, Base::Regular) {}
template <class ELFT>
InputSection<ELFT>::InputSection(elf::ObjectFile<ELFT> *F,
@@ -840,7 +841,7 @@ InputSection<ELFT> InputSection<ELFT>::c
Size += Sym->Size;
}
ArrayRef<uint8_t> Data = makeArrayRef<uint8_t>(nullptr, Size);
- InputSection Ret(SHF_ALLOC | SHF_WRITE, SHT_NOBITS, Alignment, Data);
+ InputSection Ret(SHF_ALLOC | SHF_WRITE, SHT_NOBITS, Alignment, Data, "");
Ret.Live = true;
return Ret;
}
Modified: lld/trunk/ELF/InputSection.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.h?rev=285322&r1=285321&r2=285322&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.h (original)
+++ lld/trunk/ELF/InputSection.h Thu Oct 27 12:45:40 2016
@@ -237,7 +237,7 @@ template <class ELFT> class InputSection
public:
InputSection(uintX_t Flags, uint32_t Type, uintX_t Addralign,
- ArrayRef<uint8_t> Data);
+ ArrayRef<uint8_t> Data, StringRef Name);
InputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Header, StringRef Name);
// Write this section to a mmap'ed file, assuming Buf is pointing to
Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=285322&r1=285321&r2=285322&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Thu Oct 27 12:45:40 2016
@@ -46,7 +46,8 @@ LinkerScriptBase *elf::ScriptBase;
ScriptConfiguration *elf::ScriptConfig;
template <class ELFT> static void addRegular(SymbolAssignment *Cmd) {
- Symbol *Sym = Symtab<ELFT>::X->addRegular(Cmd->Name, STB_GLOBAL, STV_DEFAULT);
+ Symbol *Sym = Symtab<ELFT>::X->addRegular(Cmd->Name, STV_DEFAULT, nullptr,
+ STB_GLOBAL, STT_NOTYPE, 0);
Sym->Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;
Cmd->Sym = Sym->body();
Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=285322&r1=285321&r2=285322&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Thu Oct 27 12:45:40 2016
@@ -53,7 +53,8 @@ template <class ELFT> void SymbolTable<E
// Binary file
if (auto *F = dyn_cast<BinaryFile>(File)) {
- addFile(F->createELF<ELFT>());
+ BinaryFiles.push_back(F);
+ F->parse<ELFT>();
return;
}
@@ -124,7 +125,7 @@ template <class ELFT>
DefinedRegular<ELFT> *SymbolTable<ELFT>::addAbsolute(StringRef Name,
uint8_t Visibility) {
return cast<DefinedRegular<ELFT>>(
- addRegular(Name, STB_GLOBAL, Visibility)->body());
+ addRegular(Name, Visibility, nullptr, STB_GLOBAL, STT_NOTYPE, 0)->body());
}
// Add Name as an "ignored" symbol. An ignored symbol is a regular
@@ -398,9 +399,11 @@ Symbol *SymbolTable<ELFT>::addRegular(St
}
template <typename ELFT>
-Symbol *SymbolTable<ELFT>::addRegular(StringRef Name, uint8_t Binding,
- uint8_t StOther) {
- return addRegular(Name, StOther, STT_NOTYPE, 0, 0, Binding, nullptr);
+Symbol *SymbolTable<ELFT>::addRegular(StringRef Name, uint8_t StOther,
+ InputSectionBase<ELFT> *Section,
+ uint8_t Binding, uint8_t Type,
+ uintX_t Value) {
+ return addRegular(Name, StOther, Type, Value, 0, Binding, Section);
}
template <typename ELFT>
Modified: lld/trunk/ELF/SymbolTable.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.h?rev=285322&r1=285321&r2=285322&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.h (original)
+++ lld/trunk/ELF/SymbolTable.h Thu Oct 27 12:45:40 2016
@@ -50,6 +50,10 @@ public:
return ObjectFiles;
}
+ const std::vector<BinaryFile *> &getBinaryFiles() const {
+ return BinaryFiles;
+ }
+
const std::vector<SharedFile<ELFT> *> &getSharedFiles() const {
return SharedFiles;
}
@@ -69,7 +73,9 @@ public:
Symbol *addRegular(StringRef Name, const Elf_Sym &Sym,
InputSectionBase<ELFT> *Section);
- Symbol *addRegular(StringRef Name, uint8_t Binding, uint8_t StOther);
+ Symbol *addRegular(StringRef Name, uint8_t StOther,
+ InputSectionBase<ELFT> *Section, uint8_t Binding,
+ uint8_t Type, uintX_t Value);
Symbol *addSynthetic(StringRef N, OutputSectionBase<ELFT> *Section,
uintX_t Value, uint8_t StOther);
void addShared(SharedFile<ELFT> *F, StringRef Name, const Elf_Sym &Sym,
@@ -131,6 +137,7 @@ private:
std::vector<ObjectFile<ELFT> *> ObjectFiles;
std::vector<SharedFile<ELFT> *> SharedFiles;
std::vector<BitcodeFile *> BitcodeFiles;
+ std::vector<BinaryFile *> BinaryFiles;
// Set of .so files to not link the same shared object file more than once.
llvm::DenseSet<StringRef> SoNames;
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=285322&r1=285321&r2=285322&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Thu Oct 27 12:45:40 2016
@@ -698,21 +698,27 @@ void Writer<ELFT>::forEachRelSec(
}
template <class ELFT> void Writer<ELFT>::createSections() {
- for (elf::ObjectFile<ELFT> *F : Symtab<ELFT>::X->getObjectFiles()) {
- for (InputSectionBase<ELFT> *IS : F->getSections()) {
- if (isDiscarded(IS)) {
- reportDiscarded(IS);
- continue;
- }
- OutputSectionBase<ELFT> *Sec;
- bool IsNew;
- StringRef OutsecName = getOutputSectionName(IS->Name, Alloc);
- std::tie(Sec, IsNew) = Factory.create(IS, OutsecName);
- if (IsNew)
- OutputSections.push_back(Sec);
- Sec->addSection(IS);
+ auto Add = [&](InputSectionBase<ELFT> *IS) {
+ if (isDiscarded(IS)) {
+ reportDiscarded(IS);
+ return;
}
- }
+ OutputSectionBase<ELFT> *Sec;
+ bool IsNew;
+ StringRef OutsecName = getOutputSectionName(IS->Name, Alloc);
+ std::tie(Sec, IsNew) = Factory.create(IS, OutsecName);
+ if (IsNew)
+ OutputSections.push_back(Sec);
+ Sec->addSection(IS);
+ };
+
+ for (elf::ObjectFile<ELFT> *F : Symtab<ELFT>::X->getObjectFiles())
+ for (InputSectionBase<ELFT> *IS : F->getSections())
+ Add(IS);
+
+ for (BinaryFile *F : Symtab<ELFT>::X->getBinaryFiles())
+ for (InputSectionData *ID : F->getSections())
+ Add(cast<InputSection<ELFT>>(ID));
sortInitFini(findSection(".init_array"));
sortInitFini(findSection(".fini_array"));
More information about the llvm-commits
mailing list