1*a9fa9459Szrj // gdb-index.h -- generate .gdb_index section for fast debug lookup -*- C++ -*- 2*a9fa9459Szrj 3*a9fa9459Szrj // Copyright (C) 2012-2016 Free Software Foundation, Inc. 4*a9fa9459Szrj // Written by Cary Coutant <ccoutant@google.com>. 5*a9fa9459Szrj 6*a9fa9459Szrj // This file is part of gold. 7*a9fa9459Szrj 8*a9fa9459Szrj // This program is free software; you can redistribute it and/or modify 9*a9fa9459Szrj // it under the terms of the GNU General Public License as published by 10*a9fa9459Szrj // the Free Software Foundation; either version 3 of the License, or 11*a9fa9459Szrj // (at your option) any later version. 12*a9fa9459Szrj 13*a9fa9459Szrj // This program is distributed in the hope that it will be useful, 14*a9fa9459Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of 15*a9fa9459Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16*a9fa9459Szrj // GNU General Public License for more details. 17*a9fa9459Szrj 18*a9fa9459Szrj // You should have received a copy of the GNU General Public License 19*a9fa9459Szrj // along with this program; if not, write to the Free Software 20*a9fa9459Szrj // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 21*a9fa9459Szrj // MA 02110-1301, USA. 22*a9fa9459Szrj 23*a9fa9459Szrj #include <sys/types.h> 24*a9fa9459Szrj #include <vector> 25*a9fa9459Szrj 26*a9fa9459Szrj #include "gold.h" 27*a9fa9459Szrj #include "output.h" 28*a9fa9459Szrj #include "mapfile.h" 29*a9fa9459Szrj #include "stringpool.h" 30*a9fa9459Szrj 31*a9fa9459Szrj #ifndef GOLD_GDB_INDEX_H 32*a9fa9459Szrj #define GOLD_GDB_INDEX_H 33*a9fa9459Szrj 34*a9fa9459Szrj namespace gold 35*a9fa9459Szrj { 36*a9fa9459Szrj 37*a9fa9459Szrj class Output_section; 38*a9fa9459Szrj class Output_file; 39*a9fa9459Szrj class Mapfile; 40*a9fa9459Szrj template<int size, bool big_endian> 41*a9fa9459Szrj class Sized_relobj; 42*a9fa9459Szrj class Dwarf_range_list; 43*a9fa9459Szrj template <typename T> 44*a9fa9459Szrj class Gdb_hashtab; 45*a9fa9459Szrj class Gdb_index_info_reader; 46*a9fa9459Szrj class Dwarf_pubnames_table; 47*a9fa9459Szrj 48*a9fa9459Szrj // This class manages the .gdb_index section, which is a fast 49*a9fa9459Szrj // lookup table for DWARF information used by the gdb debugger. 50*a9fa9459Szrj // The format of this section is described in gdb/doc/gdb.texinfo. 51*a9fa9459Szrj 52*a9fa9459Szrj class Gdb_index : public Output_section_data 53*a9fa9459Szrj { 54*a9fa9459Szrj public: 55*a9fa9459Szrj Gdb_index(Output_section* gdb_index_section); 56*a9fa9459Szrj 57*a9fa9459Szrj ~Gdb_index(); 58*a9fa9459Szrj 59*a9fa9459Szrj // Scan a .debug_info or .debug_types input section. 60*a9fa9459Szrj void scan_debug_info(bool is_type_unit, 61*a9fa9459Szrj Relobj* object, 62*a9fa9459Szrj const unsigned char* symbols, 63*a9fa9459Szrj off_t symbols_size, 64*a9fa9459Szrj unsigned int shndx, 65*a9fa9459Szrj unsigned int reloc_shndx, 66*a9fa9459Szrj unsigned int reloc_type); 67*a9fa9459Szrj 68*a9fa9459Szrj // Add a compilation unit. 69*a9fa9459Szrj int add_comp_unit(off_t cu_offset,off_t cu_length)70*a9fa9459Szrj add_comp_unit(off_t cu_offset, off_t cu_length) 71*a9fa9459Szrj { 72*a9fa9459Szrj this->comp_units_.push_back(Comp_unit(cu_offset, cu_length)); 73*a9fa9459Szrj return this->comp_units_.size() - 1; 74*a9fa9459Szrj } 75*a9fa9459Szrj 76*a9fa9459Szrj // Add a type unit. 77*a9fa9459Szrj int add_type_unit(off_t tu_offset,off_t type_offset,uint64_t signature)78*a9fa9459Szrj add_type_unit(off_t tu_offset, off_t type_offset, uint64_t signature) 79*a9fa9459Szrj { 80*a9fa9459Szrj this->type_units_.push_back(Type_unit(tu_offset, type_offset, signature)); 81*a9fa9459Szrj return this->type_units_.size() - 1; 82*a9fa9459Szrj } 83*a9fa9459Szrj 84*a9fa9459Szrj // Add an address range. 85*a9fa9459Szrj void add_address_range_list(Relobj * object,unsigned int cu_index,Dwarf_range_list * ranges)86*a9fa9459Szrj add_address_range_list(Relobj* object, unsigned int cu_index, 87*a9fa9459Szrj Dwarf_range_list* ranges) 88*a9fa9459Szrj { 89*a9fa9459Szrj this->ranges_.push_back(Per_cu_range_list(object, cu_index, ranges)); 90*a9fa9459Szrj } 91*a9fa9459Szrj 92*a9fa9459Szrj // Add a symbol. FLAGS are the gdb_index version 7 flags to be stored in 93*a9fa9459Szrj // the high-byte of the cu_index field. 94*a9fa9459Szrj void 95*a9fa9459Szrj add_symbol(int cu_index, const char* sym_name, uint8_t flags); 96*a9fa9459Szrj 97*a9fa9459Szrj // Return the offset into the pubnames table for the cu at the given 98*a9fa9459Szrj // offset. 99*a9fa9459Szrj off_t 100*a9fa9459Szrj find_pubname_offset(off_t cu_offset); 101*a9fa9459Szrj 102*a9fa9459Szrj // Return the offset into the pubtypes table for the cu at the 103*a9fa9459Szrj // given offset. 104*a9fa9459Szrj off_t 105*a9fa9459Szrj find_pubtype_offset(off_t cu_offset); 106*a9fa9459Szrj 107*a9fa9459Szrj // Return TRUE if we have already processed the pubnames and types 108*a9fa9459Szrj // set for OBJECT of the CUs and TUS associated with the statement 109*a9fa9459Szrj // list at OFFSET. 110*a9fa9459Szrj bool 111*a9fa9459Szrj pubnames_read(const Relobj* object, off_t offset); 112*a9fa9459Szrj 113*a9fa9459Szrj // Record that we have already read the pubnames associated with 114*a9fa9459Szrj // OBJECT and OFFSET. 115*a9fa9459Szrj void 116*a9fa9459Szrj set_pubnames_read(const Relobj* object, off_t offset); 117*a9fa9459Szrj 118*a9fa9459Szrj // Return a pointer to the given table. 119*a9fa9459Szrj Dwarf_pubnames_table* pubnames_table()120*a9fa9459Szrj pubnames_table() 121*a9fa9459Szrj { return pubnames_table_; } 122*a9fa9459Szrj 123*a9fa9459Szrj Dwarf_pubnames_table* pubtypes_table()124*a9fa9459Szrj pubtypes_table() 125*a9fa9459Szrj { return pubtypes_table_; } 126*a9fa9459Szrj 127*a9fa9459Szrj // Print usage statistics. 128*a9fa9459Szrj static void 129*a9fa9459Szrj print_stats(); 130*a9fa9459Szrj 131*a9fa9459Szrj protected: 132*a9fa9459Szrj // This is called to update the section size prior to assigning 133*a9fa9459Szrj // the address and file offset. 134*a9fa9459Szrj void update_data_size()135*a9fa9459Szrj update_data_size() 136*a9fa9459Szrj { this->set_final_data_size(); } 137*a9fa9459Szrj 138*a9fa9459Szrj // Set the final data size. 139*a9fa9459Szrj void 140*a9fa9459Szrj set_final_data_size(); 141*a9fa9459Szrj 142*a9fa9459Szrj // Write the data to the file. 143*a9fa9459Szrj void 144*a9fa9459Szrj do_write(Output_file*); 145*a9fa9459Szrj 146*a9fa9459Szrj // Write to a map file. 147*a9fa9459Szrj void do_print_to_mapfile(Mapfile * mapfile)148*a9fa9459Szrj do_print_to_mapfile(Mapfile* mapfile) const 149*a9fa9459Szrj { mapfile->print_output_data(this, _("** gdb_index")); } 150*a9fa9459Szrj 151*a9fa9459Szrj // Create a map from dies to pubnames. 152*a9fa9459Szrj Dwarf_pubnames_table* 153*a9fa9459Szrj map_pubtable_to_dies(unsigned int attr, 154*a9fa9459Szrj Gdb_index_info_reader* dwinfo, 155*a9fa9459Szrj Relobj* object, 156*a9fa9459Szrj const unsigned char* symbols, 157*a9fa9459Szrj off_t symbols_size); 158*a9fa9459Szrj 159*a9fa9459Szrj // Wrapper for map_pubtable_to_dies 160*a9fa9459Szrj void 161*a9fa9459Szrj map_pubnames_and_types_to_dies(Gdb_index_info_reader* dwinfo, 162*a9fa9459Szrj Relobj* object, 163*a9fa9459Szrj const unsigned char* symbols, 164*a9fa9459Szrj off_t symbols_size); 165*a9fa9459Szrj 166*a9fa9459Szrj private: 167*a9fa9459Szrj // An entry in the compilation unit list. 168*a9fa9459Szrj struct Comp_unit 169*a9fa9459Szrj { Comp_unitComp_unit170*a9fa9459Szrj Comp_unit(off_t off, off_t len) 171*a9fa9459Szrj : cu_offset(off), cu_length(len) 172*a9fa9459Szrj { } 173*a9fa9459Szrj uint64_t cu_offset; 174*a9fa9459Szrj uint64_t cu_length; 175*a9fa9459Szrj }; 176*a9fa9459Szrj 177*a9fa9459Szrj // An entry in the type unit list. 178*a9fa9459Szrj struct Type_unit 179*a9fa9459Szrj { Type_unitType_unit180*a9fa9459Szrj Type_unit(off_t off, off_t toff, uint64_t sig) 181*a9fa9459Szrj : tu_offset(off), type_offset(toff), type_signature(sig) 182*a9fa9459Szrj { } 183*a9fa9459Szrj uint64_t tu_offset; 184*a9fa9459Szrj uint64_t type_offset; 185*a9fa9459Szrj uint64_t type_signature; 186*a9fa9459Szrj }; 187*a9fa9459Szrj 188*a9fa9459Szrj // An entry in the address range list. 189*a9fa9459Szrj struct Per_cu_range_list 190*a9fa9459Szrj { Per_cu_range_listPer_cu_range_list191*a9fa9459Szrj Per_cu_range_list(Relobj* obj, uint32_t index, Dwarf_range_list* r) 192*a9fa9459Szrj : object(obj), cu_index(index), ranges(r) 193*a9fa9459Szrj { } 194*a9fa9459Szrj Relobj* object; 195*a9fa9459Szrj uint32_t cu_index; 196*a9fa9459Szrj Dwarf_range_list* ranges; 197*a9fa9459Szrj }; 198*a9fa9459Szrj 199*a9fa9459Szrj // A symbol table entry. 200*a9fa9459Szrj struct Gdb_symbol 201*a9fa9459Szrj { 202*a9fa9459Szrj Stringpool::Key name_key; 203*a9fa9459Szrj unsigned int hashval; 204*a9fa9459Szrj unsigned int cu_vector_index; 205*a9fa9459Szrj 206*a9fa9459Szrj // Return the hash value. 207*a9fa9459Szrj unsigned int hashGdb_symbol208*a9fa9459Szrj hash() 209*a9fa9459Szrj { return this->hashval; } 210*a9fa9459Szrj 211*a9fa9459Szrj // Return true if this symbol is the same as SYMBOL. 212*a9fa9459Szrj bool equalGdb_symbol213*a9fa9459Szrj equal(Gdb_symbol* symbol) 214*a9fa9459Szrj { return this->name_key == symbol->name_key; } 215*a9fa9459Szrj }; 216*a9fa9459Szrj 217*a9fa9459Szrj typedef std::vector<std::pair<int, uint8_t> > Cu_vector; 218*a9fa9459Szrj 219*a9fa9459Szrj typedef Unordered_map<off_t, off_t> Pubname_offset_map; 220*a9fa9459Szrj Pubname_offset_map cu_pubname_map_; 221*a9fa9459Szrj Pubname_offset_map cu_pubtype_map_; 222*a9fa9459Szrj 223*a9fa9459Szrj // Scan the given pubtable and build a map of the various dies it 224*a9fa9459Szrj // refers to, so we can process the entries when we encounter the 225*a9fa9459Szrj // die. 226*a9fa9459Szrj void 227*a9fa9459Szrj map_pubtable_to_dies(Dwarf_pubnames_table* table, 228*a9fa9459Szrj Pubname_offset_map* map); 229*a9fa9459Szrj 230*a9fa9459Szrj // Tables to store the pubnames section of the current object. 231*a9fa9459Szrj Dwarf_pubnames_table* pubnames_table_; 232*a9fa9459Szrj Dwarf_pubnames_table* pubtypes_table_; 233*a9fa9459Szrj 234*a9fa9459Szrj // The .gdb_index section. 235*a9fa9459Szrj Output_section* gdb_index_section_; 236*a9fa9459Szrj // The list of DWARF compilation units. 237*a9fa9459Szrj std::vector<Comp_unit> comp_units_; 238*a9fa9459Szrj // The list of DWARF type units. 239*a9fa9459Szrj std::vector<Type_unit> type_units_; 240*a9fa9459Szrj // The list of address ranges. 241*a9fa9459Szrj std::vector<Per_cu_range_list> ranges_; 242*a9fa9459Szrj // The symbol table. 243*a9fa9459Szrj Gdb_hashtab<Gdb_symbol>* gdb_symtab_; 244*a9fa9459Szrj // The CU vector portion of the constant pool. 245*a9fa9459Szrj std::vector<Cu_vector*> cu_vector_list_; 246*a9fa9459Szrj // An array to map from a CU vector index to an offset to the constant pool. 247*a9fa9459Szrj off_t* cu_vector_offsets_; 248*a9fa9459Szrj // The string portion of the constant pool. 249*a9fa9459Szrj Stringpool stringpool_; 250*a9fa9459Szrj // Offsets of the various pieces of the .gdb_index section. 251*a9fa9459Szrj off_t tu_offset_; 252*a9fa9459Szrj off_t addr_offset_; 253*a9fa9459Szrj off_t symtab_offset_; 254*a9fa9459Szrj off_t cu_pool_offset_; 255*a9fa9459Szrj off_t stringpool_offset_; 256*a9fa9459Szrj // Object, stmt list offset of the CUs and TUs associated with the 257*a9fa9459Szrj // last read pubnames and pubtypes sections. 258*a9fa9459Szrj const Relobj* pubnames_object_; 259*a9fa9459Szrj off_t stmt_list_offset_; 260*a9fa9459Szrj }; 261*a9fa9459Szrj 262*a9fa9459Szrj } // End namespace gold. 263*a9fa9459Szrj 264*a9fa9459Szrj #endif // !defined(GOLD_GDB_INDEX_H) 265