Elf interface for new unwinder.
This cl includes the code to read arm unwind information from a shared
library.
Bug: 23762183
Test: Passes all unit tests. I can dump the arm unwind information
Test: for an arm shared library.
Change-Id: I43501ea2eab843b81de8bd5128401dd1971af8d3
diff --git a/libunwindstack/Regs.h b/libunwindstack/Regs.h
index 2766c6f..718fc85 100644
--- a/libunwindstack/Regs.h
+++ b/libunwindstack/Regs.h
@@ -21,57 +21,107 @@
#include <vector>
+// Forward declarations.
+class Elf;
+struct MapInfo;
+
class Regs {
public:
- Regs(uint16_t pc_reg, uint16_t sp_reg, uint16_t total_regs)
- : pc_reg_(pc_reg), sp_reg_(sp_reg), total_regs_(total_regs) {
- }
+ enum LocationEnum : uint8_t {
+ LOCATION_UNKNOWN = 0,
+ LOCATION_REGISTER,
+ LOCATION_SP_OFFSET,
+ };
+
+ struct Location {
+ Location(LocationEnum type, int16_t value) : type(type), value(value) {}
+
+ LocationEnum type;
+ int16_t value;
+ };
+
+ Regs(uint16_t total_regs, uint16_t sp_reg, const Location& return_loc)
+ : total_regs_(total_regs), sp_reg_(sp_reg), return_loc_(return_loc) {}
virtual ~Regs() = default;
- uint16_t pc_reg() { return pc_reg_; }
- uint16_t sp_reg() { return sp_reg_; }
- uint16_t total_regs() { return total_regs_; }
-
- virtual void* raw_data() = 0;
+ virtual void* RawData() = 0;
virtual uint64_t pc() = 0;
virtual uint64_t sp() = 0;
+ virtual bool GetReturnAddressFromDefault(Memory* memory, uint64_t* value) = 0;
+
+ virtual uint64_t GetRelPc(Elf* elf, const MapInfo* map_info) = 0;
+
+ virtual uint64_t GetAdjustedPc(uint64_t rel_pc, Elf* elf) = 0;
+
+ uint16_t sp_reg() { return sp_reg_; }
+ uint16_t total_regs() { return total_regs_; }
+
+ static Regs* RemoteGet(pid_t pid, uint32_t* machine_type);
+
protected:
- uint16_t pc_reg_;
- uint16_t sp_reg_;
uint16_t total_regs_;
+ uint16_t sp_reg_;
+ Location return_loc_;
};
template <typename AddressType>
class RegsTmpl : public Regs {
public:
- RegsTmpl(uint16_t pc_reg, uint16_t sp_reg, uint16_t total_regs)
- : Regs(pc_reg, sp_reg, total_regs), regs_(total_regs) {}
+ RegsTmpl(uint16_t total_regs, uint16_t sp_reg, Location return_loc)
+ : Regs(total_regs, sp_reg, return_loc), regs_(total_regs) {}
virtual ~RegsTmpl() = default;
- uint64_t pc() override { return regs_[pc_reg_]; }
- uint64_t sp() override { return regs_[sp_reg_]; }
+ uint64_t GetRelPc(Elf* elf, const MapInfo* map_info) override;
+
+ bool GetReturnAddressFromDefault(Memory* memory, uint64_t* value) override;
+
+ uint64_t pc() override { return pc_; }
+ uint64_t sp() override { return sp_; }
+
+ void set_pc(AddressType pc) { pc_ = pc; }
+ void set_sp(AddressType sp) { sp_ = sp; }
inline AddressType& operator[](size_t reg) { return regs_[reg]; }
- void* raw_data() override { return regs_.data(); }
+ void* RawData() override { return regs_.data(); }
- private:
+ protected:
+ AddressType pc_;
+ AddressType sp_;
std::vector<AddressType> regs_;
};
-class Regs32 : public RegsTmpl<uint32_t> {
+class RegsArm : public RegsTmpl<uint32_t> {
public:
- Regs32(uint16_t pc_reg, uint16_t sp_reg, uint16_t total_regs)
- : RegsTmpl(pc_reg, sp_reg, total_regs) {}
- virtual ~Regs32() = default;
+ RegsArm();
+ virtual ~RegsArm() = default;
+
+ uint64_t GetAdjustedPc(uint64_t rel_pc, Elf* elf) override;
};
-class Regs64 : public RegsTmpl<uint64_t> {
+class RegsArm64 : public RegsTmpl<uint64_t> {
public:
- Regs64(uint16_t pc_reg, uint16_t sp_reg, uint16_t total_regs)
- : RegsTmpl(pc_reg, sp_reg, total_regs) {}
- virtual ~Regs64() = default;
+ RegsArm64();
+ virtual ~RegsArm64() = default;
+
+ uint64_t GetAdjustedPc(uint64_t rel_pc, Elf* elf) override;
+};
+
+class RegsX86 : public RegsTmpl<uint32_t> {
+ public:
+ RegsX86();
+ virtual ~RegsX86() = default;
+
+ uint64_t GetAdjustedPc(uint64_t rel_pc, Elf* elf) override;
+};
+
+class RegsX86_64 : public RegsTmpl<uint64_t> {
+ public:
+ RegsX86_64();
+ virtual ~RegsX86_64() = default;
+
+ uint64_t GetAdjustedPc(uint64_t rel_pc, Elf* elf) override;
};
#endif // _LIBUNWINDSTACK_REGS_H