diff -r 000000000000 -r 6474c204b198 toolkit/crashreporter/breakpad-patches/08-dwarf2reader-dynamic-cast.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/toolkit/crashreporter/breakpad-patches/08-dwarf2reader-dynamic-cast.patch Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,212 @@ +# HG changeset patch +# User Ted Mielczarek +# Date 1362600444 18000 +# Node ID 0eb3c7ba8a38a269ab975eff3f95a1a5d5d937b9 +# Parent 6b68e82037b8322fb392cea369d517aeeaaee9d3 +Stop using dynamic_cast in dwarf2reader +Patch by Julian Seward , R=ted + +diff --git a/src/common/dwarf/dwarf2reader.cc b/src/common/dwarf/dwarf2reader.cc +--- a/src/common/dwarf/dwarf2reader.cc ++++ b/src/common/dwarf/dwarf2reader.cc +@@ -887,68 +887,80 @@ + + // If this is a base+offset rule, change its base register to REG. + // Otherwise, do nothing. (Ugly, but required for DW_CFA_def_cfa_register.) + virtual void SetBaseRegister(unsigned reg) { } + + // If this is a base+offset rule, change its offset to OFFSET. Otherwise, + // do nothing. (Ugly, but required for DW_CFA_def_cfa_offset.) + virtual void SetOffset(long long offset) { } ++ ++ // A RTTI workaround, to make it possible to implement equality ++ // comparisons on classes derived from this one. ++ enum CFIRTag { ++ CFIR_UNDEFINED_RULE, ++ CFIR_SAME_VALUE_RULE, ++ CFIR_OFFSET_RULE, ++ CFIR_VAL_OFFSET_RULE, ++ CFIR_REGISTER_RULE, ++ CFIR_EXPRESSION_RULE, ++ CFIR_VAL_EXPRESSION_RULE ++ }; ++ ++ // Produce the tag that identifies the child class of this object. ++ virtual CFIRTag getTag() const = 0; + }; + + // Rule: the value the register had in the caller cannot be recovered. + class CallFrameInfo::UndefinedRule: public CallFrameInfo::Rule { + public: + UndefinedRule() { } + ~UndefinedRule() { } ++ CFIRTag getTag() const { return CFIR_UNDEFINED_RULE; } + bool Handle(Handler *handler, uint64 address, int reg) const { + return handler->UndefinedRule(address, reg); + } + bool operator==(const Rule &rhs) const { +- // dynamic_cast is allowed by the Google C++ Style Guide, if the use has +- // been carefully considered; cheap RTTI-like workarounds are forbidden. +- const UndefinedRule *our_rhs = dynamic_cast(&rhs); +- return (our_rhs != NULL); ++ if (rhs.getTag() != CFIR_UNDEFINED_RULE) return false; ++ return true; + } + Rule *Copy() const { return new UndefinedRule(*this); } + }; + + // Rule: the register's value is the same as that it had in the caller. + class CallFrameInfo::SameValueRule: public CallFrameInfo::Rule { + public: + SameValueRule() { } + ~SameValueRule() { } ++ CFIRTag getTag() const { return CFIR_SAME_VALUE_RULE; } + bool Handle(Handler *handler, uint64 address, int reg) const { + return handler->SameValueRule(address, reg); + } + bool operator==(const Rule &rhs) const { +- // dynamic_cast is allowed by the Google C++ Style Guide, if the use has +- // been carefully considered; cheap RTTI-like workarounds are forbidden. +- const SameValueRule *our_rhs = dynamic_cast(&rhs); +- return (our_rhs != NULL); ++ if (rhs.getTag() != CFIR_SAME_VALUE_RULE) return false; ++ return true; + } + Rule *Copy() const { return new SameValueRule(*this); } + }; + + // Rule: the register is saved at OFFSET from BASE_REGISTER. BASE_REGISTER + // may be CallFrameInfo::Handler::kCFARegister. + class CallFrameInfo::OffsetRule: public CallFrameInfo::Rule { + public: + OffsetRule(int base_register, long offset) + : base_register_(base_register), offset_(offset) { } + ~OffsetRule() { } ++ CFIRTag getTag() const { return CFIR_OFFSET_RULE; } + bool Handle(Handler *handler, uint64 address, int reg) const { + return handler->OffsetRule(address, reg, base_register_, offset_); + } + bool operator==(const Rule &rhs) const { +- // dynamic_cast is allowed by the Google C++ Style Guide, if the use has +- // been carefully considered; cheap RTTI-like workarounds are forbidden. +- const OffsetRule *our_rhs = dynamic_cast(&rhs); +- return (our_rhs && +- base_register_ == our_rhs->base_register_ && ++ if (rhs.getTag() != CFIR_OFFSET_RULE) return false; ++ const OffsetRule *our_rhs = static_cast(&rhs); ++ return (base_register_ == our_rhs->base_register_ && + offset_ == our_rhs->offset_); + } + Rule *Copy() const { return new OffsetRule(*this); } + // We don't actually need SetBaseRegister or SetOffset here, since they + // are only ever applied to CFA rules, for DW_CFA_def_cfa_offset, and it + // doesn't make sense to use OffsetRule for computing the CFA: it + // computes the address at which a register is saved, not a value. + private: +@@ -959,90 +971,89 @@ + // Rule: the value the register had in the caller is the value of + // BASE_REGISTER plus offset. BASE_REGISTER may be + // CallFrameInfo::Handler::kCFARegister. + class CallFrameInfo::ValOffsetRule: public CallFrameInfo::Rule { + public: + ValOffsetRule(int base_register, long offset) + : base_register_(base_register), offset_(offset) { } + ~ValOffsetRule() { } ++ CFIRTag getTag() const { return CFIR_VAL_OFFSET_RULE; } + bool Handle(Handler *handler, uint64 address, int reg) const { + return handler->ValOffsetRule(address, reg, base_register_, offset_); + } + bool operator==(const Rule &rhs) const { +- // dynamic_cast is allowed by the Google C++ Style Guide, if the use has +- // been carefully considered; cheap RTTI-like workarounds are forbidden. +- const ValOffsetRule *our_rhs = dynamic_cast(&rhs); +- return (our_rhs && +- base_register_ == our_rhs->base_register_ && ++ if (rhs.getTag() != CFIR_VAL_OFFSET_RULE) return false; ++ const ValOffsetRule *our_rhs = static_cast(&rhs); ++ return (base_register_ == our_rhs->base_register_ && + offset_ == our_rhs->offset_); + } + Rule *Copy() const { return new ValOffsetRule(*this); } + void SetBaseRegister(unsigned reg) { base_register_ = reg; } + void SetOffset(long long offset) { offset_ = offset; } + private: + int base_register_; + long offset_; + }; + + // Rule: the register has been saved in another register REGISTER_NUMBER_. + class CallFrameInfo::RegisterRule: public CallFrameInfo::Rule { + public: + explicit RegisterRule(int register_number) + : register_number_(register_number) { } + ~RegisterRule() { } ++ CFIRTag getTag() const { return CFIR_REGISTER_RULE; } + bool Handle(Handler *handler, uint64 address, int reg) const { + return handler->RegisterRule(address, reg, register_number_); + } + bool operator==(const Rule &rhs) const { +- // dynamic_cast is allowed by the Google C++ Style Guide, if the use has +- // been carefully considered; cheap RTTI-like workarounds are forbidden. +- const RegisterRule *our_rhs = dynamic_cast(&rhs); +- return (our_rhs && register_number_ == our_rhs->register_number_); ++ if (rhs.getTag() != CFIR_REGISTER_RULE) return false; ++ const RegisterRule *our_rhs = static_cast(&rhs); ++ return (register_number_ == our_rhs->register_number_); + } + Rule *Copy() const { return new RegisterRule(*this); } + private: + int register_number_; + }; + + // Rule: EXPRESSION evaluates to the address at which the register is saved. + class CallFrameInfo::ExpressionRule: public CallFrameInfo::Rule { + public: + explicit ExpressionRule(const string &expression) + : expression_(expression) { } + ~ExpressionRule() { } ++ CFIRTag getTag() const { return CFIR_EXPRESSION_RULE; } + bool Handle(Handler *handler, uint64 address, int reg) const { + return handler->ExpressionRule(address, reg, expression_); + } + bool operator==(const Rule &rhs) const { +- // dynamic_cast is allowed by the Google C++ Style Guide, if the use has +- // been carefully considered; cheap RTTI-like workarounds are forbidden. +- const ExpressionRule *our_rhs = dynamic_cast(&rhs); +- return (our_rhs && expression_ == our_rhs->expression_); ++ if (rhs.getTag() != CFIR_EXPRESSION_RULE) return false; ++ const ExpressionRule *our_rhs = static_cast(&rhs); ++ return (expression_ == our_rhs->expression_); + } + Rule *Copy() const { return new ExpressionRule(*this); } + private: + string expression_; + }; + + // Rule: EXPRESSION evaluates to the address at which the register is saved. + class CallFrameInfo::ValExpressionRule: public CallFrameInfo::Rule { + public: + explicit ValExpressionRule(const string &expression) + : expression_(expression) { } + ~ValExpressionRule() { } ++ CFIRTag getTag() const { return CFIR_VAL_EXPRESSION_RULE; } + bool Handle(Handler *handler, uint64 address, int reg) const { + return handler->ValExpressionRule(address, reg, expression_); + } + bool operator==(const Rule &rhs) const { +- // dynamic_cast is allowed by the Google C++ Style Guide, if the use has +- // been carefully considered; cheap RTTI-like workarounds are forbidden. ++ if (rhs.getTag() != CFIR_VAL_EXPRESSION_RULE) return false; + const ValExpressionRule *our_rhs = +- dynamic_cast(&rhs); +- return (our_rhs && expression_ == our_rhs->expression_); ++ static_cast(&rhs); ++ return (expression_ == our_rhs->expression_); + } + Rule *Copy() const { return new ValExpressionRule(*this); } + private: + string expression_; + }; + + // A map from register numbers to rules. + class CallFrameInfo::RuleMap {