gdb-index.h revision 1.1
1// gdb-index.h -- generate .gdb_index section for fast debug lookup  -*- C++ -*-
2
3// Copyright 2012 Free Software Foundation, Inc.
4// Written by Cary Coutant <ccoutant@google.com>.
5
6// This file is part of gold.
7
8// This program is free software; you can redistribute it and/or modify
9// it under the terms of the GNU General Public License as published by
10// the Free Software Foundation; either version 3 of the License, or
11// (at your option) any later version.
12
13// This program is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16// GNU General Public License for more details.
17
18// You should have received a copy of the GNU General Public License
19// along with this program; if not, write to the Free Software
20// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21// MA 02110-1301, USA.
22
23#include <sys/types.h>
24#include <vector>
25
26#include "gold.h"
27#include "output.h"
28#include "mapfile.h"
29#include "stringpool.h"
30
31#ifndef GOLD_GDB_INDEX_H
32#define GOLD_GDB_INDEX_H
33
34namespace gold
35{
36
37class Output_section;
38class Output_file;
39class Mapfile;
40template<int size, bool big_endian>
41class Sized_relobj;
42class Dwarf_range_list;
43template <typename T>
44class Gdb_hashtab;
45
46// This class manages the .gdb_index section, which is a fast
47// lookup table for DWARF information used by the gdb debugger.
48// The format of this section is described in gdb/doc/gdb.texinfo.
49
50class Gdb_index : public Output_section_data
51{
52 public:
53  Gdb_index(Output_section* gdb_index_section);
54
55  ~Gdb_index();
56
57  // Scan a .debug_info or .debug_types input section.
58  void scan_debug_info(bool is_type_unit,
59		       Relobj* object,
60		       const unsigned char* symbols,
61		       off_t symbols_size,
62		       unsigned int shndx,
63		       unsigned int reloc_shndx,
64		       unsigned int reloc_type);
65
66  // Add a compilation unit.
67  int
68  add_comp_unit(off_t cu_offset, off_t cu_length)
69  {
70    this->comp_units_.push_back(Comp_unit(cu_offset, cu_length));
71    return this->comp_units_.size() - 1;
72  }
73
74  // Add a type unit.
75  int
76  add_type_unit(off_t tu_offset, off_t type_offset, uint64_t signature)
77  {
78    this->type_units_.push_back(Type_unit(tu_offset, type_offset, signature));
79    return this->type_units_.size() - 1;
80  }
81
82  // Add an address range.
83  void
84  add_address_range_list(Relobj* object, unsigned int cu_index,
85			 Dwarf_range_list* ranges)
86  {
87    this->ranges_.push_back(Per_cu_range_list(object, cu_index, ranges));
88  }
89
90  // Add a symbol.
91  void
92  add_symbol(int cu_index, const char* sym_name);
93
94  // Return TRUE if we have already processed the pubnames set at
95  // OFFSET in section SHNDX
96  bool
97  pubnames_read(unsigned int shndx, off_t offset);
98
99  // Return TRUE if we have already processed the pubtypes set at
100  // OFFSET in section SHNDX
101  bool
102  pubtypes_read(unsigned int shndx, off_t offset);
103
104  // Print usage statistics.
105  static void
106  print_stats();
107
108 protected:
109  // This is called to update the section size prior to assigning
110  // the address and file offset.
111  void
112  update_data_size()
113  { this->set_final_data_size(); }
114
115  // Set the final data size.
116  void
117  set_final_data_size();
118
119  // Write the data to the file.
120  void
121  do_write(Output_file*);
122
123  // Write to a map file.
124  void
125  do_print_to_mapfile(Mapfile* mapfile) const
126  { mapfile->print_output_data(this, _("** gdb_index")); }
127
128 private:
129  // An entry in the compilation unit list.
130  struct Comp_unit
131  {
132    Comp_unit(off_t off, off_t len)
133      : cu_offset(off), cu_length(len)
134    { }
135    uint64_t cu_offset;
136    uint64_t cu_length;
137  };
138
139  // An entry in the type unit list.
140  struct Type_unit
141  {
142    Type_unit(off_t off, off_t toff, uint64_t sig)
143      : tu_offset(off), type_offset(toff), type_signature(sig)
144    { }
145    uint64_t tu_offset;
146    uint64_t type_offset;
147    uint64_t type_signature;
148  };
149
150  // An entry in the address range list.
151  struct Per_cu_range_list
152  {
153    Per_cu_range_list(Relobj* obj, uint32_t index, Dwarf_range_list* r)
154      : object(obj), cu_index(index), ranges(r)
155    { }
156    Relobj* object;
157    uint32_t cu_index;
158    Dwarf_range_list* ranges;
159  };
160
161  // A symbol table entry.
162  struct Gdb_symbol
163  {
164    Stringpool::Key name_key;
165    unsigned int hashval;
166    unsigned int cu_vector_index;
167
168    // Return the hash value.
169    unsigned int
170    hash()
171    { return this->hashval; }
172
173    // Return true if this symbol is the same as SYMBOL.
174    bool
175    equal(Gdb_symbol* symbol)
176    { return this->name_key == symbol->name_key; }
177  };
178
179  typedef std::vector<int> Cu_vector;
180
181  // The .gdb_index section.
182  Output_section* gdb_index_section_;
183  // The list of DWARF compilation units.
184  std::vector<Comp_unit> comp_units_;
185  // The list of DWARF type units.
186  std::vector<Type_unit> type_units_;
187  // The list of address ranges.
188  std::vector<Per_cu_range_list> ranges_;
189  // The symbol table.
190  Gdb_hashtab<Gdb_symbol>* gdb_symtab_;
191  // The CU vector portion of the constant pool.
192  std::vector<Cu_vector*> cu_vector_list_;
193  // An array to map from a CU vector index to an offset to the constant pool.
194  off_t* cu_vector_offsets_;
195  // The string portion of the constant pool.
196  Stringpool stringpool_;
197  // Offsets of the various pieces of the .gdb_index section.
198  off_t tu_offset_;
199  off_t addr_offset_;
200  off_t symtab_offset_;
201  off_t cu_pool_offset_;
202  off_t stringpool_offset_;
203  // Section index and offset of last read pubnames section.
204  unsigned int pubnames_shndx_;
205  off_t pubnames_offset_;
206  // Section index and offset of last read pubtypes section.
207  unsigned int pubtypes_shndx_;
208  off_t pubtypes_offset_;
209};
210
211} // End namespace gold.
212
213#endif // !defined(GOLD_GDB_INDEX_H)
214