14514f5e3Sopenharmony_ci/* 24514f5e3Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License. 54514f5e3Sopenharmony_ci * You may obtain a copy of the License at 64514f5e3Sopenharmony_ci * 74514f5e3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 84514f5e3Sopenharmony_ci * 94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and 134514f5e3Sopenharmony_ci * limitations under the License. 144514f5e3Sopenharmony_ci */ 154514f5e3Sopenharmony_ci 164514f5e3Sopenharmony_ci#ifndef ECMASCRIPT_JIT_DUMP_ELF_H 174514f5e3Sopenharmony_ci#define ECMASCRIPT_JIT_DUMP_ELF_H 184514f5e3Sopenharmony_ci 194514f5e3Sopenharmony_ci#include <vector> 204514f5e3Sopenharmony_ci#include <string> 214514f5e3Sopenharmony_ci#include <unistd.h> 224514f5e3Sopenharmony_ci#include <unordered_map> 234514f5e3Sopenharmony_ci 244514f5e3Sopenharmony_ci#include "ecmascript/compiler/codegen/maple/maple_be/include/cg/elf_types.h" 254514f5e3Sopenharmony_ci#include "ecmascript/log_wrapper.h" 264514f5e3Sopenharmony_ci 274514f5e3Sopenharmony_cinamespace panda::ecmascript { 284514f5e3Sopenharmony_ci 294514f5e3Sopenharmony_ciusing uint8 = uint8_t; 304514f5e3Sopenharmony_ciusing uint16 = uint16_t; 314514f5e3Sopenharmony_ciusing uint32 = uint32_t; 324514f5e3Sopenharmony_ciusing uint64 = uint64_t; 334514f5e3Sopenharmony_ciusing int8 = int8_t; 344514f5e3Sopenharmony_ciusing int16 = int16_t; 354514f5e3Sopenharmony_ciusing int32 = int32_t; 364514f5e3Sopenharmony_ciusing int64 = int64_t; 374514f5e3Sopenharmony_ciusing uintptr = uintptr_t; 384514f5e3Sopenharmony_ci 394514f5e3Sopenharmony_ciconst uint8 kLeftShift4Bits = 4; 404514f5e3Sopenharmony_cistatic const uint8 k8Bits = 8; 414514f5e3Sopenharmony_ci 424514f5e3Sopenharmony_ciclass Section { 434514f5e3Sopenharmony_cipublic: 444514f5e3Sopenharmony_ci Section(const std::string &name, maplebe::Word type, maplebe::Xword flags, maplebe::Xword align) : name(name) 454514f5e3Sopenharmony_ci { 464514f5e3Sopenharmony_ci sectionHeader.sh_type = type; 474514f5e3Sopenharmony_ci sectionHeader.sh_flags = flags; 484514f5e3Sopenharmony_ci sectionHeader.sh_addralign = align; 494514f5e3Sopenharmony_ci } 504514f5e3Sopenharmony_ci 514514f5e3Sopenharmony_ci virtual ~Section() = default; 524514f5e3Sopenharmony_ci virtual void GenerateData() = 0; 534514f5e3Sopenharmony_ci virtual void WriteSection(int fd) = 0; 544514f5e3Sopenharmony_ci 554514f5e3Sopenharmony_ci virtual void ClearData() 564514f5e3Sopenharmony_ci { 574514f5e3Sopenharmony_ci return; 584514f5e3Sopenharmony_ci } 594514f5e3Sopenharmony_ci 604514f5e3Sopenharmony_ci void SetIndex(maplebe::SectionIndex idx) 614514f5e3Sopenharmony_ci { 624514f5e3Sopenharmony_ci sectionIndex = idx; 634514f5e3Sopenharmony_ci } 644514f5e3Sopenharmony_ci 654514f5e3Sopenharmony_ci maplebe::SectionIndex GetIndex() const 664514f5e3Sopenharmony_ci { 674514f5e3Sopenharmony_ci return sectionIndex; 684514f5e3Sopenharmony_ci } 694514f5e3Sopenharmony_ci 704514f5e3Sopenharmony_ci void SetInfo(maplebe::Word value) 714514f5e3Sopenharmony_ci { 724514f5e3Sopenharmony_ci sectionHeader.sh_info = value; 734514f5e3Sopenharmony_ci } 744514f5e3Sopenharmony_ci 754514f5e3Sopenharmony_ci void SetLink(const Section §ion) 764514f5e3Sopenharmony_ci { 774514f5e3Sopenharmony_ci sectionHeader.sh_link = static_cast<maplebe::Word>(section.GetIndex()); 784514f5e3Sopenharmony_ci } 794514f5e3Sopenharmony_ci 804514f5e3Sopenharmony_ci void SetEntSize(maplebe::Xword value) 814514f5e3Sopenharmony_ci { 824514f5e3Sopenharmony_ci sectionHeader.sh_entsize = value; 834514f5e3Sopenharmony_ci } 844514f5e3Sopenharmony_ci 854514f5e3Sopenharmony_ci void SetSectionSize(maplebe::Xword size) 864514f5e3Sopenharmony_ci { 874514f5e3Sopenharmony_ci sectionHeader.sh_size = size; 884514f5e3Sopenharmony_ci } 894514f5e3Sopenharmony_ci 904514f5e3Sopenharmony_ci virtual maplebe::Xword GetSectionSize() 914514f5e3Sopenharmony_ci { 924514f5e3Sopenharmony_ci return sectionHeader.sh_size; 934514f5e3Sopenharmony_ci } 944514f5e3Sopenharmony_ci 954514f5e3Sopenharmony_ci void SetAddr(maplebe::Address addr) 964514f5e3Sopenharmony_ci { 974514f5e3Sopenharmony_ci sectionHeader.sh_addr = addr; 984514f5e3Sopenharmony_ci } 994514f5e3Sopenharmony_ci 1004514f5e3Sopenharmony_ci maplebe::Address GetAddr() const 1014514f5e3Sopenharmony_ci { 1024514f5e3Sopenharmony_ci return sectionHeader.sh_addr; 1034514f5e3Sopenharmony_ci } 1044514f5e3Sopenharmony_ci 1054514f5e3Sopenharmony_ci maplebe::Xword GetFlags() const 1064514f5e3Sopenharmony_ci { 1074514f5e3Sopenharmony_ci return sectionHeader.sh_flags; 1084514f5e3Sopenharmony_ci } 1094514f5e3Sopenharmony_ci 1104514f5e3Sopenharmony_ci void SetOffset(maplebe::Offset value) 1114514f5e3Sopenharmony_ci { 1124514f5e3Sopenharmony_ci sectionHeader.sh_offset = value; 1134514f5e3Sopenharmony_ci } 1144514f5e3Sopenharmony_ci 1154514f5e3Sopenharmony_ci maplebe::Offset GetOffset() const 1164514f5e3Sopenharmony_ci { 1174514f5e3Sopenharmony_ci return sectionHeader.sh_offset; 1184514f5e3Sopenharmony_ci } 1194514f5e3Sopenharmony_ci 1204514f5e3Sopenharmony_ci maplebe::Xword GetAlign() const 1214514f5e3Sopenharmony_ci { 1224514f5e3Sopenharmony_ci return sectionHeader.sh_addralign; 1234514f5e3Sopenharmony_ci } 1244514f5e3Sopenharmony_ci 1254514f5e3Sopenharmony_ci const std::string &GetName() const 1264514f5e3Sopenharmony_ci { 1274514f5e3Sopenharmony_ci return name; 1284514f5e3Sopenharmony_ci } 1294514f5e3Sopenharmony_ci 1304514f5e3Sopenharmony_ci void SetSectionHeaderNameIndex(maplebe::Word index) 1314514f5e3Sopenharmony_ci { 1324514f5e3Sopenharmony_ci sectionHeader.sh_name = index; 1334514f5e3Sopenharmony_ci } 1344514f5e3Sopenharmony_ci 1354514f5e3Sopenharmony_ci maplebe::Word GetType() const 1364514f5e3Sopenharmony_ci { 1374514f5e3Sopenharmony_ci return sectionHeader.sh_type; 1384514f5e3Sopenharmony_ci } 1394514f5e3Sopenharmony_ci 1404514f5e3Sopenharmony_ci const maplebe::SectionHeader &GetSectionHeader() const 1414514f5e3Sopenharmony_ci { 1424514f5e3Sopenharmony_ci return sectionHeader; 1434514f5e3Sopenharmony_ci } 1444514f5e3Sopenharmony_ci 1454514f5e3Sopenharmony_ciprivate: 1464514f5e3Sopenharmony_ci std::string name; 1474514f5e3Sopenharmony_ci maplebe::SectionIndex sectionIndex {}; 1484514f5e3Sopenharmony_ci maplebe::SectionHeader sectionHeader {}; 1494514f5e3Sopenharmony_ci}; /* class Section */ 1504514f5e3Sopenharmony_ci 1514514f5e3Sopenharmony_ciclass RelaSection : public Section { 1524514f5e3Sopenharmony_cipublic: 1534514f5e3Sopenharmony_ci RelaSection(const std::string &name, maplebe::Word type, maplebe::Xword flags, maplebe::Word info, 1544514f5e3Sopenharmony_ci maplebe::Xword align, const Section &link) : Section(name, type, flags, align) 1554514f5e3Sopenharmony_ci { 1564514f5e3Sopenharmony_ci SetEntSize(sizeof(maplebe::Rela)); 1574514f5e3Sopenharmony_ci SetInfo(info); 1584514f5e3Sopenharmony_ci SetLink(link); 1594514f5e3Sopenharmony_ci } 1604514f5e3Sopenharmony_ci 1614514f5e3Sopenharmony_ci ~RelaSection() = default; 1624514f5e3Sopenharmony_ci 1634514f5e3Sopenharmony_ci void GenerateData() override 1644514f5e3Sopenharmony_ci { 1654514f5e3Sopenharmony_ci SetSectionSize(relas.size() * sizeof(maplebe::Rela)); 1664514f5e3Sopenharmony_ci } 1674514f5e3Sopenharmony_ci 1684514f5e3Sopenharmony_ci void WriteSection(int fd) override 1694514f5e3Sopenharmony_ci { 1704514f5e3Sopenharmony_ci (void)write(fd, reinterpret_cast<const char *>(relas.data()), relas.size() * sizeof(maplebe::Rela)); 1714514f5e3Sopenharmony_ci } 1724514f5e3Sopenharmony_ci 1734514f5e3Sopenharmony_ci void AppendRela(maplebe::Rela rela) 1744514f5e3Sopenharmony_ci { 1754514f5e3Sopenharmony_ci relas.push_back(rela); 1764514f5e3Sopenharmony_ci } 1774514f5e3Sopenharmony_ci 1784514f5e3Sopenharmony_ciprivate: 1794514f5e3Sopenharmony_ci std::vector<maplebe::Rela> relas; 1804514f5e3Sopenharmony_ci}; /* class RelaSection */ 1814514f5e3Sopenharmony_ci 1824514f5e3Sopenharmony_ciclass SymbolSection : public Section { 1834514f5e3Sopenharmony_cipublic: 1844514f5e3Sopenharmony_ci SymbolSection(const std::string &name, maplebe::Word type, maplebe::Xword flags, maplebe::Xword align, 1854514f5e3Sopenharmony_ci const Section &link) : Section(name, type, flags, align) 1864514f5e3Sopenharmony_ci { 1874514f5e3Sopenharmony_ci SetEntSize(sizeof(maplebe::Symbol)); 1884514f5e3Sopenharmony_ci SetLink(link); 1894514f5e3Sopenharmony_ci SetInfo(1); 1904514f5e3Sopenharmony_ci AppendSymbol({0, 0, 0, 0, 0, 0}); 1914514f5e3Sopenharmony_ci } 1924514f5e3Sopenharmony_ci 1934514f5e3Sopenharmony_ci ~SymbolSection() = default; 1944514f5e3Sopenharmony_ci 1954514f5e3Sopenharmony_ci void GenerateData() override 1964514f5e3Sopenharmony_ci { 1974514f5e3Sopenharmony_ci SetSectionSize(symbols.size() * sizeof(maplebe::Symbol)); 1984514f5e3Sopenharmony_ci } 1994514f5e3Sopenharmony_ci 2004514f5e3Sopenharmony_ci void WriteSection(int fd) override 2014514f5e3Sopenharmony_ci { 2024514f5e3Sopenharmony_ci (void)write(fd, reinterpret_cast<const char *>(symbols.data()), symbols.size() * sizeof(maplebe::Symbol)); 2034514f5e3Sopenharmony_ci } 2044514f5e3Sopenharmony_ci 2054514f5e3Sopenharmony_ci void AppendSymbol(const maplebe::Symbol &symbol) 2064514f5e3Sopenharmony_ci { 2074514f5e3Sopenharmony_ci symbols.push_back(symbol); 2084514f5e3Sopenharmony_ci } 2094514f5e3Sopenharmony_ci 2104514f5e3Sopenharmony_ci uint32 GetSymbolsSize() const 2114514f5e3Sopenharmony_ci { 2124514f5e3Sopenharmony_ci return symbols.size(); 2134514f5e3Sopenharmony_ci } 2144514f5e3Sopenharmony_ci 2154514f5e3Sopenharmony_ci uint64 GetIdxInSymbols(int64 symIdx) const 2164514f5e3Sopenharmony_ci { 2174514f5e3Sopenharmony_ci return symbolIdxMap.at(symIdx); 2184514f5e3Sopenharmony_ci } 2194514f5e3Sopenharmony_ci 2204514f5e3Sopenharmony_ci void AppendIdxInSymbols(int64 symIdx) 2214514f5e3Sopenharmony_ci { 2224514f5e3Sopenharmony_ci symbolIdxMap[symIdx] = static_cast<uint64>(GetSymbolsSize() - 1); 2234514f5e3Sopenharmony_ci } 2244514f5e3Sopenharmony_ci 2254514f5e3Sopenharmony_ci bool ExistSymInSymbols(int64 symIdx) 2264514f5e3Sopenharmony_ci { 2274514f5e3Sopenharmony_ci return symbolIdxMap.count(symIdx) != 0; 2284514f5e3Sopenharmony_ci } 2294514f5e3Sopenharmony_ci 2304514f5e3Sopenharmony_ci uint32 GetDataSize() const 2314514f5e3Sopenharmony_ci { 2324514f5e3Sopenharmony_ci return symbols.size() * sizeof(maplebe::Symbol); 2334514f5e3Sopenharmony_ci } 2344514f5e3Sopenharmony_ci 2354514f5e3Sopenharmony_ci const char *GetAddr() 2364514f5e3Sopenharmony_ci { 2374514f5e3Sopenharmony_ci return reinterpret_cast<const char*>(symbols.data()); 2384514f5e3Sopenharmony_ci } 2394514f5e3Sopenharmony_ci 2404514f5e3Sopenharmony_ci void ClearData() override 2414514f5e3Sopenharmony_ci { 2424514f5e3Sopenharmony_ci symbols.clear(); 2434514f5e3Sopenharmony_ci symbolIdxMap.clear(); 2444514f5e3Sopenharmony_ci } 2454514f5e3Sopenharmony_ci 2464514f5e3Sopenharmony_ciprivate: 2474514f5e3Sopenharmony_ci std::vector<maplebe::Symbol> symbols; 2484514f5e3Sopenharmony_ci std::unordered_map<int64, uint64> symbolIdxMap; 2494514f5e3Sopenharmony_ci}; /* class SymbolSection */ 2504514f5e3Sopenharmony_ci 2514514f5e3Sopenharmony_ciclass DataSection : public Section { 2524514f5e3Sopenharmony_cipublic: 2534514f5e3Sopenharmony_ci DataSection(const std::string &name, maplebe::Word type, maplebe::Xword flags, maplebe::Xword align) 2544514f5e3Sopenharmony_ci : Section(name, type, flags, align) {} 2554514f5e3Sopenharmony_ci 2564514f5e3Sopenharmony_ci ~DataSection() = default; 2574514f5e3Sopenharmony_ci 2584514f5e3Sopenharmony_ci virtual void GenerateData() override 2594514f5e3Sopenharmony_ci { 2604514f5e3Sopenharmony_ci SetSectionSize(data.size()); 2614514f5e3Sopenharmony_ci } 2624514f5e3Sopenharmony_ci 2634514f5e3Sopenharmony_ci virtual void WriteSection(int fd) override 2644514f5e3Sopenharmony_ci { 2654514f5e3Sopenharmony_ci (void)write(fd, reinterpret_cast<const char *>(data.data()), data.size()); 2664514f5e3Sopenharmony_ci } 2674514f5e3Sopenharmony_ci 2684514f5e3Sopenharmony_ci void AppendData(const void *value, size_t size) 2694514f5e3Sopenharmony_ci { 2704514f5e3Sopenharmony_ci auto pdata = reinterpret_cast<const uint8 *>(value); 2714514f5e3Sopenharmony_ci data.insert(data.end(), pdata, pdata + size); 2724514f5e3Sopenharmony_ci } 2734514f5e3Sopenharmony_ci 2744514f5e3Sopenharmony_ci void AppendData(int64 value, size_t size) 2754514f5e3Sopenharmony_ci { 2764514f5e3Sopenharmony_ci for (size_t i = 0; i < size; i++) { 2774514f5e3Sopenharmony_ci auto pdata = static_cast<uint8>(value >> (i * k8Bits)); 2784514f5e3Sopenharmony_ci data.push_back(pdata); 2794514f5e3Sopenharmony_ci } 2804514f5e3Sopenharmony_ci } 2814514f5e3Sopenharmony_ci 2824514f5e3Sopenharmony_ci void ClearData() override 2834514f5e3Sopenharmony_ci { 2844514f5e3Sopenharmony_ci data.clear(); 2854514f5e3Sopenharmony_ci } 2864514f5e3Sopenharmony_ci 2874514f5e3Sopenharmony_ci uint32 GetDataSize() const 2884514f5e3Sopenharmony_ci { 2894514f5e3Sopenharmony_ci return data.size(); 2904514f5e3Sopenharmony_ci } 2914514f5e3Sopenharmony_ci 2924514f5e3Sopenharmony_ci const std::vector<uint8> &GetData() const 2934514f5e3Sopenharmony_ci { 2944514f5e3Sopenharmony_ci return data; 2954514f5e3Sopenharmony_ci } 2964514f5e3Sopenharmony_ci 2974514f5e3Sopenharmony_ciprotected: 2984514f5e3Sopenharmony_ci std::vector<uint8> data; 2994514f5e3Sopenharmony_ci}; /* class DataSection */ 3004514f5e3Sopenharmony_ci 3014514f5e3Sopenharmony_ciclass StringSection : public DataSection { 3024514f5e3Sopenharmony_cipublic: 3034514f5e3Sopenharmony_ci StringSection(const std::string &name, maplebe::Word type, maplebe::Xword flags, maplebe::Xword align) 3044514f5e3Sopenharmony_ci : DataSection(name, type, flags, align) 3054514f5e3Sopenharmony_ci { 3064514f5e3Sopenharmony_ci AddString("\0"); 3074514f5e3Sopenharmony_ci } 3084514f5e3Sopenharmony_ci 3094514f5e3Sopenharmony_ci ~StringSection() = default; 3104514f5e3Sopenharmony_ci 3114514f5e3Sopenharmony_ci size_t AddString(const std::string &str) 3124514f5e3Sopenharmony_ci { 3134514f5e3Sopenharmony_ci size_t pos = data.size(); 3144514f5e3Sopenharmony_ci AppendData(str.c_str(), str.size() + 1); 3154514f5e3Sopenharmony_ci return pos; 3164514f5e3Sopenharmony_ci } 3174514f5e3Sopenharmony_ci}; /* class StringSection */ 3184514f5e3Sopenharmony_ci 3194514f5e3Sopenharmony_ciclass Alignment { 3204514f5e3Sopenharmony_cipublic: 3214514f5e3Sopenharmony_ci template <typename T> 3224514f5e3Sopenharmony_ci static T Align(T offset, T align) 3234514f5e3Sopenharmony_ci { 3244514f5e3Sopenharmony_ci if (align <= 1) { 3254514f5e3Sopenharmony_ci return offset; 3264514f5e3Sopenharmony_ci } 3274514f5e3Sopenharmony_ci return (offset + align - 1) & (~(align - 1)); 3284514f5e3Sopenharmony_ci } 3294514f5e3Sopenharmony_ci}; /* class Alignment */ 3304514f5e3Sopenharmony_ci 3314514f5e3Sopenharmony_ciclass JsJitDumpElf { 3324514f5e3Sopenharmony_cipublic: 3334514f5e3Sopenharmony_ci void Init(); 3344514f5e3Sopenharmony_ci void SetFileOffset(int fd, uint64 offset); 3354514f5e3Sopenharmony_ci void Initx86ElfHeader(); 3364514f5e3Sopenharmony_ci void InitArmElfHeader(); 3374514f5e3Sopenharmony_ci void WriteJitElfFile(int fd); 3384514f5e3Sopenharmony_ci void LayoutSections(); 3394514f5e3Sopenharmony_ci void UpdateSectionOffset(Section §ion); 3404514f5e3Sopenharmony_ci void UpdateGlobalOffset(Section §ion); 3414514f5e3Sopenharmony_ci void RegisterSection(Section §ion); 3424514f5e3Sopenharmony_ci void AppendData(std::vector<uint8> &codeBuff); 3434514f5e3Sopenharmony_ci void AddSymToSymTab(const maplebe::Symbol &symbol, int64 symIdx); 3444514f5e3Sopenharmony_ci void AppendGlobalSymsToSymTabSec(); 3454514f5e3Sopenharmony_ci void AppendSymbolToSymTab(int64 symIdx, uint64 funcSymValue, uint64 funcSymSize, const std::string &symbolName); 3464514f5e3Sopenharmony_ci void ClearData(); 3474514f5e3Sopenharmony_ciprivate: 3484514f5e3Sopenharmony_ci std::vector<std::pair<maplebe::Symbol, int64>> localSymTab; 3494514f5e3Sopenharmony_ci DataSection *textSection = nullptr; 3504514f5e3Sopenharmony_ci SymbolSection *symbolTabSection = nullptr; 3514514f5e3Sopenharmony_ci maplebe::FileHeader header {}; 3524514f5e3Sopenharmony_ci StringSection *strTabSection = nullptr; 3534514f5e3Sopenharmony_ci std::vector<Section *> sections; 3544514f5e3Sopenharmony_ci maplebe::Offset globalOffset = 0; /* global offset of the elf file */ 3554514f5e3Sopenharmony_ci}; 3564514f5e3Sopenharmony_ci 3574514f5e3Sopenharmony_ci} // namespace panda::ecmascript 3584514f5e3Sopenharmony_ci#endif // ECMASCRIPT_JIT_DUMP_ELF_H 359