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