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 #ifndef ECMASCRIPT_COMPILER_AOT_FILE_MODULE_SECTION_DES_H
16 #define ECMASCRIPT_COMPILER_AOT_FILE_MODULE_SECTION_DES_H
17 
18 #include <cstdint>
19 #include <memory>
20 
21 #include "ecmascript/base/number_helper.h"
22 #include "ecmascript/compiler/aot_file/binary_buffer_parser.h"
23 #include "ecmascript/compiler/binary_section.h"
24 
25 namespace panda::ecmascript {
26 class ModuleSectionDes {
27 public:
28     struct ModuleRegionInfo {
29         uint32_t startIndex {0};
30         uint32_t funcCount {0};
31         uint32_t rodataSizeBeforeText {0};
32         uint32_t rodataSizeAfterText {0};
33         uint32_t textSize {0};
34         uint32_t stackMapSize {0};
35         uint32_t strtabSize {0};
36         uint32_t symtabSize {0};
37     };
38     static std::string GetSecName(ElfSecName idx);
39 
UpdateRODataInfo(uint64_t textAddr, uint64_t &addrBeforeText, uint32_t &sizeBeforeText, uint64_t &addrAfterText, uint32_t &sizeAfterText, ElfSecName sec) const40     void UpdateRODataInfo(uint64_t textAddr, uint64_t &addrBeforeText, uint32_t &sizeBeforeText,
41                           uint64_t &addrAfterText, uint32_t &sizeAfterText, ElfSecName sec) const
42     {
43         if (sectionsInfo_.find(sec) == sectionsInfo_.end()) {
44             return;
45         }
46         uint64_t curSectionAddr = GetSecAddr(sec);
47         ASSERT(curSectionAddr != 0);
48         ASSERT(curSectionAddr != textAddr);
49         if (curSectionAddr < textAddr) {
50             addrBeforeText = (curSectionAddr < addrBeforeText) ? curSectionAddr : addrBeforeText;
51             sizeBeforeText += GetSecSize(sec);
52         } else {
53             addrAfterText = (curSectionAddr < addrAfterText) ? curSectionAddr : addrAfterText;
54             sizeAfterText += GetSecSize(sec);
55         }
56     }
57 
GetMergedRODataAddrAndSize(uint64_t textAddr) const58     std::tuple<uint64_t, uint32_t, uint64_t, uint32_t> GetMergedRODataAddrAndSize(uint64_t textAddr) const
59     {
60         uint64_t addrBeforeText = base::MAX_UINT64_VALUE;
61         uint32_t sizeBeforeText = 0;
62         uint64_t addrAfterText = base::MAX_UINT64_VALUE;
63         uint32_t sizeAfterText = 0;
64         for (uint8_t i = static_cast<uint8_t>(ElfSecName::RODATA); i <= static_cast<uint8_t>(ElfSecName::RODATA_CST32);
65              i++) {
66             UpdateRODataInfo(textAddr, addrBeforeText, sizeBeforeText, addrAfterText, sizeAfterText,
67                 static_cast<ElfSecName>(i));
68         }
69         return std::make_tuple(addrBeforeText, sizeBeforeText, addrAfterText, sizeAfterText);
70     }
71 
SetArkStackMapPtr(std::shared_ptr<uint8_t> ptr)72     void SetArkStackMapPtr(std::shared_ptr<uint8_t> ptr)
73     {
74         arkStackMapPtr_ = std::move(ptr);
75     }
76 
GetArkStackMapSharePtr() const77     std::shared_ptr<uint8_t> GetArkStackMapSharePtr() const
78     {
79         return arkStackMapPtr_;
80     }
81 
GetSectionsInfo()82     std::map<ElfSecName, std::pair<uint64_t, uint32_t>> &GetSectionsInfo()
83     {
84         return sectionsInfo_;
85     }
86 
GetSectionsInfo() const87     const std::map<ElfSecName, std::pair<uint64_t, uint32_t>> &GetSectionsInfo() const
88     {
89         return sectionsInfo_;
90     }
91 
SetArkStackMapPtr(uint8_t *ptr)92     void SetArkStackMapPtr(uint8_t *ptr)
93     {
94         arkStackMapRawPtr_ = ptr;
95     }
96 
GetArkStackMapRawPtr() const97     uint8_t *GetArkStackMapRawPtr() const
98     {
99         return arkStackMapRawPtr_;
100     }
101 
SetArkStackMapSize(uint32_t size)102     void SetArkStackMapSize(uint32_t size)
103     {
104         arkStackMapSize_ = size;
105     }
106 
GetArkStackMapSize() const107     uint32_t GetArkStackMapSize() const
108     {
109         return arkStackMapSize_;
110     }
111 
SetStartIndex(uint32_t index)112     void SetStartIndex(uint32_t index)
113     {
114         startIndex_ = index;
115     }
116 
GetStartIndex() const117     uint32_t GetStartIndex() const
118     {
119         return startIndex_;
120     }
121 
SetFuncCount(uint32_t cnt)122     void SetFuncCount(uint32_t cnt)
123     {
124         funcCount_ = cnt;
125     }
126 
GetFuncCount() const127     uint32_t GetFuncCount() const
128     {
129         return funcCount_;
130     }
131 
132     ModuleSectionDes() = default;
133 
EraseSec(ElfSecName idx)134     void EraseSec(ElfSecName idx)
135     {
136         sectionsInfo_.erase(idx);
137     }
138 
SetSecAddrAndSize(ElfSecName idx, uint64_t addr, uint32_t size)139     void SetSecAddrAndSize(ElfSecName idx, uint64_t addr, uint32_t size)
140     {
141         sectionsInfo_[idx].first = addr;
142         sectionsInfo_[idx].second = size;
143     }
144 
GetSecAddr(const ElfSecName idx) const145     uint64_t GetSecAddr(const ElfSecName idx) const
146     {
147         auto it = sectionsInfo_.find(idx);
148         return it == sectionsInfo_.end() ? 0 : it->second.first;
149     }
150 
GetSecSize(const ElfSecName idx) const151     uint32_t GetSecSize(const ElfSecName idx) const
152     {
153         auto it = sectionsInfo_.find(idx);
154         return it == sectionsInfo_.end() ? 0 : it->second.second;
155     }
156 
GetSecInfosSize() const157     uint32_t GetSecInfosSize() const
158     {
159         return sectionsInfo_.size();
160     }
161 
ContainCode(uintptr_t pc) const162     bool ContainCode(uintptr_t pc) const
163     {
164         uint64_t stubStartAddr = GetSecAddr(ElfSecName::TEXT);
165         uint64_t stubEndAddr = stubStartAddr + GetSecSize(ElfSecName::TEXT);
166         return (pc >= stubStartAddr && pc <= stubEndAddr);
167     }
168 
AddArkStackMapSection()169     void AddArkStackMapSection()
170     {
171         std::shared_ptr<uint8_t> ptr = GetArkStackMapSharePtr();
172         uint64_t arkStackMapAddr = reinterpret_cast<uint64_t>(ptr.get());
173         uint32_t arkStackMapSize = GetArkStackMapSize();
174         if (arkStackMapSize > 0) {
175             sectionsInfo_[ElfSecName::ARK_STACKMAP] = std::pair(arkStackMapAddr, arkStackMapSize);
176         }
177     }
178 
HasAsmStubStrTab() const179     bool HasAsmStubStrTab() const
180     {
181         return asmStubELFInfo_.size() != 0;
182     }
183 
GetAsmStubELFInfo()184     const std::vector<std::pair<std::string, uint32_t>>& GetAsmStubELFInfo()
185     {
186         return asmStubELFInfo_;
187     }
188 
AddAsmStubELFInfo(std::vector<std::pair<std::string, uint32_t>> &asmStubELFInfo)189     void AddAsmStubELFInfo(std::vector<std::pair<std::string, uint32_t>> &asmStubELFInfo)
190     {
191         asmStubELFInfo_ = asmStubELFInfo;
192     }
193 
194 private:
195     static constexpr int DECIMAL_LENS = 2;
196     static constexpr int HUNDRED_TIME = 100;
197     static constexpr int PERCENT_LENS = 4;
198 
199     std::vector<std::pair<std::string, uint32_t>> asmStubELFInfo_ {};
200     std::map<ElfSecName, std::pair<uint64_t, uint32_t>> sectionsInfo_ {};
201     uint32_t startIndex_ {static_cast<uint32_t>(-1)};  // record current module first function index in AOTFileInfo
202     uint32_t funcCount_ {0};
203     std::shared_ptr<uint8_t> arkStackMapPtr_ {nullptr};
204     uint32_t arkStackMapSize_ {0};
205     uint8_t *arkStackMapRawPtr_ {nullptr};
206 };
207 }  // namespace panda::ecmascript
208 #endif  // ECMASCRIPT_COMPILER_AOT_FILE_MODULE_SECTION_DES_H
209