• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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_map.h"
17 
18 #include <algorithm>
19 #include <securec.h>
20 #include <sstream>
21 #if is_mingw
22 #include "dfx_nonlinux_define.h"
23 #else
24 #include <sys/mman.h>
25 #endif
26 
27 #include "dfx_define.h"
28 #include "dfx_elf.h"
29 #include "dfx_log.h"
30 #include "dfx_util.h"
31 #include "string_util.h"
32 
33 namespace OHOS {
34 namespace HiviewDFX {
35 namespace {
36 #undef LOG_DOMAIN
37 #undef LOG_TAG
38 #define LOG_DOMAIN 0xD002D11
39 #define LOG_TAG "DfxMap"
40 }
41 
Create(const std::string buf,int size)42 std::shared_ptr<DfxMap> DfxMap::Create(const std::string buf, int size)
43 {
44     auto map = std::make_shared<DfxMap>();
45     if (map->Parse(buf, size) == false) {
46         return nullptr;
47     }
48     return map;
49 }
50 
Parse(const std::string buf,int size)51 bool DfxMap::Parse(const std::string buf, int size)
52 {
53 #if is_ohos
54     uint32_t pos = 0;
55     uint64_t begin = 0;
56     uint64_t end = 0;
57     uint64_t offset = 0;
58     uint64_t major = 0;
59     uint64_t minor = 0;
60     ino_t inode = 0;
61     char perms[5] = {0}; // 5:rwxp
62 
63     // 7658d38000-7658d40000 rw-p 00000000 00:00 0                              [anon:thread signal stack]
64     if (sscanf_s(buf.c_str(), "%" SCNxPTR "-%" SCNxPTR " %4s %" SCNxPTR " %x:%x %" SCNxPTR " %n",
65         &begin, &end, &perms, sizeof(perms), &offset, &major, &minor, &inode, &pos) != 7) { // 7:scan size
66         DFXLOG_WARN("Fail to parse maps info.");
67         return false;
68     }
69 
70     this->begin = begin;
71     this->end = end;
72     this->offset = offset;
73     this->major = major;
74     this->minor = minor;
75     this->inode = inode;
76     this->perms = std::string(perms, sizeof(perms));
77     PermsToProts(this->perms, this->prots, this->flag);
78     TrimAndDupStr(buf.substr(pos), this->name);
79     return true;
80 #else
81     return false;
82 #endif
83 }
84 
IsMapExec()85 bool DfxMap::IsMapExec()
86 {
87     if ((prots & PROT_EXEC) != 0) {
88         return true;
89     }
90     return false;
91 }
92 
IsArkExecutable()93 bool DfxMap::IsArkExecutable()
94 {
95     if (name.length() == 0) {
96         return false;
97     }
98 
99     if ((!StartsWith(name, "[anon:ArkTS Code]")) && (!StartsWith(name, "/dev/zero")) && (!EndsWith(name, ".an"))) {
100         return false;
101     }
102 
103     if (!IsMapExec()) {
104         return false;
105     }
106     LOGU("current map is ark map: %s", name.c_str());
107     return true;
108 }
109 
GetRelPc(uint64_t pc)110 uint64_t DfxMap::GetRelPc(uint64_t pc)
111 {
112     if (GetElf() != nullptr) {
113         return GetElf()->GetRelPc(pc, begin, offset);
114     }
115     return (pc - begin + offset);
116 }
117 
ToString()118 std::string DfxMap::ToString()
119 {
120     char buf[LINE_BUF_SIZE] = {0};
121     int ret = snprintf_s(buf, sizeof(buf), sizeof(buf) - 1, "%" PRIx64 "-%" PRIx64 " %s %08" PRIx64 " %s\n", \
122         begin, end, perms.c_str(), offset, name.c_str());
123     if (ret <= 0) {
124         DFXLOG_ERROR("%s :: snprintf_s failed, line: %d.", __func__, __LINE__);
125     }
126     return std::string(buf);
127 }
128 
PermsToProts(const std::string perms,uint32_t & prots,uint32_t & flag)129 void DfxMap::PermsToProts(const std::string perms, uint32_t& prots, uint32_t& flag)
130 {
131     // rwxp
132     if (perms.find("r") != std::string::npos) {
133         prots |= PROT_READ;
134     }
135 
136     if (perms.find("w") != std::string::npos) {
137         prots |= PROT_WRITE;
138     }
139 
140     if (perms.find("x") != std::string::npos) {
141         prots |= PROT_EXEC;
142     }
143 
144     if (perms.find("p") != std::string::npos) {
145         flag = MAP_PRIVATE;
146     } else if (perms.find("s") != std::string::npos) {
147         flag = MAP_SHARED;
148     }
149 }
150 
GetElf()151 const std::shared_ptr<DfxElf> DfxMap::GetElf()
152 {
153     if (elf == nullptr) {
154         if (name.empty()) {
155             LOGE("Invalid map, name empty.");
156             return nullptr;
157         }
158         LOGU("GetElf name: %s", name.c_str());
159         if (EndsWith(name, ".hap")) {
160             elf = DfxElf::CreateFromHap(name, prevMap, offset);
161         } else {
162             elf = DfxElf::Create(name);
163         }
164     }
165     return elf;
166 }
167 
GetElfName()168 std::string DfxMap::GetElfName()
169 {
170     if (name.empty() || GetElf() == nullptr) {
171         return name;
172     }
173     std::string soName = name;
174     if (EndsWith(name, ".hap")) {
175         soName.append("!" + elf->GetElfName());
176     }
177     return soName;
178 }
179 } // namespace HiviewDFX
180 } // namespace OHOS
181