1 /* 2 * Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. 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 HIPERF_SYMBOLS_H 17 #define HIPERF_SYMBOLS_H 18 19 #include <cinttypes> 20 #include <iomanip> 21 #include <sstream> 22 #include <string> 23 #include "dfx_elf.h" 24 #include "dfx_symbol.h" 25 #include "perf_file_format.h" 26 #include "utilities.h" 27 28 #define HIPERF_ELF_READ_USE_MMAP 29 30 namespace OHOS { 31 namespace Developtools { 32 namespace NativeDaemon { 33 using namespace OHOS::HiviewDFX; 34 35 constexpr const char KERNEL_MMAP_NAME[] = "[kernel.kallsyms]"; 36 constexpr const char KERNEL_MODULES_EXT_NAME[] = ".ko"; 37 constexpr const char KERNEL_ELF_NAME[] = "vmlinux"; 38 constexpr const char MMAP_VDSO_NAME[] = "[vdso]"; 39 constexpr const char MMAP_ANONYMOUS_NAME[] = "[anon]"; 40 constexpr const char MMAP_ANONYMOUS_OHOS_NAME[] = "//anon"; 41 const std::string NOTE_GNU_BUILD_ID = ".note.gnu.build-id"; 42 const std::string EH_FRAME_HR = ".eh_frame_hdr"; 43 const std::string EH_FRAME = ".eh_frame"; 44 const std::string ARM_EXIDX = ".ARM.exidx"; 45 const std::string SYMTAB = ".symtab"; 46 const std::string DYNSYM = ".dynsym"; 47 const std::string GNU_DEBUGDATA = ".gnu_debugdata"; 48 const std::string PLT = ".plt"; 49 const std::string LINKER_PREFIX = "__dl_"; 50 const std::string LINKER_PREFIX_NAME = "[linker]"; 51 52 const int MAX_SYMBOLS_TYPE_NAME_LEN = 10; 53 54 class FileSymbol { 55 [[maybe_unused]] uint64_t vaddr_ = 0; 56 [[maybe_unused]] uint64_t len_ = 0; 57 std::string name_ = ""; 58 std::string demangle_ = ""; // demangle string FileSymbol(uint64_t vaddr,uint64_t len,const char * name,const char * demangle)59 FileSymbol(uint64_t vaddr, uint64_t len, const char *name, const char *demangle) 60 : vaddr_(vaddr), len_(len), name_(name), demangle_(demangle) 61 { 62 } 63 }; 64 65 enum SymbolsFileType { 66 SYMBOL_KERNEL_FILE, 67 SYMBOL_KERNEL_MODULE_FILE, 68 SYMBOL_ELF_FILE, 69 SYMBOL_JAVA_FILE, 70 SYMBOL_JS_FILE, 71 SYMBOL_HAP_FILE, 72 SYMBOL_UNKNOW_FILE, 73 }; 74 75 class SymbolsFile { 76 public: 77 SymbolsFileType symbolFileType_; 78 std::string filePath_ = ""; 79 80 // [14] .text PROGBITS 00000000002c5000 000c5000 81 // min exec addr , general it point to .text 82 // we make a default value for min compare 83 static const uint64_t maxVaddr = std::numeric_limits<uint64_t>::max(); 84 85 uint64_t textExecVaddr_ = maxVaddr; 86 uint64_t textExecVaddrFileOffset_ = 0; 87 uint64_t textExecVaddrRange_ = maxVaddr; 88 std::shared_ptr<DfxMap> map_ = nullptr; 89 SymbolsFile(SymbolsFileType symbolType,const std::string path)90 SymbolsFile(SymbolsFileType symbolType, const std::string path) 91 : symbolFileType_(symbolType), filePath_(path) {}; 92 virtual ~SymbolsFile(); 93 GetElfFile()94 virtual std::shared_ptr<DfxElf> GetElfFile() 95 { 96 return nullptr; 97 } 98 99 // create the symbols file object 100 static std::unique_ptr<SymbolsFile> CreateSymbolsFile( 101 SymbolsFileType = SYMBOL_UNKNOW_FILE, const std::string symbolFilePath = EMPTY_STRING, pid_t pid = 0); 102 static std::unique_ptr<SymbolsFile> CreateSymbolsFile(const std::string &symbolFilePath, pid_t pid = 0); 103 104 // set symbols path setSymbolsFilePath(const std::string & symbolsSearchPath)105 bool setSymbolsFilePath(const std::string &symbolsSearchPath) 106 { 107 std::vector<std::string> symbolsSearchPaths = {symbolsSearchPath}; 108 return setSymbolsFilePath(symbolsSearchPaths); 109 }; 110 bool setSymbolsFilePath(const std::vector<std::string> &); IsAbc()111 virtual bool IsAbc() 112 { 113 return false; 114 } 115 virtual void SetBoolValue(bool value); 116 // load symbol from file 117 virtual bool LoadSymbols([[maybe_unused]] std::shared_ptr<DfxMap> map = nullptr, 118 [[maybe_unused]] const std::string &symbolFilePath = EMPTY_STRING) 119 { 120 HLOGV("virtual dummy function called"); 121 symbolsLoaded_ = true; 122 return false; 123 }; 124 // load debug infor for unwind 125 virtual bool LoadDebugInfo([[maybe_unused]] std::shared_ptr<DfxMap> map = nullptr, 126 [[maybe_unused]] const std::string &symbolFilePath = EMPTY_STRING) 127 { 128 HLOGV("virtual dummy function called"); 129 debugInfoLoaded_ = true; 130 return false; 131 }; 132 // get the build if from symbols 133 const std::string GetBuildId() const; 134 135 // get the symbols vector 136 const std::vector<DfxSymbol> &GetSymbols(); 137 const std::vector<DfxSymbol *> &GetMatchedSymbols(); 138 139 // get vaddr(in symbol) from ip(real addr , after mmap reloc) 140 virtual uint64_t GetVaddrInSymbols(uint64_t ip, uint64_t mapStart, uint64_t mapOffset) const; 141 const DfxSymbol GetSymbolWithVaddr(uint64_t vaddr); 142 143 // get the section info , like .ARM.exidx GetSectionInfo(const std::string & name,uint64_t & sectionVaddr,uint64_t & sectionSize,uint64_t & sectionFileOffset)144 virtual bool GetSectionInfo([[maybe_unused]] const std::string &name, 145 [[maybe_unused]] uint64_t §ionVaddr, 146 [[maybe_unused]] uint64_t §ionSize, 147 [[maybe_unused]] uint64_t §ionFileOffset) const 148 { 149 HLOGV("virtual dummy function called"); 150 return false; 151 } 152 #ifndef __arm__ 153 // get hdr info for unwind , need provide the fde table location and entry count GetHDRSectionInfo(uint64_t & ehFrameHdrElfOffset,uint64_t & fdeTableElfOffset,uint64_t & fdeTableSize)154 virtual bool GetHDRSectionInfo([[maybe_unused]] uint64_t &ehFrameHdrElfOffset, 155 [[maybe_unused]] uint64_t &fdeTableElfOffset, 156 [[maybe_unused]] uint64_t &fdeTableSize) 157 { 158 HLOGV("virtual dummy function called"); 159 return false; 160 } 161 #endif 162 // load from symbols from the perf.data format 163 static std::unique_ptr<SymbolsFile> LoadSymbolsFromSaved(const SymbolFileStruct &); 164 // save the symbols to perf.data format 165 void ExportSymbolToFileFormat(SymbolFileStruct &symbolFileStruct); 166 SymbolsLoaded()167 bool SymbolsLoaded() 168 { 169 return symbolsLoaded_; 170 } 171 172 // this means we are in recording 173 // will try read some elf in runtime path 174 static bool onRecording_; 175 std::vector<DfxSymbol> symbols_ {}; 176 std::vector<DfxSymbol *> matchedSymbols_ {}; 177 std::map<uint64_t, DfxSymbol> symbolsMap_; GetSymbolWithPcAndMap(uint64_t pc,std::shared_ptr<DfxMap> map)178 virtual DfxSymbol GetSymbolWithPcAndMap(uint64_t pc, std::shared_ptr<DfxMap> map) 179 { 180 return DfxSymbol(); 181 } 182 183 // set map info SetMapsInfo(std::shared_ptr<DfxMap> map)184 void SetMapsInfo(std::shared_ptr<DfxMap> map) 185 { 186 map_ = map; 187 } 188 protected: 189 bool symbolsLoaded_ = false; 190 bool symbolsLoadResult_ = false; 191 bool debugInfoLoaded_ = false; 192 bool debugInfoLoadResult_ = false; 193 const std::string FindSymbolFile(const std::vector<std::string> &, 194 std::string symboleFilePath = EMPTY_STRING) const; 195 196 std::string SearchReadableFile(const std::vector<std::string> &searchPaths, 197 const std::string &filePath) const; 198 bool UpdateBuildIdIfMatch(std::string buildId); 199 std::string buildId_ = ""; 200 std::vector<std::string> symbolsFileSearchPaths_; 201 202 std::vector<FileSymbol> fileSymbols_ {}; 203 204 void AdjustSymbols(); 205 void SortMatchedSymbols(); 206 bool CheckPathReadable(const std::string &path) const; 207 }; 208 209 class CCompareSymbolsFile { 210 public: operator()211 bool operator() (const std::unique_ptr<SymbolsFile>& left, const std::unique_ptr<SymbolsFile>& right) const 212 { 213 return left->filePath_ < right->filePath_; 214 } 215 }; 216 } // namespace NativeDaemon 217 } // namespace Developtools 218 } // namespace OHOS 219 #endif