Index: ELF/Driver.cpp =================================================================== --- ELF/Driver.cpp +++ ELF/Driver.cpp @@ -7,8 +7,10 @@ // //===----------------------------------------------------------------------===// -#include "Driver.h" #include "Config.h" +#include "Driver.h" +#include "InputFiles.h" +#include "SymbolTable.h" #include "Writer.h" #include "llvm/ADT/STLExtras.h" @@ -116,25 +118,17 @@ // Write the result. ObjectFileBase &FirstObj = *Symtab.ObjectFiles[0]; switch (FirstObj.kind()) { - case InputFile::Object32LEKind: { - Writer Out(&Symtab); - Out.write(Config->OutputFile); + case InputFile::Object32LEKind: + writeResult(&Symtab, Config->OutputFile); return; - } - case InputFile::Object32BEKind: { - Writer Out(&Symtab); - Out.write(Config->OutputFile); + case InputFile::Object32BEKind: + writeResult(&Symtab, Config->OutputFile); return; - } - case InputFile::Object64LEKind: { - Writer Out(&Symtab); - Out.write(Config->OutputFile); + case InputFile::Object64LEKind: + writeResult(&Symtab, Config->OutputFile); return; - } - case InputFile::Object64BEKind: { - Writer Out(&Symtab); - Out.write(Config->OutputFile); + case InputFile::Object64BEKind: + writeResult(&Symtab, Config->OutputFile); return; } - } } Index: ELF/Writer.h =================================================================== --- ELF/Writer.h +++ ELF/Writer.h @@ -10,65 +10,15 @@ #ifndef LLD_ELF_WRITER_H #define LLD_ELF_WRITER_H -#include "Chunks.h" -#include "SymbolTable.h" -#include "llvm/Support/FileOutputBuffer.h" - namespace lld { namespace elf2 { -// OutputSection represents a section in an output file. It's a -// container of chunks. OutputSection and Chunk are 1:N relationship. -// Chunks cannot belong to more than one OutputSections. The writer -// creates multiple OutputSections and assign them unique, -// non-overlapping file offsets and VAs. -class OutputSection { -public: - OutputSection(StringRef Name) : Name(Name), Header({}) {} - void setVA(uint64_t); - void setFileOffset(uint64_t); - template void addSectionChunk(SectionChunk *C); - std::vector &getChunks() { return Chunks; } - template - void writeHeaderTo(llvm::object::Elf_Shdr_Impl *SHdr); - - // Returns the size of the section in the output file. - uint64_t getSize() { return Header.sh_size; } - -private: - StringRef Name; - llvm::ELF::Elf64_Shdr Header; - std::vector Chunks; -}; - -// The writer writes a SymbolTable result to a file. -template class Writer { -public: - typedef typename llvm::object::ELFFile::uintX_t uintX_t; - - explicit Writer(SymbolTable *Symtab); - ~Writer(); - void write(StringRef Path); - -private: - void createSections(); - void assignAddresses(); - void openFile(StringRef OutputPath); - void writeHeader(); - void writeSections(); - - SymbolTable *Symtab; - std::unique_ptr Buffer; - llvm::SpecificBumpPtrAllocator CAlloc; - std::vector OutputSections; - uint64_t FileSize; - uint64_t SizeOfHeaders; - uintX_t SectionHeaderOff; +class SymbolTable; - std::vector> Chunks; -}; +template +void writeResult(SymbolTable *Symtab, StringRef Path); -} // namespace elf2 -} // namespace lld +} +} #endif Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -7,10 +7,12 @@ // //===----------------------------------------------------------------------===// -#include "Writer.h" #include "Chunks.h" #include "Driver.h" +#include "SymbolTable.h" +#include "Writer.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/Support/FileOutputBuffer.h" using namespace llvm; using namespace llvm::ELF; @@ -21,13 +23,75 @@ static const int PageSize = 4096; +namespace lld { +namespace elf2 { + +// OutputSection represents a section in an output file. It's a +// container of chunks. OutputSection and Chunk are 1:N relationship. +// Chunks cannot belong to more than one OutputSections. The writer +// creates multiple OutputSections and assign them unique, +// non-overlapping file offsets and VAs. +class OutputSection { +public: + OutputSection(StringRef Name) : Name(Name), Header({}) {} + void setVA(uint64_t); + void setFileOffset(uint64_t); + template void addSectionChunk(SectionChunk *C); + std::vector &getChunks() { return Chunks; } + template + void writeHeaderTo(llvm::object::Elf_Shdr_Impl *SHdr); + + // Returns the size of the section in the output file. + uint64_t getSize() { return Header.sh_size; } + +private: + StringRef Name; + llvm::ELF::Elf64_Shdr Header; + std::vector Chunks; +}; + +// The writer writes a SymbolTable result to a file. +template class Writer { +public: + typedef typename llvm::object::ELFFile::uintX_t uintX_t; + Writer(SymbolTable *T, StringRef S) : Symtab(T), OutputPath(S) {} + void run(); + +private: + void createSections(); + void assignAddresses(); + void openFile(StringRef OutputPath); + void writeHeader(); + void writeSections(); + + SymbolTable *Symtab; + StringRef OutputPath; + std::unique_ptr Buffer; + llvm::SpecificBumpPtrAllocator CAlloc; + std::vector OutputSections; + + uint64_t FileSize; + uint64_t SizeOfHeaders; + uintX_t SectionHeaderOff; + + std::vector> Chunks; +}; + template -Writer::Writer(SymbolTable *Symtab) - : Symtab(Symtab) {} -template Writer::~Writer() {} +void writeResult(SymbolTable *Symtab, StringRef Path) { + Writer(Symtab, Path).run(); +} + +template void writeResult(SymbolTable *, StringRef); +template void writeResult(SymbolTable *, StringRef); +template void writeResult(SymbolTable *, StringRef); +template void writeResult(SymbolTable *, StringRef); + +} // namespace elf2 +} // namespace lld // The main function of the writer. -template void Writer::write(StringRef OutputPath) { +template void Writer::run() { createSections(); assignAddresses(); openFile(OutputPath); @@ -171,17 +235,3 @@ C->writeTo(Buf); } } - -namespace lld { -namespace elf2 { -template class Writer; -template class Writer; -template class Writer; -template class Writer; - -template void OutputSection::addSectionChunk(SectionChunk *); -template void OutputSection::addSectionChunk(SectionChunk *); -template void OutputSection::addSectionChunk(SectionChunk *); -template void OutputSection::addSectionChunk(SectionChunk *); -} -}