Commit | Line | Data |
---|---|---|
c1027032 CC |
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 | ||
34 | namespace gold | |
35 | { | |
36 | ||
37 | class Output_section; | |
38 | class Output_file; | |
39 | class Mapfile; | |
40 | template<int size, bool big_endian> | |
41 | class Sized_relobj; | |
42 | class Dwarf_range_list; | |
43 | template <typename T> | |
44 | class 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 | ||
50 | class 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 | ||
c891b3f9 SA |
94 | // Return TRUE if we have already processed the pubnames set for |
95 | // OBJECT at OFFSET in section SHNDX | |
c1027032 | 96 | bool |
c891b3f9 | 97 | pubnames_read(const Relobj* object, unsigned int shndx, off_t offset); |
c1027032 | 98 | |
c891b3f9 SA |
99 | // Return TRUE if we have already processed the pubtypes set for |
100 | // OBJECT at OFFSET in section SHNDX | |
c1027032 | 101 | bool |
c891b3f9 | 102 | pubtypes_read(const Relobj* object, unsigned int shndx, off_t offset); |
c1027032 CC |
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_; | |
c891b3f9 SA |
203 | // Object, section index and offset of last read pubnames section. |
204 | const Relobj* pubnames_object_; | |
c1027032 CC |
205 | unsigned int pubnames_shndx_; |
206 | off_t pubnames_offset_; | |
c891b3f9 SA |
207 | // Object, section index and offset of last read pubtypes section. |
208 | const Relobj* pubtypes_object_; | |
c1027032 CC |
209 | unsigned int pubtypes_shndx_; |
210 | off_t pubtypes_offset_; | |
211 | }; | |
212 | ||
213 | } // End namespace gold. | |
214 | ||
215 | #endif // !defined(GOLD_GDB_INDEX_H) |