blob: bb3901010634f7c6d449a2aa6a41e7f2a357e1c7 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
//===- lib/ReaderWriter/ELF/OutputELFWriter.h ----------------------------===//
//
// The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLD_READER_WRITER_ELF_OUTPUT_WRITER_H
#define LLD_READER_WRITER_ELF_OUTPUT_WRITER_H
#include "ELFFile.h"
#include "TargetLayout.h"
#include "lld/Core/Writer.h"
#include "llvm/ADT/StringSet.h"
namespace lld {
class ELFLinkingContext;
namespace elf {
using namespace llvm;
using namespace llvm::object;
// OutputELFWriter Class
//
/// \brief This acts as the base class for all the ELF writers that are output
/// for emitting an ELF output file. This class also acts as a common class for
/// creating static and dynamic executables. All the function in this class
/// can be overridden and an appropriate writer be created
template<class ELFT>
class OutputELFWriter : public ELFWriter {
public:
typedef Elf_Shdr_Impl<ELFT> Elf_Shdr;
typedef Elf_Sym_Impl<ELFT> Elf_Sym;
typedef Elf_Dyn_Impl<ELFT> Elf_Dyn;
OutputELFWriter(ELFLinkingContext &ctx, TargetLayout<ELFT> &layout);
protected:
// build the sections that need to be created
virtual void createDefaultSections();
// Build all the output sections
void buildChunks(const File &file) override;
// Build the output file
virtual std::error_code buildOutput(const File &file);
// Setup the ELF header.
virtual std::error_code setELFHeader();
// Write the file to the path specified
std::error_code writeFile(const File &File, StringRef path) override;
// Write to the output file.
virtual std::error_code writeOutput(const File &file, StringRef path);
// Get the size of the output file that the linker would emit.
virtual uint64_t outputFileSize() const;
// Build the atom to address map, this has to be called
// before applying relocations
virtual void buildAtomToAddressMap(const File &file);
// Build the symbol table for static linking
virtual void buildStaticSymbolTable(const File &file);
// Build the dynamic symbol table for dynamic linking
virtual void buildDynamicSymbolTable(const File &file);
// Build the section header table
virtual void buildSectionHeaderTable();
// Assign sections that have no segments such as the symbol table,
// section header table, string table etc
virtual void assignSectionsWithNoSegments();
// Add any runtime files and their atoms to the output
void createImplicitFiles(std::vector<std::unique_ptr<File>> &) override;
// Finalize the default atom values
virtual void finalizeDefaultAtomValues();
// This is called by the write section to apply relocations
uint64_t addressOfAtom(const Atom *atom) override {
auto addr = _atomToAddressMap.find(atom);
return addr == _atomToAddressMap.end() ? 0 : addr->second;
}
// This is a hook for creating default dynamic entries
virtual void createDefaultDynamicEntries() {}
/// \brief Create symbol table.
virtual unique_bump_ptr<SymbolTable<ELFT>> createSymbolTable();
/// \brief create dynamic table.
virtual unique_bump_ptr<DynamicTable<ELFT>> createDynamicTable();
/// \brief create dynamic symbol table.
virtual unique_bump_ptr<DynamicSymbolTable<ELFT>>
createDynamicSymbolTable();
/// \brief Create entry in the dynamic symbols table for this atom.
virtual bool isDynSymEntryRequired(const SharedLibraryAtom *sla) const {
return _layout.isReferencedByDefinedAtom(sla);
}
/// \brief Create DT_NEEDED dynamic tage for the shared library.
virtual bool isNeededTagRequired(const SharedLibraryAtom *sla) const {
return false;
}
/// \brief Process undefined symbols that left after resolution step.
virtual void processUndefinedSymbol(StringRef symName,
RuntimeFile<ELFT> &file) const;
/// \brief Assign addresses to atoms marking section's start and end.
void updateScopeAtomValues(StringRef sym, StringRef sec);
llvm::BumpPtrAllocator _alloc;
ELFLinkingContext &_ctx;
TargetHandler &_targetHandler;
typedef llvm::DenseMap<const Atom *, uint64_t> AtomToAddress;
AtomToAddress _atomToAddressMap;
TargetLayout<ELFT> &_layout;
unique_bump_ptr<ELFHeader<ELFT>> _elfHeader;
unique_bump_ptr<ProgramHeader<ELFT>> _programHeader;
unique_bump_ptr<SymbolTable<ELFT>> _symtab;
unique_bump_ptr<StringTable<ELFT>> _strtab;
unique_bump_ptr<StringTable<ELFT>> _shstrtab;
unique_bump_ptr<SectionHeader<ELFT>> _shdrtab;
unique_bump_ptr<EHFrameHeader<ELFT>> _ehFrameHeader;
/// \name Dynamic sections.
/// @{
unique_bump_ptr<DynamicTable<ELFT>> _dynamicTable;
unique_bump_ptr<DynamicSymbolTable<ELFT>> _dynamicSymbolTable;
unique_bump_ptr<StringTable<ELFT>> _dynamicStringTable;
unique_bump_ptr<HashSection<ELFT>> _hashTable;
llvm::StringSet<> _soNeeded;
/// @}
private:
static StringRef maybeGetSOName(Node *node);
void updateScopeAtomValues(StringRef start, StringRef end, StringRef sec);
};
} // namespace elf
} // namespace lld
#endif // LLD_READER_WRITER_ELF_OUTPUT_WRITER_H
|