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