1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/crashreporter/breakpad-patches/08-dwarf2reader-dynamic-cast.patch Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,212 @@ 1.4 +# HG changeset patch 1.5 +# User Ted Mielczarek <ted@mielczarek.org> 1.6 +# Date 1362600444 18000 1.7 +# Node ID 0eb3c7ba8a38a269ab975eff3f95a1a5d5d937b9 1.8 +# Parent 6b68e82037b8322fb392cea369d517aeeaaee9d3 1.9 +Stop using dynamic_cast in dwarf2reader 1.10 +Patch by Julian Seward <jseward@acm.org>, R=ted 1.11 + 1.12 +diff --git a/src/common/dwarf/dwarf2reader.cc b/src/common/dwarf/dwarf2reader.cc 1.13 +--- a/src/common/dwarf/dwarf2reader.cc 1.14 ++++ b/src/common/dwarf/dwarf2reader.cc 1.15 +@@ -887,68 +887,80 @@ 1.16 + 1.17 + // If this is a base+offset rule, change its base register to REG. 1.18 + // Otherwise, do nothing. (Ugly, but required for DW_CFA_def_cfa_register.) 1.19 + virtual void SetBaseRegister(unsigned reg) { } 1.20 + 1.21 + // If this is a base+offset rule, change its offset to OFFSET. Otherwise, 1.22 + // do nothing. (Ugly, but required for DW_CFA_def_cfa_offset.) 1.23 + virtual void SetOffset(long long offset) { } 1.24 ++ 1.25 ++ // A RTTI workaround, to make it possible to implement equality 1.26 ++ // comparisons on classes derived from this one. 1.27 ++ enum CFIRTag { 1.28 ++ CFIR_UNDEFINED_RULE, 1.29 ++ CFIR_SAME_VALUE_RULE, 1.30 ++ CFIR_OFFSET_RULE, 1.31 ++ CFIR_VAL_OFFSET_RULE, 1.32 ++ CFIR_REGISTER_RULE, 1.33 ++ CFIR_EXPRESSION_RULE, 1.34 ++ CFIR_VAL_EXPRESSION_RULE 1.35 ++ }; 1.36 ++ 1.37 ++ // Produce the tag that identifies the child class of this object. 1.38 ++ virtual CFIRTag getTag() const = 0; 1.39 + }; 1.40 + 1.41 + // Rule: the value the register had in the caller cannot be recovered. 1.42 + class CallFrameInfo::UndefinedRule: public CallFrameInfo::Rule { 1.43 + public: 1.44 + UndefinedRule() { } 1.45 + ~UndefinedRule() { } 1.46 ++ CFIRTag getTag() const { return CFIR_UNDEFINED_RULE; } 1.47 + bool Handle(Handler *handler, uint64 address, int reg) const { 1.48 + return handler->UndefinedRule(address, reg); 1.49 + } 1.50 + bool operator==(const Rule &rhs) const { 1.51 +- // dynamic_cast is allowed by the Google C++ Style Guide, if the use has 1.52 +- // been carefully considered; cheap RTTI-like workarounds are forbidden. 1.53 +- const UndefinedRule *our_rhs = dynamic_cast<const UndefinedRule *>(&rhs); 1.54 +- return (our_rhs != NULL); 1.55 ++ if (rhs.getTag() != CFIR_UNDEFINED_RULE) return false; 1.56 ++ return true; 1.57 + } 1.58 + Rule *Copy() const { return new UndefinedRule(*this); } 1.59 + }; 1.60 + 1.61 + // Rule: the register's value is the same as that it had in the caller. 1.62 + class CallFrameInfo::SameValueRule: public CallFrameInfo::Rule { 1.63 + public: 1.64 + SameValueRule() { } 1.65 + ~SameValueRule() { } 1.66 ++ CFIRTag getTag() const { return CFIR_SAME_VALUE_RULE; } 1.67 + bool Handle(Handler *handler, uint64 address, int reg) const { 1.68 + return handler->SameValueRule(address, reg); 1.69 + } 1.70 + bool operator==(const Rule &rhs) const { 1.71 +- // dynamic_cast is allowed by the Google C++ Style Guide, if the use has 1.72 +- // been carefully considered; cheap RTTI-like workarounds are forbidden. 1.73 +- const SameValueRule *our_rhs = dynamic_cast<const SameValueRule *>(&rhs); 1.74 +- return (our_rhs != NULL); 1.75 ++ if (rhs.getTag() != CFIR_SAME_VALUE_RULE) return false; 1.76 ++ return true; 1.77 + } 1.78 + Rule *Copy() const { return new SameValueRule(*this); } 1.79 + }; 1.80 + 1.81 + // Rule: the register is saved at OFFSET from BASE_REGISTER. BASE_REGISTER 1.82 + // may be CallFrameInfo::Handler::kCFARegister. 1.83 + class CallFrameInfo::OffsetRule: public CallFrameInfo::Rule { 1.84 + public: 1.85 + OffsetRule(int base_register, long offset) 1.86 + : base_register_(base_register), offset_(offset) { } 1.87 + ~OffsetRule() { } 1.88 ++ CFIRTag getTag() const { return CFIR_OFFSET_RULE; } 1.89 + bool Handle(Handler *handler, uint64 address, int reg) const { 1.90 + return handler->OffsetRule(address, reg, base_register_, offset_); 1.91 + } 1.92 + bool operator==(const Rule &rhs) const { 1.93 +- // dynamic_cast is allowed by the Google C++ Style Guide, if the use has 1.94 +- // been carefully considered; cheap RTTI-like workarounds are forbidden. 1.95 +- const OffsetRule *our_rhs = dynamic_cast<const OffsetRule *>(&rhs); 1.96 +- return (our_rhs && 1.97 +- base_register_ == our_rhs->base_register_ && 1.98 ++ if (rhs.getTag() != CFIR_OFFSET_RULE) return false; 1.99 ++ const OffsetRule *our_rhs = static_cast<const OffsetRule *>(&rhs); 1.100 ++ return (base_register_ == our_rhs->base_register_ && 1.101 + offset_ == our_rhs->offset_); 1.102 + } 1.103 + Rule *Copy() const { return new OffsetRule(*this); } 1.104 + // We don't actually need SetBaseRegister or SetOffset here, since they 1.105 + // are only ever applied to CFA rules, for DW_CFA_def_cfa_offset, and it 1.106 + // doesn't make sense to use OffsetRule for computing the CFA: it 1.107 + // computes the address at which a register is saved, not a value. 1.108 + private: 1.109 +@@ -959,90 +971,89 @@ 1.110 + // Rule: the value the register had in the caller is the value of 1.111 + // BASE_REGISTER plus offset. BASE_REGISTER may be 1.112 + // CallFrameInfo::Handler::kCFARegister. 1.113 + class CallFrameInfo::ValOffsetRule: public CallFrameInfo::Rule { 1.114 + public: 1.115 + ValOffsetRule(int base_register, long offset) 1.116 + : base_register_(base_register), offset_(offset) { } 1.117 + ~ValOffsetRule() { } 1.118 ++ CFIRTag getTag() const { return CFIR_VAL_OFFSET_RULE; } 1.119 + bool Handle(Handler *handler, uint64 address, int reg) const { 1.120 + return handler->ValOffsetRule(address, reg, base_register_, offset_); 1.121 + } 1.122 + bool operator==(const Rule &rhs) const { 1.123 +- // dynamic_cast is allowed by the Google C++ Style Guide, if the use has 1.124 +- // been carefully considered; cheap RTTI-like workarounds are forbidden. 1.125 +- const ValOffsetRule *our_rhs = dynamic_cast<const ValOffsetRule *>(&rhs); 1.126 +- return (our_rhs && 1.127 +- base_register_ == our_rhs->base_register_ && 1.128 ++ if (rhs.getTag() != CFIR_VAL_OFFSET_RULE) return false; 1.129 ++ const ValOffsetRule *our_rhs = static_cast<const ValOffsetRule *>(&rhs); 1.130 ++ return (base_register_ == our_rhs->base_register_ && 1.131 + offset_ == our_rhs->offset_); 1.132 + } 1.133 + Rule *Copy() const { return new ValOffsetRule(*this); } 1.134 + void SetBaseRegister(unsigned reg) { base_register_ = reg; } 1.135 + void SetOffset(long long offset) { offset_ = offset; } 1.136 + private: 1.137 + int base_register_; 1.138 + long offset_; 1.139 + }; 1.140 + 1.141 + // Rule: the register has been saved in another register REGISTER_NUMBER_. 1.142 + class CallFrameInfo::RegisterRule: public CallFrameInfo::Rule { 1.143 + public: 1.144 + explicit RegisterRule(int register_number) 1.145 + : register_number_(register_number) { } 1.146 + ~RegisterRule() { } 1.147 ++ CFIRTag getTag() const { return CFIR_REGISTER_RULE; } 1.148 + bool Handle(Handler *handler, uint64 address, int reg) const { 1.149 + return handler->RegisterRule(address, reg, register_number_); 1.150 + } 1.151 + bool operator==(const Rule &rhs) const { 1.152 +- // dynamic_cast is allowed by the Google C++ Style Guide, if the use has 1.153 +- // been carefully considered; cheap RTTI-like workarounds are forbidden. 1.154 +- const RegisterRule *our_rhs = dynamic_cast<const RegisterRule *>(&rhs); 1.155 +- return (our_rhs && register_number_ == our_rhs->register_number_); 1.156 ++ if (rhs.getTag() != CFIR_REGISTER_RULE) return false; 1.157 ++ const RegisterRule *our_rhs = static_cast<const RegisterRule *>(&rhs); 1.158 ++ return (register_number_ == our_rhs->register_number_); 1.159 + } 1.160 + Rule *Copy() const { return new RegisterRule(*this); } 1.161 + private: 1.162 + int register_number_; 1.163 + }; 1.164 + 1.165 + // Rule: EXPRESSION evaluates to the address at which the register is saved. 1.166 + class CallFrameInfo::ExpressionRule: public CallFrameInfo::Rule { 1.167 + public: 1.168 + explicit ExpressionRule(const string &expression) 1.169 + : expression_(expression) { } 1.170 + ~ExpressionRule() { } 1.171 ++ CFIRTag getTag() const { return CFIR_EXPRESSION_RULE; } 1.172 + bool Handle(Handler *handler, uint64 address, int reg) const { 1.173 + return handler->ExpressionRule(address, reg, expression_); 1.174 + } 1.175 + bool operator==(const Rule &rhs) const { 1.176 +- // dynamic_cast is allowed by the Google C++ Style Guide, if the use has 1.177 +- // been carefully considered; cheap RTTI-like workarounds are forbidden. 1.178 +- const ExpressionRule *our_rhs = dynamic_cast<const ExpressionRule *>(&rhs); 1.179 +- return (our_rhs && expression_ == our_rhs->expression_); 1.180 ++ if (rhs.getTag() != CFIR_EXPRESSION_RULE) return false; 1.181 ++ const ExpressionRule *our_rhs = static_cast<const ExpressionRule *>(&rhs); 1.182 ++ return (expression_ == our_rhs->expression_); 1.183 + } 1.184 + Rule *Copy() const { return new ExpressionRule(*this); } 1.185 + private: 1.186 + string expression_; 1.187 + }; 1.188 + 1.189 + // Rule: EXPRESSION evaluates to the address at which the register is saved. 1.190 + class CallFrameInfo::ValExpressionRule: public CallFrameInfo::Rule { 1.191 + public: 1.192 + explicit ValExpressionRule(const string &expression) 1.193 + : expression_(expression) { } 1.194 + ~ValExpressionRule() { } 1.195 ++ CFIRTag getTag() const { return CFIR_VAL_EXPRESSION_RULE; } 1.196 + bool Handle(Handler *handler, uint64 address, int reg) const { 1.197 + return handler->ValExpressionRule(address, reg, expression_); 1.198 + } 1.199 + bool operator==(const Rule &rhs) const { 1.200 +- // dynamic_cast is allowed by the Google C++ Style Guide, if the use has 1.201 +- // been carefully considered; cheap RTTI-like workarounds are forbidden. 1.202 ++ if (rhs.getTag() != CFIR_VAL_EXPRESSION_RULE) return false; 1.203 + const ValExpressionRule *our_rhs = 1.204 +- dynamic_cast<const ValExpressionRule *>(&rhs); 1.205 +- return (our_rhs && expression_ == our_rhs->expression_); 1.206 ++ static_cast<const ValExpressionRule *>(&rhs); 1.207 ++ return (expression_ == our_rhs->expression_); 1.208 + } 1.209 + Rule *Copy() const { return new ValExpressionRule(*this); } 1.210 + private: 1.211 + string expression_; 1.212 + }; 1.213 + 1.214 + // A map from register numbers to rules. 1.215 + class CallFrameInfo::RuleMap {