dso.h 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  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. #ifndef SIMPLE_PERF_DSO_H_
  17. #define SIMPLE_PERF_DSO_H_
  18. #include <memory>
  19. #include <string>
  20. #include <unordered_map>
  21. #include <vector>
  22. #include <android-base/file.h>
  23. #include <android-base/logging.h>
  24. #include "build_id.h"
  25. #include "read_elf.h"
  26. namespace simpleperf_dso_impl {
  27. // Find elf files with symbol table and debug information.
  28. class DebugElfFileFinder {
  29. public:
  30. void Reset();
  31. bool SetSymFsDir(const std::string& symfs_dir);
  32. bool AddSymbolDir(const std::string& symbol_dir);
  33. void SetVdsoFile(const std::string& vdso_file, bool is_64bit);
  34. std::string FindDebugFile(const std::string& dso_path, bool force_64bit,
  35. BuildId& build_id);
  36. // Only for testing
  37. std::string GetPathInSymFsDir(const std::string& path);
  38. private:
  39. void CollectBuildIdInDir(const std::string& dir);
  40. std::string vdso_64bit_;
  41. std::string vdso_32bit_;
  42. std::string symfs_dir_;
  43. std::unordered_map<std::string, std::string> build_id_to_file_map_;
  44. };
  45. } // namespace simpleperf_dso_impl
  46. struct Symbol {
  47. uint64_t addr;
  48. // TODO: make len uint32_t.
  49. uint64_t len;
  50. Symbol(std::string_view name, uint64_t addr, uint64_t len);
  51. const char* Name() const { return name_; }
  52. const char* DemangledName() const;
  53. bool HasDumpId() const {
  54. return dump_id_ != UINT_MAX;
  55. }
  56. bool GetDumpId(uint32_t* pdump_id) const {
  57. if (!HasDumpId()) {
  58. return false;
  59. }
  60. *pdump_id = dump_id_;
  61. return true;
  62. }
  63. static bool CompareByDumpId(const Symbol* s1, const Symbol* s2) {
  64. uint32_t id1 = UINT_MAX;
  65. s1->GetDumpId(&id1);
  66. uint32_t id2 = UINT_MAX;
  67. s2->GetDumpId(&id2);
  68. return id1 < id2;
  69. }
  70. static bool CompareByAddr(const Symbol* s1, const Symbol* s2) {
  71. return s1->addr < s2->addr;
  72. }
  73. static bool CompareValueByAddr(const Symbol& s1, const Symbol& s2) {
  74. return s1.addr < s2.addr;
  75. }
  76. private:
  77. const char* name_;
  78. mutable const char* demangled_name_;
  79. mutable uint32_t dump_id_;
  80. friend class Dso;
  81. };
  82. enum DsoType {
  83. DSO_KERNEL,
  84. DSO_KERNEL_MODULE,
  85. DSO_ELF_FILE,
  86. DSO_DEX_FILE, // For files containing dex files, like .vdex files.
  87. DSO_UNKNOWN_FILE,
  88. };
  89. struct KernelSymbol;
  90. struct ElfFileSymbol;
  91. class Dso {
  92. public:
  93. static void SetDemangle(bool demangle);
  94. static std::string Demangle(const std::string& name);
  95. // SymFsDir is used to provide an alternative root directory looking for files with symbols.
  96. // For example, if we are searching symbols for /system/lib/libc.so and SymFsDir is /data/symbols,
  97. // then we will also search file /data/symbols/system/lib/libc.so.
  98. static bool SetSymFsDir(const std::string& symfs_dir);
  99. // SymbolDir is used to add a directory containing files with symbols. Each file under it will
  100. // be searched recursively to build a build_id_map.
  101. static bool AddSymbolDir(const std::string& symbol_dir);
  102. static void SetVmlinux(const std::string& vmlinux);
  103. static void SetKallsyms(std::string kallsyms) {
  104. if (!kallsyms.empty()) {
  105. kallsyms_ = std::move(kallsyms);
  106. }
  107. }
  108. static void ReadKernelSymbolsFromProc() {
  109. read_kernel_symbols_from_proc_ = true;
  110. }
  111. static void SetBuildIds(
  112. const std::vector<std::pair<std::string, BuildId>>& build_ids);
  113. static BuildId FindExpectedBuildIdForPath(const std::string& path);
  114. static void SetVdsoFile(const std::string& vdso_file, bool is_64bit);
  115. static std::unique_ptr<Dso> CreateDso(DsoType dso_type, const std::string& dso_path,
  116. bool force_64bit = false);
  117. virtual ~Dso();
  118. DsoType type() const { return type_; }
  119. // Return the path recorded in perf.data.
  120. const std::string& Path() const { return path_; }
  121. // Return the path containing symbol table and debug information.
  122. const std::string& GetDebugFilePath() const { return debug_file_path_; }
  123. // Return the file name without directory info.
  124. const std::string& FileName() const { return file_name_; }
  125. bool HasDumpId() {
  126. return dump_id_ != UINT_MAX;
  127. }
  128. bool GetDumpId(uint32_t* pdump_id) {
  129. if (!HasDumpId()) {
  130. return false;
  131. }
  132. *pdump_id = dump_id_;
  133. return true;
  134. }
  135. uint32_t CreateDumpId();
  136. uint32_t CreateSymbolDumpId(const Symbol* symbol);
  137. virtual void SetMinExecutableVaddr(uint64_t, uint64_t) {}
  138. virtual void GetMinExecutableVaddr(uint64_t* min_vaddr, uint64_t* file_offset) {
  139. *min_vaddr = 0;
  140. *file_offset = 0;
  141. }
  142. virtual void AddDexFileOffset(uint64_t) {}
  143. virtual const std::vector<uint64_t>* DexFileOffsets() { return nullptr; }
  144. virtual uint64_t IpToVaddrInFile(uint64_t ip, uint64_t map_start, uint64_t map_pgoff) = 0;
  145. const Symbol* FindSymbol(uint64_t vaddr_in_dso);
  146. const std::vector<Symbol>& GetSymbols() { return symbols_; }
  147. void SetSymbols(std::vector<Symbol>* symbols);
  148. // Create a symbol for a virtual address which can't find a corresponding
  149. // symbol in symbol table.
  150. void AddUnknownSymbol(uint64_t vaddr_in_dso, const std::string& name);
  151. bool IsForJavaMethod();
  152. protected:
  153. static bool demangle_;
  154. static std::string vmlinux_;
  155. static std::string kallsyms_;
  156. static bool read_kernel_symbols_from_proc_;
  157. static std::unordered_map<std::string, BuildId> build_id_map_;
  158. static size_t dso_count_;
  159. static uint32_t g_dump_id_;
  160. static simpleperf_dso_impl::DebugElfFileFinder debug_elf_file_finder_;
  161. Dso(DsoType type, const std::string& path, const std::string& debug_file_path);
  162. BuildId GetExpectedBuildId();
  163. void Load();
  164. virtual std::vector<Symbol> LoadSymbols() = 0;
  165. DsoType type_;
  166. // path of the shared library used by the profiled program
  167. const std::string path_;
  168. // path of the shared library having symbol table and debug information
  169. // It is the same as path_, or has the same build id as path_.
  170. std::string debug_file_path_;
  171. // File name of the shared library, got by removing directories in path_.
  172. std::string file_name_;
  173. std::vector<Symbol> symbols_;
  174. // unknown symbols are like [libc.so+0x1234].
  175. std::unordered_map<uint64_t, Symbol> unknown_symbols_;
  176. bool is_loaded_;
  177. // Used to identify current dso if it needs to be dumped.
  178. uint32_t dump_id_;
  179. // Used to assign dump_id for symbols in current dso.
  180. uint32_t symbol_dump_id_;
  181. android::base::LogSeverity symbol_warning_loglevel_;
  182. };
  183. const char* DsoTypeToString(DsoType dso_type);
  184. bool GetBuildIdFromDsoPath(const std::string& dso_path, BuildId* build_id);
  185. #endif // SIMPLE_PERF_DSO_H_