xref: /netbsd-src/external/gpl3/binutils.old/dist/gold/gdb-index.h (revision e992f068c547fd6e84b3f104dc2340adcc955732)
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