summaryrefslogtreecommitdiff
path: root/libunwindstack/DwarfCfa.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libunwindstack/DwarfCfa.cpp')
-rw-r--r--libunwindstack/DwarfCfa.cpp36
1 files changed, 33 insertions, 3 deletions
diff --git a/libunwindstack/DwarfCfa.cpp b/libunwindstack/DwarfCfa.cpp
index c128b9bb7a..c6db209dbd 100644
--- a/libunwindstack/DwarfCfa.cpp
+++ b/libunwindstack/DwarfCfa.cpp
@@ -26,7 +26,9 @@
#include <unwindstack/DwarfError.h>
#include <unwindstack/DwarfLocation.h>
+#include <unwindstack/Elf.h>
#include <unwindstack/Log.h>
+#include <unwindstack/MachineArm64.h>
#include "DwarfCfa.h"
#include "DwarfEncoding.h"
@@ -204,8 +206,12 @@ template <typename AddressType>
bool DwarfCfa<AddressType>::LogInstruction(uint32_t indent, uint64_t cfa_offset, uint8_t op,
uint64_t* cur_pc) {
const auto* cfa = &DwarfCfaInfo::kTable[op];
- if (cfa->name[0] == '\0') {
- log(indent, "Illegal");
+ if (cfa->name[0] == '\0' || (arch_ != ARCH_ARM64 && op == 0x2d)) {
+ if (op == 0x2d) {
+ log(indent, "Illegal (Only valid on aarch64)");
+ } else {
+ log(indent, "Illegal");
+ }
log(indent, "Raw Data: 0x%02x", op);
return true;
}
@@ -514,6 +520,24 @@ bool DwarfCfa<AddressType>::cfa_gnu_negative_offset_extended(dwarf_loc_regs_t* l
return true;
}
+template <typename AddressType>
+bool DwarfCfa<AddressType>::cfa_aarch64_negate_ra_state(dwarf_loc_regs_t* loc_regs) {
+ // Only supported on aarch64.
+ if (arch_ != ARCH_ARM64) {
+ last_error_.code = DWARF_ERROR_ILLEGAL_VALUE;
+ return false;
+ }
+
+ auto cfa_location = loc_regs->find(Arm64Reg::ARM64_PREG_RA_SIGN_STATE);
+ if (cfa_location == loc_regs->end()) {
+ (*loc_regs)[Arm64Reg::ARM64_PREG_RA_SIGN_STATE] = {.type = DWARF_LOCATION_PSEUDO_REGISTER,
+ .values = {1}};
+ } else {
+ cfa_location->second.values[0] ^= 1;
+ }
+ return true;
+}
+
const DwarfCfaInfo::Info DwarfCfaInfo::kTable[64] = {
{
// 0x00 DW_CFA_nop
@@ -699,7 +723,13 @@ const DwarfCfaInfo::Info DwarfCfaInfo::kTable[64] = {
{"", 0, 0, {}, {}}, // 0x2a illegal cfa
{"", 0, 0, {}, {}}, // 0x2b illegal cfa
{"", 0, 0, {}, {}}, // 0x2c illegal cfa
- {"", 0, 0, {}, {}}, // 0x2d DW_CFA_GNU_window_save (Treat as illegal)
+ {
+ "DW_CFA_AARCH64_negate_ra_state", // 0x2d DW_CFA_AARCH64_negate_ra_state
+ 3,
+ 0,
+ {},
+ {},
+ },
{
"DW_CFA_GNU_args_size", // 0x2e DW_CFA_GNU_args_size
2,