Skip to content

Instantly share code, notes, and snippets.

@gawen
Last active October 24, 2019 12:14
Show Gist options
  • Save gawen/bf51027943c748167a7f5368b75fd82a to your computer and use it in GitHub Desktop.
Save gawen/bf51027943c748167a7f5368b75fd82a to your computer and use it in GitHub Desktop.
breakpad patch to avoid the pseudo-register .ra to be self-assigned
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