1 /* 2 * Copyright (c) 2021-2022 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 ECMASCRIPT_COMPILER_BINARY_SECTION_H 17 #define ECMASCRIPT_COMPILER_BINARY_SECTION_H 18 19 #include <string> 20 #include <map> 21 #include "ecmascript/common.h" 22 #include "libpandabase/macros.h" 23 #include "llvm/BinaryFormat/ELF.h" 24 25 namespace panda::ecmascript { 26 enum class ElfSecName : uint8_t { 27 NONE, 28 RODATA, 29 RODATA_CST4, 30 RODATA_CST8, 31 RODATA_CST16, 32 RODATA_CST32, 33 TEXT, 34 ARK_ASMSTUB, 35 DATA, 36 GOT, 37 RELATEXT, 38 STRTAB, 39 SYMTAB, 40 SHSTRTAB, 41 LLVM_STACKMAP, 42 ARK_FUNCENTRY, 43 ARK_STACKMAP, 44 ARK_MODULEINFO, 45 ARK_CHECKSUMINFO, 46 SIZE 47 }; 48 49 enum ElfSecFeature : uint8_t { 50 NOT_VALID, 51 VALID_NOT_SEQUENTIAL = 1, 52 VALID_AND_SEQUENTIAL = (1 << 1) | 1, 53 54 VALID_MASK = 0x1, 55 SEQUENTIAL_MASK = 0x2 56 }; 57 58 class PUBLIC_API ElfSection { 59 public: 60 ElfSection() = delete; 61 ElfSection(ElfSecName idx)62 explicit ElfSection(ElfSecName idx) 63 { 64 value_ = idx; 65 InitShTypeAndFlag(); 66 } ElfSection(size_t idx)67 explicit ElfSection(size_t idx) 68 { 69 value_ = static_cast<ElfSecName>(idx); 70 InitShTypeAndFlag(); 71 } ElfSection(std::string str)72 explicit ElfSection(std::string str) 73 { 74 if (str.compare(".rodata") == 0) { 75 value_ = ElfSecName::RODATA; 76 } else if (str.compare(".rodata.cst4") == 0) { 77 value_ = ElfSecName::RODATA_CST4; 78 } else if (str.compare(".rodata.cst8") == 0) { 79 value_ = ElfSecName::RODATA_CST8; 80 } else if (str.compare(".rodata.cst16") == 0) { 81 value_ = ElfSecName::RODATA_CST16; 82 } else if (str.compare(".rodata.cst32") == 0) { 83 value_ = ElfSecName::RODATA_CST32; 84 } else if (str.compare(".text") == 0) { 85 value_ = ElfSecName::TEXT; 86 } else if (str.compare(".data") == 0) { 87 value_ = ElfSecName::DATA; 88 } else if (str.compare(".got") == 0) { 89 value_ = ElfSecName::GOT; 90 } else if (str.compare(".rela.text") == 0) { 91 value_ = ElfSecName::RELATEXT; 92 } else if (str.compare(".strtab") == 0) { 93 value_ = ElfSecName::STRTAB; 94 } else if (str.compare(".symtab") == 0) { 95 value_ = ElfSecName::SYMTAB; 96 } else if (str.compare(".shstrtab") == 0) { 97 value_ = ElfSecName::SHSTRTAB; 98 } else if (str.compare(".llvm_stackmaps") == 0) { 99 value_ = ElfSecName::LLVM_STACKMAP; 100 } else if (str.compare(".ark_stackmaps") == 0) { 101 value_ = ElfSecName::ARK_STACKMAP; 102 } else if (str.compare(".ark_funcentry") == 0) { 103 value_ = ElfSecName::ARK_FUNCENTRY; 104 } else if (str.compare(".ark_asmstub") == 0) { 105 value_ = ElfSecName::ARK_ASMSTUB; 106 } else if (str.compare(".ark_moduleinfo") == 0) { 107 value_ = ElfSecName::ARK_MODULEINFO; 108 } 109 InitShTypeAndFlag(); 110 } 111 ShouldDumpToAOTFile()112 bool ShouldDumpToAOTFile() const 113 { 114 bool saveForAot = false; 115 switch (value_) { 116 case ElfSecName::TEXT: 117 case ElfSecName::STRTAB: 118 case ElfSecName::SYMTAB: 119 case ElfSecName::SHSTRTAB: 120 case ElfSecName::ARK_FUNCENTRY: 121 case ElfSecName::ARK_ASMSTUB: 122 case ElfSecName::ARK_STACKMAP: 123 case ElfSecName::ARK_MODULEINFO: 124 case ElfSecName::ARK_CHECKSUMINFO: { 125 saveForAot = true; 126 break; 127 } 128 default: { 129 break; 130 } 131 } 132 return saveForAot; 133 } 134 Value()135 ElfSecName Value() const 136 { 137 return value_; 138 } 139 Entsize()140 int Entsize() const 141 { 142 if (value_ == ElfSecName::RELATEXT || value_ == ElfSecName::SYMTAB) { 143 return FIX_SIZE; 144 } 145 return 0; 146 } 147 Link()148 int Link() const 149 { 150 // The strtab index is 2 inside An file. 151 return value_ == ElfSecName::SYMTAB ? 2 : 0; 152 } 153 InitShTypeAndFlag()154 void InitShTypeAndFlag() 155 { 156 std::map<ElfSecName, std::pair<unsigned, unsigned>> nameToTypeAndFlag = { 157 {ElfSecName::RODATA, {llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_MERGE}}, 158 {ElfSecName::RODATA_CST4, {llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_MERGE}}, 159 {ElfSecName::RODATA_CST8, {llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_MERGE}}, 160 {ElfSecName::RODATA_CST16, {llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_MERGE}}, 161 {ElfSecName::RODATA_CST32, {llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_MERGE}}, 162 {ElfSecName::TEXT, {llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR}}, 163 {ElfSecName::ARK_ASMSTUB, {llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR}}, 164 {ElfSecName::DATA, {llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE}}, 165 {ElfSecName::GOT, {llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE}}, 166 {ElfSecName::RELATEXT, {llvm::ELF::SHT_RELA, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE}}, 167 {ElfSecName::STRTAB, {llvm::ELF::SHT_STRTAB, llvm::ELF::SHF_ALLOC}}, 168 {ElfSecName::SYMTAB, {llvm::ELF::SHT_SYMTAB, llvm::ELF::SHF_ALLOC}}, 169 {ElfSecName::SHSTRTAB, {llvm::ELF::SHT_STRTAB, llvm::ELF::SHF_ALLOC}}, 170 {ElfSecName::LLVM_STACKMAP, {llvm::ELF::SHT_RELA, llvm::ELF::SHF_ALLOC}}, 171 {ElfSecName::ARK_FUNCENTRY, {llvm::ELF::SHF_WRITE, llvm::ELF::SHF_ALLOC}}, 172 {ElfSecName::ARK_STACKMAP, {llvm::ELF::SHF_WRITE, llvm::ELF::SHF_ALLOC}}, 173 {ElfSecName::ARK_MODULEINFO, {llvm::ELF::SHF_WRITE, llvm::ELF::SHF_ALLOC}}, 174 {ElfSecName::ARK_CHECKSUMINFO, {llvm::ELF::SHF_WRITE, llvm::ELF::SHF_ALLOC}}}; 175 auto it = nameToTypeAndFlag.find(value_); 176 if (it == nameToTypeAndFlag.end()) { 177 return; 178 } 179 ASSERT(it != nameToTypeAndFlag.end()); 180 type_ = it->second.first; 181 flag_ = it->second.second; 182 } 183 Type()184 unsigned Type() const 185 { 186 return type_; 187 } 188 Flag()189 unsigned Flag() const 190 { 191 return flag_; 192 } 193 isValidAOTSec()194 bool isValidAOTSec() const 195 { 196 auto idx = static_cast<size_t>(value_); 197 return static_cast<uint8_t>(AOTSecFeatureTable_[idx]) & ElfSecFeature::VALID_MASK; 198 } 199 isSequentialAOTSec()200 bool isSequentialAOTSec() const 201 { 202 auto idx = static_cast<size_t>(value_); 203 return static_cast<uint8_t>(AOTSecFeatureTable_[idx]) & ElfSecFeature::SEQUENTIAL_MASK; 204 } 205 GetElfEnumValue()206 ElfSecName GetElfEnumValue() const 207 { 208 return value_; 209 } 210 GetIntIndex()211 int GetIntIndex() const 212 { 213 return static_cast<int>(value_); 214 } 215 216 // RO data section needs 16 bytes alignment InRodataSection()217 bool InRodataSection() const 218 { 219 return ElfSecName::RODATA <= value_ && value_ <= ElfSecName::RODATA_CST32; 220 } 221 private: 222 static int const FIX_SIZE = 24; // 24:Elf_Rel 223 ElfSecName value_ {ElfSecName::NONE}; 224 unsigned type_ {0}; 225 unsigned flag_ {0}; 226 227 static constexpr size_t AOTSecFeatureTable_[static_cast<size_t>(ElfSecName::SIZE)] = { 228 ElfSecFeature::NOT_VALID, 229 ElfSecFeature::VALID_AND_SEQUENTIAL, 230 ElfSecFeature::VALID_AND_SEQUENTIAL, 231 ElfSecFeature::VALID_AND_SEQUENTIAL, 232 ElfSecFeature::VALID_AND_SEQUENTIAL, 233 ElfSecFeature::VALID_AND_SEQUENTIAL, 234 ElfSecFeature::VALID_AND_SEQUENTIAL, 235 ElfSecFeature::VALID_AND_SEQUENTIAL, 236 ElfSecFeature::VALID_AND_SEQUENTIAL, 237 ElfSecFeature::VALID_AND_SEQUENTIAL, 238 ElfSecFeature::VALID_AND_SEQUENTIAL, 239 ElfSecFeature::VALID_AND_SEQUENTIAL, 240 ElfSecFeature::VALID_AND_SEQUENTIAL, 241 ElfSecFeature::VALID_NOT_SEQUENTIAL, 242 ElfSecFeature::VALID_NOT_SEQUENTIAL, 243 }; 244 }; 245 } 246 #endif