Home | History | Annotate | Line # | Download | only in dwarf2
      1      1.1  christos /* DWARF 2 debugging format support for GDB.
      2      1.1  christos 
      3  1.1.1.3  christos    Copyright (C) 1994-2024 Free Software Foundation, Inc.
      4      1.1  christos 
      5      1.1  christos    This file is part of GDB.
      6      1.1  christos 
      7      1.1  christos    This program is free software; you can redistribute it and/or modify
      8      1.1  christos    it under the terms of the GNU General Public License as published by
      9      1.1  christos    the Free Software Foundation; either version 3 of the License, or
     10      1.1  christos    (at your option) any later version.
     11      1.1  christos 
     12      1.1  christos    This program is distributed in the hope that it will be useful,
     13      1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14      1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15      1.1  christos    GNU General Public License for more details.
     16      1.1  christos 
     17      1.1  christos    You should have received a copy of the GNU General Public License
     18      1.1  christos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     19      1.1  christos 
     20  1.1.1.4  christos #ifndef GDB_DWARF2_LINE_HEADER_H
     21  1.1.1.4  christos #define GDB_DWARF2_LINE_HEADER_H
     22  1.1.1.4  christos 
     23  1.1.1.4  christos #include "dwarf2/types.h"
     24  1.1.1.4  christos 
     25  1.1.1.4  christos struct dwarf2_per_objfile;
     26      1.1  christos 
     27      1.1  christos /* dir_index is 1-based in DWARF 4 and before, and is 0-based in DWARF 5 and
     28      1.1  christos    later.  */
     29      1.1  christos typedef int dir_index;
     30      1.1  christos 
     31      1.1  christos /* file_name_index is 1-based in DWARF 4 and before, and is 0-based in DWARF 5
     32      1.1  christos    and later.  */
     33      1.1  christos typedef int file_name_index;
     34      1.1  christos 
     35      1.1  christos struct line_header;
     36      1.1  christos 
     37      1.1  christos struct file_entry
     38      1.1  christos {
     39      1.1  christos   file_entry () = default;
     40      1.1  christos 
     41  1.1.1.2  christos   file_entry (const char *name_, file_name_index index_, dir_index d_index_,
     42      1.1  christos 	      unsigned int mod_time_, unsigned int length_)
     43      1.1  christos     : name (name_),
     44  1.1.1.2  christos       index (index_),
     45      1.1  christos       d_index (d_index_),
     46      1.1  christos       mod_time (mod_time_),
     47      1.1  christos       length (length_)
     48      1.1  christos   {}
     49      1.1  christos 
     50      1.1  christos   /* Return the include directory at D_INDEX stored in LH.  Returns
     51      1.1  christos      NULL if D_INDEX is out of bounds.  */
     52      1.1  christos   const char *include_dir (const line_header *lh) const;
     53      1.1  christos 
     54      1.1  christos   /* The file name.  Note this is an observing pointer.  The memory is
     55      1.1  christos      owned by debug_line_buffer.  */
     56      1.1  christos   const char *name {};
     57      1.1  christos 
     58  1.1.1.2  christos   /* The index of this file in the file table.  */
     59  1.1.1.2  christos   file_name_index index {};
     60  1.1.1.2  christos 
     61      1.1  christos   /* The directory index (1-based).  */
     62      1.1  christos   dir_index d_index {};
     63      1.1  christos 
     64      1.1  christos   unsigned int mod_time {};
     65      1.1  christos 
     66      1.1  christos   unsigned int length {};
     67      1.1  christos 
     68      1.1  christos   /* The associated symbol table, if any.  */
     69      1.1  christos   struct symtab *symtab {};
     70      1.1  christos };
     71      1.1  christos 
     72      1.1  christos /* The line number information for a compilation unit (found in the
     73      1.1  christos    .debug_line section) begins with a "statement program header",
     74      1.1  christos    which contains the following information.  */
     75      1.1  christos struct line_header
     76      1.1  christos {
     77  1.1.1.2  christos   /* COMP_DIR is the value of the DW_AT_comp_dir attribute of the compilation
     78  1.1.1.2  christos      unit in the context of which we are reading this line header, or nullptr
     79  1.1.1.2  christos      if unknown or not applicable.  */
     80  1.1.1.2  christos   explicit line_header (const char *comp_dir)
     81  1.1.1.2  christos     : offset_in_dwz {}, m_comp_dir (comp_dir)
     82  1.1.1.2  christos   {}
     83  1.1.1.2  christos 
     84  1.1.1.3  christos   /* This constructor should only be used to create line_header instances to do
     85  1.1.1.2  christos      hash table lookups.  */
     86  1.1.1.2  christos   line_header (sect_offset sect_off, bool offset_in_dwz)
     87  1.1.1.2  christos     : sect_off (sect_off),
     88  1.1.1.2  christos       offset_in_dwz (offset_in_dwz)
     89      1.1  christos   {}
     90      1.1  christos 
     91      1.1  christos   /* Add an entry to the include directory table.  */
     92      1.1  christos   void add_include_dir (const char *include_dir);
     93      1.1  christos 
     94      1.1  christos   /* Add an entry to the file name table.  */
     95      1.1  christos   void add_file_name (const char *name, dir_index d_index,
     96      1.1  christos 		      unsigned int mod_time, unsigned int length);
     97      1.1  christos 
     98      1.1  christos   /* Return the include dir at INDEX (0-based in DWARF 5 and 1-based before).
     99      1.1  christos      Returns NULL if INDEX is out of bounds.  */
    100      1.1  christos   const char *include_dir_at (dir_index index) const
    101      1.1  christos   {
    102      1.1  christos     int vec_index;
    103      1.1  christos     if (version >= 5)
    104      1.1  christos       vec_index = index;
    105      1.1  christos     else
    106      1.1  christos       vec_index = index - 1;
    107      1.1  christos     if (vec_index < 0 || vec_index >= m_include_dirs.size ())
    108      1.1  christos       return NULL;
    109      1.1  christos     return m_include_dirs[vec_index];
    110      1.1  christos   }
    111      1.1  christos 
    112      1.1  christos   bool is_valid_file_index (int file_index) const
    113      1.1  christos   {
    114      1.1  christos     if (version >= 5)
    115      1.1  christos       return 0 <= file_index && file_index < file_names_size ();
    116      1.1  christos     return 1 <= file_index && file_index <= file_names_size ();
    117      1.1  christos   }
    118      1.1  christos 
    119      1.1  christos   /* Return the file name at INDEX (0-based in DWARF 5 and 1-based before).
    120      1.1  christos      Returns NULL if INDEX is out of bounds.  */
    121      1.1  christos   file_entry *file_name_at (file_name_index index)
    122      1.1  christos   {
    123      1.1  christos     int vec_index;
    124      1.1  christos     if (version >= 5)
    125      1.1  christos       vec_index = index;
    126      1.1  christos     else
    127      1.1  christos       vec_index = index - 1;
    128      1.1  christos     if (vec_index < 0 || vec_index >= m_file_names.size ())
    129      1.1  christos       return NULL;
    130      1.1  christos     return &m_file_names[vec_index];
    131      1.1  christos   }
    132      1.1  christos 
    133      1.1  christos   /* A const overload of the same.  */
    134      1.1  christos   const file_entry *file_name_at (file_name_index index) const
    135      1.1  christos   {
    136      1.1  christos     line_header *lh = const_cast<line_header *> (this);
    137      1.1  christos     return lh->file_name_at (index);
    138      1.1  christos   }
    139      1.1  christos 
    140      1.1  christos   /* The indexes are 0-based in DWARF 5 and 1-based in DWARF 4. Therefore,
    141      1.1  christos      this method should only be used to iterate through all file entries in an
    142      1.1  christos      index-agnostic manner.  */
    143      1.1  christos   std::vector<file_entry> &file_names ()
    144      1.1  christos   { return m_file_names; }
    145      1.1  christos   /* A const overload of the same.  */
    146      1.1  christos   const std::vector<file_entry> &file_names () const
    147      1.1  christos   { return m_file_names; }
    148      1.1  christos 
    149      1.1  christos   /* Offset of line number information in .debug_line section.  */
    150      1.1  christos   sect_offset sect_off {};
    151      1.1  christos 
    152      1.1  christos   /* OFFSET is for struct dwz_file associated with dwarf2_per_objfile.  */
    153      1.1  christos   unsigned offset_in_dwz : 1; /* Can't initialize bitfields in-class.  */
    154      1.1  christos 
    155      1.1  christos   unsigned short version {};
    156      1.1  christos   unsigned char minimum_instruction_length {};
    157      1.1  christos   unsigned char maximum_ops_per_instruction {};
    158      1.1  christos   unsigned char default_is_stmt {};
    159      1.1  christos   int line_base {};
    160      1.1  christos   unsigned char line_range {};
    161      1.1  christos   unsigned char opcode_base {};
    162      1.1  christos 
    163      1.1  christos   /* standard_opcode_lengths[i] is the number of operands for the
    164      1.1  christos      standard opcode whose value is i.  This means that
    165      1.1  christos      standard_opcode_lengths[0] is unused, and the last meaningful
    166      1.1  christos      element is standard_opcode_lengths[opcode_base - 1].  */
    167      1.1  christos   std::unique_ptr<unsigned char[]> standard_opcode_lengths;
    168      1.1  christos 
    169      1.1  christos   int file_names_size () const
    170      1.1  christos   { return m_file_names.size(); }
    171      1.1  christos 
    172      1.1  christos   /* The start and end of the statement program following this
    173      1.1  christos      header.  These point into dwarf2_per_objfile->line_buffer.  */
    174      1.1  christos   const gdb_byte *statement_program_start {}, *statement_program_end {};
    175      1.1  christos 
    176  1.1.1.2  christos   /* Return the most "complete" file name for FILE possible.
    177  1.1.1.2  christos 
    178  1.1.1.2  christos      This means prepending the directory and compilation directory, as needed,
    179  1.1.1.2  christos      until we get an absolute path.  */
    180  1.1.1.2  christos   std::string file_file_name (const file_entry &fe) const;
    181  1.1.1.2  christos 
    182  1.1.1.2  christos   /* Return the compilation directory of the compilation unit in the context of
    183  1.1.1.2  christos      which this line header is read.  Return nullptr if non applicable.  */
    184  1.1.1.2  christos   const char *comp_dir () const
    185  1.1.1.2  christos   { return m_comp_dir; }
    186      1.1  christos 
    187      1.1  christos  private:
    188      1.1  christos   /* The include_directories table.  Note these are observing
    189      1.1  christos      pointers.  The memory is owned by debug_line_buffer.  */
    190      1.1  christos   std::vector<const char *> m_include_dirs;
    191      1.1  christos 
    192      1.1  christos   /* The file_names table. This is private because the meaning of indexes
    193      1.1  christos      differs among DWARF versions (The first valid index is 1 in DWARF 4 and
    194      1.1  christos      before, and is 0 in DWARF 5 and later).  So the client should use
    195      1.1  christos      file_name_at method for access.  */
    196      1.1  christos   std::vector<file_entry> m_file_names;
    197  1.1.1.2  christos 
    198  1.1.1.2  christos   /* Compilation directory of the compilation unit in the context of which this
    199  1.1.1.2  christos      line header is read.  nullptr if unknown or not applicable.  */
    200  1.1.1.2  christos   const char *m_comp_dir = nullptr;
    201      1.1  christos };
    202      1.1  christos 
    203      1.1  christos typedef std::unique_ptr<line_header> line_header_up;
    204      1.1  christos 
    205      1.1  christos inline const char *
    206      1.1  christos file_entry::include_dir (const line_header *lh) const
    207      1.1  christos {
    208      1.1  christos   return lh->include_dir_at (d_index);
    209      1.1  christos }
    210      1.1  christos 
    211      1.1  christos /* Read the statement program header starting at SECT_OFF in SECTION.
    212      1.1  christos    Return line_header.  Returns nullptr if there is a problem reading
    213      1.1  christos    the header, e.g., if it has a version we don't understand.
    214      1.1  christos 
    215      1.1  christos    NOTE: the strings in the include directory and file name tables of
    216      1.1  christos    the returned object point into the dwarf line section buffer,
    217      1.1  christos    and must not be freed.  */
    218      1.1  christos 
    219      1.1  christos extern line_header_up dwarf_decode_line_header
    220      1.1  christos   (sect_offset sect_off, bool is_dwz, dwarf2_per_objfile *per_objfile,
    221  1.1.1.2  christos    struct dwarf2_section_info *section, const struct comp_unit_head *cu_header,
    222  1.1.1.2  christos    const char *comp_dir);
    223      1.1  christos 
    224  1.1.1.4  christos #endif /* GDB_DWARF2_LINE_HEADER_H */
    225