]>
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 <[email protected]>. | |
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; | |
234d4ab8 SA |
45 | class Gdb_index_info_reader; |
46 | class Dwarf_pubnames_table; | |
c1027032 CC |
47 | |
48 | // This class manages the .gdb_index section, which is a fast | |
49 | // lookup table for DWARF information used by the gdb debugger. | |
50 | // The format of this section is described in gdb/doc/gdb.texinfo. | |
51 | ||
52 | class Gdb_index : public Output_section_data | |
53 | { | |
54 | public: | |
55 | Gdb_index(Output_section* gdb_index_section); | |
56 | ||
57 | ~Gdb_index(); | |
58 | ||
59 | // Scan a .debug_info or .debug_types input section. | |
60 | void scan_debug_info(bool is_type_unit, | |
61 | Relobj* object, | |
62 | const unsigned char* symbols, | |
63 | off_t symbols_size, | |
64 | unsigned int shndx, | |
65 | unsigned int reloc_shndx, | |
66 | unsigned int reloc_type); | |
67 | ||
68 | // Add a compilation unit. | |
69 | int | |
70 | add_comp_unit(off_t cu_offset, off_t cu_length) | |
71 | { | |
72 | this->comp_units_.push_back(Comp_unit(cu_offset, cu_length)); | |
73 | return this->comp_units_.size() - 1; | |
74 | } | |
75 | ||
76 | // Add a type unit. | |
77 | int | |
78 | add_type_unit(off_t tu_offset, off_t type_offset, uint64_t signature) | |
79 | { | |
80 | this->type_units_.push_back(Type_unit(tu_offset, type_offset, signature)); | |
81 | return this->type_units_.size() - 1; | |
82 | } | |
83 | ||
84 | // Add an address range. | |
85 | void | |
86 | add_address_range_list(Relobj* object, unsigned int cu_index, | |
87 | Dwarf_range_list* ranges) | |
88 | { | |
89 | this->ranges_.push_back(Per_cu_range_list(object, cu_index, ranges)); | |
90 | } | |
91 | ||
92 | // Add a symbol. | |
93 | void | |
94 | add_symbol(int cu_index, const char* sym_name); | |
95 | ||
234d4ab8 SA |
96 | // Return the offset into the pubnames table for the cu at the given |
97 | // offset. | |
98 | off_t | |
99 | find_pubname_offset(off_t cu_offset); | |
100 | ||
101 | // Return the offset into the pubtypes table for the cu at the | |
102 | // given offset. | |
103 | off_t | |
104 | find_pubtype_offset(off_t cu_offset); | |
c1027032 | 105 | |
234d4ab8 SA |
106 | // Return TRUE if we have already processed the pubnames and types |
107 | // set for OBJECT of the CUs and TUS associated with the statement | |
108 | // list at OFFSET. | |
c1027032 | 109 | bool |
234d4ab8 SA |
110 | pubnames_read(const Relobj* object, off_t offset); |
111 | ||
112 | // Record that we have already read the pubnames associated with | |
113 | // OBJECT and OFFSET. | |
114 | void | |
115 | set_pubnames_read(const Relobj* object, off_t offset); | |
116 | ||
117 | // Return a pointer to the given table. | |
118 | Dwarf_pubnames_table* | |
119 | pubnames_table() | |
120 | { return pubnames_table_; } | |
121 | ||
122 | Dwarf_pubnames_table* | |
123 | pubtypes_table() | |
124 | { return pubtypes_table_; } | |
c1027032 CC |
125 | |
126 | // Print usage statistics. | |
127 | static void | |
128 | print_stats(); | |
129 | ||
130 | protected: | |
131 | // This is called to update the section size prior to assigning | |
132 | // the address and file offset. | |
133 | void | |
134 | update_data_size() | |
135 | { this->set_final_data_size(); } | |
136 | ||
137 | // Set the final data size. | |
138 | void | |
139 | set_final_data_size(); | |
140 | ||
141 | // Write the data to the file. | |
142 | void | |
143 | do_write(Output_file*); | |
144 | ||
145 | // Write to a map file. | |
146 | void | |
147 | do_print_to_mapfile(Mapfile* mapfile) const | |
148 | { mapfile->print_output_data(this, _("** gdb_index")); } | |
149 | ||
234d4ab8 SA |
150 | // Create a map from dies to pubnames. |
151 | Dwarf_pubnames_table* | |
152 | map_pubtable_to_dies(unsigned int attr, | |
153 | Gdb_index_info_reader* dwinfo, | |
154 | Relobj* object, | |
155 | const unsigned char* symbols, | |
156 | off_t symbols_size); | |
157 | ||
158 | // Wrapper for map_pubtable_to_dies | |
159 | void | |
160 | map_pubnames_and_types_to_dies(Gdb_index_info_reader* dwinfo, | |
161 | Relobj* object, | |
162 | const unsigned char* symbols, | |
163 | off_t symbols_size); | |
164 | ||
c1027032 CC |
165 | private: |
166 | // An entry in the compilation unit list. | |
167 | struct Comp_unit | |
168 | { | |
169 | Comp_unit(off_t off, off_t len) | |
170 | : cu_offset(off), cu_length(len) | |
171 | { } | |
172 | uint64_t cu_offset; | |
173 | uint64_t cu_length; | |
174 | }; | |
175 | ||
176 | // An entry in the type unit list. | |
177 | struct Type_unit | |
178 | { | |
179 | Type_unit(off_t off, off_t toff, uint64_t sig) | |
180 | : tu_offset(off), type_offset(toff), type_signature(sig) | |
181 | { } | |
182 | uint64_t tu_offset; | |
183 | uint64_t type_offset; | |
184 | uint64_t type_signature; | |
185 | }; | |
186 | ||
187 | // An entry in the address range list. | |
188 | struct Per_cu_range_list | |
189 | { | |
190 | Per_cu_range_list(Relobj* obj, uint32_t index, Dwarf_range_list* r) | |
191 | : object(obj), cu_index(index), ranges(r) | |
192 | { } | |
193 | Relobj* object; | |
194 | uint32_t cu_index; | |
195 | Dwarf_range_list* ranges; | |
196 | }; | |
197 | ||
198 | // A symbol table entry. | |
199 | struct Gdb_symbol | |
200 | { | |
201 | Stringpool::Key name_key; | |
202 | unsigned int hashval; | |
203 | unsigned int cu_vector_index; | |
204 | ||
205 | // Return the hash value. | |
206 | unsigned int | |
207 | hash() | |
208 | { return this->hashval; } | |
209 | ||
210 | // Return true if this symbol is the same as SYMBOL. | |
211 | bool | |
212 | equal(Gdb_symbol* symbol) | |
213 | { return this->name_key == symbol->name_key; } | |
214 | }; | |
215 | ||
216 | typedef std::vector<int> Cu_vector; | |
217 | ||
234d4ab8 SA |
218 | typedef Unordered_map<off_t, off_t> Pubname_offset_map; |
219 | Pubname_offset_map cu_pubname_map_; | |
220 | Pubname_offset_map cu_pubtype_map_; | |
221 | ||
222 | // Scan the given pubtable and build a map of the various dies it | |
223 | // refers to, so we can process the entries when we encounter the | |
224 | // die. | |
225 | void | |
226 | map_pubtable_to_dies(Dwarf_pubnames_table* table, | |
227 | Pubname_offset_map* map); | |
228 | ||
229 | // Tables to store the pubnames section of the current object. | |
230 | Dwarf_pubnames_table* pubnames_table_; | |
231 | Dwarf_pubnames_table* pubtypes_table_; | |
232 | ||
c1027032 CC |
233 | // The .gdb_index section. |
234 | Output_section* gdb_index_section_; | |
235 | // The list of DWARF compilation units. | |
236 | std::vector<Comp_unit> comp_units_; | |
237 | // The list of DWARF type units. | |
238 | std::vector<Type_unit> type_units_; | |
239 | // The list of address ranges. | |
240 | std::vector<Per_cu_range_list> ranges_; | |
241 | // The symbol table. | |
242 | Gdb_hashtab<Gdb_symbol>* gdb_symtab_; | |
243 | // The CU vector portion of the constant pool. | |
244 | std::vector<Cu_vector*> cu_vector_list_; | |
245 | // An array to map from a CU vector index to an offset to the constant pool. | |
246 | off_t* cu_vector_offsets_; | |
247 | // The string portion of the constant pool. | |
248 | Stringpool stringpool_; | |
249 | // Offsets of the various pieces of the .gdb_index section. | |
250 | off_t tu_offset_; | |
251 | off_t addr_offset_; | |
252 | off_t symtab_offset_; | |
253 | off_t cu_pool_offset_; | |
254 | off_t stringpool_offset_; | |
234d4ab8 SA |
255 | // Object, stmt list offset of the CUs and TUs associated with the |
256 | // last read pubnames and pubtypes sections. | |
c891b3f9 | 257 | const Relobj* pubnames_object_; |
234d4ab8 | 258 | off_t stmt_list_offset_; |
c1027032 CC |
259 | }; |
260 | ||
261 | } // End namespace gold. | |
262 | ||
263 | #endif // !defined(GOLD_GDB_INDEX_H) |