LCOV - code coverage report
Current view: top level - tools/profiler/lul - LulCommonExt.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 1 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 1 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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: */
       3             : 
       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.
      32             : 
      33             : // Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>
      34             : 
      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.
      38             : 
      39             : 
      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             : //
      50             : 
      51             : 
      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
      57             : 
      58             : // External interface for the "Common" component of LUL.
      59             : 
      60             : #ifndef LulCommonExt_h
      61             : #define LulCommonExt_h
      62             : 
      63             : #include <stdlib.h>
      64             : #include <stdio.h>
      65             : #include <stdint.h>
      66             : 
      67             : #include <string>
      68             : #include <map>
      69             : #include <vector>
      70             : #include <cstddef>            // for std::ptrdiff_t
      71             : 
      72             : #include "mozilla/Assertions.h"
      73             : 
      74             : namespace lul {
      75             : 
      76             : using std::string;
      77             : using std::map;
      78             : 
      79             : 
      80             : ////////////////////////////////////////////////////////////////
      81             : // UniqueString
      82             : //
      83             : 
      84             : // Abstract type
      85             : class UniqueString;
      86             : 
      87             : // Get the contained C string (debugging only)
      88             : const char* FromUniqueString(const UniqueString*);
      89             : 
      90             : // Is the given string empty (that is, "") ?
      91             : bool IsEmptyUniqueString(const UniqueString*);
      92             : 
      93             : 
      94             : ////////////////////////////////////////////////////////////////
      95             : // UniqueStringUniverse
      96             : //
      97             : 
      98             : // All UniqueStrings live in some specific UniqueStringUniverse.
      99             : class UniqueStringUniverse {
     100             : public:
     101           0 :   UniqueStringUniverse() {}
     102             :   ~UniqueStringUniverse();
     103             :   // Convert a |string| to a UniqueString, that lives in this universe.
     104             :   const UniqueString* ToUniqueString(string str);
     105             : private:
     106             :   map<string, UniqueString*> map_;
     107             : };
     108             : 
     109             : 
     110             : ////////////////////////////////////////////////////////////////
     111             : // GUID
     112             : //
     113             : 
     114             : typedef struct {
     115             :   uint32_t data1;
     116             :   uint16_t data2;
     117             :   uint16_t data3;
     118             :   uint8_t  data4[8];
     119             : } MDGUID;  // GUID
     120             : 
     121             : typedef MDGUID GUID;
     122             : 
     123             : 
     124             : ////////////////////////////////////////////////////////////////
     125             : // scoped_ptr
     126             : //
     127             : 
     128             : //  scoped_ptr mimics a built-in pointer except that it guarantees deletion
     129             : //  of the object pointed to, either on destruction of the scoped_ptr or via
     130             : //  an explicit reset(). scoped_ptr is a simple solution for simple needs;
     131             : //  use shared_ptr or std::auto_ptr if your needs are more complex.
     132             : 
     133             : //  *** NOTE ***
     134             : //  If your scoped_ptr is a class member of class FOO pointing to a
     135             : //  forward declared type BAR (as shown below), then you MUST use a non-inlined
     136             : //  version of the destructor.  The destructor of a scoped_ptr (called from
     137             : //  FOO's destructor) must have a complete definition of BAR in order to
     138             : //  destroy it.  Example:
     139             : //
     140             : //  -- foo.h --
     141             : //  class BAR;
     142             : //
     143             : //  class FOO {
     144             : //   public:
     145             : //    FOO();
     146             : //    ~FOO();  // Required for sources that instantiate class FOO to compile!
     147             : //
     148             : //   private:
     149             : //    scoped_ptr<BAR> bar_;
     150             : //  };
     151             : //
     152             : //  -- foo.cc --
     153             : //  #include "foo.h"
     154             : //  FOO::~FOO() {} // Empty, but must be non-inlined to FOO's class definition.
     155             : 
     156             : //  scoped_ptr_malloc added by Google
     157             : //  When one of these goes out of scope, instead of doing a delete or
     158             : //  delete[], it calls free().  scoped_ptr_malloc<char> is likely to see
     159             : //  much more use than any other specializations.
     160             : 
     161             : //  release() added by Google
     162             : //  Use this to conditionally transfer ownership of a heap-allocated object
     163             : //  to the caller, usually on method success.
     164             : 
     165             : template <typename T>
     166             : class scoped_ptr {
     167             :  private:
     168             : 
     169             :   T* ptr;
     170             : 
     171             :   scoped_ptr(scoped_ptr const &);
     172             :   scoped_ptr & operator=(scoped_ptr const &);
     173             : 
     174             :  public:
     175             : 
     176             :   typedef T element_type;
     177             : 
     178             :   explicit scoped_ptr(T* p = 0): ptr(p) {}
     179             : 
     180             :   ~scoped_ptr() {
     181             :     delete ptr;
     182             :   }
     183             : 
     184             :   void reset(T* p = 0) {
     185             :     if (ptr != p) {
     186             :       delete ptr;
     187             :       ptr = p;
     188             :     }
     189             :   }
     190             : 
     191             :   T& operator*() const {
     192             :     MOZ_ASSERT(ptr != 0);
     193             :     return *ptr;
     194             :   }
     195             : 
     196             :   T* operator->() const  {
     197             :     MOZ_ASSERT(ptr != 0);
     198             :     return ptr;
     199             :   }
     200             : 
     201             :   bool operator==(T* p) const {
     202             :     return ptr == p;
     203             :   }
     204             : 
     205             :   bool operator!=(T* p) const {
     206             :     return ptr != p;
     207             :   }
     208             : 
     209             :   T* get() const  {
     210             :     return ptr;
     211             :   }
     212             : 
     213             :   void swap(scoped_ptr & b) {
     214             :     T* tmp = b.ptr;
     215             :     b.ptr = ptr;
     216             :     ptr = tmp;
     217             :   }
     218             : 
     219             :   T* release() {
     220             :     T* tmp = ptr;
     221             :     ptr = 0;
     222             :     return tmp;
     223             :   }
     224             : 
     225             :  private:
     226             : 
     227             :   // no reason to use these: each scoped_ptr should have its own object
     228             :   template <typename U> bool operator==(scoped_ptr<U> const& p) const;
     229             :   template <typename U> bool operator!=(scoped_ptr<U> const& p) const;
     230             : };
     231             : 
     232             : template<typename T> inline
     233             : void swap(scoped_ptr<T>& a, scoped_ptr<T>& b) {
     234             :   a.swap(b);
     235             : }
     236             : 
     237             : template<typename T> inline
     238             : bool operator==(T* p, const scoped_ptr<T>& b) {
     239             :   return p == b.get();
     240             : }
     241             : 
     242             : template<typename T> inline
     243             : bool operator!=(T* p, const scoped_ptr<T>& b) {
     244             :   return p != b.get();
     245             : }
     246             : 
     247             : //  scoped_array extends scoped_ptr to arrays. Deletion of the array pointed to
     248             : //  is guaranteed, either on destruction of the scoped_array or via an explicit
     249             : //  reset(). Use shared_array or std::vector if your needs are more complex.
     250             : 
     251             : template<typename T>
     252             : class scoped_array {
     253             :  private:
     254             : 
     255             :   T* ptr;
     256             : 
     257             :   scoped_array(scoped_array const &);
     258             :   scoped_array & operator=(scoped_array const &);
     259             : 
     260             :  public:
     261             : 
     262             :   typedef T element_type;
     263             : 
     264             :   explicit scoped_array(T* p = 0) : ptr(p) {}
     265             : 
     266             :   ~scoped_array() {
     267             :     delete[] ptr;
     268             :   }
     269             : 
     270             :   void reset(T* p = 0) {
     271             :     if (ptr != p) {
     272             :       delete [] ptr;
     273             :       ptr = p;
     274             :     }
     275             :   }
     276             : 
     277             :   T& operator[](std::ptrdiff_t i) const {
     278             :     MOZ_ASSERT(ptr != 0);
     279             :     MOZ_ASSERT(i >= 0);
     280             :     return ptr[i];
     281             :   }
     282             : 
     283             :   bool operator==(T* p) const {
     284             :     return ptr == p;
     285             :   }
     286             : 
     287             :   bool operator!=(T* p) const {
     288             :     return ptr != p;
     289             :   }
     290             : 
     291             :   T* get() const {
     292             :     return ptr;
     293             :   }
     294             : 
     295             :   void swap(scoped_array & b) {
     296             :     T* tmp = b.ptr;
     297             :     b.ptr = ptr;
     298             :     ptr = tmp;
     299             :   }
     300             : 
     301             :   T* release() {
     302             :     T* tmp = ptr;
     303             :     ptr = 0;
     304             :     return tmp;
     305             :   }
     306             : 
     307             :  private:
     308             : 
     309             :   // no reason to use these: each scoped_array should have its own object
     310             :   template <typename U> bool operator==(scoped_array<U> const& p) const;
     311             :   template <typename U> bool operator!=(scoped_array<U> const& p) const;
     312             : };
     313             : 
     314             : template<class T> inline
     315             : void swap(scoped_array<T>& a, scoped_array<T>& b) {
     316             :   a.swap(b);
     317             : }
     318             : 
     319             : template<typename T> inline
     320             : bool operator==(T* p, const scoped_array<T>& b) {
     321             :   return p == b.get();
     322             : }
     323             : 
     324             : template<typename T> inline
     325             : bool operator!=(T* p, const scoped_array<T>& b) {
     326             :   return p != b.get();
     327             : }
     328             : 
     329             : 
     330             : // This class wraps the c library function free() in a class that can be
     331             : // passed as a template argument to scoped_ptr_malloc below.
     332             : class ScopedPtrMallocFree {
     333             :  public:
     334             :   inline void operator()(void* x) const {
     335             :     free(x);
     336             :   }
     337             : };
     338             : 
     339             : // scoped_ptr_malloc<> is similar to scoped_ptr<>, but it accepts a
     340             : // second template argument, the functor used to free the object.
     341             : 
     342             : template<typename T, typename FreeProc = ScopedPtrMallocFree>
     343             : class scoped_ptr_malloc {
     344             :  private:
     345             : 
     346             :   T* ptr;
     347             : 
     348             :   scoped_ptr_malloc(scoped_ptr_malloc const &);
     349             :   scoped_ptr_malloc & operator=(scoped_ptr_malloc const &);
     350             : 
     351             :  public:
     352             : 
     353             :   typedef T element_type;
     354             : 
     355             :   explicit scoped_ptr_malloc(T* p = 0): ptr(p) {}
     356             : 
     357             :   ~scoped_ptr_malloc() {
     358             :     free_((void*) ptr);
     359             :   }
     360             : 
     361             :   void reset(T* p = 0) {
     362             :     if (ptr != p) {
     363             :       free_((void*) ptr);
     364             :       ptr = p;
     365             :     }
     366             :   }
     367             : 
     368             :   T& operator*() const {
     369             :     MOZ_ASSERT(ptr != 0);
     370             :     return *ptr;
     371             :   }
     372             : 
     373             :   T* operator->() const {
     374             :     MOZ_ASSERT(ptr != 0);
     375             :     return ptr;
     376             :   }
     377             : 
     378             :   bool operator==(T* p) const {
     379             :     return ptr == p;
     380             :   }
     381             : 
     382             :   bool operator!=(T* p) const {
     383             :     return ptr != p;
     384             :   }
     385             : 
     386             :   T* get() const {
     387             :     return ptr;
     388             :   }
     389             : 
     390             :   void swap(scoped_ptr_malloc & b) {
     391             :     T* tmp = b.ptr;
     392             :     b.ptr = ptr;
     393             :     ptr = tmp;
     394             :   }
     395             : 
     396             :   T* release() {
     397             :     T* tmp = ptr;
     398             :     ptr = 0;
     399             :     return tmp;
     400             :   }
     401             : 
     402             :  private:
     403             : 
     404             :   // no reason to use these: each scoped_ptr_malloc should have its own object
     405             :   template <typename U, typename GP>
     406             :   bool operator==(scoped_ptr_malloc<U, GP> const& p) const;
     407             :   template <typename U, typename GP>
     408             :   bool operator!=(scoped_ptr_malloc<U, GP> const& p) const;
     409             : 
     410             :   static FreeProc const free_;
     411             : };
     412             : 
     413             : template<typename T, typename FP>
     414             : FP const scoped_ptr_malloc<T,FP>::free_ = FP();
     415             : 
     416             : template<typename T, typename FP> inline
     417             : void swap(scoped_ptr_malloc<T,FP>& a, scoped_ptr_malloc<T,FP>& b) {
     418             :   a.swap(b);
     419             : }
     420             : 
     421             : template<typename T, typename FP> inline
     422             : bool operator==(T* p, const scoped_ptr_malloc<T,FP>& b) {
     423             :   return p == b.get();
     424             : }
     425             : 
     426             : template<typename T, typename FP> inline
     427             : bool operator!=(T* p, const scoped_ptr_malloc<T,FP>& b) {
     428             :   return p != b.get();
     429             : }
     430             : 
     431             : 
     432             : ////////////////////////////////////////////////////////////////
     433             : // Module
     434             : //
     435             : 
     436             : // A Module represents the contents of a module, and supports methods
     437             : // for adding information produced by parsing STABS or DWARF data
     438             : // --- possibly both from the same file --- and then writing out the
     439             : // unified contents as a Breakpad-format symbol file.
     440             : class Module {
     441             : public:
     442             :   // The type of addresses and sizes in a symbol table.
     443             :   typedef uint64_t Address;
     444             : 
     445             :   // Representation of an expression.  This can either be a postfix
     446             :   // expression, in which case it is stored as a string, or a simple
     447             :   // expression of the form (identifier + imm) or *(identifier + imm).
     448             :   // It can also be invalid (denoting "no value").
     449             :   enum ExprHow {
     450             :     kExprInvalid = 1,
     451             :     kExprPostfix,
     452             :     kExprSimple,
     453             :     kExprSimpleMem
     454             :   };
     455             : 
     456             :   struct Expr {
     457             :     // Construct a simple-form expression
     458             :     Expr(const UniqueString* ident, long offset, bool deref) {
     459             :       if (IsEmptyUniqueString(ident)) {
     460             :         Expr();
     461             :       } else {
     462             :         postfix_ = "";
     463             :         ident_ = ident;
     464             :         offset_ = offset;
     465             :         how_ = deref ? kExprSimpleMem : kExprSimple;
     466             :       }
     467             :     }
     468             : 
     469             :     // Construct an invalid expression
     470             :     Expr() {
     471             :       postfix_ = "";
     472             :       ident_ = nullptr;
     473             :       offset_ = 0;
     474             :       how_ = kExprInvalid;
     475             :     }
     476             : 
     477             :     // Return the postfix expression string, either directly,
     478             :     // if this is a postfix expression, or by synthesising it
     479             :     // for a simple expression.
     480             :     std::string getExprPostfix() const {
     481             :       switch (how_) {
     482             :         case kExprPostfix:
     483             :           return postfix_;
     484             :         case kExprSimple:
     485             :         case kExprSimpleMem: {
     486             :           char buf[40];
     487             :           sprintf(buf, " %ld %c%s", labs(offset_), offset_ < 0 ? '-' : '+',
     488             :                                     how_ == kExprSimple ? "" : " ^");
     489             :           return std::string(FromUniqueString(ident_)) + std::string(buf);
     490             :         }
     491             :         case kExprInvalid:
     492             :         default:
     493             :           MOZ_ASSERT(0 && "getExprPostfix: invalid Module::Expr type");
     494             :           return "Expr::genExprPostfix: kExprInvalid";
     495             :       }
     496             :     }
     497             : 
     498             :     // The identifier that gives the starting value for simple expressions.
     499             :     const UniqueString* ident_;
     500             :     // The offset to add for simple expressions.
     501             :     long        offset_;
     502             :     // The Postfix expression string to evaluate for non-simple expressions.
     503             :     std::string postfix_;
     504             :     // The operation expressed by this expression.
     505             :     ExprHow     how_;
     506             :   };
     507             : 
     508             :   // A map from register names to expressions that recover
     509             :   // their values. This can represent a complete set of rules to
     510             :   // follow at some address, or a set of changes to be applied to an
     511             :   // extant set of rules.
     512             :   // NOTE! there are two completely different types called RuleMap.  This
     513             :   // is one of them.
     514             :   typedef std::map<const UniqueString*, Expr> RuleMap;
     515             : 
     516             :   // A map from addresses to RuleMaps, representing changes that take
     517             :   // effect at given addresses.
     518             :   typedef std::map<Address, RuleMap> RuleChangeMap;
     519             : 
     520             :   // A range of 'STACK CFI' stack walking information. An instance of
     521             :   // this structure corresponds to a 'STACK CFI INIT' record and the
     522             :   // subsequent 'STACK CFI' records that fall within its range.
     523             :   struct StackFrameEntry {
     524             :     // The starting address and number of bytes of machine code this
     525             :     // entry covers.
     526             :     Address address, size;
     527             : 
     528             :     // The initial register recovery rules, in force at the starting
     529             :     // address.
     530             :     RuleMap initial_rules;
     531             : 
     532             :     // A map from addresses to rule changes. To find the rules in
     533             :     // force at a given address, start with initial_rules, and then
     534             :     // apply the changes given in this map for all addresses up to and
     535             :     // including the address you're interested in.
     536             :     RuleChangeMap rule_changes;
     537             :   };
     538             : 
     539             :   // Create a new module with the given name, operating system,
     540             :   // architecture, and ID string.
     541             :   Module(const std::string &name, const std::string &os,
     542             :          const std::string &architecture, const std::string &id);
     543             :   ~Module();
     544             : 
     545             : private:
     546             : 
     547             :   // Module header entries.
     548             :   std::string name_, os_, architecture_, id_;
     549             : };
     550             : 
     551             : 
     552             : }  // namespace lul
     553             : 
     554             : #endif // LulCommonExt_h

Generated by: LCOV version 1.13