1 /* 2 * Copyright (c) 2022-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 #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 = "") 66 : taskVaddr_(taskVaddr), comm_(comm) {} 67 68 DfxSymbol(const DfxSymbol &other) = default; 69 70 DfxSymbol& operator=(const DfxSymbol& other) = default; 71 EqualDfxSymbol72 inline bool Equal(const DfxSymbol &b) const 73 { 74 return ((funcVaddr_ == b.funcVaddr_) && (demangle_ == b.demangle_)); 75 } 76 77 inline bool operator==(const DfxSymbol &b) const 78 { 79 return Equal(b); 80 } 81 82 inline bool operator!=(const DfxSymbol &b) const 83 { 84 return !Equal(b); 85 } 86 IsValidDfxSymbol87 inline bool IsValid() const 88 { 89 return !module_.empty(); 90 } SetMatchFlagDfxSymbol91 void SetMatchFlag() const 92 { 93 matched_ = true; 94 } 95 HasMatchedDfxSymbol96 bool HasMatched() const 97 { 98 return matched_; 99 } 100 SetIpVAddressDfxSymbol101 void SetIpVAddress(uint64_t vaddr) 102 { 103 fileVaddr_ = vaddr; 104 offset_ = fileVaddr_ - funcVaddr_; 105 } 106 GetNameDfxSymbol107 STRING_VIEW GetName() const 108 { 109 if (!demangle_.empty()) { 110 return demangle_; 111 } 112 if (!name_.empty()) { 113 return name_; 114 } 115 if (unknow_.empty()) { 116 std::stringstream ss; 117 if (!module_.empty()) { 118 ss << module_ << "+0x" << std::hex << fileVaddr_; 119 } else { 120 ss << comm_ << "@0x" << std::hex << taskVaddr_; 121 } 122 unknow_ = StringViewHold::Get().Hold(ss.str()); 123 } 124 return unknow_; 125 } 126 ToStringDfxSymbol127 inline std::string ToString() const 128 { 129 std::stringstream ss; 130 if (fileVaddr_ != 0) { 131 ss << "0x" << std::hex << fileVaddr_; 132 } else { 133 ss << "0x" << std::hex << taskVaddr_; 134 } 135 ss << " " << GetName(); 136 return ss.str(); 137 }; 138 ToDebugStringDfxSymbol139 std::string ToDebugString() const 140 { 141 std::stringstream ss; 142 ss << "0x" << std::setfill('0') << std::setw(sizeof(funcVaddr_) * 2); // 2 : a multiplicand 143 ss << std::hex << funcVaddr_; 144 ss << "|"; 145 ss << std::setfill('0') << std::setw(sizeof(size_)) << size_; 146 ss << "|"; 147 ss << demangle_ << "|"; 148 ss << name_ << "|"; 149 ss << (matched_ ? "matched" : ""); 150 ss << " unknowname:" << unknow_.size(); 151 ss << " task:" << (comm_.size() > 0 ? comm_ : ""); 152 ss << "@" << taskVaddr_; 153 ss << " file:" << (module_.size() > 0 ? module_ : ""); 154 ss << "@" << fileVaddr_; 155 return ss.str(); 156 }; 157 ContainDfxSymbol158 inline bool Contain(uint64_t addr) const 159 { 160 if (size_ == 0) { 161 return funcVaddr_ <= addr; 162 } else { 163 return (funcVaddr_ <= addr) && ((funcVaddr_ + size_) > addr); 164 } 165 } 166 167 // The range [first, last) must be partitioned with respect to the expression 168 // !(value < element) or !comp(value, element) ValueLessThenDfxSymbol169 static bool ValueLessThen(uint64_t vaddr, const DfxSymbol &a) 170 { 171 return vaddr < a.funcVaddr_; 172 } 173 ValueLessEqualDfxSymbol174 static bool ValueLessEqual(uint64_t vaddr, const DfxSymbol &a) 175 { 176 return vaddr <= a.funcVaddr_; 177 } 178 }; 179 } // namespace HiviewDFX 180 } // namespace OHOS 181 #endif 182