1057aa1f6173501e1a62cf91fd08275e7da439166jimblandy// -*- mode: c++ -*-
2057aa1f6173501e1a62cf91fd08275e7da439166jimblandy
383e085b7a331c96237cf8e814f97b3ef4c36a70fjimblandy// Copyright (c) 2010 Google Inc.
4057aa1f6173501e1a62cf91fd08275e7da439166jimblandy// All rights reserved.
5057aa1f6173501e1a62cf91fd08275e7da439166jimblandy//
6057aa1f6173501e1a62cf91fd08275e7da439166jimblandy// Redistribution and use in source and binary forms, with or without
7057aa1f6173501e1a62cf91fd08275e7da439166jimblandy// modification, are permitted provided that the following conditions are
8057aa1f6173501e1a62cf91fd08275e7da439166jimblandy// met:
9057aa1f6173501e1a62cf91fd08275e7da439166jimblandy//
10057aa1f6173501e1a62cf91fd08275e7da439166jimblandy//     * Redistributions of source code must retain the above copyright
11057aa1f6173501e1a62cf91fd08275e7da439166jimblandy// notice, this list of conditions and the following disclaimer.
12057aa1f6173501e1a62cf91fd08275e7da439166jimblandy//     * Redistributions in binary form must reproduce the above
13057aa1f6173501e1a62cf91fd08275e7da439166jimblandy// copyright notice, this list of conditions and the following disclaimer
14057aa1f6173501e1a62cf91fd08275e7da439166jimblandy// in the documentation and/or other materials provided with the
15057aa1f6173501e1a62cf91fd08275e7da439166jimblandy// distribution.
16057aa1f6173501e1a62cf91fd08275e7da439166jimblandy//     * Neither the name of Google Inc. nor the names of its
17057aa1f6173501e1a62cf91fd08275e7da439166jimblandy// contributors may be used to endorse or promote products derived from
18057aa1f6173501e1a62cf91fd08275e7da439166jimblandy// this software without specific prior written permission.
19057aa1f6173501e1a62cf91fd08275e7da439166jimblandy//
20057aa1f6173501e1a62cf91fd08275e7da439166jimblandy// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21057aa1f6173501e1a62cf91fd08275e7da439166jimblandy// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22057aa1f6173501e1a62cf91fd08275e7da439166jimblandy// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23057aa1f6173501e1a62cf91fd08275e7da439166jimblandy// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24057aa1f6173501e1a62cf91fd08275e7da439166jimblandy// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25057aa1f6173501e1a62cf91fd08275e7da439166jimblandy// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26057aa1f6173501e1a62cf91fd08275e7da439166jimblandy// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27057aa1f6173501e1a62cf91fd08275e7da439166jimblandy// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28057aa1f6173501e1a62cf91fd08275e7da439166jimblandy// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29057aa1f6173501e1a62cf91fd08275e7da439166jimblandy// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30057aa1f6173501e1a62cf91fd08275e7da439166jimblandy// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31057aa1f6173501e1a62cf91fd08275e7da439166jimblandy
32c50e7c604cd1b12bba9421b0a95357fc942ecd7cjimblandy// Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>
33c50e7c604cd1b12bba9421b0a95357fc942ecd7cjimblandy
34c50e7c604cd1b12bba9421b0a95357fc942ecd7cjimblandy// Add DWARF debugging information to a Breakpad symbol file. This
35c50e7c604cd1b12bba9421b0a95357fc942ecd7cjimblandy// file defines the DwarfCUToModule class, which accepts parsed DWARF
36c50e7c604cd1b12bba9421b0a95357fc942ecd7cjimblandy// data and populates a google_breakpad::Module with the results; the
37c50e7c604cd1b12bba9421b0a95357fc942ecd7cjimblandy// Module can then write its contents as a Breakpad symbol file.
38c50e7c604cd1b12bba9421b0a95357fc942ecd7cjimblandy
39057aa1f6173501e1a62cf91fd08275e7da439166jimblandy#ifndef COMMON_LINUX_DWARF_CU_TO_MODULE_H__
40057aa1f6173501e1a62cf91fd08275e7da439166jimblandy#define COMMON_LINUX_DWARF_CU_TO_MODULE_H__
41057aa1f6173501e1a62cf91fd08275e7da439166jimblandy
42057aa1f6173501e1a62cf91fd08275e7da439166jimblandy#include <string>
43057aa1f6173501e1a62cf91fd08275e7da439166jimblandy
4487855248f1fab83caf002418196a34051d359f2cjimblandy#include "common/language.h"
4587855248f1fab83caf002418196a34051d359f2cjimblandy#include "common/module.h"
46057aa1f6173501e1a62cf91fd08275e7da439166jimblandy#include "common/dwarf/bytereader.h"
47057aa1f6173501e1a62cf91fd08275e7da439166jimblandy#include "common/dwarf/dwarf2diehandler.h"
48057aa1f6173501e1a62cf91fd08275e7da439166jimblandy#include "common/dwarf/dwarf2reader.h"
49b9d6ed468efaa4b65d42c4c5379fde15dcce14c5thestig@chromium.org#include "common/scoped_ptr.h"
504e518a4357a2d1c379d4a91df6d4e153ee791101ivan.penkov@gmail.com#include "common/using_std_string.h"
51057aa1f6173501e1a62cf91fd08275e7da439166jimblandy
52057aa1f6173501e1a62cf91fd08275e7da439166jimblandynamespace google_breakpad {
53057aa1f6173501e1a62cf91fd08275e7da439166jimblandy
54057aa1f6173501e1a62cf91fd08275e7da439166jimblandyusing dwarf2reader::DwarfAttribute;
55057aa1f6173501e1a62cf91fd08275e7da439166jimblandyusing dwarf2reader::DwarfForm;
56057aa1f6173501e1a62cf91fd08275e7da439166jimblandyusing dwarf2reader::DwarfLanguage;
57057aa1f6173501e1a62cf91fd08275e7da439166jimblandyusing dwarf2reader::DwarfTag;
58057aa1f6173501e1a62cf91fd08275e7da439166jimblandy
59057aa1f6173501e1a62cf91fd08275e7da439166jimblandy// Populate a google_breakpad::Module with DWARF debugging information.
60057aa1f6173501e1a62cf91fd08275e7da439166jimblandy//
61057aa1f6173501e1a62cf91fd08275e7da439166jimblandy// An instance of this class can be provided as a handler to a
62b6f2b45e968c6cbe69025d27e071eb76abbe5c96jimblandy// dwarf2reader::DIEDispatcher, which can in turn be a handler for a
63b6f2b45e968c6cbe69025d27e071eb76abbe5c96jimblandy// dwarf2reader::CompilationUnit DWARF parser. The handler uses the results
64b6f2b45e968c6cbe69025d27e071eb76abbe5c96jimblandy// of parsing to populate a google_breakpad::Module with source file,
65b6f2b45e968c6cbe69025d27e071eb76abbe5c96jimblandy// function, and source line information.
66057aa1f6173501e1a62cf91fd08275e7da439166jimblandyclass DwarfCUToModule: public dwarf2reader::RootDIEHandler {
67057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  struct FilePrivate;
68057aa1f6173501e1a62cf91fd08275e7da439166jimblandy public:
69057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // Information global to the DWARF-bearing file we are processing,
70057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // for use by DwarfCUToModule. Each DwarfCUToModule instance deals
71057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // with a single compilation unit within the file, but information
72057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // global to the whole file is held here. The client is responsible
73057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // for filling it in appropriately (except for the 'file_private'
74057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // field, which the constructor and destructor take care of), and
75057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // then providing it to the DwarfCUToModule instance for each
7652dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org  // compilation unit we process in that file. Set HANDLE_INTER_CU_REFS
7752dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org  // to true to handle debugging symbols with DW_FORM_ref_addr entries.
7852dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org  class FileContext {
7952dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org   public:
8052dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org    FileContext(const string &filename,
8152dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org                Module *module,
8252dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org                bool handle_inter_cu_refs);
83057aa1f6173501e1a62cf91fd08275e7da439166jimblandy    ~FileContext();
84057aa1f6173501e1a62cf91fd08275e7da439166jimblandy
8552dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org    // Add CONTENTS of size LENGTH to the section map as NAME.
8652dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org    void AddSectionToSectionMap(const string& name,
8752dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org                                const char* contents,
8852dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org                                uint64 length);
8952dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org
9052dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org    // Clear the section map for testing.
9152dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org    void ClearSectionMapForTest();
9252dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org
9352dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org    const dwarf2reader::SectionMap& section_map() const;
9452dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org
9552dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org   private:
9652dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org    friend class DwarfCUToModule;
9752dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org
9852dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org    // Clears all the Specifications if HANDLE_INTER_CU_REFS_ is false.
9952dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org    void ClearSpecifications();
10052dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org
10152dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org    // Given an OFFSET and a CU that starts at COMPILATION_UNIT_START, returns
10252dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org    // true if this is an inter-compilation unit reference that is not being
10352dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org    // handled.
10452dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org    bool IsUnhandledInterCUReference(uint64 offset,
10552dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org                                     uint64 compilation_unit_start) const;
10652dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org
107057aa1f6173501e1a62cf91fd08275e7da439166jimblandy    // The name of this file, for use in error messages.
10852dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org    const string filename_;
109057aa1f6173501e1a62cf91fd08275e7da439166jimblandy
110057aa1f6173501e1a62cf91fd08275e7da439166jimblandy    // A map of this file's sections, used for finding other DWARF
111057aa1f6173501e1a62cf91fd08275e7da439166jimblandy    // sections that the .debug_info section may refer to.
11252dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org    dwarf2reader::SectionMap section_map_;
113057aa1f6173501e1a62cf91fd08275e7da439166jimblandy
114057aa1f6173501e1a62cf91fd08275e7da439166jimblandy    // The Module to which we're contributing definitions.
11552dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org    Module *module_;
11652dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org
11752dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org    // True if we are handling references between compilation units.
11852dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org    const bool handle_inter_cu_refs_;
119057aa1f6173501e1a62cf91fd08275e7da439166jimblandy
120057aa1f6173501e1a62cf91fd08275e7da439166jimblandy    // Inter-compilation unit data used internally by the handlers.
121b9d6ed468efaa4b65d42c4c5379fde15dcce14c5thestig@chromium.org    scoped_ptr<FilePrivate> file_private_;
122057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  };
123057aa1f6173501e1a62cf91fd08275e7da439166jimblandy
124248c84d2006fcde85b098066866aebec72b76125ted.mielczarek@gmail.com  // An abstract base class for handlers that handle DWARF line data
125057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // for DwarfCUToModule. DwarfCUToModule could certainly just use
126057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // dwarf2reader::LineInfo itself directly, but decoupling things
127057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // this way makes unit testing a little easier.
128248c84d2006fcde85b098066866aebec72b76125ted.mielczarek@gmail.com  class LineToModuleHandler {
129057aa1f6173501e1a62cf91fd08275e7da439166jimblandy   public:
130248c84d2006fcde85b098066866aebec72b76125ted.mielczarek@gmail.com    LineToModuleHandler() { }
131248c84d2006fcde85b098066866aebec72b76125ted.mielczarek@gmail.com    virtual ~LineToModuleHandler() { }
132248c84d2006fcde85b098066866aebec72b76125ted.mielczarek@gmail.com
133248c84d2006fcde85b098066866aebec72b76125ted.mielczarek@gmail.com    // Called at the beginning of a new compilation unit, prior to calling
134248c84d2006fcde85b098066866aebec72b76125ted.mielczarek@gmail.com    // ReadProgram(). compilation_dir will indicate the path that the
135248c84d2006fcde85b098066866aebec72b76125ted.mielczarek@gmail.com    // current compilation unit was compiled in, consistent with the
136248c84d2006fcde85b098066866aebec72b76125ted.mielczarek@gmail.com    // DW_AT_comp_dir DIE.
137248c84d2006fcde85b098066866aebec72b76125ted.mielczarek@gmail.com    virtual void StartCompilationUnit(const string& compilation_dir) = 0;
138057aa1f6173501e1a62cf91fd08275e7da439166jimblandy
139057aa1f6173501e1a62cf91fd08275e7da439166jimblandy    // Populate MODULE and LINES with source file names and code/line
140057aa1f6173501e1a62cf91fd08275e7da439166jimblandy    // mappings, given a pointer to some DWARF line number data
141057aa1f6173501e1a62cf91fd08275e7da439166jimblandy    // PROGRAM, and an overestimate of its size. Add no zero-length
142057aa1f6173501e1a62cf91fd08275e7da439166jimblandy    // lines to LINES.
143248c84d2006fcde85b098066866aebec72b76125ted.mielczarek@gmail.com    virtual void ReadProgram(const char *program, uint64 length,
144248c84d2006fcde85b098066866aebec72b76125ted.mielczarek@gmail.com                             Module *module, vector<Module::Line> *lines) = 0;
145057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  };
146057aa1f6173501e1a62cf91fd08275e7da439166jimblandy
147057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // The interface DwarfCUToModule uses to report warnings. The member
148057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // function definitions for this class write messages to stderr, but
149057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // you can override them if you'd like to detect or report these
150057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // conditions yourself.
151057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  class WarningReporter {
152057aa1f6173501e1a62cf91fd08275e7da439166jimblandy   public:
153057aa1f6173501e1a62cf91fd08275e7da439166jimblandy    // Warn about problems in the DWARF file FILENAME, in the
154057aa1f6173501e1a62cf91fd08275e7da439166jimblandy    // compilation unit at OFFSET.
155057aa1f6173501e1a62cf91fd08275e7da439166jimblandy    WarningReporter(const string &filename, uint64 cu_offset)
156057aa1f6173501e1a62cf91fd08275e7da439166jimblandy        : filename_(filename), cu_offset_(cu_offset), printed_cu_header_(false),
1579e6b619ad084c58af9fb8983b1a646192adb3835jimblandy          printed_unpaired_header_(false),
1589e6b619ad084c58af9fb8983b1a646192adb3835jimblandy          uncovered_warnings_enabled_(false) { }
159057aa1f6173501e1a62cf91fd08275e7da439166jimblandy    virtual ~WarningReporter() { }
160057aa1f6173501e1a62cf91fd08275e7da439166jimblandy
161057aa1f6173501e1a62cf91fd08275e7da439166jimblandy    // Set the name of the compilation unit we're processing to NAME.
162057aa1f6173501e1a62cf91fd08275e7da439166jimblandy    virtual void SetCUName(const string &name) { cu_name_ = name; }
163057aa1f6173501e1a62cf91fd08275e7da439166jimblandy
1649e6b619ad084c58af9fb8983b1a646192adb3835jimblandy    // Accessor and setter for uncovered_warnings_enabled_.
1659e6b619ad084c58af9fb8983b1a646192adb3835jimblandy    // UncoveredFunction and UncoveredLine only report a problem if that is
1669e6b619ad084c58af9fb8983b1a646192adb3835jimblandy    // true. By default, these warnings are disabled, because those
1679e6b619ad084c58af9fb8983b1a646192adb3835jimblandy    // conditions occur occasionally in healthy code.
1689e6b619ad084c58af9fb8983b1a646192adb3835jimblandy    virtual bool uncovered_warnings_enabled() const {
1699e6b619ad084c58af9fb8983b1a646192adb3835jimblandy      return uncovered_warnings_enabled_;
1709e6b619ad084c58af9fb8983b1a646192adb3835jimblandy    }
1719e6b619ad084c58af9fb8983b1a646192adb3835jimblandy    virtual void set_uncovered_warnings_enabled(bool value) {
1729e6b619ad084c58af9fb8983b1a646192adb3835jimblandy      uncovered_warnings_enabled_ = value;
1739e6b619ad084c58af9fb8983b1a646192adb3835jimblandy    }
1749e6b619ad084c58af9fb8983b1a646192adb3835jimblandy
175057aa1f6173501e1a62cf91fd08275e7da439166jimblandy    // A DW_AT_specification in the DIE at OFFSET refers to a DIE we
176057aa1f6173501e1a62cf91fd08275e7da439166jimblandy    // haven't processed yet, or that wasn't marked as a declaration,
177057aa1f6173501e1a62cf91fd08275e7da439166jimblandy    // at TARGET.
178057aa1f6173501e1a62cf91fd08275e7da439166jimblandy    virtual void UnknownSpecification(uint64 offset, uint64 target);
179dd5067f391baee2561404f8e2915429b3d638ff7jimblandy
180dd5067f391baee2561404f8e2915429b3d638ff7jimblandy    // A DW_AT_abstract_origin in the DIE at OFFSET refers to a DIE we
181dd5067f391baee2561404f8e2915429b3d638ff7jimblandy    // haven't processed yet, or that wasn't marked as inline, at TARGET.
182dd5067f391baee2561404f8e2915429b3d638ff7jimblandy    virtual void UnknownAbstractOrigin(uint64 offset, uint64 target);
183dd5067f391baee2561404f8e2915429b3d638ff7jimblandy
184057aa1f6173501e1a62cf91fd08275e7da439166jimblandy    // We were unable to find the DWARF section named SECTION_NAME.
185057aa1f6173501e1a62cf91fd08275e7da439166jimblandy    virtual void MissingSection(const string &section_name);
186057aa1f6173501e1a62cf91fd08275e7da439166jimblandy
187057aa1f6173501e1a62cf91fd08275e7da439166jimblandy    // The CU's DW_AT_stmt_list offset OFFSET is bogus.
188057aa1f6173501e1a62cf91fd08275e7da439166jimblandy    virtual void BadLineInfoOffset(uint64 offset);
189057aa1f6173501e1a62cf91fd08275e7da439166jimblandy
190057aa1f6173501e1a62cf91fd08275e7da439166jimblandy    // FUNCTION includes code covered by no line number data.
191057aa1f6173501e1a62cf91fd08275e7da439166jimblandy    virtual void UncoveredFunction(const Module::Function &function);
192057aa1f6173501e1a62cf91fd08275e7da439166jimblandy
193057aa1f6173501e1a62cf91fd08275e7da439166jimblandy    // Line number NUMBER in LINE_FILE, of length LENGTH, includes code
194057aa1f6173501e1a62cf91fd08275e7da439166jimblandy    // covered by no function.
195057aa1f6173501e1a62cf91fd08275e7da439166jimblandy    virtual void UncoveredLine(const Module::Line &line);
196057aa1f6173501e1a62cf91fd08275e7da439166jimblandy
197fd18beeb5c817aa3ecdb21caceee8e6ce08c6ab3jimblandy    // The DW_TAG_subprogram DIE at OFFSET has no name specified directly
198fd18beeb5c817aa3ecdb21caceee8e6ce08c6ab3jimblandy    // in the DIE, nor via a DW_AT_specification or DW_AT_abstract_origin
199fd18beeb5c817aa3ecdb21caceee8e6ce08c6ab3jimblandy    // link.
200fd18beeb5c817aa3ecdb21caceee8e6ce08c6ab3jimblandy    virtual void UnnamedFunction(uint64 offset);
201fd18beeb5c817aa3ecdb21caceee8e6ce08c6ab3jimblandy
2026105ae42dc0a63fe651b050244c9bbc6a549bfc5erikchen@chromium.org    // __cxa_demangle() failed to demangle INPUT.
2036105ae42dc0a63fe651b050244c9bbc6a549bfc5erikchen@chromium.org    virtual void DemangleError(const string &input, int error);
2046105ae42dc0a63fe651b050244c9bbc6a549bfc5erikchen@chromium.org
20552dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org    // The DW_FORM_ref_addr at OFFSET to TARGET was not handled because
20652dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org    // FilePrivate did not retain the inter-CU specification data.
20752dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org    virtual void UnhandledInterCUReference(uint64 offset, uint64 target);
20852dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org
20952dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org    uint64 cu_offset() const {
21052dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org      return cu_offset_;
21152dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org    }
21252dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org
213057aa1f6173501e1a62cf91fd08275e7da439166jimblandy   protected:
21452dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org    const string filename_;
21552dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org    const uint64 cu_offset_;
216057aa1f6173501e1a62cf91fd08275e7da439166jimblandy    string cu_name_;
217057aa1f6173501e1a62cf91fd08275e7da439166jimblandy    bool printed_cu_header_;
218057aa1f6173501e1a62cf91fd08275e7da439166jimblandy    bool printed_unpaired_header_;
2199e6b619ad084c58af9fb8983b1a646192adb3835jimblandy    bool uncovered_warnings_enabled_;
220057aa1f6173501e1a62cf91fd08275e7da439166jimblandy
221057aa1f6173501e1a62cf91fd08275e7da439166jimblandy   private:
222057aa1f6173501e1a62cf91fd08275e7da439166jimblandy    // Print a per-CU heading, once.
223057aa1f6173501e1a62cf91fd08275e7da439166jimblandy    void CUHeading();
224057aa1f6173501e1a62cf91fd08275e7da439166jimblandy    // Print an unpaired function/line heading, once.
225057aa1f6173501e1a62cf91fd08275e7da439166jimblandy    void UncoveredHeading();
226057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  };
227057aa1f6173501e1a62cf91fd08275e7da439166jimblandy
228057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // Create a DWARF debugging info handler for a compilation unit
229057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // within FILE_CONTEXT. This uses information received from the
230057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // dwarf2reader::CompilationUnit DWARF parser to populate
231057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // FILE_CONTEXT->module. Use LINE_READER to handle the compilation
232057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // unit's line number data. Use REPORTER to report problems with the
233057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // data we find.
234057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  DwarfCUToModule(FileContext *file_context,
235248c84d2006fcde85b098066866aebec72b76125ted.mielczarek@gmail.com                  LineToModuleHandler *line_reader,
236057aa1f6173501e1a62cf91fd08275e7da439166jimblandy                  WarningReporter *reporter);
237057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  ~DwarfCUToModule();
238057aa1f6173501e1a62cf91fd08275e7da439166jimblandy
239057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  void ProcessAttributeSigned(enum DwarfAttribute attr,
240057aa1f6173501e1a62cf91fd08275e7da439166jimblandy                              enum DwarfForm form,
241057aa1f6173501e1a62cf91fd08275e7da439166jimblandy                              int64 data);
242057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  void ProcessAttributeUnsigned(enum DwarfAttribute attr,
243057aa1f6173501e1a62cf91fd08275e7da439166jimblandy                                enum DwarfForm form,
244057aa1f6173501e1a62cf91fd08275e7da439166jimblandy                                uint64 data);
245057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  void ProcessAttributeString(enum DwarfAttribute attr,
246057aa1f6173501e1a62cf91fd08275e7da439166jimblandy                              enum DwarfForm form,
247057aa1f6173501e1a62cf91fd08275e7da439166jimblandy                              const string &data);
248057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  bool EndAttributes();
2497c2350868e7f53728866d304bc6a7ce8ba3b5d05mark@chromium.org  DIEHandler *FindChildHandler(uint64 offset, enum DwarfTag tag);
250057aa1f6173501e1a62cf91fd08275e7da439166jimblandy
251057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // Assign all our source Lines to the Functions that cover their
252057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // addresses, and then add them to module_.
253057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  void Finish();
254057aa1f6173501e1a62cf91fd08275e7da439166jimblandy
255057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  bool StartCompilationUnit(uint64 offset, uint8 address_size,
256057aa1f6173501e1a62cf91fd08275e7da439166jimblandy                            uint8 offset_size, uint64 cu_length,
257057aa1f6173501e1a62cf91fd08275e7da439166jimblandy                            uint8 dwarf_version);
2587c2350868e7f53728866d304bc6a7ce8ba3b5d05mark@chromium.org  bool StartRootDIE(uint64 offset, enum DwarfTag tag);
259057aa1f6173501e1a62cf91fd08275e7da439166jimblandy
260057aa1f6173501e1a62cf91fd08275e7da439166jimblandy private:
261057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // Used internally by the handler. Full definitions are in
262057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // dwarf_cu_to_module.cc.
263057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  struct CUContext;
264057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  struct DIEContext;
26552dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org  struct Specification;
266057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  class GenericDIEHandler;
267057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  class FuncHandler;
268057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  class NamedScopeHandler;
269057aa1f6173501e1a62cf91fd08275e7da439166jimblandy
270057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // A map from section offsets to specifications.
271057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  typedef map<uint64, Specification> SpecificationByOffset;
272057aa1f6173501e1a62cf91fd08275e7da439166jimblandy
273057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // Set this compilation unit's source language to LANGUAGE.
274057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  void SetLanguage(DwarfLanguage language);
27552dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org
276057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // Read source line information at OFFSET in the .debug_line
277057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // section.  Record source files in module_, but record source lines
278057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // in lines_; we apportion them to functions in
279057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // AssignLinesToFunctions.
280057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  void ReadSourceLines(uint64 offset);
281057aa1f6173501e1a62cf91fd08275e7da439166jimblandy
282057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // Assign the lines in lines_ to the individual line lists of the
283057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // functions in functions_.  (DWARF line information maps an entire
284057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // compilation unit at a time, and gives no indication of which
285057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // lines belong to which functions, beyond their addresses.)
286057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  void AssignLinesToFunctions();
287057aa1f6173501e1a62cf91fd08275e7da439166jimblandy
288057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // The only reason cu_context_ and child_context_ are pointers is
289057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // that we want to keep their definitions private to
290057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // dwarf_cu_to_module.cc, instead of listing them all here. They are
291057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // owned by this DwarfCUToModule: the constructor sets them, and the
292057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // destructor deletes them.
293057aa1f6173501e1a62cf91fd08275e7da439166jimblandy
294248c84d2006fcde85b098066866aebec72b76125ted.mielczarek@gmail.com  // The handler to use to handle line number data.
295248c84d2006fcde85b098066866aebec72b76125ted.mielczarek@gmail.com  LineToModuleHandler *line_reader_;
296057aa1f6173501e1a62cf91fd08275e7da439166jimblandy
297057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // This compilation unit's context.
298b9d6ed468efaa4b65d42c4c5379fde15dcce14c5thestig@chromium.org  scoped_ptr<CUContext> cu_context_;
299057aa1f6173501e1a62cf91fd08275e7da439166jimblandy
300057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // A context for our children.
301b9d6ed468efaa4b65d42c4c5379fde15dcce14c5thestig@chromium.org  scoped_ptr<DIEContext> child_context_;
302057aa1f6173501e1a62cf91fd08275e7da439166jimblandy
303057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // True if this compilation unit has source line information.
304057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  bool has_source_line_info_;
305057aa1f6173501e1a62cf91fd08275e7da439166jimblandy
306057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // The offset of this compilation unit's line number information in
307057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // the .debug_line section.
308057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  uint64 source_line_offset_;
309057aa1f6173501e1a62cf91fd08275e7da439166jimblandy
310057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // The line numbers we have seen thus far.  We accumulate these here
311057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // during parsing.  Then, in Finish, we call AssignLinesToFunctions
312057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  // to dole them out to the appropriate functions.
313057aa1f6173501e1a62cf91fd08275e7da439166jimblandy  vector<Module::Line> lines_;
314057aa1f6173501e1a62cf91fd08275e7da439166jimblandy};
315057aa1f6173501e1a62cf91fd08275e7da439166jimblandy
31652dc308f4271478a77415f6b71b7e1c96fe56e5athestig@chromium.org}  // namespace google_breakpad
317057aa1f6173501e1a62cf91fd08275e7da439166jimblandy
318057aa1f6173501e1a62cf91fd08275e7da439166jimblandy#endif  // COMMON_LINUX_DWARF_CU_TO_MODULE_H__
319