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