xref: /aosp_15_r20/external/google-breakpad/src/common/dwarf/dwarf2diehandler.h (revision 9712c20fc9bbfbac4935993a2ca0b3958c5adad2)
1*9712c20fSFrederick Mayle // -*- mode: c++ -*-
2*9712c20fSFrederick Mayle 
3*9712c20fSFrederick Mayle // Copyright 2010 Google LLC
4*9712c20fSFrederick Mayle //
5*9712c20fSFrederick Mayle // Redistribution and use in source and binary forms, with or without
6*9712c20fSFrederick Mayle // modification, are permitted provided that the following conditions are
7*9712c20fSFrederick Mayle // met:
8*9712c20fSFrederick Mayle //
9*9712c20fSFrederick Mayle //     * Redistributions of source code must retain the above copyright
10*9712c20fSFrederick Mayle // notice, this list of conditions and the following disclaimer.
11*9712c20fSFrederick Mayle //     * Redistributions in binary form must reproduce the above
12*9712c20fSFrederick Mayle // copyright notice, this list of conditions and the following disclaimer
13*9712c20fSFrederick Mayle // in the documentation and/or other materials provided with the
14*9712c20fSFrederick Mayle // distribution.
15*9712c20fSFrederick Mayle //     * Neither the name of Google LLC nor the names of its
16*9712c20fSFrederick Mayle // contributors may be used to endorse or promote products derived from
17*9712c20fSFrederick Mayle // this software without specific prior written permission.
18*9712c20fSFrederick Mayle //
19*9712c20fSFrederick Mayle // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20*9712c20fSFrederick Mayle // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21*9712c20fSFrederick Mayle // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22*9712c20fSFrederick Mayle // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23*9712c20fSFrederick Mayle // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24*9712c20fSFrederick Mayle // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25*9712c20fSFrederick Mayle // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26*9712c20fSFrederick Mayle // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27*9712c20fSFrederick Mayle // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28*9712c20fSFrederick Mayle // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29*9712c20fSFrederick Mayle // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30*9712c20fSFrederick Mayle 
31*9712c20fSFrederick Mayle // Original author: Jim Blandy <[email protected]> <[email protected]>
32*9712c20fSFrederick Mayle 
33*9712c20fSFrederick Mayle // dwarf2reader::CompilationUnit is a simple and direct parser for
34*9712c20fSFrederick Mayle // DWARF data, but its handler interface is not convenient to use.  In
35*9712c20fSFrederick Mayle // particular:
36*9712c20fSFrederick Mayle //
37*9712c20fSFrederick Mayle // - CompilationUnit calls Dwarf2Handler's member functions to report
38*9712c20fSFrederick Mayle //   every attribute's value, regardless of what sort of DIE it is.
39*9712c20fSFrederick Mayle //   As a result, the ProcessAttributeX functions end up looking like
40*9712c20fSFrederick Mayle //   this:
41*9712c20fSFrederick Mayle //
42*9712c20fSFrederick Mayle //     switch (parent_die_tag) {
43*9712c20fSFrederick Mayle //       case DW_TAG_x:
44*9712c20fSFrederick Mayle //         switch (attribute_name) {
45*9712c20fSFrederick Mayle //           case DW_AT_y:
46*9712c20fSFrederick Mayle //             handle attribute y of DIE type x
47*9712c20fSFrederick Mayle //           ...
48*9712c20fSFrederick Mayle //         } break;
49*9712c20fSFrederick Mayle //       ...
50*9712c20fSFrederick Mayle //     }
51*9712c20fSFrederick Mayle //
52*9712c20fSFrederick Mayle //   In C++ it's much nicer to use virtual function dispatch to find
53*9712c20fSFrederick Mayle //   the right code for a given case than to switch on the DIE tag
54*9712c20fSFrederick Mayle //   like this.
55*9712c20fSFrederick Mayle //
56*9712c20fSFrederick Mayle // - Processing different kinds of DIEs requires different sets of
57*9712c20fSFrederick Mayle //   data: lexical block DIEs have start and end addresses, but struct
58*9712c20fSFrederick Mayle //   type DIEs don't.  It would be nice to be able to have separate
59*9712c20fSFrederick Mayle //   handler classes for separate kinds of DIEs, each with the members
60*9712c20fSFrederick Mayle //   appropriate to its role, instead of having one handler class that
61*9712c20fSFrederick Mayle //   needs to hold data for every DIE type.
62*9712c20fSFrederick Mayle //
63*9712c20fSFrederick Mayle // - There should be a separate instance of the appropriate handler
64*9712c20fSFrederick Mayle //   class for each DIE, instead of a single object with tables
65*9712c20fSFrederick Mayle //   tracking all the dies in the compilation unit.
66*9712c20fSFrederick Mayle //
67*9712c20fSFrederick Mayle // - It's not convenient to take some action after all a DIE's
68*9712c20fSFrederick Mayle //   attributes have been seen, but before visiting any of its
69*9712c20fSFrederick Mayle //   children.  The only indication you have that a DIE's attribute
70*9712c20fSFrederick Mayle //   list is complete is that you get either a StartDIE or an EndDIE
71*9712c20fSFrederick Mayle //   call.
72*9712c20fSFrederick Mayle //
73*9712c20fSFrederick Mayle // - It's not convenient to make use of the tree structure of the
74*9712c20fSFrederick Mayle //   DIEs.  Skipping all the children of a given die requires
75*9712c20fSFrederick Mayle //   maintaining state and returning false from StartDIE until we get
76*9712c20fSFrederick Mayle //   an EndDIE call with the appropriate offset.
77*9712c20fSFrederick Mayle //
78*9712c20fSFrederick Mayle // This interface tries to take care of all that.  (You're shocked, I'm sure.)
79*9712c20fSFrederick Mayle //
80*9712c20fSFrederick Mayle // Using the classes here, you provide an initial handler for the root
81*9712c20fSFrederick Mayle // DIE of the compilation unit.  Each handler receives its DIE's
82*9712c20fSFrederick Mayle // attributes, and provides fresh handler objects for children of
83*9712c20fSFrederick Mayle // interest, if any.  The three classes are:
84*9712c20fSFrederick Mayle //
85*9712c20fSFrederick Mayle // - DIEHandler: the base class for your DIE-type-specific handler
86*9712c20fSFrederick Mayle //   classes.
87*9712c20fSFrederick Mayle //
88*9712c20fSFrederick Mayle // - RootDIEHandler: derived from DIEHandler, the base class for your
89*9712c20fSFrederick Mayle //   root DIE handler class.
90*9712c20fSFrederick Mayle //
91*9712c20fSFrederick Mayle // - DIEDispatcher: derived from Dwarf2Handler, an instance of this
92*9712c20fSFrederick Mayle //   invokes your DIE-type-specific handler objects.
93*9712c20fSFrederick Mayle //
94*9712c20fSFrederick Mayle // In detail:
95*9712c20fSFrederick Mayle //
96*9712c20fSFrederick Mayle // - Define handler classes specialized for the DIE types you're
97*9712c20fSFrederick Mayle //   interested in.  These handler classes must inherit from
98*9712c20fSFrederick Mayle //   DIEHandler.  Thus:
99*9712c20fSFrederick Mayle //
100*9712c20fSFrederick Mayle //     class My_DW_TAG_X_Handler: public DIEHandler { ... };
101*9712c20fSFrederick Mayle //     class My_DW_TAG_Y_Handler: public DIEHandler { ... };
102*9712c20fSFrederick Mayle //
103*9712c20fSFrederick Mayle //   DIEHandler subclasses needn't correspond exactly to single DIE
104*9712c20fSFrederick Mayle //   types, as shown here; the point is that you can have several
105*9712c20fSFrederick Mayle //   different classes appropriate to different kinds of DIEs.
106*9712c20fSFrederick Mayle //
107*9712c20fSFrederick Mayle // - In particular, define a handler class for the compilation
108*9712c20fSFrederick Mayle //   unit's root DIE, that inherits from RootDIEHandler:
109*9712c20fSFrederick Mayle //
110*9712c20fSFrederick Mayle //     class My_DW_TAG_compile_unit_Handler: public RootDIEHandler { ... };
111*9712c20fSFrederick Mayle //
112*9712c20fSFrederick Mayle //   RootDIEHandler inherits from DIEHandler, adding a few additional
113*9712c20fSFrederick Mayle //   member functions for examining the compilation unit as a whole,
114*9712c20fSFrederick Mayle //   and other quirks of rootness.
115*9712c20fSFrederick Mayle //
116*9712c20fSFrederick Mayle // - Then, create a DIEDispatcher instance, passing it an instance of
117*9712c20fSFrederick Mayle //   your root DIE handler class, and use that DIEDispatcher as the
118*9712c20fSFrederick Mayle //   dwarf2reader::CompilationUnit's handler:
119*9712c20fSFrederick Mayle //
120*9712c20fSFrederick Mayle //     My_DW_TAG_compile_unit_Handler root_die_handler(...);
121*9712c20fSFrederick Mayle //     DIEDispatcher die_dispatcher(&root_die_handler);
122*9712c20fSFrederick Mayle //     CompilationUnit reader(sections, offset, bytereader, &die_dispatcher);
123*9712c20fSFrederick Mayle //
124*9712c20fSFrederick Mayle //   Here, 'die_dispatcher' acts as a shim between 'reader' and the
125*9712c20fSFrederick Mayle //   various DIE-specific handlers you have defined.
126*9712c20fSFrederick Mayle //
127*9712c20fSFrederick Mayle // - When you call reader.Start(), die_dispatcher behaves as follows,
128*9712c20fSFrederick Mayle //   starting with your root die handler and the compilation unit's
129*9712c20fSFrederick Mayle //   root DIE:
130*9712c20fSFrederick Mayle //
131*9712c20fSFrederick Mayle //   - It calls the handler's ProcessAttributeX member functions for
132*9712c20fSFrederick Mayle //     each of the DIE's attributes.
133*9712c20fSFrederick Mayle //
134*9712c20fSFrederick Mayle //   - It calls the handler's EndAttributes member function.  This
135*9712c20fSFrederick Mayle //     should return true if any of the DIE's children should be
136*9712c20fSFrederick Mayle //     visited, in which case:
137*9712c20fSFrederick Mayle //
138*9712c20fSFrederick Mayle //     - For each of the DIE's children, die_dispatcher calls the
139*9712c20fSFrederick Mayle //       DIE's handler's FindChildHandler member function.  If that
140*9712c20fSFrederick Mayle //       returns a pointer to a DIEHandler instance, then
141*9712c20fSFrederick Mayle //       die_dispatcher uses that handler to process the child, using
142*9712c20fSFrederick Mayle //       this procedure recursively.  Alternatively, if
143*9712c20fSFrederick Mayle //       FindChildHandler returns NULL, die_dispatcher ignores that
144*9712c20fSFrederick Mayle //       child and its descendants.
145*9712c20fSFrederick Mayle //
146*9712c20fSFrederick Mayle //   - When die_dispatcher has finished processing all the DIE's
147*9712c20fSFrederick Mayle //     children, it invokes the handler's Finish() member function,
148*9712c20fSFrederick Mayle //     and destroys the handler.  (As a special case, it doesn't
149*9712c20fSFrederick Mayle //     destroy the root DIE handler.)
150*9712c20fSFrederick Mayle //
151*9712c20fSFrederick Mayle // This allows the code for handling a particular kind of DIE to be
152*9712c20fSFrederick Mayle // gathered together in a single class, makes it easy to skip all the
153*9712c20fSFrederick Mayle // children or individual children of a particular DIE, and provides
154*9712c20fSFrederick Mayle // appropriate parental context for each die.
155*9712c20fSFrederick Mayle 
156*9712c20fSFrederick Mayle #ifndef COMMON_DWARF_DWARF2DIEHANDLER_H__
157*9712c20fSFrederick Mayle #define COMMON_DWARF_DWARF2DIEHANDLER_H__
158*9712c20fSFrederick Mayle 
159*9712c20fSFrederick Mayle #include <stdint.h>
160*9712c20fSFrederick Mayle 
161*9712c20fSFrederick Mayle #include <stack>
162*9712c20fSFrederick Mayle #include <string>
163*9712c20fSFrederick Mayle 
164*9712c20fSFrederick Mayle #include "common/dwarf/types.h"
165*9712c20fSFrederick Mayle #include "common/dwarf/dwarf2enums.h"
166*9712c20fSFrederick Mayle #include "common/dwarf/dwarf2reader.h"
167*9712c20fSFrederick Mayle #include "common/using_std_string.h"
168*9712c20fSFrederick Mayle 
169*9712c20fSFrederick Mayle namespace google_breakpad {
170*9712c20fSFrederick Mayle 
171*9712c20fSFrederick Mayle // A base class for handlers for specific DIE types.  The series of
172*9712c20fSFrederick Mayle // calls made on a DIE handler is as follows:
173*9712c20fSFrederick Mayle //
174*9712c20fSFrederick Mayle // - for each attribute of the DIE:
175*9712c20fSFrederick Mayle //   - ProcessAttributeX()
176*9712c20fSFrederick Mayle // - EndAttributes()
177*9712c20fSFrederick Mayle // - if that returned true, then for each child:
178*9712c20fSFrederick Mayle //   - FindChildHandler()
179*9712c20fSFrederick Mayle //   - if that returns a non-NULL pointer to a new handler:
180*9712c20fSFrederick Mayle //     - recurse, with the new handler and the child die
181*9712c20fSFrederick Mayle // - Finish()
182*9712c20fSFrederick Mayle // - destruction
183*9712c20fSFrederick Mayle class DIEHandler {
184*9712c20fSFrederick Mayle  public:
DIEHandler()185*9712c20fSFrederick Mayle   DIEHandler() { }
~DIEHandler()186*9712c20fSFrederick Mayle   virtual ~DIEHandler() { }
187*9712c20fSFrederick Mayle 
188*9712c20fSFrederick Mayle   // When we visit a DIE, we first use these member functions to
189*9712c20fSFrederick Mayle   // report the DIE's attributes and their values.  These have the
190*9712c20fSFrederick Mayle   // same restrictions as the corresponding member functions of
191*9712c20fSFrederick Mayle   // dwarf2reader::Dwarf2Handler.
192*9712c20fSFrederick Mayle   //
193*9712c20fSFrederick Mayle   // Since DWARF does not specify in what order attributes must
194*9712c20fSFrederick Mayle   // appear, avoid making decisions in these functions that would be
195*9712c20fSFrederick Mayle   // affected by the presence of other attributes. The EndAttributes
196*9712c20fSFrederick Mayle   // function is a more appropriate place for such work, as all the
197*9712c20fSFrederick Mayle   // DIE's attributes have been seen at that point.
198*9712c20fSFrederick Mayle   //
199*9712c20fSFrederick Mayle   // The default definitions ignore the values they are passed.
ProcessAttributeUnsigned(enum DwarfAttribute attr,enum DwarfForm form,uint64_t data)200*9712c20fSFrederick Mayle   virtual void ProcessAttributeUnsigned(enum DwarfAttribute attr,
201*9712c20fSFrederick Mayle                                         enum DwarfForm form,
202*9712c20fSFrederick Mayle                                         uint64_t data) { }
ProcessAttributeSigned(enum DwarfAttribute attr,enum DwarfForm form,int64_t data)203*9712c20fSFrederick Mayle   virtual void ProcessAttributeSigned(enum DwarfAttribute attr,
204*9712c20fSFrederick Mayle                                       enum DwarfForm form,
205*9712c20fSFrederick Mayle                                       int64_t data) { }
ProcessAttributeReference(enum DwarfAttribute attr,enum DwarfForm form,uint64_t data)206*9712c20fSFrederick Mayle   virtual void ProcessAttributeReference(enum DwarfAttribute attr,
207*9712c20fSFrederick Mayle                                          enum DwarfForm form,
208*9712c20fSFrederick Mayle                                          uint64_t data) { }
ProcessAttributeBuffer(enum DwarfAttribute attr,enum DwarfForm form,const uint8_t * data,uint64_t len)209*9712c20fSFrederick Mayle   virtual void ProcessAttributeBuffer(enum DwarfAttribute attr,
210*9712c20fSFrederick Mayle                                       enum DwarfForm form,
211*9712c20fSFrederick Mayle                                       const uint8_t* data,
212*9712c20fSFrederick Mayle                                       uint64_t len) { }
ProcessAttributeString(enum DwarfAttribute attr,enum DwarfForm form,const string & data)213*9712c20fSFrederick Mayle   virtual void ProcessAttributeString(enum DwarfAttribute attr,
214*9712c20fSFrederick Mayle                                       enum DwarfForm form,
215*9712c20fSFrederick Mayle                                       const string& data) { }
ProcessAttributeSignature(enum DwarfAttribute attr,enum DwarfForm form,uint64_t signture)216*9712c20fSFrederick Mayle   virtual void ProcessAttributeSignature(enum DwarfAttribute attr,
217*9712c20fSFrederick Mayle                                          enum DwarfForm form,
218*9712c20fSFrederick Mayle                                          uint64_t signture) { }
219*9712c20fSFrederick Mayle 
220*9712c20fSFrederick Mayle   // Once we have reported all the DIE's attributes' values, we call
221*9712c20fSFrederick Mayle   // this member function.  If it returns false, we skip all the DIE's
222*9712c20fSFrederick Mayle   // children.  If it returns true, we call FindChildHandler on each
223*9712c20fSFrederick Mayle   // child.  If that returns a handler object, we use that to visit
224*9712c20fSFrederick Mayle   // the child; otherwise, we skip the child.
225*9712c20fSFrederick Mayle   //
226*9712c20fSFrederick Mayle   // This is a good place to make decisions that depend on more than
227*9712c20fSFrederick Mayle   // one attribute. DWARF does not specify in what order attributes
228*9712c20fSFrederick Mayle   // must appear, so only when the EndAttributes function is called
229*9712c20fSFrederick Mayle   // does the handler have a complete picture of the DIE's attributes.
230*9712c20fSFrederick Mayle   //
231*9712c20fSFrederick Mayle   // The default definition elects to ignore the DIE's children.
232*9712c20fSFrederick Mayle   // You'll need to override this if you override FindChildHandler,
233*9712c20fSFrederick Mayle   // but at least the default behavior isn't to pass the children to
234*9712c20fSFrederick Mayle   // FindChildHandler, which then ignores them all.
EndAttributes()235*9712c20fSFrederick Mayle   virtual bool EndAttributes() { return false; }
236*9712c20fSFrederick Mayle 
237*9712c20fSFrederick Mayle   // If EndAttributes returns true to indicate that some of the DIE's
238*9712c20fSFrederick Mayle   // children might be of interest, then we apply this function to
239*9712c20fSFrederick Mayle   // each of the DIE's children.  If it returns a handler object, then
240*9712c20fSFrederick Mayle   // we use that to visit the child DIE.  If it returns NULL, we skip
241*9712c20fSFrederick Mayle   // that child DIE (and all its descendants).
242*9712c20fSFrederick Mayle   //
243*9712c20fSFrederick Mayle   // OFFSET is the offset of the child; TAG indicates what kind of DIE
244*9712c20fSFrederick Mayle   // it is.
245*9712c20fSFrederick Mayle   //
246*9712c20fSFrederick Mayle   // The default definition skips all children.
FindChildHandler(uint64_t offset,enum DwarfTag tag)247*9712c20fSFrederick Mayle   virtual DIEHandler* FindChildHandler(uint64_t offset, enum DwarfTag tag) {
248*9712c20fSFrederick Mayle     return NULL;
249*9712c20fSFrederick Mayle   }
250*9712c20fSFrederick Mayle 
251*9712c20fSFrederick Mayle   // When we are done processing a DIE, we call this member function.
252*9712c20fSFrederick Mayle   // This happens after the EndAttributes call, all FindChildHandler
253*9712c20fSFrederick Mayle   // calls (if any), and all operations on the children themselves (if
254*9712c20fSFrederick Mayle   // any). We call Finish on every handler --- even if EndAttributes
255*9712c20fSFrederick Mayle   // returns false.
Finish()256*9712c20fSFrederick Mayle   virtual void Finish() { };
257*9712c20fSFrederick Mayle };
258*9712c20fSFrederick Mayle 
259*9712c20fSFrederick Mayle // A subclass of DIEHandler, with additional kludges for handling the
260*9712c20fSFrederick Mayle // compilation unit's root die.
261*9712c20fSFrederick Mayle class RootDIEHandler : public DIEHandler {
262*9712c20fSFrederick Mayle  public:
263*9712c20fSFrederick Mayle   bool handle_inline;
264*9712c20fSFrederick Mayle 
265*9712c20fSFrederick Mayle   explicit RootDIEHandler(bool handle_inline = false)
handle_inline(handle_inline)266*9712c20fSFrederick Mayle       : handle_inline(handle_inline) {}
~RootDIEHandler()267*9712c20fSFrederick Mayle   virtual ~RootDIEHandler() {}
268*9712c20fSFrederick Mayle 
269*9712c20fSFrederick Mayle   // We pass the values reported via Dwarf2Handler::StartCompilationUnit
270*9712c20fSFrederick Mayle   // to this member function, and skip the entire compilation unit if it
271*9712c20fSFrederick Mayle   // returns false.  So the root DIE handler is actually also
272*9712c20fSFrederick Mayle   // responsible for handling the compilation unit metadata.
273*9712c20fSFrederick Mayle   // The default definition always visits the compilation unit.
StartCompilationUnit(uint64_t offset,uint8_t address_size,uint8_t offset_size,uint64_t cu_length,uint8_t dwarf_version)274*9712c20fSFrederick Mayle   virtual bool StartCompilationUnit(uint64_t offset, uint8_t address_size,
275*9712c20fSFrederick Mayle                                     uint8_t offset_size, uint64_t cu_length,
276*9712c20fSFrederick Mayle                                     uint8_t dwarf_version) { return true; }
277*9712c20fSFrederick Mayle 
278*9712c20fSFrederick Mayle   // For the root DIE handler only, we pass the offset, tag and
279*9712c20fSFrederick Mayle   // attributes of the compilation unit's root DIE.  This is the only
280*9712c20fSFrederick Mayle   // way the root DIE handler can find the root DIE's tag.  If this
281*9712c20fSFrederick Mayle   // function returns true, we will visit the root DIE using the usual
282*9712c20fSFrederick Mayle   // DIEHandler methods; otherwise, we skip the entire compilation
283*9712c20fSFrederick Mayle   // unit.
284*9712c20fSFrederick Mayle   //
285*9712c20fSFrederick Mayle   // The default definition elects to visit the root DIE.
StartRootDIE(uint64_t offset,enum DwarfTag tag)286*9712c20fSFrederick Mayle   virtual bool StartRootDIE(uint64_t offset, enum DwarfTag tag) { return true; }
287*9712c20fSFrederick Mayle };
288*9712c20fSFrederick Mayle 
289*9712c20fSFrederick Mayle class DIEDispatcher: public Dwarf2Handler {
290*9712c20fSFrederick Mayle  public:
291*9712c20fSFrederick Mayle   // Create a Dwarf2Handler which uses ROOT_HANDLER as the handler for
292*9712c20fSFrederick Mayle   // the compilation unit's root die, as described for the DIEHandler
293*9712c20fSFrederick Mayle   // class.
DIEDispatcher(RootDIEHandler * root_handler)294*9712c20fSFrederick Mayle   DIEDispatcher(RootDIEHandler* root_handler) : root_handler_(root_handler) { }
295*9712c20fSFrederick Mayle   // Destroying a DIEDispatcher destroys all active handler objects
296*9712c20fSFrederick Mayle   // except the root handler.
297*9712c20fSFrederick Mayle   ~DIEDispatcher();
298*9712c20fSFrederick Mayle   bool StartCompilationUnit(uint64_t offset, uint8_t address_size,
299*9712c20fSFrederick Mayle                             uint8_t offset_size, uint64_t cu_length,
300*9712c20fSFrederick Mayle                             uint8_t dwarf_version);
301*9712c20fSFrederick Mayle   bool StartDIE(uint64_t offset, enum DwarfTag tag);
302*9712c20fSFrederick Mayle   void ProcessAttributeUnsigned(uint64_t offset,
303*9712c20fSFrederick Mayle                                 enum DwarfAttribute attr,
304*9712c20fSFrederick Mayle                                 enum DwarfForm form,
305*9712c20fSFrederick Mayle                                 uint64_t data);
306*9712c20fSFrederick Mayle   void ProcessAttributeSigned(uint64_t offset,
307*9712c20fSFrederick Mayle                               enum DwarfAttribute attr,
308*9712c20fSFrederick Mayle                               enum DwarfForm form,
309*9712c20fSFrederick Mayle                               int64_t data);
310*9712c20fSFrederick Mayle   void ProcessAttributeReference(uint64_t offset,
311*9712c20fSFrederick Mayle                                  enum DwarfAttribute attr,
312*9712c20fSFrederick Mayle                                  enum DwarfForm form,
313*9712c20fSFrederick Mayle                                  uint64_t data);
314*9712c20fSFrederick Mayle   void ProcessAttributeBuffer(uint64_t offset,
315*9712c20fSFrederick Mayle                               enum DwarfAttribute attr,
316*9712c20fSFrederick Mayle                               enum DwarfForm form,
317*9712c20fSFrederick Mayle                               const uint8_t* data,
318*9712c20fSFrederick Mayle                               uint64_t len);
319*9712c20fSFrederick Mayle   void ProcessAttributeString(uint64_t offset,
320*9712c20fSFrederick Mayle                               enum DwarfAttribute attr,
321*9712c20fSFrederick Mayle                               enum DwarfForm form,
322*9712c20fSFrederick Mayle                               const string& data);
323*9712c20fSFrederick Mayle   void ProcessAttributeSignature(uint64_t offset,
324*9712c20fSFrederick Mayle                                  enum DwarfAttribute attr,
325*9712c20fSFrederick Mayle                                  enum DwarfForm form,
326*9712c20fSFrederick Mayle                                  uint64_t signature);
327*9712c20fSFrederick Mayle   void EndDIE(uint64_t offset);
328*9712c20fSFrederick Mayle 
329*9712c20fSFrederick Mayle  private:
330*9712c20fSFrederick Mayle 
331*9712c20fSFrederick Mayle   // The type of a handler stack entry.  This includes some fields
332*9712c20fSFrederick Mayle   // which don't really need to be on the stack --- they could just be
333*9712c20fSFrederick Mayle   // single data members of DIEDispatcher --- but putting them here
334*9712c20fSFrederick Mayle   // makes it easier to see that the code is correct.
335*9712c20fSFrederick Mayle   struct HandlerStack {
336*9712c20fSFrederick Mayle     // The offset of the DIE for this handler stack entry.
337*9712c20fSFrederick Mayle     uint64_t offset_;
338*9712c20fSFrederick Mayle 
339*9712c20fSFrederick Mayle     // The handler object interested in this DIE's attributes and
340*9712c20fSFrederick Mayle     // children.  If NULL, we're not interested in either.
341*9712c20fSFrederick Mayle     DIEHandler* handler_;
342*9712c20fSFrederick Mayle 
343*9712c20fSFrederick Mayle     // Have we reported the end of this DIE's attributes to the handler?
344*9712c20fSFrederick Mayle     bool reported_attributes_end_;
345*9712c20fSFrederick Mayle   };
346*9712c20fSFrederick Mayle 
347*9712c20fSFrederick Mayle   // Stack of DIE attribute handlers.  At StartDIE(D), the top of the
348*9712c20fSFrederick Mayle   // stack is the handler of D's parent, whom we may ask for a handler
349*9712c20fSFrederick Mayle   // for D itself.  At EndDIE(D), the top of the stack is D's handler.
350*9712c20fSFrederick Mayle   // Special cases:
351*9712c20fSFrederick Mayle   //
352*9712c20fSFrederick Mayle   // - Before we've seen the compilation unit's root DIE, the stack is
353*9712c20fSFrederick Mayle   //   empty; we'll call root_handler_'s special member functions, and
354*9712c20fSFrederick Mayle   //   perhaps push root_handler_ on the stack to look at the root's
355*9712c20fSFrederick Mayle   //   immediate children.
356*9712c20fSFrederick Mayle   //
357*9712c20fSFrederick Mayle   // - When we decide to ignore a subtree, we only push an entry on
358*9712c20fSFrederick Mayle   //   the stack for the root of the tree being ignored, rather than
359*9712c20fSFrederick Mayle   //   pushing lots of stack entries with handler_ set to NULL.
360*9712c20fSFrederick Mayle   std::stack<HandlerStack> die_handlers_;
361*9712c20fSFrederick Mayle 
362*9712c20fSFrederick Mayle   // The root handler.  We don't push it on die_handlers_ until we
363*9712c20fSFrederick Mayle   // actually get the StartDIE call for the root.
364*9712c20fSFrederick Mayle   RootDIEHandler* root_handler_;
365*9712c20fSFrederick Mayle };
366*9712c20fSFrederick Mayle 
367*9712c20fSFrederick Mayle } // namespace google_breakpad
368*9712c20fSFrederick Mayle #endif  // COMMON_DWARF_DWARF2DIEHANDLER_H__
369