1f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh/* 2f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh * Copyright (C) 2016 The Android Open Source Project 3f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh * 4f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh * Licensed under the Apache License, Version 2.0 (the "License"); 5f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh * you may not use this file except in compliance with the License. 6f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh * You may obtain a copy of the License at 7f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh * 8f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh * http://www.apache.org/licenses/LICENSE-2.0 9f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh * 10f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh * Unless required by applicable law or agreed to in writing, software 11f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh * distributed under the License is distributed on an "AS IS" BASIS, 12f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh * See the License for the specific language governing permissions and 14f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh * limitations under the License. 15f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh */ 16f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh 17f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh#ifndef SIMPLE_PERF_READ_APK_H_ 18f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh#define SIMPLE_PERF_READ_APK_H_ 19f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh 2041e32ca272f474d35a84a6e7c7f0a28c3160abc3Yabin Cui#include <stdint.h> 2141e32ca272f474d35a84a6e7c7f0a28c3160abc3Yabin Cui 22b1a885b014540a2f7798b5a35ea0f0ec150d93eeYabin Cui#include <map> 23f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh#include <memory> 24f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh#include <string> 25b1a885b014540a2f7798b5a35ea0f0ec150d93eeYabin Cui#include <tuple> 26f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh 27b1a885b014540a2f7798b5a35ea0f0ec150d93eeYabin Cui#include "read_elf.h" 28f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh 29f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh// Container for info an on ELF file embedded into an APK file 30f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntoshclass EmbeddedElf { 31f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh public: 32f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh EmbeddedElf() 33f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh : entry_offset_(0) 34f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh , entry_size_(0) 35f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh { 36f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh } 37f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh 38f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh EmbeddedElf(std::string filepath, 39f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh std::string entry_name, 40f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh size_t entry_offset, 41f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh size_t entry_size) 42f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh : filepath_(filepath) 43f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh , entry_name_(entry_name) 44f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh , entry_offset_(entry_offset) 45f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh , entry_size_(entry_size) 46f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh { 47f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh } 48f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh 49f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh // Path to APK file 50f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh const std::string &filepath() const { return filepath_; } 51f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh 52f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh // Entry name within zip archive 53f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh const std::string &entry_name() const { return entry_name_; } 54f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh 55f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh // Offset of zip entry from start of containing APK file 5641e32ca272f474d35a84a6e7c7f0a28c3160abc3Yabin Cui uint64_t entry_offset() const { return entry_offset_; } 57f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh 58f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh // Size of zip entry (length of embedded ELF) 59f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh uint32_t entry_size() const { return entry_size_; } 60f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh 61f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh private: 62f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh std::string filepath_; // containing APK path 63f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh std::string entry_name_; // name of entry in zip index of embedded elf file 6441e32ca272f474d35a84a6e7c7f0a28c3160abc3Yabin Cui uint64_t entry_offset_; // offset of ELF from start of containing APK file 65f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh uint32_t entry_size_; // size of ELF file in zip 66f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh}; 67f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh 68f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh// APK inspector helper class 69f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntoshclass ApkInspector { 70f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh public: 71f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh // Given an APK/ZIP/JAR file and an offset into that file, if the 72f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh // corresponding region of the APK corresponds to an uncompressed 73f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh // ELF file, then return pertinent info on the ELF. 7441e32ca272f474d35a84a6e7c7f0a28c3160abc3Yabin Cui static EmbeddedElf* FindElfInApkByOffset(const std::string& apk_path, uint64_t file_offset); 75b1a885b014540a2f7798b5a35ea0f0ec150d93eeYabin Cui static std::unique_ptr<EmbeddedElf> FindElfInApkByName(const std::string& apk_path, 76b1a885b014540a2f7798b5a35ea0f0ec150d93eeYabin Cui const std::string& elf_filename); 77f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh 78f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh private: 79b1a885b014540a2f7798b5a35ea0f0ec150d93eeYabin Cui static std::unique_ptr<EmbeddedElf> FindElfInApkByOffsetWithoutCache(const std::string& apk_path, 8041e32ca272f474d35a84a6e7c7f0a28c3160abc3Yabin Cui uint64_t file_offset); 81b1a885b014540a2f7798b5a35ea0f0ec150d93eeYabin Cui 82b1a885b014540a2f7798b5a35ea0f0ec150d93eeYabin Cui // First component of pair is APK file path, second is offset into APK. 8341e32ca272f474d35a84a6e7c7f0a28c3160abc3Yabin Cui typedef std::pair<std::string, uint64_t> ApkOffset; 84b1a885b014540a2f7798b5a35ea0f0ec150d93eeYabin Cui 85b1a885b014540a2f7798b5a35ea0f0ec150d93eeYabin Cui static std::map<ApkOffset, std::unique_ptr<EmbeddedElf>> embedded_elf_cache_; 86f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh}; 87f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh 88b1a885b014540a2f7798b5a35ea0f0ec150d93eeYabin Cui// Export for test only. 89b1a885b014540a2f7798b5a35ea0f0ec150d93eeYabin Cuibool IsValidApkPath(const std::string& apk_path); 90b1a885b014540a2f7798b5a35ea0f0ec150d93eeYabin Cui 91b1a885b014540a2f7798b5a35ea0f0ec150d93eeYabin Cuistd::string GetUrlInApk(const std::string& apk_path, const std::string& elf_filename); 92b1a885b014540a2f7798b5a35ea0f0ec150d93eeYabin Cuistd::tuple<bool, std::string, std::string> SplitUrlInApk(const std::string& path); 93b1a885b014540a2f7798b5a35ea0f0ec150d93eeYabin Cui 94dec43c18d06415a955b8f32355bca925be901905Yabin CuiElfStatus GetBuildIdFromApkFile(const std::string& apk_path, const std::string& elf_filename, 95dec43c18d06415a955b8f32355bca925be901905Yabin Cui BuildId* build_id); 96b1a885b014540a2f7798b5a35ea0f0ec150d93eeYabin Cui 97dec43c18d06415a955b8f32355bca925be901905Yabin CuiElfStatus ParseSymbolsFromApkFile(const std::string& apk_path, const std::string& elf_filename, 98dec43c18d06415a955b8f32355bca925be901905Yabin Cui const BuildId& expected_build_id, 99dec43c18d06415a955b8f32355bca925be901905Yabin Cui const std::function<void(const ElfFileSymbol&)>& callback); 100b1a885b014540a2f7798b5a35ea0f0ec150d93eeYabin Cui 101b1a885b014540a2f7798b5a35ea0f0ec150d93eeYabin Cui 102f831e6d12ca2298cb34b155a9d91ef002d0482f3Than McIntosh#endif // SIMPLE_PERF_READ_APK_H_ 103