1 /** 2 * Copyright (c) 2021-2024 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 LIBPANDAFILE_PANDA_FILE_SUPPORT_H 17 #define LIBPANDAFILE_PANDA_FILE_SUPPORT_H 18 #include "file_ext.h" 19 #include <vector> 20 #include <memory> 21 22 namespace panda_api::panda_file { 23 24 #ifdef __cplusplus 25 extern "C" { 26 #endif 27 28 void LoadPandFileExt(); 29 30 #ifdef __cplusplus 31 } // extern "C" 32 #endif 33 34 // NOLINTNEXTLINE(cppcoreguidelines-special-member-functions, hicpp-special-member-functions) 35 class PandaFileWrapper { 36 public: OpenPandafileFromMemory(void * addr,uint64_t * size,const std::string & fileName)37 static std::unique_ptr<PandaFileWrapper> OpenPandafileFromMemory(void *addr, uint64_t *size, 38 const std::string &fileName) 39 { 40 if (pOpenPandafileFromMemoryExt == nullptr) { 41 LoadPandFileExt(); 42 } 43 44 PandaFileExt *pfExt = nullptr; 45 std::unique_ptr<PandaFileWrapper> pfw; 46 auto ret = pOpenPandafileFromMemoryExt(addr, size, fileName, &pfExt); 47 if (ret) { 48 pfw.reset(new PandaFileWrapper(pfExt)); 49 } 50 return pfw; 51 } 52 OpenPandafileFromFd(int fd,uint64_t offset,const std::string & fileName)53 static std::unique_ptr<PandaFileWrapper> OpenPandafileFromFd(int fd, uint64_t offset, const std::string &fileName) 54 { 55 if (pOpenPandafileFromFdExt == nullptr) { 56 LoadPandFileExt(); 57 } 58 59 PandaFileExt *pfExt = nullptr; 60 std::unique_ptr<PandaFileWrapper> pfw; 61 auto ret = pOpenPandafileFromFdExt(fd, offset, fileName, &pfExt); 62 if (ret) { 63 pfw.reset(new PandaFileWrapper(pfExt)); 64 } 65 return pfw; 66 } 67 QueryMethodSymByOffset(uint64_t offset)68 MethodSymInfoExt QueryMethodSymByOffset(uint64_t offset) 69 { 70 MethodSymInfoExt methodInfo {0, 0, std::string()}; 71 if (pQueryMethodSymByOffsetExt == nullptr) { 72 return {0, 0, std::string()}; 73 } 74 auto ret = pQueryMethodSymByOffsetExt(pfExt_, offset, &methodInfo); 75 if (ret) { 76 return methodInfo; 77 } 78 return {0, 0, std::string()}; 79 } 80 QueryMethodSymAndLineByOffset(uint64_t offset)81 MethodSymInfoExt QueryMethodSymAndLineByOffset(uint64_t offset) const 82 { 83 MethodSymInfoExt methodInfo {0, 0, std::string()}; 84 if (pQueryMethodSymAndLineByOffsetExt == nullptr) { 85 return {0, 0, std::string()}; 86 } 87 auto ret = pQueryMethodSymAndLineByOffsetExt(pfExt_, offset, &methodInfo); 88 if (ret) { 89 return methodInfo; 90 } 91 return {0, 0, std::string()}; 92 } 93 QueryAllMethodSyms()94 std::vector<MethodSymInfoExt> QueryAllMethodSyms() 95 { 96 std::vector<MethodSymInfoExt> methodInfos; 97 if (pQueryAllMethodSymsExt == nullptr) { 98 return methodInfos; 99 } 100 pQueryAllMethodSymsExt(pfExt_, AppendMethodInfo, static_cast<void *>(&methodInfos)); 101 return methodInfos; 102 } 103 104 // NOLINTNEXTLINE(readability-identifier-naming) 105 static decltype(OpenPandafileFromFdExt) *pOpenPandafileFromFdExt; 106 // NOLINTNEXTLINE(readability-identifier-naming) 107 static decltype(OpenPandafileFromMemoryExt) *pOpenPandafileFromMemoryExt; 108 // NOLINTNEXTLINE(readability-identifier-naming) 109 static decltype(QueryMethodSymByOffsetExt) *pQueryMethodSymByOffsetExt; 110 // NOLINTNEXTLINE(readability-identifier-naming) 111 static decltype(QueryMethodSymAndLineByOffsetExt) *pQueryMethodSymAndLineByOffsetExt; 112 // NOLINTNEXTLINE(readability-identifier-naming) 113 static decltype(QueryAllMethodSymsExt) *pQueryAllMethodSymsExt; 114 115 ~PandaFileWrapper() = default; 116 117 private: PandaFileWrapper(PandaFileExt * pfExt)118 explicit PandaFileWrapper(PandaFileExt *pfExt) : pfExt_(pfExt) {} 119 PandaFileExt *pfExt_; 120 121 // callback AppendMethodInfo(MethodSymInfoExt * methodInfo,void * userData)122 static void AppendMethodInfo(MethodSymInfoExt *methodInfo, void *userData) 123 { 124 auto methodInfos = reinterpret_cast<std::vector<MethodSymInfoExt> *>(userData); 125 methodInfos->push_back(*methodInfo); 126 } 127 128 friend void LoadPandFileExt(); 129 }; 130 131 } // namespace panda_api::panda_file 132 133 #endif 134