diff options
author | Treehugger Robot <treehugger-gerrit@google.com> | 2018-10-05 20:26:26 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2018-10-05 20:26:26 +0000 |
commit | 5fc1de62342d1b8fa638f1bda202ff51311a589f (patch) | |
tree | b3ea24759f6588ea69b789d5c9384a84c243761f /perfprofd/symbolizer.cc | |
parent | c87973354a2be3ccc470f40e29f59df699a930b1 (diff) | |
parent | a3b752cdcf107a3c245f4e9704022dbdcfd0e678 (diff) | |
download | extras-5fc1de62342d1b8fa638f1bda202ff51311a589f.tar.gz |
Merge "Perfprofd: Introduce libsimpleperf_dex_read and read vdex files"android-o-mr1-iot-release-smart-display-r3oreo-mr1-1.2-iot-releasemaster-cuttlefish-testing-release
Diffstat (limited to 'perfprofd/symbolizer.cc')
-rw-r--r-- | perfprofd/symbolizer.cc | 111 |
1 files changed, 93 insertions, 18 deletions
diff --git a/perfprofd/symbolizer.cc b/perfprofd/symbolizer.cc index bde680f5..58ff280b 100644 --- a/perfprofd/symbolizer.cc +++ b/perfprofd/symbolizer.cc @@ -22,9 +22,11 @@ #include <unordered_map> #include <android-base/logging.h> - -#include "build_id.h" -#include "read_elf.h" +#include <base/mem_map.h> +#include <build_id.h> +#include <read_dex_file.h> +#include <read_elf.h> +#include <vdex_file.h> namespace perfprofd { @@ -33,6 +35,8 @@ namespace { struct SimpleperfSymbolizer : public Symbolizer { // For simplicity, we assume non-overlapping symbols. struct Symbol { + Symbol(const std::string& n, uint64_t l) : name(n), length(l) {} + std::string name; uint64_t length; }; @@ -66,28 +70,99 @@ struct SimpleperfSymbolizer : public Symbolizer { } void LoadDso(const std::string& dso) { - SymbolMap data; - auto callback = [&data](const ElfFileSymbol& sym) { - if (sym.is_func) { - Symbol symbol; - symbol.name = sym.name; - symbol.length = sym.len; - if (sym.len == 0) { - LOG(ERROR) << "Symbol size is zero for " << sym.name; + // See whether it's an ELF file. + { + SymbolMap elf_data; + auto callback = [&elf_data](const ElfFileSymbol& sym) { + if (sym.is_func) { + if (sym.len == 0) { + LOG(ERROR) << "Symbol size is zero for " << sym.name; + } + elf_data.emplace(sym.vaddr, Symbol(sym.name, sym.len)); } - data.emplace(sym.vaddr, std::move(symbol)); + }; + ElfStatus status = ParseSymbolsFromElfFile(dso, BuildId(), callback); + if (status == ElfStatus::NO_ERROR) { + dsos.emplace(dso, std::move(elf_data)); + return; + } + } + + // See whether it's a vdex file. + { + ::art::MemMap::Init(); + + using VdexFile = ::art::VdexFile; + std::string error_msg; + std::unique_ptr<VdexFile> vdex = VdexFile::Open(dso, + /* writable= */ false, + /* low_4gb= */ false, + /* unquicken= */ false, + &error_msg); + if (vdex != nullptr) { + const uint8_t* cur = nullptr; + std::vector<uint64_t> dex_file_offsets; + const uint8_t* base = vdex->Begin(); + for (;;) { + cur = vdex->GetNextDexFileData(cur); + if (cur == nullptr) { + break; + } + dex_file_offsets.push_back(cur - base); + } + + if (!dex_file_offsets.empty()) { + std::vector<DexFileSymbol> symbols; + if (ReadSymbolsFromDexFile(dso, dex_file_offsets, &symbols)) { + SymbolMap vdex_data; + for (const DexFileSymbol& symbol : symbols) { + vdex_data.emplace(symbol.offset, Symbol(symbol.name, symbol.len)); + } + dsos.emplace(dso, std::move(vdex_data)); + LOG(INFO) << "Found " << symbols.size() << " dex symbols in " << dso; + return; + } else { + LOG(WARNING) << "Could not read symbols from dex files in " << dso; + } + } else { + LOG(WARNING) << "Could not find dex files for vdex " << dso; + dsos.emplace(dso, SymbolMap()); + } + } else { + LOG(WARNING) << dso << " is not a vdex: " << error_msg; } - }; - ElfStatus status = ParseSymbolsFromElfFile(dso, BuildId(), callback); - if (status != ElfStatus::NO_ERROR) { - LOG(WARNING) << "Could not parse dso " << dso << ": " << status; } - dsos.emplace(dso, std::move(data)); + + // TODO: See whether it's a dex file. + + // OK, give up. + LOG(WARNING) << "Could not symbolize " << dso; + dsos.emplace(dso, SymbolMap()); } bool GetMinExecutableVAddr(const std::string& dso, uint64_t* addr) override { ElfStatus status = ReadMinExecutableVirtualAddressFromElfFile(dso, BuildId(), addr); - return status == ElfStatus::NO_ERROR; + if (status != ElfStatus::NO_ERROR) { + return true; + } + + { + ::art::MemMap::Init(); + + using VdexFile = ::art::VdexFile; + std::string error_msg; + std::unique_ptr<VdexFile> vdex = VdexFile::Open(dso, + /* writable= */ false, + /* low_4gb= */ false, + /* unquicken= */ false, + &error_msg); + if (vdex != nullptr) { + *addr = 0u; + return true; + } + } + + return false; } std::unordered_map<std::string, SymbolMap> dsos; |