1800b99b8Sopenharmony_ci/* 2800b99b8Sopenharmony_ci * Copyright (c) 2022-2024 Huawei Device Co., Ltd. 3800b99b8Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4800b99b8Sopenharmony_ci * you may not use this file except in compliance with the License. 5800b99b8Sopenharmony_ci * You may obtain a copy of the License at 6800b99b8Sopenharmony_ci * 7800b99b8Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8800b99b8Sopenharmony_ci * 9800b99b8Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10800b99b8Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11800b99b8Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12800b99b8Sopenharmony_ci * See the License for the specific language governing permissions and 13800b99b8Sopenharmony_ci * limitations under the License. 14800b99b8Sopenharmony_ci */ 15800b99b8Sopenharmony_ci#ifndef DFX_SYMBOL_H 16800b99b8Sopenharmony_ci#define DFX_SYMBOL_H 17800b99b8Sopenharmony_ci 18800b99b8Sopenharmony_ci#include <cstdint> 19800b99b8Sopenharmony_ci#include <iomanip> 20800b99b8Sopenharmony_ci#include <sstream> 21800b99b8Sopenharmony_ci#include <string> 22800b99b8Sopenharmony_ci#include <vector> 23800b99b8Sopenharmony_ci#include "string_view_util.h" 24800b99b8Sopenharmony_ci 25800b99b8Sopenharmony_cinamespace OHOS { 26800b99b8Sopenharmony_cinamespace HiviewDFX { 27800b99b8Sopenharmony_cistruct DfxSymbol { 28800b99b8Sopenharmony_ci uint64_t funcVaddr_ = 0; 29800b99b8Sopenharmony_ci uint64_t offsetToVaddr_ = 0; 30800b99b8Sopenharmony_ci uint64_t fileVaddr_ = 0; 31800b99b8Sopenharmony_ci uint64_t taskVaddr_ = 0; 32800b99b8Sopenharmony_ci uint64_t size_ = 0; 33800b99b8Sopenharmony_ci uint32_t filePathId_ = 0; // for memMpaItem filePathId_ 34800b99b8Sopenharmony_ci uint32_t symbolNameId_ = 0; // for symbolName_ id 35800b99b8Sopenharmony_ci int32_t symbolFileIndex_ = -1; // symbols file index, used to report protobuf file 36800b99b8Sopenharmony_ci int32_t index_ = -1; 37800b99b8Sopenharmony_ci uint32_t symbolId_ = 0; // for frame map id 38800b99b8Sopenharmony_ci STRING_VIEW name_ = ""; 39800b99b8Sopenharmony_ci STRING_VIEW demangle_ = ""; // demangle string 40800b99b8Sopenharmony_ci STRING_VIEW module_ = ""; // maybe empty 41800b99b8Sopenharmony_ci STRING_VIEW comm_ = ""; // we need a comm name like comm@0x1234 42800b99b8Sopenharmony_ci STRING_VIEW symbolName_ = ""; 43800b99b8Sopenharmony_ci mutable STRING_VIEW unknow_ = ""; 44800b99b8Sopenharmony_ci uint64_t offset_ = 0; 45800b99b8Sopenharmony_ci mutable bool matched_ = false; // if some callstack match this 46800b99b8Sopenharmony_ci int32_t hit_ = 0; 47800b99b8Sopenharmony_ci 48800b99b8Sopenharmony_ci // elf use this 49800b99b8Sopenharmony_ci DfxSymbol(uint64_t vaddr, uint64_t size, const std::string &name, const std::string &demangle, 50800b99b8Sopenharmony_ci const std::string module) 51800b99b8Sopenharmony_ci : funcVaddr_(vaddr), 52800b99b8Sopenharmony_ci fileVaddr_(vaddr), 53800b99b8Sopenharmony_ci size_(size), 54800b99b8Sopenharmony_ci name_(StringViewHold::Get().Hold(name)), 55800b99b8Sopenharmony_ci demangle_(StringViewHold::Get().Hold(demangle)), 56800b99b8Sopenharmony_ci module_(StringViewHold::Get().Hold(module)) {} 57800b99b8Sopenharmony_ci DfxSymbol(uint64_t vaddr, uint64_t size, const std::string &name, const std::string &module) 58800b99b8Sopenharmony_ci : DfxSymbol(vaddr, size, name, name, module) {} 59800b99b8Sopenharmony_ci 60800b99b8Sopenharmony_ci // kernel use this 61800b99b8Sopenharmony_ci DfxSymbol(uint64_t vaddr, const std::string &name, const std::string &module) 62800b99b8Sopenharmony_ci : DfxSymbol(vaddr, 0, name, name, module) {} 63800b99b8Sopenharmony_ci 64800b99b8Sopenharmony_ci // Symbolic use this 65800b99b8Sopenharmony_ci DfxSymbol(uint64_t taskVaddr = 0, const std::string &comm = "") 66800b99b8Sopenharmony_ci : taskVaddr_(taskVaddr), comm_(comm) {} 67800b99b8Sopenharmony_ci 68800b99b8Sopenharmony_ci DfxSymbol(const DfxSymbol &other) = default; 69800b99b8Sopenharmony_ci 70800b99b8Sopenharmony_ci DfxSymbol& operator=(const DfxSymbol& other) = default; 71800b99b8Sopenharmony_ci 72800b99b8Sopenharmony_ci inline bool Equal(const DfxSymbol &b) const 73800b99b8Sopenharmony_ci { 74800b99b8Sopenharmony_ci return ((funcVaddr_ == b.funcVaddr_) && (demangle_ == b.demangle_)); 75800b99b8Sopenharmony_ci } 76800b99b8Sopenharmony_ci 77800b99b8Sopenharmony_ci inline bool operator==(const DfxSymbol &b) const 78800b99b8Sopenharmony_ci { 79800b99b8Sopenharmony_ci return Equal(b); 80800b99b8Sopenharmony_ci } 81800b99b8Sopenharmony_ci 82800b99b8Sopenharmony_ci inline bool operator!=(const DfxSymbol &b) const 83800b99b8Sopenharmony_ci { 84800b99b8Sopenharmony_ci return !Equal(b); 85800b99b8Sopenharmony_ci } 86800b99b8Sopenharmony_ci 87800b99b8Sopenharmony_ci inline bool IsValid() const 88800b99b8Sopenharmony_ci { 89800b99b8Sopenharmony_ci return !module_.empty(); 90800b99b8Sopenharmony_ci } 91800b99b8Sopenharmony_ci void SetMatchFlag() const 92800b99b8Sopenharmony_ci { 93800b99b8Sopenharmony_ci matched_ = true; 94800b99b8Sopenharmony_ci } 95800b99b8Sopenharmony_ci 96800b99b8Sopenharmony_ci bool HasMatched() const 97800b99b8Sopenharmony_ci { 98800b99b8Sopenharmony_ci return matched_; 99800b99b8Sopenharmony_ci } 100800b99b8Sopenharmony_ci 101800b99b8Sopenharmony_ci void SetIpVAddress(uint64_t vaddr) 102800b99b8Sopenharmony_ci { 103800b99b8Sopenharmony_ci fileVaddr_ = vaddr; 104800b99b8Sopenharmony_ci offset_ = fileVaddr_ - funcVaddr_; 105800b99b8Sopenharmony_ci } 106800b99b8Sopenharmony_ci 107800b99b8Sopenharmony_ci STRING_VIEW GetName() const 108800b99b8Sopenharmony_ci { 109800b99b8Sopenharmony_ci if (!demangle_.empty()) { 110800b99b8Sopenharmony_ci return demangle_; 111800b99b8Sopenharmony_ci } 112800b99b8Sopenharmony_ci if (!name_.empty()) { 113800b99b8Sopenharmony_ci return name_; 114800b99b8Sopenharmony_ci } 115800b99b8Sopenharmony_ci if (unknow_.empty()) { 116800b99b8Sopenharmony_ci std::stringstream ss; 117800b99b8Sopenharmony_ci if (!module_.empty()) { 118800b99b8Sopenharmony_ci ss << module_ << "+0x" << std::hex << fileVaddr_; 119800b99b8Sopenharmony_ci } else { 120800b99b8Sopenharmony_ci ss << comm_ << "@0x" << std::hex << taskVaddr_; 121800b99b8Sopenharmony_ci } 122800b99b8Sopenharmony_ci unknow_ = StringViewHold::Get().Hold(ss.str()); 123800b99b8Sopenharmony_ci } 124800b99b8Sopenharmony_ci return unknow_; 125800b99b8Sopenharmony_ci } 126800b99b8Sopenharmony_ci 127800b99b8Sopenharmony_ci inline std::string ToString() const 128800b99b8Sopenharmony_ci { 129800b99b8Sopenharmony_ci std::stringstream ss; 130800b99b8Sopenharmony_ci if (fileVaddr_ != 0) { 131800b99b8Sopenharmony_ci ss << "0x" << std::hex << fileVaddr_; 132800b99b8Sopenharmony_ci } else { 133800b99b8Sopenharmony_ci ss << "0x" << std::hex << taskVaddr_; 134800b99b8Sopenharmony_ci } 135800b99b8Sopenharmony_ci ss << " " << GetName(); 136800b99b8Sopenharmony_ci return ss.str(); 137800b99b8Sopenharmony_ci }; 138800b99b8Sopenharmony_ci 139800b99b8Sopenharmony_ci std::string ToDebugString() const 140800b99b8Sopenharmony_ci { 141800b99b8Sopenharmony_ci std::stringstream ss; 142800b99b8Sopenharmony_ci ss << "0x" << std::setfill('0') << std::setw(sizeof(funcVaddr_) * 2); // 2 : a multiplicand 143800b99b8Sopenharmony_ci ss << std::hex << funcVaddr_; 144800b99b8Sopenharmony_ci ss << "|"; 145800b99b8Sopenharmony_ci ss << std::setfill('0') << std::setw(sizeof(size_)) << size_; 146800b99b8Sopenharmony_ci ss << "|"; 147800b99b8Sopenharmony_ci ss << demangle_ << "|"; 148800b99b8Sopenharmony_ci ss << name_ << "|"; 149800b99b8Sopenharmony_ci ss << (matched_ ? "matched" : ""); 150800b99b8Sopenharmony_ci ss << " unknowname:" << unknow_.size(); 151800b99b8Sopenharmony_ci ss << " task:" << (comm_.size() > 0 ? comm_ : ""); 152800b99b8Sopenharmony_ci ss << "@" << taskVaddr_; 153800b99b8Sopenharmony_ci ss << " file:" << (module_.size() > 0 ? module_ : ""); 154800b99b8Sopenharmony_ci ss << "@" << fileVaddr_; 155800b99b8Sopenharmony_ci return ss.str(); 156800b99b8Sopenharmony_ci }; 157800b99b8Sopenharmony_ci 158800b99b8Sopenharmony_ci inline bool Contain(uint64_t addr) const 159800b99b8Sopenharmony_ci { 160800b99b8Sopenharmony_ci if (size_ == 0) { 161800b99b8Sopenharmony_ci return funcVaddr_ <= addr; 162800b99b8Sopenharmony_ci } else { 163800b99b8Sopenharmony_ci return (funcVaddr_ <= addr) && ((funcVaddr_ + size_) > addr); 164800b99b8Sopenharmony_ci } 165800b99b8Sopenharmony_ci } 166800b99b8Sopenharmony_ci 167800b99b8Sopenharmony_ci // The range [first, last) must be partitioned with respect to the expression 168800b99b8Sopenharmony_ci // !(value < element) or !comp(value, element) 169800b99b8Sopenharmony_ci static bool ValueLessThen(uint64_t vaddr, const DfxSymbol &a) 170800b99b8Sopenharmony_ci { 171800b99b8Sopenharmony_ci return vaddr < a.funcVaddr_; 172800b99b8Sopenharmony_ci } 173800b99b8Sopenharmony_ci 174800b99b8Sopenharmony_ci static bool ValueLessEqual(uint64_t vaddr, const DfxSymbol &a) 175800b99b8Sopenharmony_ci { 176800b99b8Sopenharmony_ci return vaddr <= a.funcVaddr_; 177800b99b8Sopenharmony_ci } 178800b99b8Sopenharmony_ci}; 179800b99b8Sopenharmony_ci} // namespace HiviewDFX 180800b99b8Sopenharmony_ci} // namespace OHOS 181800b99b8Sopenharmony_ci#endif 182