3 * Copyright 2018, The Android Open Source Project
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
18 #include "symbolizer.h"
22 #include <unordered_map>
24 #include <android-base/logging.h>
33 struct SimpleperfSymbolizer : public Symbolizer {
34 // For simplicity, we assume non-overlapping symbols.
39 using SymbolMap = std::map<uint64_t, Symbol>;
41 std::string Decode(const std::string& dso, uint64_t address) override {
42 auto it = dsos.find(dso);
43 if (it == dsos.end()) {
46 DCHECK(it != dsos.end());
49 const SymbolMap& map = it->second;
53 auto upper_bound = map.upper_bound(address);
54 if (upper_bound == map.begin()) {
55 // Nope, not in the map.
60 if (upper_bound->first + upper_bound->second.length > address) {
61 // This element covers the given address, return its name.
62 return upper_bound->second.name;
68 void LoadDso(const std::string& dso) {
70 auto callback = [&data](const ElfFileSymbol& sym) {
72 symbol.name = sym.name;
73 symbol.length = sym.len;
74 data.emplace(sym.vaddr, std::move(symbol));
76 ElfStatus status = ParseSymbolsFromElfFile(dso, BuildId(), callback);
77 if (status != ElfStatus::NO_ERROR) {
78 LOG(WARNING) << "Could not parse dso " << dso << ": " << status;
80 dsos.emplace(dso, std::move(data));
83 std::unordered_map<std::string, SymbolMap> dsos;
88 std::unique_ptr<Symbolizer> CreateELFSymbolizer() {
89 return std::unique_ptr<Symbolizer>(new SimpleperfSymbolizer());
92 } // namespace perfprofd