toolkit/crashreporter/breakpad-patches/08-dwarf2reader-dynamic-cast.patch

changeset 0
6474c204b198
     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 {

mercurial