• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &sectionVaddr,
146                                 [[maybe_unused]] uint64_t &sectionSize,
147                                 [[maybe_unused]] uint64_t &sectionFileOffset) 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