• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 namespace simpleperf {
30 
31 // Container for info an on ELF file embedded into an APK file
32 class EmbeddedElf {
33  public:
EmbeddedElf()34   EmbeddedElf() : entry_offset_(0), entry_size_(0) {}
35 
EmbeddedElf(const std::string & filepath,const std::string & entry_name,uint64_t entry_offset,size_t entry_size)36   EmbeddedElf(const std::string& filepath, const std::string& entry_name, uint64_t entry_offset,
37               size_t entry_size)
38       : filepath_(filepath),
39         entry_name_(entry_name),
40         entry_offset_(entry_offset),
41         entry_size_(entry_size) {}
42 
43   // Path to APK file
filepath()44   const std::string& filepath() const { return filepath_; }
45 
46   // Entry name within zip archive
entry_name()47   const std::string& entry_name() const { return entry_name_; }
48 
49   // Offset of zip entry from start of containing APK file
entry_offset()50   uint64_t entry_offset() const { return entry_offset_; }
51 
52   // Size of zip entry (length of embedded ELF)
entry_size()53   uint32_t entry_size() const { return entry_size_; }
54 
55  private:
56   std::string filepath_;    // containing APK path
57   std::string entry_name_;  // name of entry in zip index of embedded elf file
58   uint64_t entry_offset_;   // offset of ELF from start of containing APK file
59   uint32_t entry_size_;     // size of ELF file in zip
60 };
61 
62 // APK inspector helper class
63 class ApkInspector {
64  public:
65   static EmbeddedElf* FindElfInApkByOffset(const std::string& apk_path, uint64_t file_offset);
66   static EmbeddedElf* FindElfInApkByName(const std::string& apk_path,
67                                          const std::string& entry_name);
68 
69  private:
70   static std::unique_ptr<EmbeddedElf> FindElfInApkByOffsetWithoutCache(const std::string& apk_path,
71                                                                        uint64_t file_offset);
72   static std::unique_ptr<EmbeddedElf> FindElfInApkByNameWithoutCache(const std::string& apk_path,
73                                                                      const std::string& entry_name);
74 
75   struct ApkNode {
76     // Map from entry_offset to EmbeddedElf.
77     std::unordered_map<uint64_t, std::unique_ptr<EmbeddedElf>> offset_map;
78     // Map from entry_name to EmbeddedElf.
79     std::unordered_map<std::string, EmbeddedElf*> name_map;
80   };
81   static std::unordered_map<std::string, ApkNode> embedded_elf_cache_;
82 };
83 
84 std::string GetUrlInApk(const std::string& apk_path, const std::string& elf_filename);
85 std::tuple<bool, std::string, std::string> SplitUrlInApk(const std::string& path);
86 
87 // Parse path like "[anon:dalvik-classes.dex extracted in memory from /..base.apk] (deleted)",
88 // or "/dev/ashmem/dalvik-classes.dex extracted in memory from /..base.apk (deleted)" on Android P.
89 bool ParseExtractedInMemoryPath(const std::string& path, std::string* zip_path,
90                                 std::string* entry_name);
91 
92 }  // namespace simpleperf
93 
94 #endif  // SIMPLE_PERF_READ_APK_H_
95