tools/profiler/LulCommonExt.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
     4 // Copyright (c) 2006, 2010, 2012, 2013 Google Inc.
     5 // All rights reserved.
     6 //
     7 // Redistribution and use in source and binary forms, with or without
     8 // modification, are permitted provided that the following conditions are
     9 // met:
    10 //
    11 //     * Redistributions of source code must retain the above copyright
    12 // notice, this list of conditions and the following disclaimer.
    13 //     * Redistributions in binary form must reproduce the above
    14 // copyright notice, this list of conditions and the following disclaimer
    15 // in the documentation and/or other materials provided with the
    16 // distribution.
    17 //     * Neither the name of Google Inc. nor the names of its
    18 // contributors may be used to endorse or promote products derived from
    19 // this software without specific prior written permission.
    20 //
    21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    33 // Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>
    35 // module.h: Define google_breakpad::Module. A Module holds debugging
    36 // information, and can write that information out as a Breakpad
    37 // symbol file.
    40 //  (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
    41 //  Copyright (c) 2001, 2002 Peter Dimov
    42 //
    43 //  Permission to copy, use, modify, sell and distribute this software
    44 //  is granted provided this copyright notice appears in all copies.
    45 //  This software is provided "as is" without express or implied
    46 //  warranty, and with no claim as to its suitability for any purpose.
    47 //
    48 //  See http://www.boost.org/libs/smart_ptr/scoped_ptr.htm for documentation.
    49 //
    52 // This file is derived from the following files in
    53 // toolkit/crashreporter/google-breakpad:
    54 //   src/common/unique_string.h
    55 //   src/common/scoped_ptr.h
    56 //   src/common/module.h
    58 // External interface for the "Common" component of LUL.
    60 #ifndef LulCommonExt_h
    61 #define LulCommonExt_h
    63 #include <stdlib.h>
    64 #include <stdio.h>
    65 #include <stdint.h>
    67 #include <string>
    68 #include <map>
    69 #include <vector>
    70 #include <cstddef>            // for std::ptrdiff_t
    72 #include "mozilla/Assertions.h"
    73 #include "mozilla/NullPtr.h"
    75 namespace lul {
    77 ////////////////////////////////////////////////////////////////
    78 // UniqueString
    79 //
    81 // Abstract type
    82 class UniqueString;
    84 // Unique-ify a string.  |ToUniqueString| can never return nullptr.
    85 const UniqueString* ToUniqueString(std::string);
    87 // Get the contained C string (debugging only)
    88 const char* const FromUniqueString(const UniqueString*);
    90 // Some handy pre-uniqified strings.  Z is an escape character:
    91 //   ZS        '$'
    92 //   ZD        '.'
    93 //   Zeq       '='
    94 //   Zplus     '+'
    95 //   Zstar     '*'
    96 //   Zslash    '/'
    97 //   Zpercent  '%'
    98 //   Zat       '@'
    99 //   Zcaret    '^'
   101 // Note that ustr__empty and (UniqueString*)nullptr are considered
   102 // to be different.
   103 //
   104 // Unfortunately these have to be written as functions so as to
   105 // make them safe to use in static initialisers.
   107 // ""
   108 inline static const UniqueString* ustr__empty() {
   109   static const UniqueString* us = nullptr;
   110   if (!us) us = ToUniqueString("");
   111   return us;
   112 }
   114 // ".cfa"
   115 inline static const UniqueString* ustr__ZDcfa() {
   116   static const UniqueString* us = nullptr;
   117   if (!us) us = ToUniqueString(".cfa");
   118   return us;
   119 }
   121 // ".ra"
   122 inline static const UniqueString* ustr__ZDra() {
   123   static const UniqueString* us = nullptr;
   124   if (!us) us = ToUniqueString(".ra");
   125   return us;
   126 }
   129 ////////////////////////////////////////////////////////////////
   130 // GUID
   131 //
   133 typedef struct {
   134   uint32_t data1;
   135   uint16_t data2;
   136   uint16_t data3;
   137   uint8_t  data4[8];
   138 } MDGUID;  // GUID
   140 typedef MDGUID GUID;
   143 ////////////////////////////////////////////////////////////////
   144 // scoped_ptr
   145 //
   147 //  scoped_ptr mimics a built-in pointer except that it guarantees deletion
   148 //  of the object pointed to, either on destruction of the scoped_ptr or via
   149 //  an explicit reset(). scoped_ptr is a simple solution for simple needs;
   150 //  use shared_ptr or std::auto_ptr if your needs are more complex.
   152 //  *** NOTE ***
   153 //  If your scoped_ptr is a class member of class FOO pointing to a
   154 //  forward declared type BAR (as shown below), then you MUST use a non-inlined
   155 //  version of the destructor.  The destructor of a scoped_ptr (called from
   156 //  FOO's destructor) must have a complete definition of BAR in order to
   157 //  destroy it.  Example:
   158 //
   159 //  -- foo.h --
   160 //  class BAR;
   161 //
   162 //  class FOO {
   163 //   public:
   164 //    FOO();
   165 //    ~FOO();  // Required for sources that instantiate class FOO to compile!
   166 //
   167 //   private:
   168 //    scoped_ptr<BAR> bar_;
   169 //  };
   170 //
   171 //  -- foo.cc --
   172 //  #include "foo.h"
   173 //  FOO::~FOO() {} // Empty, but must be non-inlined to FOO's class definition.
   175 //  scoped_ptr_malloc added by Google
   176 //  When one of these goes out of scope, instead of doing a delete or
   177 //  delete[], it calls free().  scoped_ptr_malloc<char> is likely to see
   178 //  much more use than any other specializations.
   180 //  release() added by Google
   181 //  Use this to conditionally transfer ownership of a heap-allocated object
   182 //  to the caller, usually on method success.
   184 template <typename T>
   185 class scoped_ptr {
   186  private:
   188   T* ptr;
   190   scoped_ptr(scoped_ptr const &);
   191   scoped_ptr & operator=(scoped_ptr const &);
   193  public:
   195   typedef T element_type;
   197   explicit scoped_ptr(T* p = 0): ptr(p) {}
   199   ~scoped_ptr() {
   200     delete ptr;
   201   }
   203   void reset(T* p = 0) {
   204     if (ptr != p) {
   205       delete ptr;
   206       ptr = p;
   207     }
   208   }
   210   T& operator*() const {
   211     MOZ_ASSERT(ptr != 0);
   212     return *ptr;
   213   }
   215   T* operator->() const  {
   216     MOZ_ASSERT(ptr != 0);
   217     return ptr;
   218   }
   220   bool operator==(T* p) const {
   221     return ptr == p;
   222   }
   224   bool operator!=(T* p) const {
   225     return ptr != p;
   226   }
   228   T* get() const  {
   229     return ptr;
   230   }
   232   void swap(scoped_ptr & b) {
   233     T* tmp = b.ptr;
   234     b.ptr = ptr;
   235     ptr = tmp;
   236   }
   238   T* release() {
   239     T* tmp = ptr;
   240     ptr = 0;
   241     return tmp;
   242   }
   244  private:
   246   // no reason to use these: each scoped_ptr should have its own object
   247   template <typename U> bool operator==(scoped_ptr<U> const& p) const;
   248   template <typename U> bool operator!=(scoped_ptr<U> const& p) const;
   249 };
   251 template<typename T> inline
   252 void swap(scoped_ptr<T>& a, scoped_ptr<T>& b) {
   253   a.swap(b);
   254 }
   256 template<typename T> inline
   257 bool operator==(T* p, const scoped_ptr<T>& b) {
   258   return p == b.get();
   259 }
   261 template<typename T> inline
   262 bool operator!=(T* p, const scoped_ptr<T>& b) {
   263   return p != b.get();
   264 }
   266 //  scoped_array extends scoped_ptr to arrays. Deletion of the array pointed to
   267 //  is guaranteed, either on destruction of the scoped_array or via an explicit
   268 //  reset(). Use shared_array or std::vector if your needs are more complex.
   270 template<typename T>
   271 class scoped_array {
   272  private:
   274   T* ptr;
   276   scoped_array(scoped_array const &);
   277   scoped_array & operator=(scoped_array const &);
   279  public:
   281   typedef T element_type;
   283   explicit scoped_array(T* p = 0) : ptr(p) {}
   285   ~scoped_array() {
   286     delete[] ptr;
   287   }
   289   void reset(T* p = 0) {
   290     if (ptr != p) {
   291       delete [] ptr;
   292       ptr = p;
   293     }
   294   }
   296   T& operator[](std::ptrdiff_t i) const {
   297     MOZ_ASSERT(ptr != 0);
   298     MOZ_ASSERT(i >= 0);
   299     return ptr[i];
   300   }
   302   bool operator==(T* p) const {
   303     return ptr == p;
   304   }
   306   bool operator!=(T* p) const {
   307     return ptr != p;
   308   }
   310   T* get() const {
   311     return ptr;
   312   }
   314   void swap(scoped_array & b) {
   315     T* tmp = b.ptr;
   316     b.ptr = ptr;
   317     ptr = tmp;
   318   }
   320   T* release() {
   321     T* tmp = ptr;
   322     ptr = 0;
   323     return tmp;
   324   }
   326  private:
   328   // no reason to use these: each scoped_array should have its own object
   329   template <typename U> bool operator==(scoped_array<U> const& p) const;
   330   template <typename U> bool operator!=(scoped_array<U> const& p) const;
   331 };
   333 template<class T> inline
   334 void swap(scoped_array<T>& a, scoped_array<T>& b) {
   335   a.swap(b);
   336 }
   338 template<typename T> inline
   339 bool operator==(T* p, const scoped_array<T>& b) {
   340   return p == b.get();
   341 }
   343 template<typename T> inline
   344 bool operator!=(T* p, const scoped_array<T>& b) {
   345   return p != b.get();
   346 }
   349 // This class wraps the c library function free() in a class that can be
   350 // passed as a template argument to scoped_ptr_malloc below.
   351 class ScopedPtrMallocFree {
   352  public:
   353   inline void operator()(void* x) const {
   354     free(x);
   355   }
   356 };
   358 // scoped_ptr_malloc<> is similar to scoped_ptr<>, but it accepts a
   359 // second template argument, the functor used to free the object.
   361 template<typename T, typename FreeProc = ScopedPtrMallocFree>
   362 class scoped_ptr_malloc {
   363  private:
   365   T* ptr;
   367   scoped_ptr_malloc(scoped_ptr_malloc const &);
   368   scoped_ptr_malloc & operator=(scoped_ptr_malloc const &);
   370  public:
   372   typedef T element_type;
   374   explicit scoped_ptr_malloc(T* p = 0): ptr(p) {}
   376   ~scoped_ptr_malloc() {
   377     free_((void*) ptr);
   378   }
   380   void reset(T* p = 0) {
   381     if (ptr != p) {
   382       free_((void*) ptr);
   383       ptr = p;
   384     }
   385   }
   387   T& operator*() const {
   388     MOZ_ASSERT(ptr != 0);
   389     return *ptr;
   390   }
   392   T* operator->() const {
   393     MOZ_ASSERT(ptr != 0);
   394     return ptr;
   395   }
   397   bool operator==(T* p) const {
   398     return ptr == p;
   399   }
   401   bool operator!=(T* p) const {
   402     return ptr != p;
   403   }
   405   T* get() const {
   406     return ptr;
   407   }
   409   void swap(scoped_ptr_malloc & b) {
   410     T* tmp = b.ptr;
   411     b.ptr = ptr;
   412     ptr = tmp;
   413   }
   415   T* release() {
   416     T* tmp = ptr;
   417     ptr = 0;
   418     return tmp;
   419   }
   421  private:
   423   // no reason to use these: each scoped_ptr_malloc should have its own object
   424   template <typename U, typename GP>
   425   bool operator==(scoped_ptr_malloc<U, GP> const& p) const;
   426   template <typename U, typename GP>
   427   bool operator!=(scoped_ptr_malloc<U, GP> const& p) const;
   429   static FreeProc const free_;
   430 };
   432 template<typename T, typename FP>
   433 FP const scoped_ptr_malloc<T,FP>::free_ = FP();
   435 template<typename T, typename FP> inline
   436 void swap(scoped_ptr_malloc<T,FP>& a, scoped_ptr_malloc<T,FP>& b) {
   437   a.swap(b);
   438 }
   440 template<typename T, typename FP> inline
   441 bool operator==(T* p, const scoped_ptr_malloc<T,FP>& b) {
   442   return p == b.get();
   443 }
   445 template<typename T, typename FP> inline
   446 bool operator!=(T* p, const scoped_ptr_malloc<T,FP>& b) {
   447   return p != b.get();
   448 }
   451 ////////////////////////////////////////////////////////////////
   452 // Module
   453 //
   455 // A Module represents the contents of a module, and supports methods
   456 // for adding information produced by parsing STABS or DWARF data
   457 // --- possibly both from the same file --- and then writing out the
   458 // unified contents as a Breakpad-format symbol file.
   459 class Module {
   460 public:
   461   // The type of addresses and sizes in a symbol table.
   462   typedef uint64_t Address;
   464   // Representation of an expression.  This can either be a postfix
   465   // expression, in which case it is stored as a string, or a simple
   466   // expression of the form (identifier + imm) or *(identifier + imm).
   467   // It can also be invalid (denoting "no value").
   468   enum ExprHow {
   469     kExprInvalid = 1,
   470     kExprPostfix,
   471     kExprSimple,
   472     kExprSimpleMem
   473   };
   475   struct Expr {
   476     // Construct a simple-form expression
   477     Expr(const UniqueString* ident, long offset, bool deref) {
   478       if (ident == ustr__empty()) {
   479         Expr();
   480       } else {
   481         postfix_ = "";
   482         ident_ = ident;
   483         offset_ = offset;
   484         how_ = deref ? kExprSimpleMem : kExprSimple;
   485       }
   486     }
   488     // Construct an invalid expression
   489     Expr() {
   490       postfix_ = "";
   491       ident_ = nullptr;
   492       offset_ = 0;
   493       how_ = kExprInvalid;
   494     }
   496     // Return the postfix expression string, either directly,
   497     // if this is a postfix expression, or by synthesising it
   498     // for a simple expression.
   499     std::string getExprPostfix() const {
   500       switch (how_) {
   501         case kExprPostfix:
   502           return postfix_;
   503         case kExprSimple:
   504         case kExprSimpleMem: {
   505           char buf[40];
   506           sprintf(buf, " %ld %c%s", labs(offset_), offset_ < 0 ? '-' : '+',
   507                                     how_ == kExprSimple ? "" : " ^");
   508           return std::string(FromUniqueString(ident_)) + std::string(buf);
   509         }
   510         case kExprInvalid:
   511         default:
   512           MOZ_ASSERT(0 && "getExprPostfix: invalid Module::Expr type");
   513           return "Expr::genExprPostfix: kExprInvalid";
   514       }
   515     }
   517     // The identifier that gives the starting value for simple expressions.
   518     const UniqueString* ident_;
   519     // The offset to add for simple expressions.
   520     long        offset_;
   521     // The Postfix expression string to evaluate for non-simple expressions.
   522     std::string postfix_;
   523     // The operation expressed by this expression.
   524     ExprHow     how_;
   525   };
   527   // A map from register names to expressions that recover
   528   // their values. This can represent a complete set of rules to
   529   // follow at some address, or a set of changes to be applied to an
   530   // extant set of rules.
   531   // NOTE! there are two completely different types called RuleMap.  This
   532   // is one of them.
   533   typedef std::map<const UniqueString*, Expr> RuleMap;
   535   // A map from addresses to RuleMaps, representing changes that take
   536   // effect at given addresses.
   537   typedef std::map<Address, RuleMap> RuleChangeMap;
   539   // A range of 'STACK CFI' stack walking information. An instance of
   540   // this structure corresponds to a 'STACK CFI INIT' record and the
   541   // subsequent 'STACK CFI' records that fall within its range.
   542   struct StackFrameEntry {
   543     // The starting address and number of bytes of machine code this
   544     // entry covers.
   545     Address address, size;
   547     // The initial register recovery rules, in force at the starting
   548     // address.
   549     RuleMap initial_rules;
   551     // A map from addresses to rule changes. To find the rules in
   552     // force at a given address, start with initial_rules, and then
   553     // apply the changes given in this map for all addresses up to and
   554     // including the address you're interested in.
   555     RuleChangeMap rule_changes;
   556   };
   558   // Create a new module with the given name, operating system,
   559   // architecture, and ID string.
   560   Module(const std::string &name, const std::string &os,
   561          const std::string &architecture, const std::string &id);
   562   ~Module();
   564 private:
   566   // Module header entries.
   567   std::string name_, os_, architecture_, id_;
   568 };
   571 }  // namespace lul
   573 #endif // LulCommonExt_h

mercurial