1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright (C) 2014 The Android Open Source Project 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 5bf215546Sopenharmony_ci * you may not use this file except in compliance with the License. 6bf215546Sopenharmony_ci * You may obtain a copy of the License at 7bf215546Sopenharmony_ci * 8bf215546Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 9bf215546Sopenharmony_ci * 10bf215546Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 11bf215546Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 12bf215546Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bf215546Sopenharmony_ci * See the License for the specific language governing permissions and 14bf215546Sopenharmony_ci * limitations under the License. 15bf215546Sopenharmony_ci */ 16bf215546Sopenharmony_ci 17bf215546Sopenharmony_ci#ifndef _BACKTRACE_BACKTRACE_MAP_H 18bf215546Sopenharmony_ci#define _BACKTRACE_BACKTRACE_MAP_H 19bf215546Sopenharmony_ci 20bf215546Sopenharmony_ci#include <stdint.h> 21bf215546Sopenharmony_ci#include <sys/types.h> 22bf215546Sopenharmony_ci#ifdef _WIN32 23bf215546Sopenharmony_ci// MINGW does not define these constants. 24bf215546Sopenharmony_ci#define PROT_NONE 0 25bf215546Sopenharmony_ci#define PROT_READ 0x1 26bf215546Sopenharmony_ci#define PROT_WRITE 0x2 27bf215546Sopenharmony_ci#define PROT_EXEC 0x4 28bf215546Sopenharmony_ci#else 29bf215546Sopenharmony_ci#include <sys/mman.h> 30bf215546Sopenharmony_ci#endif 31bf215546Sopenharmony_ci 32bf215546Sopenharmony_ci#include <deque> 33bf215546Sopenharmony_ci#include <iterator> 34bf215546Sopenharmony_ci#include <memory> 35bf215546Sopenharmony_ci#include <string> 36bf215546Sopenharmony_ci#include <vector> 37bf215546Sopenharmony_ci 38bf215546Sopenharmony_ci// Forward declaration. 39bf215546Sopenharmony_cistruct backtrace_stackinfo_t; 40bf215546Sopenharmony_ci 41bf215546Sopenharmony_ci// Special flag to indicate a map is in /dev/. However, a map in 42bf215546Sopenharmony_ci// /dev/ashmem/... does not set this flag. 43bf215546Sopenharmony_cistatic constexpr int PROT_DEVICE_MAP = 0x8000; 44bf215546Sopenharmony_ci// Special flag to indicate that this map represents an elf file 45bf215546Sopenharmony_ci// created by ART for use with the gdb jit debug interface. 46bf215546Sopenharmony_ci// This should only ever appear in offline maps data. 47bf215546Sopenharmony_cistatic constexpr int PROT_JIT_SYMFILE_MAP = 0x4000; 48bf215546Sopenharmony_ci 49bf215546Sopenharmony_cistruct backtrace_map_t { 50bf215546Sopenharmony_ci uint64_t start = 0; 51bf215546Sopenharmony_ci uint64_t end = 0; 52bf215546Sopenharmony_ci uint64_t offset = 0; 53bf215546Sopenharmony_ci uint64_t load_bias = 0; 54bf215546Sopenharmony_ci int flags = 0; 55bf215546Sopenharmony_ci std::string name; 56bf215546Sopenharmony_ci 57bf215546Sopenharmony_ci // Returns `name` if non-empty, or `<anonymous:0x...>` otherwise. 58bf215546Sopenharmony_ci std::string Name() const; 59bf215546Sopenharmony_ci}; 60bf215546Sopenharmony_ci 61bf215546Sopenharmony_cinamespace unwindstack { 62bf215546Sopenharmony_ciclass Memory; 63bf215546Sopenharmony_ci} 64bf215546Sopenharmony_ci 65bf215546Sopenharmony_ciclass BacktraceMap { 66bf215546Sopenharmony_cipublic: 67bf215546Sopenharmony_ci // If uncached is true, then parse the current process map as of the call. 68bf215546Sopenharmony_ci // Passing a map created with uncached set to true to Backtrace::Create() 69bf215546Sopenharmony_ci // is unsupported. 70bf215546Sopenharmony_ci static BacktraceMap* Create(pid_t pid, bool uncached = false); 71bf215546Sopenharmony_ci 72bf215546Sopenharmony_ci virtual ~BacktraceMap(); 73bf215546Sopenharmony_ci 74bf215546Sopenharmony_ci class iterator : public std::iterator<std::bidirectional_iterator_tag, backtrace_map_t*> { 75bf215546Sopenharmony_ci public: 76bf215546Sopenharmony_ci iterator(BacktraceMap* map, size_t index) : map_(map), index_(index) {} 77bf215546Sopenharmony_ci 78bf215546Sopenharmony_ci iterator& operator++() { 79bf215546Sopenharmony_ci index_++; 80bf215546Sopenharmony_ci return *this; 81bf215546Sopenharmony_ci } 82bf215546Sopenharmony_ci const iterator operator++(int increment) { 83bf215546Sopenharmony_ci index_ += increment; 84bf215546Sopenharmony_ci return *this; 85bf215546Sopenharmony_ci } 86bf215546Sopenharmony_ci iterator& operator--() { 87bf215546Sopenharmony_ci index_--; 88bf215546Sopenharmony_ci return *this; 89bf215546Sopenharmony_ci } 90bf215546Sopenharmony_ci const iterator operator--(int decrement) { 91bf215546Sopenharmony_ci index_ -= decrement; 92bf215546Sopenharmony_ci return *this; 93bf215546Sopenharmony_ci } 94bf215546Sopenharmony_ci 95bf215546Sopenharmony_ci bool operator==(const iterator& rhs) { return this->index_ == rhs.index_; } 96bf215546Sopenharmony_ci bool operator!=(const iterator& rhs) { return this->index_ != rhs.index_; } 97bf215546Sopenharmony_ci 98bf215546Sopenharmony_ci const backtrace_map_t* operator*() { 99bf215546Sopenharmony_ci if (index_ >= map_->size()) { 100bf215546Sopenharmony_ci return nullptr; 101bf215546Sopenharmony_ci } 102bf215546Sopenharmony_ci backtrace_map_t* map = &map_->maps_[index_]; 103bf215546Sopenharmony_ci if (map->load_bias == static_cast<uint64_t>(-1)) { 104bf215546Sopenharmony_ci map->load_bias = map_->GetLoadBias(index_); 105bf215546Sopenharmony_ci } 106bf215546Sopenharmony_ci return map; 107bf215546Sopenharmony_ci } 108bf215546Sopenharmony_ci 109bf215546Sopenharmony_ci private: 110bf215546Sopenharmony_ci BacktraceMap* map_ = nullptr; 111bf215546Sopenharmony_ci size_t index_ = 0; 112bf215546Sopenharmony_ci }; 113bf215546Sopenharmony_ci 114bf215546Sopenharmony_ci iterator begin() { return iterator(this, 0); } 115bf215546Sopenharmony_ci iterator end() { return iterator(this, maps_.size()); } 116bf215546Sopenharmony_ci 117bf215546Sopenharmony_ci // Fill in the map data structure for the given address. 118bf215546Sopenharmony_ci virtual void FillIn(uint64_t addr, backtrace_map_t* map); 119bf215546Sopenharmony_ci 120bf215546Sopenharmony_ci // Only supported with the new unwinder. 121bf215546Sopenharmony_ci virtual std::string GetFunctionName(uint64_t /*pc*/, uint64_t* /*offset*/) { return ""; } 122bf215546Sopenharmony_ci virtual std::shared_ptr<unwindstack::Memory> GetProcessMemory() { return nullptr; } 123bf215546Sopenharmony_ci 124bf215546Sopenharmony_ci // The flags returned are the same flags as used by the mmap call. 125bf215546Sopenharmony_ci // The values are PROT_*. 126bf215546Sopenharmony_ci int GetFlags(uint64_t pc) { 127bf215546Sopenharmony_ci backtrace_map_t map; 128bf215546Sopenharmony_ci FillIn(pc, &map); 129bf215546Sopenharmony_ci if (IsValid(map)) { 130bf215546Sopenharmony_ci return map.flags; 131bf215546Sopenharmony_ci } 132bf215546Sopenharmony_ci return PROT_NONE; 133bf215546Sopenharmony_ci } 134bf215546Sopenharmony_ci 135bf215546Sopenharmony_ci bool IsReadable(uint64_t pc) { return GetFlags(pc) & PROT_READ; } 136bf215546Sopenharmony_ci bool IsWritable(uint64_t pc) { return GetFlags(pc) & PROT_WRITE; } 137bf215546Sopenharmony_ci bool IsExecutable(uint64_t pc) { return GetFlags(pc) & PROT_EXEC; } 138bf215546Sopenharmony_ci 139bf215546Sopenharmony_ci // In order to use the iterators on this object, a caller must 140bf215546Sopenharmony_ci // call the LockIterator and UnlockIterator function to guarantee 141bf215546Sopenharmony_ci // that the data does not change while it's being used. 142bf215546Sopenharmony_ci virtual void LockIterator() {} 143bf215546Sopenharmony_ci virtual void UnlockIterator() {} 144bf215546Sopenharmony_ci 145bf215546Sopenharmony_ci size_t size() const { return maps_.size(); } 146bf215546Sopenharmony_ci 147bf215546Sopenharmony_ci virtual bool Build(); 148bf215546Sopenharmony_ci 149bf215546Sopenharmony_ci static inline bool IsValid(const backtrace_map_t& map) { 150bf215546Sopenharmony_ci return map.end > 0; 151bf215546Sopenharmony_ci } 152bf215546Sopenharmony_ci 153bf215546Sopenharmony_ci void SetSuffixesToIgnore(std::vector<std::string> suffixes) { 154bf215546Sopenharmony_ci suffixes_to_ignore_.insert(suffixes_to_ignore_.end(), suffixes.begin(), suffixes.end()); 155bf215546Sopenharmony_ci } 156bf215546Sopenharmony_ci 157bf215546Sopenharmony_ci const std::vector<std::string>& GetSuffixesToIgnore() { return suffixes_to_ignore_; } 158bf215546Sopenharmony_ci 159bf215546Sopenharmony_ci // Disabling the resolving of names results in the function name being 160bf215546Sopenharmony_ci // set to an empty string and the function offset being set to zero 161bf215546Sopenharmony_ci // in the frame data when unwinding. 162bf215546Sopenharmony_ci void SetResolveNames(bool resolve) { resolve_names_ = resolve; } 163bf215546Sopenharmony_ci 164bf215546Sopenharmony_ci bool ResolveNames() { return resolve_names_; } 165bf215546Sopenharmony_ci 166bf215546Sopenharmony_ci protected: 167bf215546Sopenharmony_ci BacktraceMap(pid_t pid); 168bf215546Sopenharmony_ci 169bf215546Sopenharmony_ci virtual uint64_t GetLoadBias(size_t /* index */) { return 0; } 170bf215546Sopenharmony_ci 171bf215546Sopenharmony_ci pid_t pid_; 172bf215546Sopenharmony_ci std::deque<backtrace_map_t> maps_; 173bf215546Sopenharmony_ci std::vector<std::string> suffixes_to_ignore_; 174bf215546Sopenharmony_ci bool resolve_names_ = true; 175bf215546Sopenharmony_ci}; 176bf215546Sopenharmony_ci 177bf215546Sopenharmony_ciclass ScopedBacktraceMapIteratorLock { 178bf215546Sopenharmony_cipublic: 179bf215546Sopenharmony_ci explicit ScopedBacktraceMapIteratorLock(BacktraceMap* map) : map_(map) { 180bf215546Sopenharmony_ci map->LockIterator(); 181bf215546Sopenharmony_ci } 182bf215546Sopenharmony_ci 183bf215546Sopenharmony_ci ~ScopedBacktraceMapIteratorLock() { 184bf215546Sopenharmony_ci map_->UnlockIterator(); 185bf215546Sopenharmony_ci } 186bf215546Sopenharmony_ci 187bf215546Sopenharmony_ciprivate: 188bf215546Sopenharmony_ci BacktraceMap* map_; 189bf215546Sopenharmony_ci}; 190bf215546Sopenharmony_ci 191bf215546Sopenharmony_ci#endif // _BACKTRACE_BACKTRACE_MAP_H 192