175fd0b74Schristos // gdb-index.h -- generate .gdb_index section for fast debug lookup -*- C++ -*- 275fd0b74Schristos 3*e992f068Schristos // Copyright (C) 2012-2022 Free Software Foundation, Inc. 475fd0b74Schristos // Written by Cary Coutant <ccoutant@google.com>. 575fd0b74Schristos 675fd0b74Schristos // This file is part of gold. 775fd0b74Schristos 875fd0b74Schristos // This program is free software; you can redistribute it and/or modify 975fd0b74Schristos // it under the terms of the GNU General Public License as published by 1075fd0b74Schristos // the Free Software Foundation; either version 3 of the License, or 1175fd0b74Schristos // (at your option) any later version. 1275fd0b74Schristos 1375fd0b74Schristos // This program is distributed in the hope that it will be useful, 1475fd0b74Schristos // but WITHOUT ANY WARRANTY; without even the implied warranty of 1575fd0b74Schristos // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1675fd0b74Schristos // GNU General Public License for more details. 1775fd0b74Schristos 1875fd0b74Schristos // You should have received a copy of the GNU General Public License 1975fd0b74Schristos // along with this program; if not, write to the Free Software 2075fd0b74Schristos // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 2175fd0b74Schristos // MA 02110-1301, USA. 2275fd0b74Schristos 2375fd0b74Schristos #include <sys/types.h> 2475fd0b74Schristos #include <vector> 2575fd0b74Schristos 2675fd0b74Schristos #include "gold.h" 2775fd0b74Schristos #include "output.h" 2875fd0b74Schristos #include "mapfile.h" 2975fd0b74Schristos #include "stringpool.h" 3075fd0b74Schristos 3175fd0b74Schristos #ifndef GOLD_GDB_INDEX_H 3275fd0b74Schristos #define GOLD_GDB_INDEX_H 3375fd0b74Schristos 3475fd0b74Schristos namespace gold 3575fd0b74Schristos { 3675fd0b74Schristos 3775fd0b74Schristos class Output_section; 3875fd0b74Schristos class Output_file; 3975fd0b74Schristos class Mapfile; 4075fd0b74Schristos template<int size, bool big_endian> 4175fd0b74Schristos class Sized_relobj; 4275fd0b74Schristos class Dwarf_range_list; 4375fd0b74Schristos template <typename T> 4475fd0b74Schristos class Gdb_hashtab; 4575fd0b74Schristos class Gdb_index_info_reader; 4675fd0b74Schristos class Dwarf_pubnames_table; 4775fd0b74Schristos 4875fd0b74Schristos // This class manages the .gdb_index section, which is a fast 4975fd0b74Schristos // lookup table for DWARF information used by the gdb debugger. 5075fd0b74Schristos // The format of this section is described in gdb/doc/gdb.texinfo. 5175fd0b74Schristos 5275fd0b74Schristos class Gdb_index : public Output_section_data 5375fd0b74Schristos { 5475fd0b74Schristos public: 5575fd0b74Schristos Gdb_index(Output_section* gdb_index_section); 5675fd0b74Schristos 5775fd0b74Schristos ~Gdb_index(); 5875fd0b74Schristos 5975fd0b74Schristos // Scan a .debug_info or .debug_types input section. 6075fd0b74Schristos void scan_debug_info(bool is_type_unit, 6175fd0b74Schristos Relobj* object, 6275fd0b74Schristos const unsigned char* symbols, 6375fd0b74Schristos off_t symbols_size, 6475fd0b74Schristos unsigned int shndx, 6575fd0b74Schristos unsigned int reloc_shndx, 6675fd0b74Schristos unsigned int reloc_type); 6775fd0b74Schristos 6875fd0b74Schristos // Add a compilation unit. 6975fd0b74Schristos int add_comp_unit(off_t cu_offset,off_t cu_length)7075fd0b74Schristos add_comp_unit(off_t cu_offset, off_t cu_length) 7175fd0b74Schristos { 7275fd0b74Schristos this->comp_units_.push_back(Comp_unit(cu_offset, cu_length)); 7375fd0b74Schristos return this->comp_units_.size() - 1; 7475fd0b74Schristos } 7575fd0b74Schristos 7675fd0b74Schristos // Add a type unit. 7775fd0b74Schristos int add_type_unit(off_t tu_offset,off_t type_offset,uint64_t signature)7875fd0b74Schristos add_type_unit(off_t tu_offset, off_t type_offset, uint64_t signature) 7975fd0b74Schristos { 8075fd0b74Schristos this->type_units_.push_back(Type_unit(tu_offset, type_offset, signature)); 8175fd0b74Schristos return this->type_units_.size() - 1; 8275fd0b74Schristos } 8375fd0b74Schristos 8475fd0b74Schristos // Add an address range. 8575fd0b74Schristos void add_address_range_list(Relobj * object,unsigned int cu_index,Dwarf_range_list * ranges)8675fd0b74Schristos add_address_range_list(Relobj* object, unsigned int cu_index, 8775fd0b74Schristos Dwarf_range_list* ranges) 8875fd0b74Schristos { 8975fd0b74Schristos this->ranges_.push_back(Per_cu_range_list(object, cu_index, ranges)); 9075fd0b74Schristos } 9175fd0b74Schristos 9275fd0b74Schristos // Add a symbol. FLAGS are the gdb_index version 7 flags to be stored in 9375fd0b74Schristos // the high-byte of the cu_index field. 9475fd0b74Schristos void 9575fd0b74Schristos add_symbol(int cu_index, const char* sym_name, uint8_t flags); 9675fd0b74Schristos 9775fd0b74Schristos // Return the offset into the pubnames table for the cu at the given 9875fd0b74Schristos // offset. 9975fd0b74Schristos off_t 10075fd0b74Schristos find_pubname_offset(off_t cu_offset); 10175fd0b74Schristos 10275fd0b74Schristos // Return the offset into the pubtypes table for the cu at the 10375fd0b74Schristos // given offset. 10475fd0b74Schristos off_t 10575fd0b74Schristos find_pubtype_offset(off_t cu_offset); 10675fd0b74Schristos 10775fd0b74Schristos // Return TRUE if we have already processed the pubnames and types 10875fd0b74Schristos // set for OBJECT of the CUs and TUS associated with the statement 10975fd0b74Schristos // list at OFFSET. 11075fd0b74Schristos bool 11175fd0b74Schristos pubnames_read(const Relobj* object, off_t offset); 11275fd0b74Schristos 11375fd0b74Schristos // Record that we have already read the pubnames associated with 11475fd0b74Schristos // OBJECT and OFFSET. 11575fd0b74Schristos void 11675fd0b74Schristos set_pubnames_read(const Relobj* object, off_t offset); 11775fd0b74Schristos 11875fd0b74Schristos // Return a pointer to the given table. 11975fd0b74Schristos Dwarf_pubnames_table* pubnames_table()12075fd0b74Schristos pubnames_table() 12175fd0b74Schristos { return pubnames_table_; } 12275fd0b74Schristos 12375fd0b74Schristos Dwarf_pubnames_table* pubtypes_table()12475fd0b74Schristos pubtypes_table() 12575fd0b74Schristos { return pubtypes_table_; } 12675fd0b74Schristos 12775fd0b74Schristos // Print usage statistics. 12875fd0b74Schristos static void 12975fd0b74Schristos print_stats(); 13075fd0b74Schristos 13175fd0b74Schristos protected: 13275fd0b74Schristos // This is called to update the section size prior to assigning 13375fd0b74Schristos // the address and file offset. 13475fd0b74Schristos void update_data_size()13575fd0b74Schristos update_data_size() 13675fd0b74Schristos { this->set_final_data_size(); } 13775fd0b74Schristos 13875fd0b74Schristos // Set the final data size. 13975fd0b74Schristos void 14075fd0b74Schristos set_final_data_size(); 14175fd0b74Schristos 14275fd0b74Schristos // Write the data to the file. 14375fd0b74Schristos void 14475fd0b74Schristos do_write(Output_file*); 14575fd0b74Schristos 14675fd0b74Schristos // Write to a map file. 14775fd0b74Schristos void do_print_to_mapfile(Mapfile * mapfile)14875fd0b74Schristos do_print_to_mapfile(Mapfile* mapfile) const 14975fd0b74Schristos { mapfile->print_output_data(this, _("** gdb_index")); } 15075fd0b74Schristos 15175fd0b74Schristos // Create a map from dies to pubnames. 15275fd0b74Schristos Dwarf_pubnames_table* 15375fd0b74Schristos map_pubtable_to_dies(unsigned int attr, 15475fd0b74Schristos Gdb_index_info_reader* dwinfo, 15575fd0b74Schristos Relobj* object, 15675fd0b74Schristos const unsigned char* symbols, 15775fd0b74Schristos off_t symbols_size); 15875fd0b74Schristos 15975fd0b74Schristos // Wrapper for map_pubtable_to_dies 16075fd0b74Schristos void 16175fd0b74Schristos map_pubnames_and_types_to_dies(Gdb_index_info_reader* dwinfo, 16275fd0b74Schristos Relobj* object, 16375fd0b74Schristos const unsigned char* symbols, 16475fd0b74Schristos off_t symbols_size); 16575fd0b74Schristos 16675fd0b74Schristos private: 16775fd0b74Schristos // An entry in the compilation unit list. 16875fd0b74Schristos struct Comp_unit 16975fd0b74Schristos { Comp_unitComp_unit17075fd0b74Schristos Comp_unit(off_t off, off_t len) 17175fd0b74Schristos : cu_offset(off), cu_length(len) 17275fd0b74Schristos { } 17375fd0b74Schristos uint64_t cu_offset; 17475fd0b74Schristos uint64_t cu_length; 17575fd0b74Schristos }; 17675fd0b74Schristos 17775fd0b74Schristos // An entry in the type unit list. 17875fd0b74Schristos struct Type_unit 17975fd0b74Schristos { Type_unitType_unit18075fd0b74Schristos Type_unit(off_t off, off_t toff, uint64_t sig) 18175fd0b74Schristos : tu_offset(off), type_offset(toff), type_signature(sig) 18275fd0b74Schristos { } 18375fd0b74Schristos uint64_t tu_offset; 18475fd0b74Schristos uint64_t type_offset; 18575fd0b74Schristos uint64_t type_signature; 18675fd0b74Schristos }; 18775fd0b74Schristos 18875fd0b74Schristos // An entry in the address range list. 18975fd0b74Schristos struct Per_cu_range_list 19075fd0b74Schristos { Per_cu_range_listPer_cu_range_list19175fd0b74Schristos Per_cu_range_list(Relobj* obj, uint32_t index, Dwarf_range_list* r) 19275fd0b74Schristos : object(obj), cu_index(index), ranges(r) 19375fd0b74Schristos { } 19475fd0b74Schristos Relobj* object; 19575fd0b74Schristos uint32_t cu_index; 19675fd0b74Schristos Dwarf_range_list* ranges; 19775fd0b74Schristos }; 19875fd0b74Schristos 19975fd0b74Schristos // A symbol table entry. 20075fd0b74Schristos struct Gdb_symbol 20175fd0b74Schristos { 20275fd0b74Schristos Stringpool::Key name_key; 20375fd0b74Schristos unsigned int hashval; 20475fd0b74Schristos unsigned int cu_vector_index; 20575fd0b74Schristos 20675fd0b74Schristos // Return the hash value. 20775fd0b74Schristos unsigned int hashGdb_symbol20875fd0b74Schristos hash() 20975fd0b74Schristos { return this->hashval; } 21075fd0b74Schristos 21175fd0b74Schristos // Return true if this symbol is the same as SYMBOL. 21275fd0b74Schristos bool equalGdb_symbol21375fd0b74Schristos equal(Gdb_symbol* symbol) 21475fd0b74Schristos { return this->name_key == symbol->name_key; } 21575fd0b74Schristos }; 21675fd0b74Schristos 21775fd0b74Schristos typedef std::vector<std::pair<int, uint8_t> > Cu_vector; 21875fd0b74Schristos 21975fd0b74Schristos typedef Unordered_map<off_t, off_t> Pubname_offset_map; 22075fd0b74Schristos Pubname_offset_map cu_pubname_map_; 22175fd0b74Schristos Pubname_offset_map cu_pubtype_map_; 22275fd0b74Schristos 22375fd0b74Schristos // Scan the given pubtable and build a map of the various dies it 22475fd0b74Schristos // refers to, so we can process the entries when we encounter the 22575fd0b74Schristos // die. 22675fd0b74Schristos void 22775fd0b74Schristos map_pubtable_to_dies(Dwarf_pubnames_table* table, 22875fd0b74Schristos Pubname_offset_map* map); 22975fd0b74Schristos 23075fd0b74Schristos // Tables to store the pubnames section of the current object. 23175fd0b74Schristos Dwarf_pubnames_table* pubnames_table_; 23275fd0b74Schristos Dwarf_pubnames_table* pubtypes_table_; 23375fd0b74Schristos 23475fd0b74Schristos // The .gdb_index section. 23575fd0b74Schristos Output_section* gdb_index_section_; 23675fd0b74Schristos // The list of DWARF compilation units. 23775fd0b74Schristos std::vector<Comp_unit> comp_units_; 23875fd0b74Schristos // The list of DWARF type units. 23975fd0b74Schristos std::vector<Type_unit> type_units_; 24075fd0b74Schristos // The list of address ranges. 24175fd0b74Schristos std::vector<Per_cu_range_list> ranges_; 24275fd0b74Schristos // The symbol table. 24375fd0b74Schristos Gdb_hashtab<Gdb_symbol>* gdb_symtab_; 24475fd0b74Schristos // The CU vector portion of the constant pool. 24575fd0b74Schristos std::vector<Cu_vector*> cu_vector_list_; 24675fd0b74Schristos // An array to map from a CU vector index to an offset to the constant pool. 24775fd0b74Schristos off_t* cu_vector_offsets_; 24875fd0b74Schristos // The string portion of the constant pool. 24975fd0b74Schristos Stringpool stringpool_; 25075fd0b74Schristos // Offsets of the various pieces of the .gdb_index section. 25175fd0b74Schristos off_t tu_offset_; 25275fd0b74Schristos off_t addr_offset_; 25375fd0b74Schristos off_t symtab_offset_; 25475fd0b74Schristos off_t cu_pool_offset_; 25575fd0b74Schristos off_t stringpool_offset_; 25675fd0b74Schristos // Object, stmt list offset of the CUs and TUs associated with the 25775fd0b74Schristos // last read pubnames and pubtypes sections. 25875fd0b74Schristos const Relobj* pubnames_object_; 25975fd0b74Schristos off_t stmt_list_offset_; 26075fd0b74Schristos }; 26175fd0b74Schristos 26275fd0b74Schristos } // End namespace gold. 26375fd0b74Schristos 26475fd0b74Schristos #endif // !defined(GOLD_GDB_INDEX_H) 265