• 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 MAPLEBE_INCLUDE_CG_IFILE_H
17 #define MAPLEBE_INCLUDE_CG_IFILE_H
18 
19 #include <fstream>
20 #include <sstream>
21 #include "elf_types.h"
22 #include "types_def.h"
23 #include "common_utils.h"
24 #include "mempool.h"
25 #include "mempool_allocator.h"
26 #include "maple_string.h"
27 #include "mir_symbol.h"
28 #include "cg.h"
29 
30 namespace maplebe {
31 class ObjEmitter;
32 class Fixup;
33 
34 class Alignment {
35 public:
36     template <typename T>
Align(T offset,T align)37     static T Align(T offset, T align)
38     {
39         if (align <= 1) {
40             return offset;
41         }
42         return (offset + align - 1) & (~(align - 1));
43     }
44 }; /* class Alignment */
45 
46 struct ObjLabel {
47     Offset offset;
48     size_t size;
49 };
50 
51 enum LabelFixupKind : uint8 {
52     kLabelFixupDirect,
53     kLabelFixupInDirect,
54     kLabelFixupInDirectAdd,
55     kLabelFixupSize,
56     kLabelFixupDirect64,
57     kLabelFixupInDirect64,
58     kLabelFixupInDirectAdd64,
59     kLabelFixupSize64,
60     kLabelFixupGctib,
61 };
62 
63 enum IFileClassStatus : uint32 { kIFileClassResolved, kIFileClassUnresolved, kIFileClassUnknown };
64 
65 class LabelFixup {
66 public:
LabelFixup(const std::string & label,uint32 offset,LabelFixupKind kind)67     LabelFixup(const std::string &label, uint32 offset, LabelFixupKind kind) : label(label), offset(offset), kind(kind)
68     {
69     }
70     ~LabelFixup() = default;
71 
GetLabel()72     const std::string GetLabel() const
73     {
74         return label;
75     }
76 
GetOffset()77     uint32 GetOffset() const
78     {
79         return offset;
80     }
81 
GetFixupKind()82     LabelFixupKind GetFixupKind() const
83     {
84         return kind;
85     }
86 
87 private:
88     std::string label;
89     uint32 offset;
90     LabelFixupKind kind;
91 };
92 
93 using Label2OffsetMap = std::unordered_map<std::string, ObjLabel>;
94 using LabelFixupVec = MapleVector<LabelFixup *>;
95 
96 struct SectionDesc {
97     uint32 sectionOffset = 0;
98     uint32 sectionSize = 0;
99 };
100 
101 class Section {
102 public:
103     Section(std::string name, Word type, Word flags, uint32 align, ObjEmitter &emitter, MemPool &memPool);
104 
105     virtual ~Section() = default;
106     virtual void GenerateData() = 0;
107     virtual void WriteSection(std::ostringstream &outStream) = 0;
ClearData()108     virtual void ClearData()
109     {
110         return;
111     }
112 
HandleGlobalFixup(const Label2OffsetMap & globalLabel2Offset)113     virtual void HandleGlobalFixup(const Label2OffsetMap &globalLabel2Offset)
114     {
115         (void)globalLabel2Offset;
116         return;
117     }
118 
HandleLocalFixup()119     virtual void HandleLocalFixup() {}
120 
121     virtual void Layout();
122 
SetIndex(uint32 idx)123     void SetIndex(uint32 idx)
124     {
125         index = idx;
126     }
127 
SetInfo(uint32 value)128     void SetInfo(uint32 value)
129     {
130         secHeader.sh_info = value;
131     }
132 
SetLink(const Section & section)133     void SetLink(const Section &section)
134     {
135         secHeader.sh_link = section.GetIndex();
136     }
137 
SetEntSize(uint32 value)138     void SetEntSize(uint32 value)
139     {
140         secHeader.sh_entsize = value;
141     }
142 
SetDataSize(Word size)143     void SetDataSize(Word size)
144     {
145         secHeader.sh_size = size;
146     }
147 
GetDataSize()148     virtual uint32 GetDataSize()
149     {
150         return secHeader.sh_size;
151     }
152 
SetAddr(Address addr)153     void SetAddr(Address addr)
154     {
155         secHeader.sh_addr = addr;
156     }
157 
GetAddr()158     Address GetAddr() const
159     {
160         return secHeader.sh_addr;
161     }
162 
GetFlags()163     Word GetFlags() const
164     {
165         return secHeader.sh_flags;
166     }
167 
SetOffset(Offset value)168     void SetOffset(Offset value)
169     {
170         secHeader.sh_offset = value;
171     }
172 
GetOffset()173     Offset GetOffset() const
174     {
175         return secHeader.sh_offset;
176     }
177 
GetIndex()178     SectionIndex GetIndex() const
179     {
180         return index;
181     }
182 
GetAlign()183     Word GetAlign() const
184     {
185         return secHeader.sh_addralign;
186     }
187 
GetName()188     const MapleString &GetName() const
189     {
190         return name;
191     }
192 
SetSectionHeaderNameIndex(size_t index)193     void SetSectionHeaderNameIndex(size_t index)
194     {
195         secHeader.sh_name = index;
196     }
197 
GetType()198     Word GetType() const
199     {
200         return secHeader.sh_type;
201     }
202 
GetSectionHeader()203     const SectionHeader &GetSectionHeader() const
204     {
205         return secHeader;
206     }
207 
208 protected:
209     ObjEmitter &emitter;
210 
211 private:
212     MapleString name;
213     SectionIndex index {};
214     SectionHeader secHeader {};
215 };
216 
217 class DataSection : public Section {
218 public:
DataSection(const std::string & name,Word type,Word flags,Word align,ObjEmitter & emitter,MemPool & inputMemPool)219     DataSection(const std::string &name, Word type, Word flags, Word align, ObjEmitter &emitter, MemPool &inputMemPool)
220         : Section(name, type, flags, align, emitter, inputMemPool),
221           memPool(inputMemPool),
222           alloc(&memPool),
223           data(alloc.Adapter())
224     {
225     }
226 
227     ~DataSection() = default;
228 
GenerateData()229     virtual void GenerateData() override
230     {
231         SetDataSize(data.size());
232         if (GetName() == ".ifile.hex") {
233             SetDataSize(k8BitSize);
234         }
235     }
236 
ClearData()237     virtual void ClearData() override
238     {
239         data.clear();
240     }
241 
HandleGlobalFixup(const Label2OffsetMap & globalLabel2Offset)242     virtual void HandleGlobalFixup(const Label2OffsetMap &globalLabel2Offset) override
243     {
244         (void)globalLabel2Offset;
245         return;
246     }
247 
WriteSection(std::ostringstream & outStream)248     virtual void WriteSection(std::ostringstream &outStream) override
249     {
250         outStream.write(reinterpret_cast<const char *>(data.data()), data.size());
251     }
252 
AppendData(const void * value,size_t size)253     void AppendData(const void *value, size_t size)
254     {
255         auto pdata = reinterpret_cast<const uint8 *>(value);
256         data.insert(data.end(), pdata, pdata + size);
257     }
258 
AppendData(MapleVector<uint8> value)259     void AppendData(MapleVector<uint8> value)
260     {
261         data.insert(data.end(), value.begin(), value.end());
262     }
263 
GetDataSize()264     uint32 GetDataSize() override
265     {
266         return data.size();
267     }
268 
FillPadding(uint32 paddingNum)269     void FillPadding(uint32 paddingNum)
270     {
271         if (paddingNum == 0) {
272             return;
273         }
274         std::vector<uint8> paddingData(paddingNum, 0);
275         auto pdata = reinterpret_cast<const uint8 *>(paddingData.data());
276         data.insert(data.end(), pdata, pdata + paddingNum);
277     }
278 
GetDataElem32(size_t index)279     uint32 GetDataElem32(size_t index)
280     {
281         uint32 value = 0;
282         errno_t res = memcpy_s(&value, sizeof(uint32), data.data() + index, sizeof(uint32));
283         CHECK_FATAL(res == EOK, "call memcpy_s failed");
284         return value;
285     }
286 
GetDataElem64(size_t index)287     uint64 GetDataElem64(size_t index)
288     {
289         uint64 value = 0;
290         errno_t res = memcpy_s(&value, sizeof(uint64), data.data() + index, sizeof(uint64));
291         CHECK_FATAL(res == EOK, "call memcpy_s failed");
292         return value;
293     }
294 
GetData()295     const MapleVector<uint8> &GetData() const
296     {
297         return data;
298     }
299 
Swap(const void * value,size_t index,size_t size)300     void Swap(const void *value, size_t index, size_t size)
301     {
302         errno_t res = memcpy_s(data.data() + index, size, value, size);
303         CHECK_FATAL(res == EOK, "call memcpy_s failed");
304     }
305 
AddLabel2Offset(Label2OffsetMap & label2Offsets,const std::string & name,ObjLabel & objLabel)306     static void AddLabel2Offset(Label2OffsetMap &label2Offsets, const std::string &name, ObjLabel &objLabel)
307     {
308         label2Offsets.insert(std::make_pair(name, objLabel));
309     }
310 
AddLabelFixup(LabelFixupVec & labelFixups,LabelFixup & labelFixup)311     static void AddLabelFixup(LabelFixupVec &labelFixups, LabelFixup &labelFixup)
312     {
313         labelFixups.emplace_back(&labelFixup);
314     }
315 
316 protected:
317     MemPool &memPool;
318     MapleAllocator alloc;
319     MapleVector<uint8> data;
320 };
321 
322 struct MethodHeader {
323     uint32 methodMetaOffset = 0;
324     uint16 localRefOffset = 0;
325     uint16 localRefNumber = 0;
326     uint32 codeInfoOffset = 0;
327     uint32 codeSize = 0;
328 };
329 
330 class StringSection : public DataSection {
331 public:
StringSection(const std::string & name,Word type,Word flags,Word align,ObjEmitter & emitter,MemPool & memPool)332     StringSection(const std::string &name, Word type, Word flags, Word align, ObjEmitter &emitter, MemPool &memPool)
333         : DataSection(name, type, flags, align, emitter, memPool)
334     {
335         AddString("\0");
336     }
337 
338     ~StringSection() = default;
339 
AddString(const std::string & str)340     size_t AddString(const std::string &str)
341     {
342         size_t pos = data.size();
343         AppendData(str.c_str(), str.size() + 1);
344         return pos;
345     }
346 
AddString(const MapleString & str)347     size_t AddString(const MapleString &str)
348     {
349         size_t pos = data.size();
350         AppendData(str.c_str(), str.length() + 1);
351         return pos;
352     }
353 };
354 
355 class SymbolSection : public Section {
356 public:
SymbolSection(const std::string & name,Word type,Word flags,Word align,ObjEmitter & emitter,MemPool & memPool,const Section & link)357     SymbolSection(const std::string &name, Word type, Word flags, Word align, ObjEmitter &emitter, MemPool &memPool,
358                   const Section &link)
359         : Section(name, type, flags, align, emitter, memPool), alloc(&memPool), symbols(alloc.Adapter())
360     {
361         SetEntSize(sizeof(Symbol));
362         SetLink(link);
363         SetInfo(1);
364         AppendSymbol({0, 0, 0, 0, 0, 0});
365     }
366 
367     ~SymbolSection() = default;
368 
GenerateData()369     void GenerateData() override
370     {
371         SetDataSize(symbols.size() * sizeof(Symbol));
372     }
373 
WriteSection(std::ostringstream & outStream)374     void WriteSection(std::ostringstream &outStream) override
375     {
376         outStream.write(reinterpret_cast<const char *>(symbols.data()), symbols.size() * sizeof(Symbol));
377     }
378 
AppendSymbol(Symbol symbol)379     void AppendSymbol(Symbol symbol)
380     {
381         symbols.push_back(symbol);
382     }
383 
GetSymbolsSize()384     uint32 GetSymbolsSize() const
385     {
386         return symbols.size();
387     }
388 
GetIdxInSymbols(int64 symIdx)389     uint64 GetIdxInSymbols(int64 symIdx) const
390     {
391         return symbolIdxMap.at(symIdx);
392     }
393 
AppendIdxInSymbols(int64 symIdx)394     void AppendIdxInSymbols(int64 symIdx)
395     {
396         CHECK_FATAL(GetSymbolsSize() > 0, "must not be zero");
397         symbolIdxMap[symIdx] = static_cast<uint64>(GetSymbolsSize() - 1);
398     }
399 
ExistSymInSymbols(int64 symIdx)400     bool ExistSymInSymbols(int64 symIdx)
401     {
402         return symbolIdxMap.count(symIdx) != 0;
403     }
404 
GetAddr()405     const char *GetAddr()
406     {
407         return reinterpret_cast<const char*>(symbols.data());
408     }
409 private:
410     MapleAllocator alloc;
411     MapleVector<Symbol> symbols;
412     std::unordered_map<int64, uint64> symbolIdxMap;
413 };
414 
415 class RelaSection : public Section {
416 public:
RelaSection(const std::string & name,Word type,Word flags,Word info,Word align,const Section & link,ObjEmitter & emitter,MemPool & memPool)417     RelaSection(const std::string &name, Word type, Word flags, Word info, Word align, const Section &link,
418                 ObjEmitter &emitter, MemPool &memPool)
419         : Section(name, type, flags, align, emitter, memPool), alloc(&memPool), relas(alloc.Adapter())
420     {
421         SetEntSize(sizeof(Rela));
422         SetInfo(info);
423         SetLink(link);
424     }
425 
426     ~RelaSection() = default;
427 
GenerateData()428     void GenerateData() override
429     {
430         SetDataSize(relas.size() * sizeof(Rela));
431     }
432 
WriteSection(std::ostringstream & outStream)433     void WriteSection(std::ostringstream &outStream) override
434     {
435         outStream.write(reinterpret_cast<const char *>(relas.data()), relas.size() * sizeof(Rela));
436     }
437 
AppendRela(Rela rela)438     void AppendRela(Rela rela)
439     {
440         relas.push_back(rela);
441     }
442 
443 private:
444     MapleAllocator alloc;
445     MapleVector<Rela> relas;
446 }; /* class RelaSection */
447 
448 struct EmitInfo {
449     MIRConst &elemConst;
450     Offset &offset;
451     Label2OffsetMap &label2Offsets;
452     LabelFixupVec &labelFixups;
453 };
454 } /* namespace maplebe */
455 
456 #endif /* MAPLEBE_INCLUDE_CG_IFILE_H */
457