1 /* 2 * Copyright (c) 2022-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 #ifndef DFX_SYMBOL_H 16 #define DFX_SYMBOL_H 17 18 #include <cstdint> 19 #include <iomanip> 20 #include <sstream> 21 #include <string> 22 #include <vector> 23 #include "string_view_util.h" 24 25 namespace OHOS { 26 namespace HiviewDFX { 27 struct DfxSymbol { 28 uint64_t funcVaddr_ = 0; 29 uint64_t offsetToVaddr_ = 0; 30 uint64_t fileVaddr_ = 0; 31 uint64_t taskVaddr_ = 0; 32 uint64_t size_ = 0; 33 uint32_t filePathId_ = 0; // for memMpaItem filePathId_ 34 uint32_t symbolNameId_ = 0; // for symbolName_ id 35 int32_t symbolFileIndex_ = -1; // symbols file index, used to report protobuf file 36 int32_t index_ = -1; 37 uint32_t symbolId_ = 0; // for frame map id 38 STRING_VIEW name_ = ""; 39 STRING_VIEW demangle_ = ""; // demangle string 40 STRING_VIEW module_ = ""; // maybe empty 41 STRING_VIEW comm_ = ""; // we need a comm name like comm@0x1234 42 STRING_VIEW symbolName_ = ""; 43 mutable STRING_VIEW unknow_ = ""; 44 uint64_t offset_ = 0; 45 mutable bool matched_ = false; // if some callstack match this 46 int32_t hit_ = 0; 47 48 // elf use this DfxSymbolDfxSymbol49 DfxSymbol(uint64_t vaddr, uint64_t size, const std::string &name, const std::string &demangle, 50 const std::string module) 51 : funcVaddr_(vaddr), 52 fileVaddr_(vaddr), 53 size_(size), 54 name_(StringViewHold::Get().Hold(name)), 55 demangle_(StringViewHold::Get().Hold(demangle)), 56 module_(StringViewHold::Get().Hold(module)) {} DfxSymbolDfxSymbol57 DfxSymbol(uint64_t vaddr, uint64_t size, const std::string &name, const std::string &module) 58 : DfxSymbol(vaddr, size, name, name, module) {} 59 60 // kernel use this DfxSymbolDfxSymbol61 DfxSymbol(uint64_t vaddr, const std::string &name, const std::string &module) 62 : DfxSymbol(vaddr, 0, name, name, module) {} 63 64 // Symbolic use this 65 DfxSymbol(uint64_t taskVaddr = 0, const std::string &comm = "") taskVaddr_DfxSymbol66 : taskVaddr_(taskVaddr), comm_(comm) 67 { 68 } 69 70 DfxSymbol(const DfxSymbol &other) = default; 71 72 DfxSymbol& operator=(const DfxSymbol& other) = default; 73 EqualDfxSymbol74 inline bool Equal(const DfxSymbol &b) const 75 { 76 return ((funcVaddr_ == b.funcVaddr_) && (demangle_ == b.demangle_)); 77 } 78 79 inline bool operator==(const DfxSymbol &b) const 80 { 81 return Equal(b); 82 } 83 84 inline bool operator!=(const DfxSymbol &b) const 85 { 86 return !Equal(b); 87 } 88 IsValidDfxSymbol89 inline bool IsValid() const 90 { 91 return !module_.empty(); 92 } SetMatchFlagDfxSymbol93 void SetMatchFlag() const 94 { 95 matched_ = true; 96 } 97 HasMatchedDfxSymbol98 bool HasMatched() const 99 { 100 return matched_; 101 } 102 SetIpVAddressDfxSymbol103 void SetIpVAddress(uint64_t vaddr) 104 { 105 fileVaddr_ = vaddr; 106 offset_ = fileVaddr_ - funcVaddr_; 107 } 108 GetNameDfxSymbol109 STRING_VIEW GetName() const 110 { 111 if (!demangle_.empty()) { 112 return demangle_; 113 } 114 if (!name_.empty()) { 115 return name_; 116 } 117 if (unknow_.empty()) { 118 std::stringstream ss; 119 if (!module_.empty()) { 120 ss << module_ << "+0x" << std::hex << fileVaddr_; 121 } else { 122 ss << comm_ << "@0x" << std::hex << taskVaddr_; 123 } 124 unknow_ = StringViewHold::Get().Hold(ss.str()); 125 } 126 return unknow_; 127 } 128 ToStringDfxSymbol129 inline std::string ToString() const 130 { 131 std::stringstream ss; 132 if (fileVaddr_ != 0) { 133 ss << "0x" << std::hex << fileVaddr_; 134 } else { 135 ss << "0x" << std::hex << taskVaddr_; 136 } 137 ss << " " << GetName(); 138 return ss.str(); 139 }; 140 ToDebugStringDfxSymbol141 std::string ToDebugString() const 142 { 143 std::stringstream ss; 144 ss << "0x" << std::setfill('0') << std::setw(sizeof(funcVaddr_) * 2); // 2 : a multiplicand 145 ss << std::hex << funcVaddr_; 146 ss << "|"; 147 ss << std::setfill('0') << std::setw(sizeof(size_)) << size_; 148 ss << "|"; 149 ss << demangle_ << "|"; 150 ss << name_ << "|"; 151 ss << (matched_ ? "matched" : ""); 152 ss << " unknowname:" << unknow_.size(); 153 ss << " task:" << (comm_.size() > 0 ? comm_ : ""); 154 ss << "@" << taskVaddr_; 155 ss << " file:" << (module_.size() > 0 ? module_ : ""); 156 ss << "@" << fileVaddr_; 157 return ss.str(); 158 }; 159 ContainDfxSymbol160 inline bool Contain(uint64_t addr) const 161 { 162 if (size_ == 0) { 163 return funcVaddr_ <= addr; 164 } else { 165 return (funcVaddr_ <= addr) && ((funcVaddr_ + size_) > addr); 166 } 167 } 168 169 // The range [first, last) must be partitioned with respect to the expression 170 // !(value < element) or !comp(value, element) ValueLessThenDfxSymbol171 static bool ValueLessThen(uint64_t vaddr, const DfxSymbol &a) 172 { 173 return vaddr < a.funcVaddr_; 174 } 175 ValueLessEqualDfxSymbol176 static bool ValueLessEqual(uint64_t vaddr, const DfxSymbol &a) 177 { 178 return vaddr <= a.funcVaddr_; 179 } 180 }; 181 } // namespace HiviewDFX 182 } // namespace OHOS 183 #endif 184