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