1723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris/* 2723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris * Copyright (C) 2016 The Android Open Source Project 3723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris * 4723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris * Licensed under the Apache License, Version 2.0 (the "License"); 5723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris * you may not use this file except in compliance with the License. 6723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris * You may obtain a copy of the License at 7723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris * 8723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris * http://www.apache.org/licenses/LICENSE-2.0 9723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris * 10723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris * Unless required by applicable law or agreed to in writing, software 11723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris * distributed under the License is distributed on an "AS IS" BASIS, 12723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris * See the License for the specific language governing permissions and 14723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris * limitations under the License. 15723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris */ 16723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris 17723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris#ifndef _LIBUNWINDSTACK_REGS_H 18723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris#define _LIBUNWINDSTACK_REGS_H 19723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris 20723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris#include <stdint.h> 21723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris 226f580d8b843f4caac8c12383684941ca02de12a8Josh Gao#include <functional> 236f580d8b843f4caac8c12383684941ca02de12a8Josh Gao#include <string> 24723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris#include <vector> 25723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris 26d226a5140989f509a0ed3e2723f05d5fc93ce8dfChristopher Ferrisnamespace unwindstack { 27d226a5140989f509a0ed3e2723f05d5fc93ce8dfChristopher Ferris 283958f8060ac0adccd977c0fab7a53d45f3fce58dChristopher Ferris// Forward declarations. 293958f8060ac0adccd977c0fab7a53d45f3fce58dChristopher Ferrisclass Elf; 30d06001d6e07b14b865f3294fff82d2571ed7cb2cChristopher Ferrisenum ArchEnum : uint8_t; 31d226a5140989f509a0ed3e2723f05d5fc93ce8dfChristopher Ferrisclass Memory; 323958f8060ac0adccd977c0fab7a53d45f3fce58dChristopher Ferris 33723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferrisclass Regs { 34723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris public: 353958f8060ac0adccd977c0fab7a53d45f3fce58dChristopher Ferris enum LocationEnum : uint8_t { 363958f8060ac0adccd977c0fab7a53d45f3fce58dChristopher Ferris LOCATION_UNKNOWN = 0, 373958f8060ac0adccd977c0fab7a53d45f3fce58dChristopher Ferris LOCATION_REGISTER, 383958f8060ac0adccd977c0fab7a53d45f3fce58dChristopher Ferris LOCATION_SP_OFFSET, 393958f8060ac0adccd977c0fab7a53d45f3fce58dChristopher Ferris }; 403958f8060ac0adccd977c0fab7a53d45f3fce58dChristopher Ferris 413958f8060ac0adccd977c0fab7a53d45f3fce58dChristopher Ferris struct Location { 423958f8060ac0adccd977c0fab7a53d45f3fce58dChristopher Ferris Location(LocationEnum type, int16_t value) : type(type), value(value) {} 433958f8060ac0adccd977c0fab7a53d45f3fce58dChristopher Ferris 443958f8060ac0adccd977c0fab7a53d45f3fce58dChristopher Ferris LocationEnum type; 453958f8060ac0adccd977c0fab7a53d45f3fce58dChristopher Ferris int16_t value; 463958f8060ac0adccd977c0fab7a53d45f3fce58dChristopher Ferris }; 473958f8060ac0adccd977c0fab7a53d45f3fce58dChristopher Ferris 48414df3e583c21023a22a11b64e703cd4ab38b29aYabin Cui Regs(uint16_t total_regs, const Location& return_loc) 49414df3e583c21023a22a11b64e703cd4ab38b29aYabin Cui : total_regs_(total_regs), return_loc_(return_loc) {} 50723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris virtual ~Regs() = default; 51723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris 52d06001d6e07b14b865f3294fff82d2571ed7cb2cChristopher Ferris virtual ArchEnum Arch() = 0; 530953ecd03a90350117d6881c55959c6644972b79Josh Gao 54150db124f3f3c0f8e1c341fd33c6c64310e0ac39Christopher Ferris virtual bool Is32Bit() = 0; 5502fdb569f65f85730cca514311fd0965dec0b6a1Christopher Ferris 563958f8060ac0adccd977c0fab7a53d45f3fce58dChristopher Ferris virtual void* RawData() = 0; 573958f8060ac0adccd977c0fab7a53d45f3fce58dChristopher Ferris virtual uint64_t pc() = 0; 583958f8060ac0adccd977c0fab7a53d45f3fce58dChristopher Ferris virtual uint64_t sp() = 0; 593958f8060ac0adccd977c0fab7a53d45f3fce58dChristopher Ferris 60414df3e583c21023a22a11b64e703cd4ab38b29aYabin Cui virtual void set_pc(uint64_t pc) = 0; 61414df3e583c21023a22a11b64e703cd4ab38b29aYabin Cui virtual void set_sp(uint64_t sp) = 0; 62414df3e583c21023a22a11b64e703cd4ab38b29aYabin Cui 6398984b41da78448df24d8d9ced842066328d5f11Christopher Ferris uint64_t dex_pc() { return dex_pc_; } 6498984b41da78448df24d8d9ced842066328d5f11Christopher Ferris void set_dex_pc(uint64_t dex_pc) { dex_pc_ = dex_pc; } 6598984b41da78448df24d8d9ced842066328d5f11Christopher Ferris 66a2ec50bf57c9dba78459ef011cd13f8525ea57b4Christopher Ferris virtual uint64_t GetPcAdjustment(uint64_t rel_pc, Elf* elf) = 0; 673958f8060ac0adccd977c0fab7a53d45f3fce58dChristopher Ferris 68eb4a6dbf5c6697c953942d079744c05da0c09d51Christopher Ferris virtual bool StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) = 0; 69a019665b3cb73609c888af7f17c64bf80ec40283Christopher Ferris 70b9de87f7edefd7a2473134b267716c5fd750e89fChristopher Ferris virtual bool SetPcFromReturnAddress(Memory* process_memory) = 0; 71b9de87f7edefd7a2473134b267716c5fd750e89fChristopher Ferris 726f580d8b843f4caac8c12383684941ca02de12a8Josh Gao virtual void IterateRegisters(std::function<void(const char*, uint64_t)>) = 0; 736f580d8b843f4caac8c12383684941ca02de12a8Josh Gao 74723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris uint16_t total_regs() { return total_regs_; } 75723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris 76fe3963143f16833b14b505cf41a2e19a9e304efbJosh Gao virtual Regs* Clone() = 0; 77fe3963143f16833b14b505cf41a2e19a9e304efbJosh Gao 78d06001d6e07b14b865f3294fff82d2571ed7cb2cChristopher Ferris static ArchEnum CurrentArch(); 790953ecd03a90350117d6881c55959c6644972b79Josh Gao static Regs* RemoteGet(pid_t pid); 80d06001d6e07b14b865f3294fff82d2571ed7cb2cChristopher Ferris static Regs* CreateFromUcontext(ArchEnum arch, void* ucontext); 812a25c4aab5c7d0f0f6018789cce0b6e8c4abb03bChristopher Ferris static Regs* CreateFromLocal(); 82723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris 83723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris protected: 84723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris uint16_t total_regs_; 853958f8060ac0adccd977c0fab7a53d45f3fce58dChristopher Ferris Location return_loc_; 8698984b41da78448df24d8d9ced842066328d5f11Christopher Ferris uint64_t dex_pc_ = 0; 87723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris}; 88723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris 89723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferristemplate <typename AddressType> 907b8e4671926486d61aab693968d8a0256a856033Christopher Ferrisclass RegsImpl : public Regs { 91723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris public: 92414df3e583c21023a22a11b64e703cd4ab38b29aYabin Cui RegsImpl(uint16_t total_regs, Location return_loc) 93414df3e583c21023a22a11b64e703cd4ab38b29aYabin Cui : Regs(total_regs, return_loc), regs_(total_regs) {} 947b8e4671926486d61aab693968d8a0256a856033Christopher Ferris virtual ~RegsImpl() = default; 95723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris 96150db124f3f3c0f8e1c341fd33c6c64310e0ac39Christopher Ferris bool Is32Bit() override { return sizeof(AddressType) == sizeof(uint32_t); } 9702fdb569f65f85730cca514311fd0965dec0b6a1Christopher Ferris 98723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris inline AddressType& operator[](size_t reg) { return regs_[reg]; } 99723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris 1003958f8060ac0adccd977c0fab7a53d45f3fce58dChristopher Ferris void* RawData() override { return regs_.data(); } 101723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris 1026f580d8b843f4caac8c12383684941ca02de12a8Josh Gao virtual void IterateRegisters(std::function<void(const char*, uint64_t)> fn) override { 1036f580d8b843f4caac8c12383684941ca02de12a8Josh Gao for (size_t i = 0; i < regs_.size(); ++i) { 1046f580d8b843f4caac8c12383684941ca02de12a8Josh Gao fn(std::to_string(i).c_str(), regs_[i]); 1056f580d8b843f4caac8c12383684941ca02de12a8Josh Gao } 1066f580d8b843f4caac8c12383684941ca02de12a8Josh Gao } 1076f580d8b843f4caac8c12383684941ca02de12a8Josh Gao 1083958f8060ac0adccd977c0fab7a53d45f3fce58dChristopher Ferris protected: 109723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris std::vector<AddressType> regs_; 110723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris}; 111723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris 112d226a5140989f509a0ed3e2723f05d5fc93ce8dfChristopher Ferris} // namespace unwindstack 113d226a5140989f509a0ed3e2723f05d5fc93ce8dfChristopher Ferris 114723cf9b6e61744f7a20a807e67ab50adb9db5d42Christopher Ferris#endif // _LIBUNWINDSTACK_REGS_H 115