• 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 "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