1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #ifndef DFX_EXTRACTOR_UTILS_H
16 #define DFX_EXTRACTOR_UTILS_H
17 
18 #include <memory>
19 #include <vector>
20 #include "dfx_define.h"
21 #ifdef ENABLE_HAP_EXTRACTOR
22 #include "dfx_log.h"
23 #include "extractor.h"
24 #include "string_util.h"
25 #include "zip_file.h"
26 #endif
27 
28 namespace OHOS {
29 namespace HiviewDFX {
30 namespace {
31 #ifdef ENABLE_HAP_EXTRACTOR
32 #undef LOG_DOMAIN
33 #undef LOG_TAG
34 #define LOG_DOMAIN 0xD002D11
35 #define LOG_TAG "DfxExtractor"
36 #endif
37 }
38 
39 struct HapExtractorInfo {
40     uintptr_t loadOffset;
41     uint8_t* abcData;
42     size_t abcDataSize;
43 };
44 
45 class DfxExtractor final {
46 public:
DfxExtractor(const std::string & file)47     explicit DfxExtractor(const std::string& file) { Init(file); }
~DfxExtractor()48     ~DfxExtractor() { Clear(); }
49 
GetHapAbcInfo(uintptr_t & loadOffset,std::unique_ptr<uint8_t[]> & abcDataPtr,size_t & abcDataSize)50     bool GetHapAbcInfo(uintptr_t& loadOffset, std::unique_ptr<uint8_t[]>& abcDataPtr, size_t& abcDataSize)
51     {
52         bool ret = false;
53 #ifdef ENABLE_HAP_EXTRACTOR
54         if (zipFile_ == nullptr) {
55             return false;
56         }
57 
58         auto &entrys = zipFile_->GetAllEntries();
59         for (const auto &entry : entrys) {
60             std::string fileName = entry.first;
61             if (!EndsWith(fileName, "modules.abc")) {
62                 continue;
63             }
64 
65             AbilityBase::ZipPos offset = 0;
66             uint32_t length = 0;
67             if (!zipFile_->GetDataOffsetRelative(fileName, offset, length)) {
68                 break;
69             }
70 
71             LOGU("Hap entry file: %s, offset: 0x%016" PRIx64 "", fileName.c_str(), (uint64_t)offset);
72             loadOffset = static_cast<uintptr_t>(offset);
73             if (zipFile_->ExtractToBufByName(fileName, abcDataPtr, abcDataSize)) {
74                 LOGU("Hap abc: %s, size: %zu", fileName.c_str(), abcDataSize);
75                 ret = true;
76                 break;
77             }
78         }
79 #endif
80         return ret;
81     }
82 
GetHapSourceMapInfo(uintptr_t & loadOffset,std::unique_ptr<uint8_t[]> & sourceMapPtr,size_t & sourceMapSize)83     bool GetHapSourceMapInfo(uintptr_t& loadOffset, std::unique_ptr<uint8_t[]>& sourceMapPtr, size_t& sourceMapSize)
84     {
85         bool ret = false;
86 #ifdef ENABLE_HAP_EXTRACTOR
87         if (zipFile_ == nullptr) {
88             return false;
89         }
90 
91         auto &entrys = zipFile_->GetAllEntries();
92         for (const auto &entry : entrys) {
93             std::string fileName = entry.first;
94             if (!EndsWith(fileName, ".map")) {
95                 continue;
96             }
97 
98             AbilityBase::ZipPos offset = 0;
99             uint32_t length = 0;
100             if (!zipFile_->GetDataOffsetRelative(fileName, offset, length)) {
101                 break;
102             }
103 
104             LOGU("Hap entry file: %s, offset: 0x%016" PRIx64 "", fileName.c_str(), (uint64_t)offset);
105             loadOffset = static_cast<uintptr_t>(offset);
106             if (zipFile_->ExtractToBufByName(fileName, sourceMapPtr, sourceMapSize)) {
107                 LOGU("Hap sourcemap: %s, size: %zu", fileName.c_str(), sourceMapSize);
108                 ret = true;
109                 break;
110             }
111         }
112 #endif
113         return ret;
114     }
115 
116 protected:
Init(const std::string & file)117     bool Init(const std::string& file)
118     {
119 #ifdef ENABLE_HAP_EXTRACTOR
120         if (zipFile_ == nullptr) {
121             zipFile_ = std::make_shared<AbilityBase::ZipFile>(file);
122         }
123         if ((zipFile_ == nullptr) || (!zipFile_->Open())) {
124             LOGE("Failed to open zip file(%s)", file.c_str());
125             zipFile_ = nullptr;
126             return false;
127         }
128         LOGU("Done load zip file %s", file.c_str());
129         return true;
130 #endif
131         return false;
132     }
133 
Clear()134     void Clear()
135     {
136 #ifdef ENABLE_HAP_EXTRACTOR
137         if (zipFile_ == nullptr) {
138             return;
139         }
140         zipFile_ = nullptr;
141 #endif
142     }
143 
144 private:
145 #ifdef ENABLE_HAP_EXTRACTOR
146     std::shared_ptr<AbilityBase::ZipFile> zipFile_ = nullptr;
147 #endif
148 };
149 }   // namespace HiviewDFX
150 }   // namespace OHOS
151 #endif