xref: /aosp_15_r20/system/extras/simpleperf/read_apk.h (revision 288bf5226967eb3dac5cce6c939ccc2a7f2b4fe5)
1*288bf522SAndroid Build Coastguard Worker /*
2*288bf522SAndroid Build Coastguard Worker  * Copyright (C) 2016 The Android Open Source Project
3*288bf522SAndroid Build Coastguard Worker  *
4*288bf522SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*288bf522SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*288bf522SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*288bf522SAndroid Build Coastguard Worker  *
8*288bf522SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*288bf522SAndroid Build Coastguard Worker  *
10*288bf522SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*288bf522SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*288bf522SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*288bf522SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*288bf522SAndroid Build Coastguard Worker  * limitations under the License.
15*288bf522SAndroid Build Coastguard Worker  */
16*288bf522SAndroid Build Coastguard Worker 
17*288bf522SAndroid Build Coastguard Worker #ifndef SIMPLE_PERF_READ_APK_H_
18*288bf522SAndroid Build Coastguard Worker #define SIMPLE_PERF_READ_APK_H_
19*288bf522SAndroid Build Coastguard Worker 
20*288bf522SAndroid Build Coastguard Worker #include <stdint.h>
21*288bf522SAndroid Build Coastguard Worker 
22*288bf522SAndroid Build Coastguard Worker #include <memory>
23*288bf522SAndroid Build Coastguard Worker #include <string>
24*288bf522SAndroid Build Coastguard Worker #include <tuple>
25*288bf522SAndroid Build Coastguard Worker #include <unordered_map>
26*288bf522SAndroid Build Coastguard Worker 
27*288bf522SAndroid Build Coastguard Worker #include "read_elf.h"
28*288bf522SAndroid Build Coastguard Worker 
29*288bf522SAndroid Build Coastguard Worker namespace simpleperf {
30*288bf522SAndroid Build Coastguard Worker 
31*288bf522SAndroid Build Coastguard Worker // Container for info an on ELF file embedded into an APK file
32*288bf522SAndroid Build Coastguard Worker class EmbeddedElf {
33*288bf522SAndroid Build Coastguard Worker  public:
EmbeddedElf()34*288bf522SAndroid Build Coastguard Worker   EmbeddedElf() : entry_offset_(0), entry_size_(0) {}
35*288bf522SAndroid Build Coastguard Worker 
EmbeddedElf(const std::string & filepath,const std::string & entry_name,uint64_t entry_offset,size_t entry_size)36*288bf522SAndroid Build Coastguard Worker   EmbeddedElf(const std::string& filepath, const std::string& entry_name, uint64_t entry_offset,
37*288bf522SAndroid Build Coastguard Worker               size_t entry_size)
38*288bf522SAndroid Build Coastguard Worker       : filepath_(filepath),
39*288bf522SAndroid Build Coastguard Worker         entry_name_(entry_name),
40*288bf522SAndroid Build Coastguard Worker         entry_offset_(entry_offset),
41*288bf522SAndroid Build Coastguard Worker         entry_size_(entry_size) {}
42*288bf522SAndroid Build Coastguard Worker 
43*288bf522SAndroid Build Coastguard Worker   // Path to APK file
filepath()44*288bf522SAndroid Build Coastguard Worker   const std::string& filepath() const { return filepath_; }
45*288bf522SAndroid Build Coastguard Worker 
46*288bf522SAndroid Build Coastguard Worker   // Entry name within zip archive
entry_name()47*288bf522SAndroid Build Coastguard Worker   const std::string& entry_name() const { return entry_name_; }
48*288bf522SAndroid Build Coastguard Worker 
49*288bf522SAndroid Build Coastguard Worker   // Offset of zip entry from start of containing APK file
entry_offset()50*288bf522SAndroid Build Coastguard Worker   uint64_t entry_offset() const { return entry_offset_; }
51*288bf522SAndroid Build Coastguard Worker 
52*288bf522SAndroid Build Coastguard Worker   // Size of zip entry (length of embedded ELF)
entry_size()53*288bf522SAndroid Build Coastguard Worker   uint32_t entry_size() const { return entry_size_; }
54*288bf522SAndroid Build Coastguard Worker 
55*288bf522SAndroid Build Coastguard Worker  private:
56*288bf522SAndroid Build Coastguard Worker   std::string filepath_;    // containing APK path
57*288bf522SAndroid Build Coastguard Worker   std::string entry_name_;  // name of entry in zip index of embedded elf file
58*288bf522SAndroid Build Coastguard Worker   uint64_t entry_offset_;   // offset of ELF from start of containing APK file
59*288bf522SAndroid Build Coastguard Worker   uint32_t entry_size_;     // size of ELF file in zip
60*288bf522SAndroid Build Coastguard Worker };
61*288bf522SAndroid Build Coastguard Worker 
62*288bf522SAndroid Build Coastguard Worker // APK inspector helper class
63*288bf522SAndroid Build Coastguard Worker class ApkInspector {
64*288bf522SAndroid Build Coastguard Worker  public:
65*288bf522SAndroid Build Coastguard Worker   static EmbeddedElf* FindElfInApkByOffset(const std::string& apk_path, uint64_t file_offset);
66*288bf522SAndroid Build Coastguard Worker   static EmbeddedElf* FindElfInApkByName(const std::string& apk_path,
67*288bf522SAndroid Build Coastguard Worker                                          const std::string& entry_name);
68*288bf522SAndroid Build Coastguard Worker 
69*288bf522SAndroid Build Coastguard Worker  private:
70*288bf522SAndroid Build Coastguard Worker   static std::unique_ptr<EmbeddedElf> FindElfInApkByOffsetWithoutCache(const std::string& apk_path,
71*288bf522SAndroid Build Coastguard Worker                                                                        uint64_t file_offset);
72*288bf522SAndroid Build Coastguard Worker   static std::unique_ptr<EmbeddedElf> FindElfInApkByNameWithoutCache(const std::string& apk_path,
73*288bf522SAndroid Build Coastguard Worker                                                                      const std::string& entry_name);
74*288bf522SAndroid Build Coastguard Worker 
75*288bf522SAndroid Build Coastguard Worker   struct ApkNode {
76*288bf522SAndroid Build Coastguard Worker     // Map from entry_offset to EmbeddedElf.
77*288bf522SAndroid Build Coastguard Worker     std::unordered_map<uint64_t, std::unique_ptr<EmbeddedElf>> offset_map;
78*288bf522SAndroid Build Coastguard Worker     // Map from entry_name to EmbeddedElf.
79*288bf522SAndroid Build Coastguard Worker     std::unordered_map<std::string, EmbeddedElf*> name_map;
80*288bf522SAndroid Build Coastguard Worker   };
81*288bf522SAndroid Build Coastguard Worker   static std::unordered_map<std::string, ApkNode> embedded_elf_cache_;
82*288bf522SAndroid Build Coastguard Worker };
83*288bf522SAndroid Build Coastguard Worker 
84*288bf522SAndroid Build Coastguard Worker std::string GetUrlInApk(const std::string& apk_path, const std::string& elf_filename);
85*288bf522SAndroid Build Coastguard Worker std::tuple<bool, std::string, std::string> SplitUrlInApk(const std::string& path);
86*288bf522SAndroid Build Coastguard Worker 
87*288bf522SAndroid Build Coastguard Worker // Parse path like "[anon:dalvik-classes.dex extracted in memory from /..base.apk] (deleted)",
88*288bf522SAndroid Build Coastguard Worker // or "/dev/ashmem/dalvik-classes.dex extracted in memory from /..base.apk (deleted)" on Android P.
89*288bf522SAndroid Build Coastguard Worker bool ParseExtractedInMemoryPath(const std::string& path, std::string* zip_path,
90*288bf522SAndroid Build Coastguard Worker                                 std::string* entry_name);
91*288bf522SAndroid Build Coastguard Worker 
92*288bf522SAndroid Build Coastguard Worker }  // namespace simpleperf
93*288bf522SAndroid Build Coastguard Worker 
94*288bf522SAndroid Build Coastguard Worker #endif  // SIMPLE_PERF_READ_APK_H_
95