• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef X64_ASSEMBLER_ELF_FILE_H
17 #define X64_ASSEMBLER_ELF_FILE_H
18 
19 #include <vector>
20 #include "elf_types.h"
21 #include "operand.h"
22 
23 namespace assembler {
24 using namespace maplebe;
25 
26 class Alignment {
27 public:
28     template <typename T>
Align(T offset,T align)29     static T Align(T offset, T align)
30     {
31         if (align <= 1) {
32             return offset;
33         }
34         return (offset + align - 1) & (~(align - 1));
35     }
36 }; /* class Alignment */
37 
38 class Section {
39 public:
Section(const std::string & name,Word type,Xword flags,Xword align)40     Section(const std::string &name, Word type, Xword flags, Xword align) : name(name)
41     {
42         sectionHeader.sh_type = type;
43         sectionHeader.sh_flags = flags;
44         sectionHeader.sh_addralign = align;
45     }
46 
47     virtual ~Section() = default;
48     virtual void GenerateData() = 0;
49     virtual void WriteSection(std::ofstream &outStream) = 0;
50 
ClearData()51     virtual void ClearData()
52     {
53         return;
54     }
55 
SetIndex(SectionIndex idx)56     void SetIndex(SectionIndex idx)
57     {
58         index = idx;
59     }
60 
GetIndex()61     SectionIndex GetIndex() const
62     {
63         return index;
64     }
65 
SetInfo(Word value)66     void SetInfo(Word value)
67     {
68         sectionHeader.sh_info = value;
69     }
70 
SetLink(const Section & section)71     void SetLink(const Section &section)
72     {
73         sectionHeader.sh_link = static_cast<Word>(section.GetIndex());
74     }
75 
SetEntSize(Xword value)76     void SetEntSize(Xword value)
77     {
78         sectionHeader.sh_entsize = value;
79     }
80 
SetSectionSize(Xword size)81     void SetSectionSize(Xword size)
82     {
83         sectionHeader.sh_size = size;
84     }
85 
GetSectionSize()86     virtual Xword GetSectionSize()
87     {
88         return sectionHeader.sh_size;
89     }
90 
SetAddr(Address addr)91     void SetAddr(Address addr)
92     {
93         sectionHeader.sh_addr = addr;
94     }
95 
GetAddr()96     Address GetAddr() const
97     {
98         return sectionHeader.sh_addr;
99     }
100 
GetFlags()101     Xword GetFlags() const
102     {
103         return sectionHeader.sh_flags;
104     }
105 
SetOffset(Offset value)106     void SetOffset(Offset value)
107     {
108         sectionHeader.sh_offset = value;
109     }
110 
GetOffset()111     Offset GetOffset() const
112     {
113         return sectionHeader.sh_offset;
114     }
115 
GetAlign()116     Xword GetAlign() const
117     {
118         return sectionHeader.sh_addralign;
119     }
120 
GetName()121     const std::string &GetName() const
122     {
123         return name;
124     }
125 
SetSectionHeaderNameIndex(Word index)126     void SetSectionHeaderNameIndex(Word index)
127     {
128         sectionHeader.sh_name = index;
129     }
130 
GetType()131     Word GetType() const
132     {
133         return sectionHeader.sh_type;
134     }
135 
GetSectionHeader()136     const SectionHeader &GetSectionHeader() const
137     {
138         return sectionHeader;
139     }
140 
141 private:
142     std::string name;
143     SectionIndex index {};
144     SectionHeader sectionHeader {};
145 }; /* class Section */
146 
147 class DataSection : public Section {
148 public:
DataSection(const std::string & name,Word type,Xword flags,Xword align)149     DataSection(const std::string &name, Word type, Xword flags, Xword align) : Section(name, type, flags, align) {}
150 
151     ~DataSection() = default;
152 
GenerateData()153     virtual void GenerateData() override
154     {
155         SetSectionSize(data.size());
156     }
157 
WriteSection(std::ofstream & outStream)158     virtual void WriteSection(std::ofstream &outStream) override
159     {
160         outStream.write(reinterpret_cast<const char *>(data.data()), data.size());
161     }
162 
AppendData(const void * value,size_t size)163     void AppendData(const void *value, size_t size)
164     {
165         auto pdata = reinterpret_cast<const uint8 *>(value);
166         data.insert(data.end(), pdata, pdata + size);
167     }
168 
AppendData(int64 value,size_t size)169     void AppendData(int64 value, size_t size)
170     {
171         for (size_t i = 0; i < size; i++) {
172             auto pdata = static_cast<uint8>(static_cast<uint64>(value) >> (i * k8Bits));
173             data.push_back(pdata);
174         }
175     }
176 
ClearData()177     void ClearData() override
178     {
179         data.clear();
180     }
181 
GetDataSize()182     uint32 GetDataSize() const
183     {
184         return data.size();
185     }
186 
GetData()187     const std::vector<uint8> &GetData() const
188     {
189         return data;
190     }
191 
192 protected:
193     std::vector<uint8> data;
194 }; /* class DataSection */
195 
196 class StringSection : public DataSection {
197 public:
StringSection(const std::string & name,Word type,Xword flags,Xword align)198     StringSection(const std::string &name, Word type, Xword flags, Xword align) : DataSection(name, type, flags, align)
199     {
200         AddString("\0");
201     }
202 
203     ~StringSection() = default;
204 
AddString(const std::string & str)205     size_t AddString(const std::string &str)
206     {
207         size_t pos = data.size();
208         AppendData(str.c_str(), str.size() + 1);
209         return pos;
210     }
211 }; /* class StringSection */
212 
213 class RelaSection : public Section {
214 public:
RelaSection(const std::string & name,Word type,Xword flags,Word info,Xword align,const Section & link)215     RelaSection(const std::string &name, Word type, Xword flags, Word info, Xword align, const Section &link)
216         : Section(name, type, flags, align)
217     {
218         SetEntSize(sizeof(Rela));
219         SetInfo(info);
220         SetLink(link);
221     }
222 
223     ~RelaSection() = default;
224 
GenerateData()225     void GenerateData() override
226     {
227         SetSectionSize(relas.size() * sizeof(Rela));
228     }
229 
WriteSection(std::ofstream & outStream)230     void WriteSection(std::ofstream &outStream) override
231     {
232         outStream.write(reinterpret_cast<const char *>(relas.data()), relas.size() * sizeof(Rela));
233     }
234 
AppendRela(Rela rela)235     void AppendRela(Rela rela)
236     {
237         relas.push_back(rela);
238     }
239 
240 private:
241     std::vector<Rela> relas;
242 }; /* class RelaSection */
243 
244 class SymbolSection : public Section {
245 public:
SymbolSection(const std::string & name,Word type,Xword flags,Xword align,const Section & link)246     SymbolSection(const std::string &name, Word type, Xword flags, Xword align, const Section &link)
247         : Section(name, type, flags, align)
248     {
249         SetEntSize(sizeof(Symbol));
250         SetLink(link);
251         SetInfo(1);
252         AppendSymbol({0, 0, 0, 0, 0, 0});
253     }
254 
255     ~SymbolSection() = default;
256 
GenerateData()257     void GenerateData() override
258     {
259         SetSectionSize(symbols.size() * sizeof(Symbol));
260     }
261 
WriteSection(std::ofstream & outStream)262     void WriteSection(std::ofstream &outStream) override
263     {
264         outStream.write(reinterpret_cast<const char *>(symbols.data()), symbols.size() * sizeof(Symbol));
265     }
266 
AppendSymbol(const Symbol & symbol)267     void AppendSymbol(const Symbol &symbol)
268     {
269         symbols.push_back(symbol);
270     }
271 
GetSymbolsSize()272     uint32 GetSymbolsSize() const
273     {
274         return symbols.size();
275     }
276 
GetIdxInSymbols(int64 symIdx)277     uint64 GetIdxInSymbols(int64 symIdx) const
278     {
279         return symbolIdxMap.at(symIdx);
280     }
281 
AppendIdxInSymbols(int64 symIdx)282     void AppendIdxInSymbols(int64 symIdx)
283     {
284         CHECK_FATAL(GetSymbolsSize() > 0, "must not be zero");
285         symbolIdxMap[symIdx] = static_cast<uint64>(GetSymbolsSize() - 1);
286     }
287 
ExistSymInSymbols(int64 symIdx)288     bool ExistSymInSymbols(int64 symIdx)
289     {
290         return symbolIdxMap.count(symIdx) != 0;
291     }
292 
GetDataSize()293     uint32 GetDataSize() const
294     {
295         return symbols.size() * sizeof(Symbol);
296     }
297 
GetAddr()298     const char *GetAddr()
299     {
300         return reinterpret_cast<const char*>(symbols.data());
301     }
302 
303 private:
304     std::vector<Symbol> symbols;
305     std::unordered_map<int64, uint64> symbolIdxMap;
306 }; /* class SymbolSection */
307 } /* namespace assembler */
308 
309 #endif /* X64_ASSEMBLER_ELF_FILE_H */
310