1 /*
2  * Copyright (c) 2023-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 
16 #include "dfx_mmap.h"
17 
18 #include <fcntl.h>
19 #include <securec.h>
20 
21 #include "dfx_define.h"
22 #include "dfx_log.h"
23 #include "dfx_util.h"
24 
25 namespace OHOS {
26 namespace HiviewDFX {
27 namespace {
28 #undef LOG_DOMAIN
29 #undef LOG_TAG
30 #define LOG_DOMAIN 0xD002D11
31 #define LOG_TAG "DfxMmap"
32 }
33 
Init(const int fd,const size_t size,const off_t offset)34 bool DfxMmap::Init(const int fd, const size_t size, const off_t offset)
35 {
36     Clear();
37 
38     if (fd < 0) {
39         return false;
40     }
41     mmap_ = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, offset);
42     if (mmap_ == MAP_FAILED) {
43         LOGE("Failed to mmap, errno(%d)", errno);
44         size_ = 0;
45         return false;
46     }
47     size_ = size;
48     LOGD("mmap size %zu", size_);
49     return true;
50 }
51 
Init(uint8_t * decompressedData,size_t size)52 bool DfxMmap::Init(uint8_t *decompressedData, size_t size)
53 {
54     if (!decompressedData || size == 0) {
55         return false;
56     }
57 
58     // this pointer was managed by shared_ptr will not occur double free issue.
59     mmap_ = decompressedData;
60     size_ = size;
61     return true;
62 }
63 
Clear()64 void DfxMmap::Clear()
65 {
66     if ((mmap_ != MAP_FAILED) && (needUnmap_)) {
67         munmap(mmap_, size_);
68         mmap_ = MAP_FAILED;
69     }
70 }
71 
Read(uintptr_t & addr,void * val,size_t size,bool incre)72 size_t DfxMmap::Read(uintptr_t& addr, void* val, size_t size, bool incre)
73 {
74     if ((mmap_ == MAP_FAILED) || (val == nullptr)) {
75         return 0;
76     }
77 
78     size_t ptr = static_cast<size_t>(addr);
79     if (ptr >= size_) {
80         LOGU("pos: %zu, size: %zu", ptr, size_);
81         return 0;
82     }
83 
84     size_t left = size_ - ptr;
85     const uint8_t* actualBase = static_cast<const uint8_t*>(mmap_) + ptr;
86     size_t actualLen = std::min(left, size);
87     if (memcpy_s(val, actualLen, actualBase, actualLen) != 0) {
88         LOGE("%s", "Failed to memcpy_s");
89         return 0;
90     }
91     if (incre) {
92         addr += actualLen;
93     }
94     return actualLen;
95 }
96 } // namespace HiviewDFX
97 } // namespace OHOS
98