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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
|
//===- lib/ReaderWriter/ELF/HexagonELFFile.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_HEXAGON_ELF_FILE_H
#define LLD_READER_WRITER_ELF_HEXAGON_ELF_FILE_H
#include "ELFReader.h"
#include "HexagonLinkingContext.h"
namespace lld {
namespace elf {
template <class ELFT> class HexagonELFFile;
template <class ELFT>
class HexagonELFDefinedAtom : public ELFDefinedAtom<ELFT> {
typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
typedef llvm::object::Elf_Shdr_Impl<ELFT> Elf_Shdr;
public:
HexagonELFDefinedAtom(const HexagonELFFile<ELFT> &file, StringRef symbolName,
StringRef sectionName, const Elf_Sym *symbol,
const Elf_Shdr *section, ArrayRef<uint8_t> contentData,
unsigned int referenceStart, unsigned int referenceEnd,
std::vector<ELFReference<ELFT> *> &referenceList)
: ELFDefinedAtom<ELFT>(file, symbolName, sectionName, symbol, section,
contentData, referenceStart, referenceEnd,
referenceList) {}
virtual DefinedAtom::ContentType contentType() const {
if (this->_contentType != DefinedAtom::typeUnknown)
return this->_contentType;
else if (this->_section->sh_flags & llvm::ELF::SHF_HEX_GPREL) {
if (this->_section->sh_type == llvm::ELF::SHT_NOBITS)
return (this->_contentType = DefinedAtom::typeZeroFillFast);
else
return (this->_contentType = DefinedAtom::typeDataFast);
}
return ELFDefinedAtom<ELFT>::contentType();
}
virtual DefinedAtom::ContentPermissions permissions() const {
if (this->_section->sh_flags & llvm::ELF::SHF_HEX_GPREL)
return DefinedAtom::permRW_;
return ELFDefinedAtom<ELFT>::permissions();
}
};
template <class ELFT> class HexagonELFCommonAtom : public ELFCommonAtom<ELFT> {
typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
typedef llvm::object::Elf_Shdr_Impl<ELFT> Elf_Shdr;
public:
HexagonELFCommonAtom(const HexagonELFFile<ELFT> &file, StringRef symbolName,
const Elf_Sym *symbol)
: ELFCommonAtom<ELFT>(file, symbolName, symbol) {}
virtual bool isSmallCommonSymbol() const {
switch (this->_symbol->st_shndx) {
// Common symbols
case llvm::ELF::SHN_HEXAGON_SCOMMON:
case llvm::ELF::SHN_HEXAGON_SCOMMON_1:
case llvm::ELF::SHN_HEXAGON_SCOMMON_2:
case llvm::ELF::SHN_HEXAGON_SCOMMON_4:
case llvm::ELF::SHN_HEXAGON_SCOMMON_8:
return true;
default:
break;
}
return false;
}
virtual uint64_t size() const {
if (isSmallCommonSymbol())
return this->_symbol->st_size;
return ELFCommonAtom<ELFT>::size();
}
virtual DefinedAtom::Merge merge() const {
if (this->_symbol->getBinding() == llvm::ELF::STB_WEAK)
return DefinedAtom::mergeAsWeak;
if (isSmallCommonSymbol())
return DefinedAtom::mergeAsTentative;
return ELFCommonAtom<ELFT>::merge();
}
virtual DefinedAtom::ContentType contentType() const {
if (isSmallCommonSymbol())
return DefinedAtom::typeZeroFillFast;
return ELFCommonAtom<ELFT>::contentType();
}
virtual DefinedAtom::Alignment alignment() const {
if (isSmallCommonSymbol())
return DefinedAtom::Alignment(llvm::Log2_64(this->_symbol->st_value));
return ELFCommonAtom<ELFT>::alignment();
}
virtual DefinedAtom::ContentPermissions permissions() const {
if (isSmallCommonSymbol())
return DefinedAtom::permRW_;
return ELFCommonAtom<ELFT>::permissions();
}
};
template <class ELFT> class HexagonELFFile : public ELFFile<ELFT> {
typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
typedef llvm::object::Elf_Shdr_Impl<ELFT> Elf_Shdr;
public:
HexagonELFFile(StringRef name, bool atomizeStrings)
: ELFFile<ELFT>(name, atomizeStrings) {}
HexagonELFFile(std::unique_ptr<MemoryBuffer> mb, bool atomizeStrings,
error_code &ec)
: ELFFile<ELFT>(std::move(mb), atomizeStrings, ec) {}
static ErrorOr<std::unique_ptr<HexagonELFFile>>
create(std::unique_ptr<MemoryBuffer> mb, bool atomizeStrings) {
error_code ec;
std::unique_ptr<HexagonELFFile<ELFT>> file(
new HexagonELFFile<ELFT>(mb->getBufferIdentifier(), atomizeStrings));
file->_objFile.reset(new llvm::object::ELFFile<ELFT>(mb.release(), ec));
if (ec)
return ec;
// Read input sections from the input file that need to be converted to
// atoms
if ((ec = file->createAtomizableSections()))
return ec;
// For mergeable strings, we would need to split the section into various
// atoms
if ((ec = file->createMergeableAtoms()))
return ec;
// Create the necessary symbols that are part of the section that we
// created in createAtomizableSections function
if ((ec = file->createSymbolsFromAtomizableSections()))
return ec;
// Create the appropriate atoms from the file
if ((ec = file->createAtoms()))
return ec;
return std::move(file);
}
virtual bool isCommonSymbol(const Elf_Sym *symbol) const {
switch (symbol->st_shndx) {
// Common symbols
case llvm::ELF::SHN_HEXAGON_SCOMMON:
case llvm::ELF::SHN_HEXAGON_SCOMMON_1:
case llvm::ELF::SHN_HEXAGON_SCOMMON_2:
case llvm::ELF::SHN_HEXAGON_SCOMMON_4:
case llvm::ELF::SHN_HEXAGON_SCOMMON_8:
return true;
default:
break;
}
return ELFFile<ELFT>::isCommonSymbol(symbol);
}
/// Process the Defined symbol and create an atom for it.
virtual ErrorOr<ELFDefinedAtom<ELFT> *>
handleDefinedSymbol(StringRef symName, StringRef sectionName,
const Elf_Sym *sym, const Elf_Shdr *sectionHdr,
ArrayRef<uint8_t> contentData,
unsigned int referenceStart, unsigned int referenceEnd,
std::vector<ELFReference<ELFT> *> &referenceList) {
return new (this->_readerStorage) HexagonELFDefinedAtom<ELFT>(
*this, symName, sectionName, sym, sectionHdr, contentData,
referenceStart, referenceEnd, referenceList);
}
/// Process the Common symbol and create an atom for it.
virtual ErrorOr<ELFCommonAtom<ELFT> *>
handleCommonSymbol(StringRef symName, const Elf_Sym *sym) {
return new (this->_readerStorage)
HexagonELFCommonAtom<ELFT>(*this, symName, sym);
}
};
template <class ELFT> class HexagonDynamicFile : public DynamicFile<ELFT> {
public:
HexagonDynamicFile(const HexagonLinkingContext &context, StringRef name)
: DynamicFile<ELFT>(context, name) {}
};
} // elf
} // lld
#endif // LLD_READER_WRITER_ELF_HEXAGON_ELF_FILE_H
|