1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef SIMPLE_PERF_DSO_H_ 18 #define SIMPLE_PERF_DSO_H_ 19 20 #include <memory> 21 #include <string> 22 #include <unordered_map> 23 #include <vector> 24 25 #include <android-base/test_utils.h> 26 27 #include "build_id.h" 28 #include "read_elf.h" 29 30 struct Symbol { 31 uint64_t addr; 32 // TODO: make len uint32_t. 33 uint64_t len; 34 35 Symbol(const std::string& name, uint64_t addr, uint64_t len); NameSymbol36 const char* Name() const { return name_; } 37 38 const char* DemangledName() const; 39 HasDumpIdSymbol40 bool HasDumpId() const { 41 return dump_id_ != UINT_MAX; 42 } 43 GetDumpIdSymbol44 bool GetDumpId(uint32_t* pdump_id) const { 45 if (!HasDumpId()) { 46 return false; 47 } 48 *pdump_id = dump_id_; 49 return true; 50 } 51 CompareByDumpIdSymbol52 static bool CompareByDumpId(const Symbol* s1, const Symbol* s2) { 53 uint32_t id1 = UINT_MAX; 54 s1->GetDumpId(&id1); 55 uint32_t id2 = UINT_MAX; 56 s2->GetDumpId(&id2); 57 return id1 < id2; 58 } 59 CompareByAddrSymbol60 static bool CompareByAddr(const Symbol* s1, const Symbol* s2) { 61 return s1->addr < s2->addr; 62 } 63 CompareValueByAddrSymbol64 static bool CompareValueByAddr(const Symbol& s1, const Symbol& s2) { 65 return s1.addr < s2.addr; 66 } 67 68 private: 69 const char* name_; 70 mutable const char* demangled_name_; 71 mutable uint32_t dump_id_; 72 73 friend class Dso; 74 }; 75 76 enum DsoType { 77 DSO_KERNEL, 78 DSO_KERNEL_MODULE, 79 DSO_ELF_FILE, 80 }; 81 82 struct KernelSymbol; 83 struct ElfFileSymbol; 84 85 class Dso { 86 public: 87 static void SetDemangle(bool demangle); 88 static std::string Demangle(const std::string& name); 89 static bool SetSymFsDir(const std::string& symfs_dir); 90 static void SetVmlinux(const std::string& vmlinux); SetKallsyms(std::string kallsyms)91 static void SetKallsyms(std::string kallsyms) { 92 if (!kallsyms.empty()) { 93 kallsyms_ = std::move(kallsyms); 94 } 95 } ReadKernelSymbolsFromProc()96 static void ReadKernelSymbolsFromProc() { 97 read_kernel_symbols_from_proc_ = true; 98 } 99 static void SetBuildIds( 100 const std::vector<std::pair<std::string, BuildId>>& build_ids); 101 static BuildId FindExpectedBuildIdForPath(const std::string& path); 102 static void SetVdsoFile(std::unique_ptr<TemporaryFile> vdso_file, bool is_64bit); 103 104 static std::unique_ptr<Dso> CreateDso(DsoType dso_type, const std::string& dso_path, 105 bool force_64bit = false); 106 107 ~Dso(); 108 type()109 DsoType type() const { return type_; } 110 111 // Return the path recorded in perf.data. Path()112 const std::string& Path() const { return path_; } 113 // Return the path containing symbol table and debug information. GetDebugFilePath()114 const std::string& GetDebugFilePath() const { return debug_file_path_; } 115 // Return the file name without directory info. FileName()116 const std::string& FileName() const { return file_name_; } 117 HasDumpId()118 bool HasDumpId() { 119 return dump_id_ != UINT_MAX; 120 } 121 GetDumpId(uint32_t * pdump_id)122 bool GetDumpId(uint32_t* pdump_id) { 123 if (!HasDumpId()) { 124 return false; 125 } 126 *pdump_id = dump_id_; 127 return true; 128 } 129 130 uint32_t CreateDumpId(); 131 uint32_t CreateSymbolDumpId(const Symbol* symbol); 132 133 // Return the minimum virtual address in program header. 134 uint64_t MinVirtualAddress(); SetMinVirtualAddress(uint64_t min_vaddr)135 void SetMinVirtualAddress(uint64_t min_vaddr) { min_vaddr_ = min_vaddr; } 136 137 const Symbol* FindSymbol(uint64_t vaddr_in_dso); 138 139 const std::vector<Symbol>& GetSymbols(); 140 void SetSymbols(std::vector<Symbol>* symbols); 141 142 // Create a symbol for a virtual address which can't find a corresponding 143 // symbol in symbol table. 144 void AddUnknownSymbol(uint64_t vaddr_in_dso, const std::string& name); 145 146 private: 147 static bool demangle_; 148 static std::string symfs_dir_; 149 static std::string vmlinux_; 150 static std::string kallsyms_; 151 static bool read_kernel_symbols_from_proc_; 152 static std::unordered_map<std::string, BuildId> build_id_map_; 153 static size_t dso_count_; 154 static uint32_t g_dump_id_; 155 static std::unique_ptr<TemporaryFile> vdso_64bit_; 156 static std::unique_ptr<TemporaryFile> vdso_32bit_; 157 158 Dso(DsoType type, const std::string& path, bool force_64bit); 159 void Load(); 160 bool LoadKernel(); 161 bool LoadKernelModule(); 162 bool LoadElfFile(); 163 bool LoadEmbeddedElfFile(); 164 void FixupSymbolLength(); 165 BuildId GetExpectedBuildId(); 166 bool CheckReadSymbolResult(ElfStatus result, const std::string& filename); 167 168 const DsoType type_; 169 // path of the shared library used by the profiled program 170 const std::string path_; 171 // path of the shared library having symbol table and debug information 172 // It is the same as path_, or has the same build id as path_. 173 std::string debug_file_path_; 174 // File name of the shared library, got by removing directories in path_. 175 std::string file_name_; 176 uint64_t min_vaddr_; 177 std::vector<Symbol> symbols_; 178 // unknown symbols are like [libc.so+0x1234]. 179 std::unordered_map<uint64_t, Symbol> unknown_symbols_; 180 bool is_loaded_; 181 // Used to identify current dso if it needs to be dumped. 182 uint32_t dump_id_; 183 // Used to assign dump_id for symbols in current dso. 184 uint32_t symbol_dump_id_; 185 }; 186 187 const char* DsoTypeToString(DsoType dso_type); 188 189 #endif // SIMPLE_PERF_DSO_H_ 190