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 <memory> 23 #include <string> 24 #include <tuple> 25 #include <unordered_map> 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(const std::string & filepath,const std::string & entry_name,uint64_t entry_offset,size_t entry_size)38 EmbeddedElf(const std::string& filepath, 39 const std::string& entry_name, 40 uint64_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 static EmbeddedElf* FindElfInApkByOffset(const std::string& apk_path, uint64_t file_offset); 72 static EmbeddedElf* FindElfInApkByName(const std::string& apk_path, 73 const std::string& entry_name); 74 75 private: 76 static std::unique_ptr<EmbeddedElf> FindElfInApkByOffsetWithoutCache(const std::string& apk_path, 77 uint64_t file_offset); 78 static std::unique_ptr<EmbeddedElf> FindElfInApkByNameWithoutCache( 79 const std::string& apk_path, const std::string& entry_name); 80 81 struct ApkNode { 82 // Map from entry_offset to EmbeddedElf. 83 std::unordered_map<uint64_t, std::unique_ptr<EmbeddedElf>> offset_map; 84 // Map from entry_name to EmbeddedElf. 85 std::unordered_map<std::string, EmbeddedElf*> name_map; 86 }; 87 static std::unordered_map<std::string, ApkNode> embedded_elf_cache_; 88 }; 89 90 std::string GetUrlInApk(const std::string& apk_path, const std::string& elf_filename); 91 std::tuple<bool, std::string, std::string> SplitUrlInApk(const std::string& path); 92 93 // Parse path like "[anon:dalvik-classes.dex extracted in memory from /..base.apk] (deleted)", 94 // or "/dev/ashmem/dalvik-classes.dex extracted in memory from /..base.apk (deleted)" on Android P. 95 bool ParseExtractedInMemoryPath(const std::string& path, std::string* zip_path, 96 std::string* entry_name); 97 98 #endif // SIMPLE_PERF_READ_APK_H_ 99