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, MAP_PRIVATE, fd, offset);
42 if (mmap_ == MAP_FAILED) {
43 DFXLOGE("Failed to mmap, errno(%{public}d)", errno);
44 size_ = 0;
45 return false;
46 }
47 needUnmap_ = true;
48 size_ = size;
49 DFXLOGD("mmap size %{public}zu", size_);
50 return true;
51 }
52
Init(std::vector<uint8_t> && data)53 bool DfxMmap::Init(std::vector<uint8_t>&& data)
54 {
55 if (data.size() == 0) {
56 return false;
57 }
58
59 data_ = std::move(data);
60 mmap_ = data_.data();
61 size_ = data_.size();
62 needUnmap_ = false;
63 return true;
64 }
65
Clear()66 void DfxMmap::Clear()
67 {
68 if ((mmap_ != MAP_FAILED) && (needUnmap_)) {
69 munmap(mmap_, size_);
70 mmap_ = MAP_FAILED;
71 }
72 }
73
Read(uintptr_t & addr,void * val,size_t size,bool incre)74 size_t DfxMmap::Read(uintptr_t& addr, void* val, size_t size, bool incre)
75 {
76 if ((mmap_ == MAP_FAILED) || (val == nullptr)) {
77 return 0;
78 }
79
80 size_t ptr = static_cast<size_t>(addr);
81 if (ptr >= size_) {
82 DFXLOGU("pos: %{public}zu, size: %{public}zu", ptr, size_);
83 return 0;
84 }
85
86 size_t left = size_ - ptr;
87 const uint8_t* actualBase = static_cast<const uint8_t*>(mmap_) + ptr;
88 size_t actualLen = std::min(left, size);
89 if (memcpy_s(val, size, actualBase, actualLen) != 0) {
90 DFXLOGE("Failed to memcpy_s");
91 return 0;
92 }
93 if (incre) {
94 addr += actualLen;
95 }
96 return actualLen;
97 }
98 } // namespace HiviewDFX
99 } // namespace OHOS
100