Home | History | Annotate | Download | only in gold
      1 // gdb-index.h -- generate .gdb_index section for fast debug lookup  -*- C++ -*-
      2 
      3 // Copyright (C) 2012-2016 Free Software Foundation, Inc.
      4 // Written by Cary Coutant <ccoutant (at) 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;
     45 class Gdb_index_info_reader;
     46 class Dwarf_pubnames_table;
     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.  FLAGS are the gdb_index version 7 flags to be stored in
     93   // the high-byte of the cu_index field.
     94   void
     95   add_symbol(int cu_index, const char* sym_name, uint8_t flags);
     96 
     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);
    106 
    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.
    110   bool
    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_; }
    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 
    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 
    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 
    217   typedef std::vector<std::pair<int, uint8_t> > Cu_vector;
    218 
    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 
    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_;
    256   // Object, stmt list offset of the CUs and TUs associated with the
    257   // last read pubnames and pubtypes sections.
    258   const Relobj* pubnames_object_;
    259   off_t stmt_list_offset_;
    260 };
    261 
    262 } // End namespace gold.
    263 
    264 #endif // !defined(GOLD_GDB_INDEX_H)
    265