183e085b7a331c96237cf8e814f97b3ef4c36a70fjimblandy// Copyright (c) 2010 Google Inc. All Rights Reserved.
2cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid//
3cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// Redistribution and use in source and binary forms, with or without
4cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// modification, are permitted provided that the following conditions are
5cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// met:
6cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid//
7cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid//     * Redistributions of source code must retain the above copyright
8cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// notice, this list of conditions and the following disclaimer.
9cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid//     * Redistributions in binary form must reproduce the above
10cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// copyright notice, this list of conditions and the following disclaimer
11cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// in the documentation and/or other materials provided with the
12cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// distribution.
13cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid//     * Neither the name of Google Inc. nor the names of its
14cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// contributors may be used to endorse or promote products derived from
15cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// this software without specific prior written permission.
16cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid//
17cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
29cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
30cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// This file contains the definitions for a DWARF2/3 information
31cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// collector that uses the DWARF2/3 reader interface to build a mapping
32cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// of addresses to files, lines, and functions.
33cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
344969cfc6477c56afb2d4f2f6c1733c3120690b6djimblandy@gmail.com#ifndef COMMON_DWARF_FUNCTIONINFO_H__
354969cfc6477c56afb2d4f2f6c1733c3120690b6djimblandy@gmail.com#define COMMON_DWARF_FUNCTIONINFO_H__
36cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
37cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid#include <map>
38cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid#include <string>
39cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid#include <utility>
40cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid#include <vector>
41cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
424969cfc6477c56afb2d4f2f6c1733c3120690b6djimblandy@gmail.com#include "common/dwarf/dwarf2reader.h"
434e518a4357a2d1c379d4a91df6d4e153ee791101ivan.penkov@gmail.com#include "common/using_std_string.h"
44cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
45cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
46cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsidnamespace dwarf2reader {
47cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
48cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsidstruct FunctionInfo {
49cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  // Name of the function
504e518a4357a2d1c379d4a91df6d4e153ee791101ivan.penkov@gmail.com  string name;
51d3441c2c96346611abd752270144d5f71d4f68b3ted.mielczarek  // Mangled name of the function
524e518a4357a2d1c379d4a91df6d4e153ee791101ivan.penkov@gmail.com  string mangled_name;
53cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  // File containing this function
544e518a4357a2d1c379d4a91df6d4e153ee791101ivan.penkov@gmail.com  string file;
55cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  // Line number for start of function.
56cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  uint32 line;
57cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  // Beginning address for this function
58cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  uint64 lowpc;
59cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  // End address for this function.
60cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  uint64 highpc;
61cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid};
62cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
63cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsidstruct SourceFileInfo {
64cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  // Name of the source file name
654e518a4357a2d1c379d4a91df6d4e153ee791101ivan.penkov@gmail.com  string name;
66cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  // Low address of source file name
67cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  uint64 lowpc;
68cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid};
69cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
708f4d15f86e8326674b35ca7c9dc310f01be19768mark@chromium.orgtypedef std::map<uint64, FunctionInfo*> FunctionMap;
714e518a4357a2d1c379d4a91df6d4e153ee791101ivan.penkov@gmail.comtypedef std::map<uint64, std::pair<string, uint32> > LineMap;
72cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
73cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// This class is a basic line info handler that fills in the dirs,
74cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// file, and linemap passed into it with the data produced from the
75cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid// LineInfoHandler.
76cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsidclass CULineInfoHandler: public LineInfoHandler {
77cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid public:
78cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
79cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  //
808f4d15f86e8326674b35ca7c9dc310f01be19768mark@chromium.org  CULineInfoHandler(std::vector<SourceFileInfo>* files,
814e518a4357a2d1c379d4a91df6d4e153ee791101ivan.penkov@gmail.com                    std::vector<string>* dirs,
82cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid                    LineMap* linemap);
83cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  virtual ~CULineInfoHandler() { }
84cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
85cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  // Called when we define a directory.  We just place NAME into dirs_
86cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  // at position DIR_NUM.
874e518a4357a2d1c379d4a91df6d4e153ee791101ivan.penkov@gmail.com  virtual void DefineDir(const string& name, uint32 dir_num);
88cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
89cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  // Called when we define a filename.  We just place
90cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  // concat(dirs_[DIR_NUM], NAME) into files_ at position FILE_NUM.
914e518a4357a2d1c379d4a91df6d4e153ee791101ivan.penkov@gmail.com  virtual void DefineFile(const string& name, int32 file_num,
92cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid                          uint32 dir_num, uint64 mod_time, uint64 length);
93cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
94cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
95cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  // Called when the line info reader has a new line, address pair
968bfcc2683f6cb4345b56c898eabe45efeb77dc3ejimblandy  // ready for us. ADDRESS is the address of the code, LENGTH is the
978bfcc2683f6cb4345b56c898eabe45efeb77dc3ejimblandy  // length of its machine code in bytes, FILE_NUM is the file number
988bfcc2683f6cb4345b56c898eabe45efeb77dc3ejimblandy  // containing the code, LINE_NUM is the line number in that file for
998bfcc2683f6cb4345b56c898eabe45efeb77dc3ejimblandy  // the code, and COLUMN_NUM is the column number the code starts at,
1008bfcc2683f6cb4345b56c898eabe45efeb77dc3ejimblandy  // if we know it (0 otherwise).
1018bfcc2683f6cb4345b56c898eabe45efeb77dc3ejimblandy  virtual void AddLine(uint64 address, uint64 length,
1028bfcc2683f6cb4345b56c898eabe45efeb77dc3ejimblandy                       uint32 file_num, uint32 line_num, uint32 column_num);
103cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
104cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid private:
105cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  LineMap* linemap_;
1068f4d15f86e8326674b35ca7c9dc310f01be19768mark@chromium.org  std::vector<SourceFileInfo>* files_;
1074e518a4357a2d1c379d4a91df6d4e153ee791101ivan.penkov@gmail.com  std::vector<string>* dirs_;
108cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid};
109cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
110cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsidclass CUFunctionInfoHandler: public Dwarf2Handler {
111cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid public:
1128f4d15f86e8326674b35ca7c9dc310f01be19768mark@chromium.org  CUFunctionInfoHandler(std::vector<SourceFileInfo>* files,
1134e518a4357a2d1c379d4a91df6d4e153ee791101ivan.penkov@gmail.com                        std::vector<string>* dirs,
114cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid                        LineMap* linemap,
115cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid                        FunctionMap* offset_to_funcinfo,
116cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid                        FunctionMap* address_to_funcinfo,
117cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid                        CULineInfoHandler* linehandler,
118cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid                        const SectionMap& sections,
119cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid                        ByteReader* reader)
120cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid      : files_(files), dirs_(dirs), linemap_(linemap),
121cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid        offset_to_funcinfo_(offset_to_funcinfo),
122cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid        address_to_funcinfo_(address_to_funcinfo),
123cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid        linehandler_(linehandler), sections_(sections),
124cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid        reader_(reader), current_function_info_(NULL) { }
125cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
126cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  virtual ~CUFunctionInfoHandler() { }
127cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
128cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  // Start to process a compilation unit at OFFSET from the beginning of the
1297a77f45f7999d47b2d3cde1b30a8d86363f01e5ejimblandy@gmail.com  // .debug_info section.  We want to see all compilation units, so we
130cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  // always return true.
131cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
132cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  virtual bool StartCompilationUnit(uint64 offset, uint8 address_size,
133cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid                                    uint8 offset_size, uint64 cu_length,
134cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid                                    uint8 dwarf_version);
135cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
136cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  // Start to process a DIE at OFFSET from the beginning of the
1377a77f45f7999d47b2d3cde1b30a8d86363f01e5ejimblandy@gmail.com  // .debug_info section.  We only care about function related DIE's.
1387c2350868e7f53728866d304bc6a7ce8ba3b5d05mark@chromium.org  virtual bool StartDIE(uint64 offset, enum DwarfTag tag);
139cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
140cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  // Called when we have an attribute with unsigned data to give to
141cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  // our handler.  The attribute is for the DIE at OFFSET from the
1427a77f45f7999d47b2d3cde1b30a8d86363f01e5ejimblandy@gmail.com  // beginning of the .debug_info section, has a name of ATTR, a form of
143cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  // FORM, and the actual data of the attribute is in DATA.
144cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  virtual void ProcessAttributeUnsigned(uint64 offset,
145cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid                                        enum DwarfAttribute attr,
146cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid                                        enum DwarfForm form,
147cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid                                        uint64 data);
148cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
149330ca2f7c71d84a01626b1198ef600540eb320b8jimblandy  // Called when we have an attribute with a DIE reference to give to
150330ca2f7c71d84a01626b1198ef600540eb320b8jimblandy  // our handler.  The attribute is for the DIE at OFFSET from the
151330ca2f7c71d84a01626b1198ef600540eb320b8jimblandy  // beginning of the .debug_info section, has a name of ATTR, a form of
152330ca2f7c71d84a01626b1198ef600540eb320b8jimblandy  // FORM, and the offset of the referenced DIE from the start of the
153330ca2f7c71d84a01626b1198ef600540eb320b8jimblandy  // .debug_info section is in DATA.
154330ca2f7c71d84a01626b1198ef600540eb320b8jimblandy  virtual void ProcessAttributeReference(uint64 offset,
155330ca2f7c71d84a01626b1198ef600540eb320b8jimblandy                                         enum DwarfAttribute attr,
156330ca2f7c71d84a01626b1198ef600540eb320b8jimblandy                                         enum DwarfForm form,
157330ca2f7c71d84a01626b1198ef600540eb320b8jimblandy                                         uint64 data);
158330ca2f7c71d84a01626b1198ef600540eb320b8jimblandy
159cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  // Called when we have an attribute with string data to give to
160cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  // our handler.  The attribute is for the DIE at OFFSET from the
1617a77f45f7999d47b2d3cde1b30a8d86363f01e5ejimblandy@gmail.com  // beginning of the .debug_info section, has a name of ATTR, a form of
162cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  // FORM, and the actual data of the attribute is in DATA.
163cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  virtual void ProcessAttributeString(uint64 offset,
164cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid                                      enum DwarfAttribute attr,
165cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid                                      enum DwarfForm form,
1664e518a4357a2d1c379d4a91df6d4e153ee791101ivan.penkov@gmail.com                                      const string& data);
167cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
168cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  // Called when finished processing the DIE at OFFSET.
169cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  // Because DWARF2/3 specifies a tree of DIEs, you may get starts
170cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  // before ends of the previous DIE, as we process children before
171cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  // ending the parent.
172cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  virtual void EndDIE(uint64 offset);
173cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
174cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid private:
1758f4d15f86e8326674b35ca7c9dc310f01be19768mark@chromium.org  std::vector<SourceFileInfo>* files_;
1764e518a4357a2d1c379d4a91df6d4e153ee791101ivan.penkov@gmail.com  std::vector<string>* dirs_;
177cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  LineMap* linemap_;
178cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  FunctionMap* offset_to_funcinfo_;
179cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  FunctionMap* address_to_funcinfo_;
180cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  CULineInfoHandler* linehandler_;
181cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  const SectionMap& sections_;
182cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  ByteReader* reader_;
183cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid  FunctionInfo* current_function_info_;
1843751b053540ab3d51887cd27f1992cc4dee50542ted.mielczarek  uint64 current_compilation_unit_offset_;
185cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid};
186cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid
187cb4aa6b804d9c4a5d43aa50bfbc46257bc55c001nealsid}  // namespace dwarf2reader
1884969cfc6477c56afb2d4f2f6c1733c3120690b6djimblandy@gmail.com#endif  // COMMON_DWARF_FUNCTIONINFO_H__
189