1 /*
2  * Copyright (C) 2019 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 SRC_PROFILING_SYMBOLIZER_LOCAL_SYMBOLIZER_H_
18 #define SRC_PROFILING_SYMBOLIZER_LOCAL_SYMBOLIZER_H_
19 
20 #include <map>
21 #include <memory>
22 #include <string>
23 #include <vector>
24 
25 #include "perfetto/ext/base/optional.h"
26 #include "perfetto/ext/base/scoped_file.h"
27 #include "src/profiling/symbolizer/subprocess.h"
28 #include "src/profiling/symbolizer/symbolizer.h"
29 
30 namespace perfetto {
31 namespace profiling {
32 
33 bool ParseLlvmSymbolizerLine(const std::string& line,
34                              std::string* file_name,
35                              uint32_t* line_no);
36 std::vector<std::string> GetLines(
37     std::function<int64_t(char*, size_t)> fn_read);
38 
39 struct FoundBinary {
40   std::string file_name;
41   uint64_t load_bias;
42 };
43 
44 class BinaryFinder {
45  public:
46   virtual ~BinaryFinder();
47   virtual base::Optional<FoundBinary> FindBinary(
48       const std::string& abspath,
49       const std::string& build_id) = 0;
50 };
51 
52 class LocalBinaryIndexer : public BinaryFinder {
53  public:
54   explicit LocalBinaryIndexer(std::vector<std::string> roots);
55 
56   base::Optional<FoundBinary> FindBinary(const std::string& abspath,
57                                          const std::string& build_id) override;
58   ~LocalBinaryIndexer() override;
59 
60  private:
61   std::map<std::string, FoundBinary> buildid_to_file_;
62 };
63 
64 class LocalBinaryFinder : public BinaryFinder {
65  public:
66   explicit LocalBinaryFinder(std::vector<std::string> roots);
67 
68   base::Optional<FoundBinary> FindBinary(const std::string& abspath,
69                                          const std::string& build_id) override;
70 
71   ~LocalBinaryFinder() override;
72 
73  private:
74   base::Optional<FoundBinary> IsCorrectFile(const std::string& symbol_file,
75                                             const std::string& build_id);
76 
77   base::Optional<FoundBinary> FindBinaryInRoot(const std::string& root_str,
78                                                const std::string& abspath,
79                                                const std::string& build_id);
80 
81  private:
82   std::vector<std::string> roots_;
83   std::map<std::string, base::Optional<FoundBinary>> cache_;
84 };
85 
86 class LLVMSymbolizerProcess {
87  public:
88   explicit LLVMSymbolizerProcess(const std::string& symbolizer_path);
89 
90   std::vector<SymbolizedFrame> Symbolize(const std::string& binary,
91                                          uint64_t address);
92 
93  private:
94   Subprocess subprocess_;
95 };
96 
97 class LocalSymbolizer : public Symbolizer {
98  public:
99   LocalSymbolizer(const std::string& symbolizer_path,
100                   std::unique_ptr<BinaryFinder> finder);
101 
102   explicit LocalSymbolizer(std::unique_ptr<BinaryFinder> finder);
103 
104   std::vector<std::vector<SymbolizedFrame>> Symbolize(
105       const std::string& mapping_name,
106       const std::string& build_id,
107       uint64_t load_bias,
108       const std::vector<uint64_t>& address) override;
109 
110   ~LocalSymbolizer() override;
111 
112  private:
113   LLVMSymbolizerProcess llvm_symbolizer_;
114   std::unique_ptr<BinaryFinder> finder_;
115 };
116 
117 std::unique_ptr<Symbolizer> LocalSymbolizerOrDie(
118     std::vector<std::string> binary_path,
119     const char* mode);
120 
121 }  // namespace profiling
122 }  // namespace perfetto
123 
124 #endif  // SRC_PROFILING_SYMBOLIZER_LOCAL_SYMBOLIZER_H_
125