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.
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions are
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
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.
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
40 // (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
41 // Copyright (c) 2001, 2002 Peter Dimov
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.
48 // See http://www.boost.org/libs/smart_ptr/scoped_ptr.htm for documentation.
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
70 #include <cstddef> // for std::ptrdiff_t
72 #include "mozilla/Assertions.h"
73 #include "mozilla/NullPtr.h"
77 ////////////////////////////////////////////////////////////////
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:
101 // Note that ustr__empty and (UniqueString*)nullptr are considered
104 // Unfortunately these have to be written as functions so as to
105 // make them safe to use in static initialisers.
108 inline static const UniqueString
* ustr__empty() {
109 static const UniqueString
* us
= nullptr;
110 if (!us
) us
= ToUniqueString("");
115 inline static const UniqueString
* ustr__ZDcfa() {
116 static const UniqueString
* us
= nullptr;
117 if (!us
) us
= ToUniqueString(".cfa");
122 inline static const UniqueString
* ustr__ZDra() {
123 static const UniqueString
* us
= nullptr;
124 if (!us
) us
= ToUniqueString(".ra");
129 ////////////////////////////////////////////////////////////////
143 ////////////////////////////////////////////////////////////////
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.
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:
165 // ~FOO(); // Required for sources that instantiate class FOO to compile!
168 // scoped_ptr<BAR> bar_;
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
>
190 scoped_ptr(scoped_ptr
const &);
191 scoped_ptr
& operator=(scoped_ptr
const &);
195 typedef T element_type
;
197 explicit scoped_ptr(T
* p
= 0): ptr(p
) {}
203 void reset(T
* p
= 0) {
210 T
& operator*() const {
211 MOZ_ASSERT(ptr
!= 0);
215 T
* operator->() const {
216 MOZ_ASSERT(ptr
!= 0);
220 bool operator==(T
* p
) const {
224 bool operator!=(T
* p
) const {
232 void swap(scoped_ptr
& b
) {
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;
251 template<typename T
> inline
252 void swap(scoped_ptr
<T
>& a
, scoped_ptr
<T
>& b
) {
256 template<typename T
> inline
257 bool operator==(T
* p
, const scoped_ptr
<T
>& b
) {
261 template<typename T
> inline
262 bool operator!=(T
* p
, const scoped_ptr
<T
>& b
) {
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.
276 scoped_array(scoped_array
const &);
277 scoped_array
& operator=(scoped_array
const &);
281 typedef T element_type
;
283 explicit scoped_array(T
* p
= 0) : ptr(p
) {}
289 void reset(T
* p
= 0) {
296 T
& operator[](std::ptrdiff_t i
) const {
297 MOZ_ASSERT(ptr
!= 0);
302 bool operator==(T
* p
) const {
306 bool operator!=(T
* p
) const {
314 void swap(scoped_array
& b
) {
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;
333 template<class T
> inline
334 void swap(scoped_array
<T
>& a
, scoped_array
<T
>& b
) {
338 template<typename T
> inline
339 bool operator==(T
* p
, const scoped_array
<T
>& b
) {
343 template<typename T
> inline
344 bool operator!=(T
* p
, const scoped_array
<T
>& b
) {
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
{
353 inline void operator()(void* x
) const {
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
{
367 scoped_ptr_malloc(scoped_ptr_malloc
const &);
368 scoped_ptr_malloc
& operator=(scoped_ptr_malloc
const &);
372 typedef T element_type
;
374 explicit scoped_ptr_malloc(T
* p
= 0): ptr(p
) {}
376 ~scoped_ptr_malloc() {
380 void reset(T
* p
= 0) {
387 T
& operator*() const {
388 MOZ_ASSERT(ptr
!= 0);
392 T
* operator->() const {
393 MOZ_ASSERT(ptr
!= 0);
397 bool operator==(T
* p
) const {
401 bool operator!=(T
* p
) const {
409 void swap(scoped_ptr_malloc
& b
) {
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_
;
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
) {
440 template<typename T
, typename FP
> inline
441 bool operator==(T
* p
, const scoped_ptr_malloc
<T
,FP
>& b
) {
445 template<typename T
, typename FP
> inline
446 bool operator!=(T
* p
, const scoped_ptr_malloc
<T
,FP
>& b
) {
451 ////////////////////////////////////////////////////////////////
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.
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").
476 // Construct a simple-form expression
477 Expr(const UniqueString
* ident
, long offset
, bool deref
) {
478 if (ident
== ustr__empty()) {
484 how_
= deref
? kExprSimpleMem
: kExprSimple
;
488 // Construct an invalid expression
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 {
504 case kExprSimpleMem
: {
506 sprintf(buf
, " %ld %c%s", labs(offset_
), offset_
< 0 ? '-' : '+',
507 how_
== kExprSimple
? "" : " ^");
508 return std::string(FromUniqueString(ident_
)) + std::string(buf
);
512 MOZ_ASSERT(0 && "getExprPostfix: invalid Module::Expr type");
513 return "Expr::genExprPostfix: kExprInvalid";
517 // The identifier that gives the starting value for simple expressions.
518 const UniqueString
* ident_
;
519 // The offset to add for simple expressions.
521 // The Postfix expression string to evaluate for non-simple expressions.
522 std::string postfix_
;
523 // The operation expressed by this expression.
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
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
545 Address address
, size
;
547 // The initial register recovery rules, in force at the starting
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
;
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
);
566 // Module header entries.
567 std::string name_
, os_
, architecture_
, id_
;
573 #endif // LulCommonExt_h