146756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris/* 246756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris * Copyright (C) 2014 The Android Open Source Project 346756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris * 446756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris * Licensed under the Apache License, Version 2.0 (the "License"); 546756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris * you may not use this file except in compliance with the License. 646756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris * You may obtain a copy of the License at 746756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris * 846756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris * http://www.apache.org/licenses/LICENSE-2.0 946756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris * 1046756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris * Unless required by applicable law or agreed to in writing, software 1146756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris * distributed under the License is distributed on an "AS IS" BASIS, 1246756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1346756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris * See the License for the specific language governing permissions and 1446756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris * limitations under the License. 1546756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris */ 1646756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris 1746756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris#ifndef _BACKTRACE_BACKTRACE_MAP_H 1846756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris#define _BACKTRACE_BACKTRACE_MAP_H 1946756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris 2046756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris#include <stdint.h> 21ac2fe7eb81789274ab98573d0c4b0866bed1f254Dan Albert#include <sys/types.h> 220dbce4564bd697bc2603f6c05ac47b81977cd41fChristopher Ferris#ifdef USE_MINGW 230dbce4564bd697bc2603f6c05ac47b81977cd41fChristopher Ferris// MINGW does not define these constants. 240dbce4564bd697bc2603f6c05ac47b81977cd41fChristopher Ferris#define PROT_NONE 0 250dbce4564bd697bc2603f6c05ac47b81977cd41fChristopher Ferris#define PROT_READ 0x1 260dbce4564bd697bc2603f6c05ac47b81977cd41fChristopher Ferris#define PROT_WRITE 0x2 270dbce4564bd697bc2603f6c05ac47b81977cd41fChristopher Ferris#define PROT_EXEC 0x4 280dbce4564bd697bc2603f6c05ac47b81977cd41fChristopher Ferris#else 2946756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris#include <sys/mman.h> 300dbce4564bd697bc2603f6c05ac47b81977cd41fChristopher Ferris#endif 3146756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris 32df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris#include <deque> 3346756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris#include <string> 3446756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris 3546756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferrisstruct backtrace_map_t { 3621bd040effcfc48e8794558c91bbfdc159a98f00Christopher Ferris uintptr_t start = 0; 3721bd040effcfc48e8794558c91bbfdc159a98f00Christopher Ferris uintptr_t end = 0; 3821bd040effcfc48e8794558c91bbfdc159a98f00Christopher Ferris uintptr_t offset = 0; 3921bd040effcfc48e8794558c91bbfdc159a98f00Christopher Ferris uintptr_t load_base = 0; 4021bd040effcfc48e8794558c91bbfdc159a98f00Christopher Ferris int flags = 0; 4146756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris std::string name; 4246756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris}; 4346756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris 4446756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferrisclass BacktraceMap { 4546756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferrispublic: 46dda47b786835ef3689f06e24650eb65176e2dc5eChristopher Ferris // If uncached is true, then parse the current process map as of the call. 47dda47b786835ef3689f06e24650eb65176e2dc5eChristopher Ferris // Passing a map created with uncached set to true to Backtrace::Create() 48dda47b786835ef3689f06e24650eb65176e2dc5eChristopher Ferris // is unsupported. 49dda47b786835ef3689f06e24650eb65176e2dc5eChristopher Ferris static BacktraceMap* Create(pid_t pid, bool uncached = false); 50df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris 5146756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris virtual ~BacktraceMap(); 5246756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris 5312385e3ad085aa1ac06c26529b32b688503a9fcfChristopher Ferris // Fill in the map data structure for the given address. 5412385e3ad085aa1ac06c26529b32b688503a9fcfChristopher Ferris virtual void FillIn(uintptr_t addr, backtrace_map_t* map); 5546756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris 5646756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris // The flags returned are the same flags as used by the mmap call. 5746756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris // The values are PROT_*. 5846756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris int GetFlags(uintptr_t pc) { 5912385e3ad085aa1ac06c26529b32b688503a9fcfChristopher Ferris backtrace_map_t map; 6012385e3ad085aa1ac06c26529b32b688503a9fcfChristopher Ferris FillIn(pc, &map); 6112385e3ad085aa1ac06c26529b32b688503a9fcfChristopher Ferris if (IsValid(map)) { 6212385e3ad085aa1ac06c26529b32b688503a9fcfChristopher Ferris return map.flags; 6346756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris } 6446756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris return PROT_NONE; 6546756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris } 6646756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris 6746756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris bool IsReadable(uintptr_t pc) { return GetFlags(pc) & PROT_READ; } 6846756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris bool IsWritable(uintptr_t pc) { return GetFlags(pc) & PROT_WRITE; } 6946756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris bool IsExecutable(uintptr_t pc) { return GetFlags(pc) & PROT_EXEC; } 7046756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris 71df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris typedef std::deque<backtrace_map_t>::iterator iterator; 7246756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris iterator begin() { return maps_.begin(); } 7346756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris iterator end() { return maps_.end(); } 7446756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris 75df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris typedef std::deque<backtrace_map_t>::const_iterator const_iterator; 7646756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris const_iterator begin() const { return maps_.begin(); } 7746756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris const_iterator end() const { return maps_.end(); } 7846756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris 7946756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris virtual bool Build(); 8046756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris 8112385e3ad085aa1ac06c26529b32b688503a9fcfChristopher Ferris static inline bool IsValid(const backtrace_map_t& map) { 8212385e3ad085aa1ac06c26529b32b688503a9fcfChristopher Ferris return map.end > 0; 8312385e3ad085aa1ac06c26529b32b688503a9fcfChristopher Ferris } 8412385e3ad085aa1ac06c26529b32b688503a9fcfChristopher Ferris 85329ed7dae49eba09bdf865dd999d1a7e73bb9687Christopher Ferris static uintptr_t GetRelativePc(const backtrace_map_t& map, uintptr_t pc) { 86329ed7dae49eba09bdf865dd999d1a7e73bb9687Christopher Ferris if (IsValid(map)) { 87329ed7dae49eba09bdf865dd999d1a7e73bb9687Christopher Ferris return pc - map.start + map.load_base; 88329ed7dae49eba09bdf865dd999d1a7e73bb9687Christopher Ferris } else { 89329ed7dae49eba09bdf865dd999d1a7e73bb9687Christopher Ferris return pc; 90329ed7dae49eba09bdf865dd999d1a7e73bb9687Christopher Ferris } 91329ed7dae49eba09bdf865dd999d1a7e73bb9687Christopher Ferris } 92329ed7dae49eba09bdf865dd999d1a7e73bb9687Christopher Ferris 9346756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferrisprotected: 94df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris BacktraceMap(pid_t pid); 95df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris 9646756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris virtual bool ParseLine(const char* line, backtrace_map_t* map); 9746756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris 98df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris std::deque<backtrace_map_t> maps_; 9946756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris pid_t pid_; 10046756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris}; 10146756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris 10246756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris#endif // _BACKTRACE_BACKTRACE_MAP_H 103