Home | History | Annotate | Download | only in simpleperf
      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:
     32   EmbeddedElf()
     33       : entry_offset_(0)
     34       , entry_size_(0)
     35   {
     36   }
     37 
     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
     50   const std::string &filepath() const { return filepath_; }
     51 
     52   // Entry name within zip archive
     53   const std::string &entry_name() const { return entry_name_; }
     54 
     55   // Offset of zip entry from start of containing APK file
     56   uint64_t entry_offset() const { return entry_offset_; }
     57 
     58   // Size of zip entry (length of embedded ELF)
     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