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
25namespace panda::ecmascript {
26class ModuleSectionDes {
27public:
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
40    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
58    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
72    void SetArkStackMapPtr(std::shared_ptr<uint8_t> ptr)
73    {
74        arkStackMapPtr_ = std::move(ptr);
75    }
76
77    std::shared_ptr<uint8_t> GetArkStackMapSharePtr() const
78    {
79        return arkStackMapPtr_;
80    }
81
82    std::map<ElfSecName, std::pair<uint64_t, uint32_t>> &GetSectionsInfo()
83    {
84        return sectionsInfo_;
85    }
86
87    const std::map<ElfSecName, std::pair<uint64_t, uint32_t>> &GetSectionsInfo() const
88    {
89        return sectionsInfo_;
90    }
91
92    void SetArkStackMapPtr(uint8_t *ptr)
93    {
94        arkStackMapRawPtr_ = ptr;
95    }
96
97    uint8_t *GetArkStackMapRawPtr() const
98    {
99        return arkStackMapRawPtr_;
100    }
101
102    void SetArkStackMapSize(uint32_t size)
103    {
104        arkStackMapSize_ = size;
105    }
106
107    uint32_t GetArkStackMapSize() const
108    {
109        return arkStackMapSize_;
110    }
111
112    void SetStartIndex(uint32_t index)
113    {
114        startIndex_ = index;
115    }
116
117    uint32_t GetStartIndex() const
118    {
119        return startIndex_;
120    }
121
122    void SetFuncCount(uint32_t cnt)
123    {
124        funcCount_ = cnt;
125    }
126
127    uint32_t GetFuncCount() const
128    {
129        return funcCount_;
130    }
131
132    ModuleSectionDes() = default;
133
134    void EraseSec(ElfSecName idx)
135    {
136        sectionsInfo_.erase(idx);
137    }
138
139    void SetSecAddrAndSize(ElfSecName idx, uint64_t addr, uint32_t size)
140    {
141        sectionsInfo_[idx].first = addr;
142        sectionsInfo_[idx].second = size;
143    }
144
145    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
151    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
157    uint32_t GetSecInfosSize() const
158    {
159        return sectionsInfo_.size();
160    }
161
162    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
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
179    bool HasAsmStubStrTab() const
180    {
181        return asmStubELFInfo_.size() != 0;
182    }
183
184    const std::vector<std::pair<std::string, uint32_t>>& GetAsmStubELFInfo()
185    {
186        return asmStubELFInfo_;
187    }
188
189    void AddAsmStubELFInfo(std::vector<std::pair<std::string, uint32_t>> &asmStubELFInfo)
190    {
191        asmStubELFInfo_ = asmStubELFInfo;
192    }
193
194private:
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