summaryrefslogtreecommitdiff
path: root/libunwindstack/DwarfCfa.h
diff options
context:
space:
mode:
Diffstat (limited to 'libunwindstack/DwarfCfa.h')
-rw-r--r--libunwindstack/DwarfCfa.h13
1 files changed, 10 insertions, 3 deletions
diff --git a/libunwindstack/DwarfCfa.h b/libunwindstack/DwarfCfa.h
index 569c17ceff..d627e156b7 100644
--- a/libunwindstack/DwarfCfa.h
+++ b/libunwindstack/DwarfCfa.h
@@ -31,6 +31,9 @@
namespace unwindstack {
+// Forward declarations.
+enum ArchEnum : uint8_t;
+
// DWARF Standard home: http://dwarfstd.org/
// This code is based on DWARF 4: http://http://dwarfstd.org/doc/DWARF4.pdf
// See section 6.4.2.1 for a description of the DW_CFA_xxx values.
@@ -72,7 +75,8 @@ class DwarfCfa {
typedef typename std::make_signed<AddressType>::type SignedType;
public:
- DwarfCfa(DwarfMemory* memory, const DwarfFde* fde) : memory_(memory), fde_(fde) {}
+ DwarfCfa(DwarfMemory* memory, const DwarfFde* fde, ArchEnum arch)
+ : memory_(memory), fde_(fde), arch_(arch) {}
virtual ~DwarfCfa() = default;
bool GetLocationInfo(uint64_t pc, uint64_t start_offset, uint64_t end_offset,
@@ -99,6 +103,7 @@ class DwarfCfa {
DwarfErrorData last_error_;
DwarfMemory* memory_;
const DwarfFde* fde_;
+ ArchEnum arch_;
AddressType cur_pc_;
const dwarf_loc_regs_t* cie_loc_regs_ = nullptr;
@@ -128,6 +133,7 @@ class DwarfCfa {
bool cfa_val_offset_sf(dwarf_loc_regs_t*);
bool cfa_val_expression(dwarf_loc_regs_t*);
bool cfa_gnu_negative_offset_extended(dwarf_loc_regs_t*);
+ bool cfa_aarch64_negate_ra_state(dwarf_loc_regs_t*);
using process_func = bool (DwarfCfa::*)(dwarf_loc_regs_t*);
constexpr static process_func kCallbackTable[64] = {
@@ -221,8 +227,9 @@ class DwarfCfa {
nullptr,
// 0x2c illegal cfa
nullptr,
- // 0x2d DW_CFA_GNU_window_save (Treat this as illegal)
- nullptr,
+ // 0x2d DW_CFA_AARCH64_negate_ra_state (aarch64 only)
+ // DW_CFA_GNU_window_save on other architectures.
+ &DwarfCfa::cfa_aarch64_negate_ra_state,
// 0x2e DW_CFA_GNU_args_size
&DwarfCfa::cfa_nop,
// 0x2f DW_CFA_GNU_negative_offset_extended