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
16 #include "ecmascript/compiler/aot_file/elf_reader.h"
17
18 namespace panda::ecmascript {
VerifyELFHeader(uint32_t version, bool strictMatch)19 bool ElfReader::VerifyELFHeader(uint32_t version, bool strictMatch)
20 {
21 llvm::ELF::Elf64_Ehdr header = *(reinterpret_cast<llvm::ELF::Elf64_Ehdr *>(fileMapMem_.GetOriginAddr()));
22 if (header.e_ident[llvm::ELF::EI_MAG0] != llvm::ELF::ElfMagic[llvm::ELF::EI_MAG0]
23 || header.e_ident[llvm::ELF::EI_MAG1] != llvm::ELF::ElfMagic[llvm::ELF::EI_MAG1]
24 || header.e_ident[llvm::ELF::EI_MAG2] != llvm::ELF::ElfMagic[llvm::ELF::EI_MAG2]
25 || header.e_ident[llvm::ELF::EI_MAG3] != llvm::ELF::ElfMagic[llvm::ELF::EI_MAG3]) {
26 LOG_ECMA(ERROR) << "ELF format error, expected magic is " << llvm::ELF::ElfMagic
27 << ", but got " << header.e_ident[llvm::ELF::EI_MAG0] << header.e_ident[llvm::ELF::EI_MAG1]
28 << header.e_ident[llvm::ELF::EI_MAG2] << header.e_ident[llvm::ELF::EI_MAG3];
29 return false;
30 }
31 if (!base::FileHeaderBase::VerifyVersion("Elf", header.e_version, version, strictMatch)) {
32 return false;
33 }
34 if (ElfChecker(fileMapMem_).CheckValidElf() == false) {
35 LOG_ECMA(ERROR) << "ELF file content is not valid";
36 return false;
37 }
38 return true;
39 }
40
GetCurModuleInfo(uint32_t i, llvm::ELF::Elf64_Off offset)41 ModuleSectionDes::ModuleRegionInfo *ElfReader::GetCurModuleInfo(uint32_t i, llvm::ELF::Elf64_Off offset)
42 {
43 uint64_t codeAddress = reinterpret_cast<uint64_t>(fileMapMem_.GetOriginAddr());
44 uint64_t info = codeAddress + offset + i * sizeof(ModuleSectionDes::ModuleRegionInfo);
45 return reinterpret_cast<ModuleSectionDes::ModuleRegionInfo *>(info);
46 }
47
ParseELFSections(ModuleSectionDes &des, std::vector<ElfSecName> &secs)48 void ElfReader::ParseELFSections(ModuleSectionDes &des, std::vector<ElfSecName> &secs)
49 {
50 llvm::ELF::Elf64_Ehdr *ehdr = reinterpret_cast<llvm::ELF::Elf64_Ehdr *>(fileMapMem_.GetOriginAddr());
51 char *addr = reinterpret_cast<char *>(ehdr);
52 llvm::ELF::Elf64_Shdr *shdr = reinterpret_cast<llvm::ELF::Elf64_Shdr *>(addr + ehdr->e_shoff);
53 ASSERT(ehdr->e_shstrndx != static_cast<llvm::ELF::Elf64_Half>(-1));
54 llvm::ELF::Elf64_Shdr strdr = shdr[ehdr->e_shstrndx];
55 for (size_t j = 0; j < secs.size(); ++j) {
56 int secId = -1;
57 ElfSecName sec = secs[j];
58 std::string sectionName = ModuleSectionDes::GetSecName(sec);
59 for (size_t i = 0; i < ehdr->e_shnum; ++i) {
60 llvm::ELF::Elf64_Word shName = shdr[i].sh_name;
61 char *curShName = reinterpret_cast<char *>(addr) + shName + strdr.sh_offset;
62 if (sectionName.compare(curShName) == 0) {
63 secId = static_cast<int>(i);
64 break;
65 }
66 }
67 if (secId == -1) {
68 LOG_COMPILER(DEBUG) << "sectionName: " << sectionName << " not found in strtab";
69 continue;
70 }
71 ASSERT(secId > 0 && secId < ehdr->e_shnum);
72 llvm::ELF::Elf64_Shdr secShdr = shdr[secId];
73 uintptr_t secAddr = reinterpret_cast<uintptr_t>(addr + secShdr.sh_offset);
74 uint32_t secSize = secShdr.sh_size;
75 if (sec == ElfSecName::ARK_FUNCENTRY) {
76 ASSERT((secSize > 0) && (secSize % sizeof(AOTFileInfo::FuncEntryDes) == 0));
77 }
78 if (sec == ElfSecName::ARK_STACKMAP) {
79 des.SetArkStackMapPtr(reinterpret_cast<uint8_t *>(secAddr));
80 des.SetArkStackMapSize(secSize);
81 } else {
82 des.SetSecAddrAndSize(sec, secAddr, secSize);
83 }
84 }
85 }
86
ParseELFSections(std::vector<ModuleSectionDes> &des, std::vector<ElfSecName> &secs)87 void ElfReader::ParseELFSections(std::vector<ModuleSectionDes> &des, std::vector<ElfSecName> &secs)
88 {
89 llvm::ELF::Elf64_Ehdr *ehdr = reinterpret_cast<llvm::ELF::Elf64_Ehdr *>(fileMapMem_.GetOriginAddr());
90 char *addr = reinterpret_cast<char *>(ehdr);
91 llvm::ELF::Elf64_Shdr *shdrs = reinterpret_cast<llvm::ELF::Elf64_Shdr *>(addr + ehdr->e_shoff);
92 ASSERT(ehdr->e_shstrndx != static_cast<llvm::ELF::Elf64_Half>(-1));
93 llvm::ELF::Elf64_Shdr strdr = shdrs[ehdr->e_shstrndx];
94 ASSERT(ehdr->e_flags != static_cast<llvm::ELF::Elf64_Word>(-1));
95 llvm::ELF::Elf64_Shdr moduledr = shdrs[ehdr->e_flags];
96 size_t moduleInfoSize = moduledr.sh_size;
97 uint32_t moduleNum = GetModuleNum(moduleInfoSize);
98 des.resize(moduleNum);
99 std::set<ElfSecName> secSet(secs.begin(), secs.end());
100 for (ElfSecName sec : secSet) {
101 int secId = -1;
102 std::string sectionName = ModuleSectionDes::GetSecName(sec);
103 for (size_t i = 0; i < ehdr->e_shnum; ++i) {
104 llvm::ELF::Elf64_Word shName = shdrs[i].sh_name;
105 char *curShName = reinterpret_cast<char *>(addr) + shName + strdr.sh_offset;
106 if (sectionName.compare(curShName) == 0) {
107 secId = static_cast<int>(i);
108 break;
109 }
110 }
111 if (secId == -1) {
112 LOG_COMPILER(DEBUG) << "sectionName: " << sectionName << " not found in strtab";
113 continue;
114 }
115 ASSERT(secId > 0 && secId < ehdr->e_shnum);
116 llvm::ELF::Elf64_Shdr secShdr = shdrs[secId];
117 uintptr_t secAddr = reinterpret_cast<uintptr_t>(addr + secShdr.sh_offset);
118 uint32_t secSize = secShdr.sh_size;
119 switch (sec) {
120 case ElfSecName::TEXT: {
121 llvm::ELF::Elf64_Off secOffset = 0;
122 SeparateTextSections(des, secAddr, secOffset, moduledr.sh_offset);
123 ASSERT(static_cast<uint32_t>(secOffset) == secSize);
124 break;
125 }
126 case ElfSecName::ARK_STACKMAP: {
127 llvm::ELF::Elf64_Off secOffset = 0;
128 SeparateArkStackMapSections(des, secAddr, secOffset, moduledr.sh_offset);
129 ASSERT(static_cast<uint32_t>(secOffset) == secSize);
130 break;
131 }
132 case ElfSecName::STRTAB: {
133 llvm::ELF::Elf64_Off secOffset = 0;
134 SeparateStrtabSections(des, secAddr, secOffset, moduledr.sh_offset);
135 ASSERT(static_cast<uint32_t>(secOffset) == secSize);
136 break;
137 }
138 case ElfSecName::SYMTAB: {
139 llvm::ELF::Elf64_Off secOffset = 0;
140 SeparateSymtabSections(des, secAddr, secOffset, moduledr.sh_offset);
141 ASSERT(static_cast<uint32_t>(secOffset) == secSize);
142 break;
143 }
144 case ElfSecName::SHSTRTAB:
145 case ElfSecName::ARK_FUNCENTRY:
146 case ElfSecName::ARK_ASMSTUB:
147 case ElfSecName::ARK_MODULEINFO: {
148 if (sec == ElfSecName::ARK_FUNCENTRY) {
149 ASSERT((secSize > 0) && (secSize % sizeof(AOTFileInfo::FuncEntryDes) == 0));
150 }
151 des[0].SetSecAddrAndSize(sec, secAddr, secSize);
152 break;
153 }
154 default: {
155 LOG_ECMA(FATAL) << "this section should not dump to stub file";
156 break;
157 }
158 }
159 }
160 }
161
ParseELFSections(BinaryBufferParser &parser, std::vector<ModuleSectionDes> &des, std::vector<ElfSecName> &secs)162 void ElfReader::ParseELFSections(BinaryBufferParser &parser,
163 std::vector<ModuleSectionDes> &des,
164 std::vector<ElfSecName> &secs)
165 {
166 ASSERT(des.size() == ASMSTUB_MODULE_NUM);
167 uint64_t codeAddress = reinterpret_cast<uint64_t>(stubsMem_.addr_);
168 llvm::ELF::Elf64_Ehdr ehdr;
169 parser.ParseBuffer(&ehdr, sizeof(ehdr), 0);
170 std::vector<llvm::ELF::Elf64_Shdr> shdrs(ehdr.e_shnum);
171 parser.ParseBuffer(shdrs.data(), sizeof(llvm::ELF::Elf64_Shdr) * ehdr.e_shnum, ehdr.e_shoff);
172
173 ASSERT(ehdr.e_shstrndx != static_cast<llvm::ELF::Elf64_Half>(-1));
174 llvm::ELF::Elf64_Shdr strdr = shdrs[ehdr.e_shstrndx];
175 ASSERT(ehdr.e_flags != static_cast<llvm::ELF::Elf64_Word>(-1));
176 llvm::ELF::Elf64_Shdr moduledr = shdrs[ehdr.e_flags];
177 [[maybe_unused]] size_t moduleInfoSize = moduledr.sh_size;
178 uint32_t moduleNum = GetModuleNum(moduleInfoSize);
179 ASSERT(moduleNum == ASMSTUB_MODULE_NUM);
180 moduleInfo_.resize(moduleNum);
181 parser.ParseBuffer(moduleInfo_.data(), moduleInfoSize, moduledr.sh_offset);
182 std::set<ElfSecName> secSet(secs.begin(), secs.end());
183 for (ElfSecName sec : secSet) {
184 int secId = -1;
185 std::string sectionName = ModuleSectionDes::GetSecName(sec);
186 for (size_t i = 0; i < ehdr.e_shnum; ++i) {
187 llvm::ELF::Elf64_Word shName = shdrs[i].sh_name;
188 char *curShName = reinterpret_cast<char *>(parser.GetAddr()) + shName + strdr.sh_offset;
189 if (sectionName.compare(curShName) == 0) {
190 secId = static_cast<int>(i);
191 break;
192 }
193 }
194 if (secId == -1) {
195 LOG_COMPILER(DEBUG) << "sectionName: " << sectionName << " not found in strtab";
196 continue;
197 }
198 ASSERT(secId > 0 && secId < ehdr.e_shnum);
199 llvm::ELF::Elf64_Shdr secShdr = shdrs[secId];
200 uint64_t secAddr = static_cast<uint64_t>(codeAddress + secShdr.sh_offset);
201 uint32_t secSize = secShdr.sh_size;
202 switch (sec) {
203 case ElfSecName::TEXT: {
204 llvm::ELF::Elf64_Off secOffset = 0;
205 SeparateTextSections(parser, des, secAddr, secOffset, secShdr.sh_offset);
206 ASSERT(static_cast<uint32_t>(secOffset) == secSize);
207 break;
208 }
209 case ElfSecName::ARK_STACKMAP: {
210 llvm::ELF::Elf64_Off secOffset = 0;
211 SeparateArkStackMapSections(parser, des, secAddr, secOffset, secShdr.sh_offset);
212 ASSERT(static_cast<uint32_t>(secOffset) == secSize);
213 break;
214 }
215 case ElfSecName::STRTAB: {
216 llvm::ELF::Elf64_Off secOffset = 0;
217 SeparateStrtabSections(parser, des, secAddr, secOffset, secShdr.sh_offset);
218 ASSERT(static_cast<uint32_t>(secOffset) == secSize);
219 break;
220 }
221 case ElfSecName::SYMTAB: {
222 llvm::ELF::Elf64_Off secOffset = 0;
223 SeparateSymtabSections(parser, des, secAddr, secOffset, secShdr.sh_offset);
224 ASSERT(static_cast<uint32_t>(secOffset) == secSize);
225 break;
226 }
227 case ElfSecName::SHSTRTAB:
228 case ElfSecName::ARK_FUNCENTRY:
229 case ElfSecName::ARK_ASMSTUB:
230 case ElfSecName::ARK_MODULEINFO: {
231 if (sec == ElfSecName::ARK_FUNCENTRY) {
232 ASSERT((secSize > 0) && (secSize % sizeof(AOTFileInfo::FuncEntryDes) == 0));
233 }
234 parser.ParseBuffer(reinterpret_cast<void *>(secAddr), secSize, secShdr.sh_offset);
235 des[0].SetSecAddrAndSize(sec, secAddr, secSize);
236 break;
237 }
238 default: {
239 LOG_ECMA(FATAL) << "this section should not dump to stub file";
240 break;
241 }
242 }
243 }
244 }
245
ParseELFSegment()246 bool ElfReader::ParseELFSegment()
247 {
248 if (fileMapMem_.GetOriginAddr() == nullptr) {
249 return false;
250 }
251 char *addr = reinterpret_cast<char *>(fileMapMem_.GetOriginAddr());
252 llvm::ELF::Elf64_Ehdr *ehdr = reinterpret_cast<llvm::ELF::Elf64_Ehdr *>(fileMapMem_.GetOriginAddr());
253 llvm::ELF::Elf64_Phdr *phdr = reinterpret_cast<llvm::ELF::Elf64_Phdr *>(addr + ehdr->e_phoff);
254 for (int i = 0; i < ehdr->e_phnum; ++i) {
255 if (phdr[i].p_type != llvm::ELF::PT_LOAD) {
256 continue;
257 }
258 if (phdr[i].p_filesz > phdr[i].p_memsz) {
259 LOG_COMPILER(ERROR) << " p_filesz:0x" << std::hex << phdr[i].p_filesz << " > p_memsz:0x"
260 << phdr[i].p_memsz;
261 return false;
262 }
263 if (!phdr[i].p_filesz) {
264 continue;
265 }
266 unsigned char *virtualAddr = reinterpret_cast<unsigned char *>(addr + phdr[i].p_vaddr);
267 ASSERT(phdr[i].p_offset % PageSize() == 0);
268 if ((phdr[i].p_flags & llvm::ELF::PF_X) != 0) {
269 ASSERT(reinterpret_cast<uintptr_t>(virtualAddr) % PageSize() == 0);
270 if (!PageProtect(virtualAddr, phdr[i].p_memsz, PAGE_PROT_EXEC_READ)) {
271 return false;
272 }
273 }
274 }
275 return true;
276 }
277
SeparateTextSections(std::vector<ModuleSectionDes> &des, const uintptr_t &secAddr, llvm::ELF::Elf64_Off &secOffset, const llvm::ELF::Elf64_Off &moduleInfoOffset)278 void ElfReader::SeparateTextSections(std::vector<ModuleSectionDes> &des,
279 const uintptr_t &secAddr,
280 llvm::ELF::Elf64_Off &secOffset,
281 const llvm::ELF::Elf64_Off &moduleInfoOffset)
282 {
283 for (size_t i = 0; i < des.size(); ++i) {
284 auto moduleInfo = GetCurModuleInfo(i, moduleInfoOffset);
285 secOffset = AlignUp(secOffset, AOTFileInfo::PAGE_ALIGN);
286 uint32_t rodataSizeBeforeText = moduleInfo->rodataSizeBeforeText;
287 uint32_t rodataSizeAfterText = moduleInfo->rodataSizeAfterText;
288 if (rodataSizeBeforeText != 0) {
289 secOffset += rodataSizeBeforeText;
290 secOffset = AlignUp(secOffset, AOTFileInfo::TEXT_SEC_ALIGN);
291 }
292 uint32_t textSize = moduleInfo->textSize;
293 des[i].SetSecAddrAndSize(ElfSecName::TEXT, secAddr + secOffset, textSize);
294 secOffset += textSize;
295 if (rodataSizeAfterText != 0) {
296 secOffset = AlignUp(secOffset, AOTFileInfo::DATA_SEC_ALIGN);
297 secOffset += rodataSizeAfterText;
298 }
299 }
300 }
301
SeparateArkStackMapSections(std::vector<ModuleSectionDes> &des, const uintptr_t &secAddr, llvm::ELF::Elf64_Off &secOffset, const llvm::ELF::Elf64_Off &moduleInfoOffset)302 void ElfReader::SeparateArkStackMapSections(std::vector<ModuleSectionDes> &des,
303 const uintptr_t &secAddr,
304 llvm::ELF::Elf64_Off &secOffset,
305 const llvm::ELF::Elf64_Off &moduleInfoOffset)
306 {
307 for (size_t i = 0; i < des.size(); ++i) {
308 auto moduleInfo = GetCurModuleInfo(i, moduleInfoOffset);
309 uint32_t stackMapSize = moduleInfo->stackMapSize;
310 des[i].SetArkStackMapPtr(reinterpret_cast<uint8_t *>(secAddr + secOffset));
311 des[i].SetArkStackMapSize(stackMapSize);
312 uint32_t index = moduleInfo->startIndex;
313 uint32_t cnt = moduleInfo->funcCount;
314 des[i].SetStartIndex(index);
315 des[i].SetFuncCount(cnt);
316 secOffset += stackMapSize;
317 }
318 }
319
SeparateStrtabSections(std::vector<ModuleSectionDes> &des, const uintptr_t &secAddr, llvm::ELF::Elf64_Off &secOffset, const llvm::ELF::Elf64_Off &moduleInfoOffset)320 void ElfReader::SeparateStrtabSections(std::vector<ModuleSectionDes> &des,
321 const uintptr_t &secAddr,
322 llvm::ELF::Elf64_Off &secOffset,
323 const llvm::ELF::Elf64_Off &moduleInfoOffset)
324 {
325 for (size_t i = 0; i < des.size(); ++i) {
326 auto moduleInfo = GetCurModuleInfo(i, moduleInfoOffset);
327 uint32_t strtabSize = moduleInfo->strtabSize;
328 des[i].SetSecAddrAndSize(ElfSecName::STRTAB, secAddr + secOffset, strtabSize);
329 secOffset += strtabSize;
330 }
331 }
332
SeparateSymtabSections(std::vector<ModuleSectionDes> &des, const uintptr_t &secAddr, llvm::ELF::Elf64_Off &secOffset, const llvm::ELF::Elf64_Off &moduleInfoOffset)333 void ElfReader::SeparateSymtabSections(std::vector<ModuleSectionDes> &des,
334 const uintptr_t &secAddr,
335 llvm::ELF::Elf64_Off &secOffset,
336 const llvm::ELF::Elf64_Off &moduleInfoOffset)
337 {
338 for (size_t i = 0; i < des.size(); ++i) {
339 auto moduleInfo = GetCurModuleInfo(i, moduleInfoOffset);
340 uint32_t symtabSize = moduleInfo->symtabSize;
341 des[i].SetSecAddrAndSize(ElfSecName::SYMTAB, secAddr + secOffset, symtabSize);
342 secOffset += symtabSize;
343 }
344 }
345
SeparateTextSections(BinaryBufferParser &parser, std::vector<ModuleSectionDes> &des, const uint64_t &secAddr, llvm::ELF::Elf64_Off &secOffset, const llvm::ELF::Elf64_Off &curShOffset)346 void ElfReader::SeparateTextSections(BinaryBufferParser &parser,
347 std::vector<ModuleSectionDes> &des,
348 const uint64_t &secAddr,
349 llvm::ELF::Elf64_Off &secOffset,
350 const llvm::ELF::Elf64_Off &curShOffset)
351 {
352 for (size_t i = 0; i < des.size(); ++i) {
353 auto moduleInfo = moduleInfo_[i];
354 secOffset = AlignUp(secOffset, AOTFileInfo::PAGE_ALIGN);
355 uint32_t rodataSizeBeforeText = moduleInfo.rodataSizeBeforeText;
356 uint32_t rodataSizeAfterText = moduleInfo.rodataSizeAfterText;
357 if (rodataSizeBeforeText != 0) {
358 parser.ParseBuffer(reinterpret_cast<void *>(secAddr + secOffset), rodataSizeBeforeText,
359 curShOffset + secOffset);
360 secOffset += rodataSizeBeforeText;
361 secOffset = AlignUp(secOffset, AOTFileInfo::TEXT_SEC_ALIGN);
362 }
363 uint32_t textSize = moduleInfo.textSize;
364 parser.ParseBuffer(reinterpret_cast<void *>(secAddr + secOffset), textSize, curShOffset + secOffset);
365 des[i].SetSecAddrAndSize(ElfSecName::TEXT, secAddr + secOffset, textSize);
366 secOffset += textSize;
367 if (rodataSizeAfterText != 0) {
368 secOffset = AlignUp(secOffset, AOTFileInfo::DATA_SEC_ALIGN);
369 parser.ParseBuffer(reinterpret_cast<void *>(secAddr + secOffset), rodataSizeAfterText,
370 curShOffset + secOffset);
371 secOffset += rodataSizeAfterText;
372 }
373 }
374 }
375
SeparateArkStackMapSections(BinaryBufferParser &parser, std::vector<ModuleSectionDes> &des, const uint64_t &secAddr, llvm::ELF::Elf64_Off &secOffset, const llvm::ELF::Elf64_Off &curShOffset)376 void ElfReader::SeparateArkStackMapSections(BinaryBufferParser &parser,
377 std::vector<ModuleSectionDes> &des,
378 const uint64_t &secAddr,
379 llvm::ELF::Elf64_Off &secOffset,
380 const llvm::ELF::Elf64_Off &curShOffset)
381 {
382 for (size_t i = 0; i < des.size(); ++i) {
383 auto moduleInfo = moduleInfo_[i];
384 uint32_t stackMapSize = moduleInfo.stackMapSize;
385 parser.ParseBuffer(reinterpret_cast<void *>(secAddr + secOffset), stackMapSize, curShOffset + secOffset);
386 des[i].SetArkStackMapPtr(reinterpret_cast<uint8_t *>(secAddr + secOffset));
387 des[i].SetArkStackMapSize(stackMapSize);
388 uint32_t index = moduleInfo.startIndex;
389 uint32_t cnt = moduleInfo.funcCount;
390 des[i].SetStartIndex(index);
391 des[i].SetFuncCount(cnt);
392 secOffset += stackMapSize;
393 }
394 }
395
SeparateStrtabSections(BinaryBufferParser &parser, std::vector<ModuleSectionDes> &des, const uintptr_t &secAddr, llvm::ELF::Elf64_Off &secOffset, const llvm::ELF::Elf64_Off &curShOffset)396 void ElfReader::SeparateStrtabSections(BinaryBufferParser &parser,
397 std::vector<ModuleSectionDes> &des,
398 const uintptr_t &secAddr,
399 llvm::ELF::Elf64_Off &secOffset,
400 const llvm::ELF::Elf64_Off &curShOffset)
401 {
402 for (size_t i = 0; i < des.size(); ++i) {
403 auto moduleInfo = moduleInfo_[i];
404 uint32_t strtabSize = moduleInfo.strtabSize;
405 parser.ParseBuffer(reinterpret_cast<void *>(secAddr + secOffset), strtabSize, curShOffset + secOffset);
406 des[i].SetSecAddrAndSize(ElfSecName::STRTAB, secAddr + secOffset, strtabSize);
407 secOffset += strtabSize;
408 }
409 }
410
SeparateSymtabSections(BinaryBufferParser &parser, std::vector<ModuleSectionDes> &des, const uintptr_t &secAddr, llvm::ELF::Elf64_Off &secOffset, const llvm::ELF::Elf64_Off &curShOffset)411 void ElfReader::SeparateSymtabSections(BinaryBufferParser &parser,
412 std::vector<ModuleSectionDes> &des,
413 const uintptr_t &secAddr,
414 llvm::ELF::Elf64_Off &secOffset,
415 const llvm::ELF::Elf64_Off &curShOffset)
416 {
417 for (size_t i = 0; i < des.size(); ++i) {
418 auto moduleInfo = moduleInfo_[i];
419 uint32_t symtabSize = moduleInfo.symtabSize;
420 parser.ParseBuffer(reinterpret_cast<void *>(secAddr + secOffset), symtabSize, curShOffset + secOffset);
421 des[i].SetSecAddrAndSize(ElfSecName::SYMTAB, secAddr + secOffset, symtabSize);
422 secOffset += symtabSize;
423 }
424 }
425 } // namespace panda::ecmascript
426