1 /* 2 * Copyright (C) 2016 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_READ_APK_H_ 18 #define SIMPLE_PERF_READ_APK_H_ 19 20 #include <stdint.h> 21 22 #include <map> 23 #include <memory> 24 #include <string> 25 #include <tuple> 26 27 #include "read_elf.h" 28 29 // Container for info an on ELF file embedded into an APK file 30 class EmbeddedElf { 31 public: EmbeddedElf()32 EmbeddedElf() 33 : entry_offset_(0) 34 , entry_size_(0) 35 { 36 } 37 EmbeddedElf(std::string filepath,std::string entry_name,size_t entry_offset,size_t entry_size)38 EmbeddedElf(std::string filepath, 39 std::string entry_name, 40 size_t entry_offset, 41 size_t entry_size) 42 : filepath_(filepath) 43 , entry_name_(entry_name) 44 , entry_offset_(entry_offset) 45 , entry_size_(entry_size) 46 { 47 } 48 49 // Path to APK file filepath()50 const std::string &filepath() const { return filepath_; } 51 52 // Entry name within zip archive entry_name()53 const std::string &entry_name() const { return entry_name_; } 54 55 // Offset of zip entry from start of containing APK file entry_offset()56 uint64_t entry_offset() const { return entry_offset_; } 57 58 // Size of zip entry (length of embedded ELF) entry_size()59 uint32_t entry_size() const { return entry_size_; } 60 61 private: 62 std::string filepath_; // containing APK path 63 std::string entry_name_; // name of entry in zip index of embedded elf file 64 uint64_t entry_offset_; // offset of ELF from start of containing APK file 65 uint32_t entry_size_; // size of ELF file in zip 66 }; 67 68 // APK inspector helper class 69 class ApkInspector { 70 public: 71 // Given an APK/ZIP/JAR file and an offset into that file, if the 72 // corresponding region of the APK corresponds to an uncompressed 73 // ELF file, then return pertinent info on the ELF. 74 static EmbeddedElf* FindElfInApkByOffset(const std::string& apk_path, uint64_t file_offset); 75 static std::unique_ptr<EmbeddedElf> FindElfInApkByName(const std::string& apk_path, 76 const std::string& elf_filename); 77 78 private: 79 static std::unique_ptr<EmbeddedElf> FindElfInApkByOffsetWithoutCache(const std::string& apk_path, 80 uint64_t file_offset); 81 82 // First component of pair is APK file path, second is offset into APK. 83 typedef std::pair<std::string, uint64_t> ApkOffset; 84 85 static std::map<ApkOffset, std::unique_ptr<EmbeddedElf>> embedded_elf_cache_; 86 }; 87 88 // Export for test only. 89 bool IsValidApkPath(const std::string& apk_path); 90 91 std::string GetUrlInApk(const std::string& apk_path, const std::string& elf_filename); 92 std::tuple<bool, std::string, std::string> SplitUrlInApk(const std::string& path); 93 94 ElfStatus GetBuildIdFromApkFile(const std::string& apk_path, const std::string& elf_filename, 95 BuildId* build_id); 96 97 ElfStatus ParseSymbolsFromApkFile(const std::string& apk_path, const std::string& elf_filename, 98 const BuildId& expected_build_id, 99 const std::function<void(const ElfFileSymbol&)>& callback); 100 101 102 #endif // SIMPLE_PERF_READ_APK_H_ 103