Last active
October 24, 2019 12:14
-
-
Save gawen/bf51027943c748167a7f5368b75fd82a to your computer and use it in GitHub Desktop.
breakpad patch to avoid the pseudo-register .ra to be self-assigned
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 13a5ab8b7f1a427182027ad6e3a2f64246fe27a7 Mon Sep 17 00:00:00 2001 | |
From: Gawen Arab <[email protected]> | |
Date: Thu, 24 Oct 2019 12:54:16 +0200 | |
Subject: [PATCH] fix: DW_CFA_same_value of the return address for .ra | |
A DWARF CFI rule `DW_CFA_same_value` of the return address register | |
assigned to `.ra` should reload the return address register and assign | |
it to `.ra`. The recorded rule should be `.ra: <address register>`. | |
But `DwarfCFIToModule::RegisterName` always replaced the return address | |
register by `.ra` (dwarf_cfi_to_module.cc:179), and the rule becomes | |
`.ra: .ra`. The assignment is cyclic and makes Breakpad reject the CFI | |
when unwinding a stacktrace. | |
This fix forces to assign the physical return address register when a | |
same value rule is emitted for `.ra`. | |
--- | |
src/common/dwarf_cfi_to_module.cc | 6 +++--- | |
src/common/dwarf_cfi_to_module.h | 14 +++++++++++++- | |
2 files changed, 16 insertions(+), 4 deletions(-) | |
diff --git a/src/common/dwarf_cfi_to_module.cc b/src/common/dwarf_cfi_to_module.cc | |
index bd298a2f..ae3550a5 100644 | |
--- a/src/common/dwarf_cfi_to_module.cc | |
+++ b/src/common/dwarf_cfi_to_module.cc | |
@@ -169,14 +169,14 @@ bool DwarfCFIToModule::Entry(size_t offset, uint64 address, uint64 length, | |
return true; | |
} | |
-string DwarfCFIToModule::RegisterName(int i) { | |
+string DwarfCFIToModule::RegisterName(int i, enum RegisterNameOption opt) { | |
assert(entry_); | |
if (i < 0) { | |
assert(i == kCFARegister); | |
return cfa_name_; | |
} | |
unsigned reg = i; | |
- if (reg == return_address_) | |
+ if (opt != REGISTER_NAME_KEEP_RETURN_ADDRESS && reg == return_address_) | |
return ra_name_; | |
// Ensure that a non-empty name exists for this register value. | |
@@ -217,7 +217,7 @@ bool DwarfCFIToModule::UndefinedRule(uint64 address, int reg) { | |
bool DwarfCFIToModule::SameValueRule(uint64 address, int reg) { | |
ostringstream s; | |
- s << RegisterName(reg); | |
+ s << RegisterName(reg, REGISTER_NAME_KEEP_RETURN_ADDRESS); | |
Record(address, reg, s.str()); | |
return true; | |
} | |
diff --git a/src/common/dwarf_cfi_to_module.h b/src/common/dwarf_cfi_to_module.h | |
index a5302e15..5ce01c52 100644 | |
--- a/src/common/dwarf_cfi_to_module.h | |
+++ b/src/common/dwarf_cfi_to_module.h | |
@@ -154,8 +154,20 @@ class DwarfCFIToModule: public CallFrameInfo::Handler { | |
virtual bool End(); | |
private: | |
+ enum RegisterNameOption { | |
+ REGISTER_NAME_NORMAL = 0, | |
+ | |
+ // do not replace register return_address_ by '.ra' | |
+ REGISTER_NAME_KEEP_RETURN_ADDRESS, | |
+ }; | |
+ | |
// Return the name to use for register REG. | |
- string RegisterName(int i); | |
+ string RegisterName(int i, enum RegisterNameOption opt); | |
+ inline string RegisterName(int i) { | |
+ return RegisterName(i, REGISTER_NAME_NORMAL); | |
+ } | |
+ | |
+ // Return the name to use for register REG | |
// Record RULE for register REG at ADDRESS. | |
void Record(Module::Address address, int reg, const string &rule); | |
-- | |
2.23.0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment