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