xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/dwarf2/line-header.h (revision 6881a4007f077b54e5f51159c52b9b25f57deb0d)
17d62b00eSchristos /* DWARF 2 debugging format support for GDB.
27d62b00eSchristos 
3*6881a400Schristos    Copyright (C) 1994-2023 Free Software Foundation, Inc.
47d62b00eSchristos 
57d62b00eSchristos    This file is part of GDB.
67d62b00eSchristos 
77d62b00eSchristos    This program is free software; you can redistribute it and/or modify
87d62b00eSchristos    it under the terms of the GNU General Public License as published by
97d62b00eSchristos    the Free Software Foundation; either version 3 of the License, or
107d62b00eSchristos    (at your option) any later version.
117d62b00eSchristos 
127d62b00eSchristos    This program is distributed in the hope that it will be useful,
137d62b00eSchristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
147d62b00eSchristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
157d62b00eSchristos    GNU General Public License for more details.
167d62b00eSchristos 
177d62b00eSchristos    You should have received a copy of the GNU General Public License
187d62b00eSchristos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
197d62b00eSchristos 
207d62b00eSchristos #ifndef DWARF2_LINE_HEADER_H
217d62b00eSchristos #define DWARF2_LINE_HEADER_H
227d62b00eSchristos 
237d62b00eSchristos #include "gdbtypes.h"
247d62b00eSchristos 
257d62b00eSchristos /* dir_index is 1-based in DWARF 4 and before, and is 0-based in DWARF 5 and
267d62b00eSchristos    later.  */
277d62b00eSchristos typedef int dir_index;
287d62b00eSchristos 
297d62b00eSchristos /* file_name_index is 1-based in DWARF 4 and before, and is 0-based in DWARF 5
307d62b00eSchristos    and later.  */
317d62b00eSchristos typedef int file_name_index;
327d62b00eSchristos 
337d62b00eSchristos struct line_header;
347d62b00eSchristos 
357d62b00eSchristos struct file_entry
367d62b00eSchristos {
377d62b00eSchristos   file_entry () = default;
387d62b00eSchristos 
39*6881a400Schristos   file_entry (const char *name_, file_name_index index_, dir_index d_index_,
407d62b00eSchristos 	      unsigned int mod_time_, unsigned int length_)
417d62b00eSchristos     : name (name_),
42*6881a400Schristos       index (index_),
437d62b00eSchristos       d_index (d_index_),
447d62b00eSchristos       mod_time (mod_time_),
457d62b00eSchristos       length (length_)
467d62b00eSchristos   {}
477d62b00eSchristos 
487d62b00eSchristos   /* Return the include directory at D_INDEX stored in LH.  Returns
497d62b00eSchristos      NULL if D_INDEX is out of bounds.  */
507d62b00eSchristos   const char *include_dir (const line_header *lh) const;
517d62b00eSchristos 
527d62b00eSchristos   /* The file name.  Note this is an observing pointer.  The memory is
537d62b00eSchristos      owned by debug_line_buffer.  */
547d62b00eSchristos   const char *name {};
557d62b00eSchristos 
56*6881a400Schristos   /* The index of this file in the file table.  */
57*6881a400Schristos   file_name_index index {};
58*6881a400Schristos 
597d62b00eSchristos   /* The directory index (1-based).  */
607d62b00eSchristos   dir_index d_index {};
617d62b00eSchristos 
627d62b00eSchristos   unsigned int mod_time {};
637d62b00eSchristos 
647d62b00eSchristos   unsigned int length {};
657d62b00eSchristos 
667d62b00eSchristos   /* The associated symbol table, if any.  */
677d62b00eSchristos   struct symtab *symtab {};
687d62b00eSchristos };
697d62b00eSchristos 
707d62b00eSchristos /* The line number information for a compilation unit (found in the
717d62b00eSchristos    .debug_line section) begins with a "statement program header",
727d62b00eSchristos    which contains the following information.  */
737d62b00eSchristos struct line_header
747d62b00eSchristos {
75*6881a400Schristos   /* COMP_DIR is the value of the DW_AT_comp_dir attribute of the compilation
76*6881a400Schristos      unit in the context of which we are reading this line header, or nullptr
77*6881a400Schristos      if unknown or not applicable.  */
78*6881a400Schristos   explicit line_header (const char *comp_dir)
79*6881a400Schristos     : offset_in_dwz {}, m_comp_dir (comp_dir)
80*6881a400Schristos   {}
81*6881a400Schristos 
82*6881a400Schristos   /* This constructor should only be used to create line_header intances to do
83*6881a400Schristos      hash table lookups.  */
84*6881a400Schristos   line_header (sect_offset sect_off, bool offset_in_dwz)
85*6881a400Schristos     : sect_off (sect_off),
86*6881a400Schristos       offset_in_dwz (offset_in_dwz)
877d62b00eSchristos   {}
887d62b00eSchristos 
897d62b00eSchristos   /* Add an entry to the include directory table.  */
907d62b00eSchristos   void add_include_dir (const char *include_dir);
917d62b00eSchristos 
927d62b00eSchristos   /* Add an entry to the file name table.  */
937d62b00eSchristos   void add_file_name (const char *name, dir_index d_index,
947d62b00eSchristos 		      unsigned int mod_time, unsigned int length);
957d62b00eSchristos 
967d62b00eSchristos   /* Return the include dir at INDEX (0-based in DWARF 5 and 1-based before).
977d62b00eSchristos      Returns NULL if INDEX is out of bounds.  */
987d62b00eSchristos   const char *include_dir_at (dir_index index) const
997d62b00eSchristos   {
1007d62b00eSchristos     int vec_index;
1017d62b00eSchristos     if (version >= 5)
1027d62b00eSchristos       vec_index = index;
1037d62b00eSchristos     else
1047d62b00eSchristos       vec_index = index - 1;
1057d62b00eSchristos     if (vec_index < 0 || vec_index >= m_include_dirs.size ())
1067d62b00eSchristos       return NULL;
1077d62b00eSchristos     return m_include_dirs[vec_index];
1087d62b00eSchristos   }
1097d62b00eSchristos 
1107d62b00eSchristos   bool is_valid_file_index (int file_index) const
1117d62b00eSchristos   {
1127d62b00eSchristos     if (version >= 5)
1137d62b00eSchristos       return 0 <= file_index && file_index < file_names_size ();
1147d62b00eSchristos     return 1 <= file_index && file_index <= file_names_size ();
1157d62b00eSchristos   }
1167d62b00eSchristos 
1177d62b00eSchristos   /* Return the file name at INDEX (0-based in DWARF 5 and 1-based before).
1187d62b00eSchristos      Returns NULL if INDEX is out of bounds.  */
1197d62b00eSchristos   file_entry *file_name_at (file_name_index index)
1207d62b00eSchristos   {
1217d62b00eSchristos     int vec_index;
1227d62b00eSchristos     if (version >= 5)
1237d62b00eSchristos       vec_index = index;
1247d62b00eSchristos     else
1257d62b00eSchristos       vec_index = index - 1;
1267d62b00eSchristos     if (vec_index < 0 || vec_index >= m_file_names.size ())
1277d62b00eSchristos       return NULL;
1287d62b00eSchristos     return &m_file_names[vec_index];
1297d62b00eSchristos   }
1307d62b00eSchristos 
1317d62b00eSchristos   /* A const overload of the same.  */
1327d62b00eSchristos   const file_entry *file_name_at (file_name_index index) const
1337d62b00eSchristos   {
1347d62b00eSchristos     line_header *lh = const_cast<line_header *> (this);
1357d62b00eSchristos     return lh->file_name_at (index);
1367d62b00eSchristos   }
1377d62b00eSchristos 
1387d62b00eSchristos   /* The indexes are 0-based in DWARF 5 and 1-based in DWARF 4. Therefore,
1397d62b00eSchristos      this method should only be used to iterate through all file entries in an
1407d62b00eSchristos      index-agnostic manner.  */
1417d62b00eSchristos   std::vector<file_entry> &file_names ()
1427d62b00eSchristos   { return m_file_names; }
1437d62b00eSchristos   /* A const overload of the same.  */
1447d62b00eSchristos   const std::vector<file_entry> &file_names () const
1457d62b00eSchristos   { return m_file_names; }
1467d62b00eSchristos 
1477d62b00eSchristos   /* Offset of line number information in .debug_line section.  */
1487d62b00eSchristos   sect_offset sect_off {};
1497d62b00eSchristos 
1507d62b00eSchristos   /* OFFSET is for struct dwz_file associated with dwarf2_per_objfile.  */
1517d62b00eSchristos   unsigned offset_in_dwz : 1; /* Can't initialize bitfields in-class.  */
1527d62b00eSchristos 
1537d62b00eSchristos   unsigned short version {};
1547d62b00eSchristos   unsigned char minimum_instruction_length {};
1557d62b00eSchristos   unsigned char maximum_ops_per_instruction {};
1567d62b00eSchristos   unsigned char default_is_stmt {};
1577d62b00eSchristos   int line_base {};
1587d62b00eSchristos   unsigned char line_range {};
1597d62b00eSchristos   unsigned char opcode_base {};
1607d62b00eSchristos 
1617d62b00eSchristos   /* standard_opcode_lengths[i] is the number of operands for the
1627d62b00eSchristos      standard opcode whose value is i.  This means that
1637d62b00eSchristos      standard_opcode_lengths[0] is unused, and the last meaningful
1647d62b00eSchristos      element is standard_opcode_lengths[opcode_base - 1].  */
1657d62b00eSchristos   std::unique_ptr<unsigned char[]> standard_opcode_lengths;
1667d62b00eSchristos 
1677d62b00eSchristos   int file_names_size () const
1687d62b00eSchristos   { return m_file_names.size(); }
1697d62b00eSchristos 
1707d62b00eSchristos   /* The start and end of the statement program following this
1717d62b00eSchristos      header.  These point into dwarf2_per_objfile->line_buffer.  */
1727d62b00eSchristos   const gdb_byte *statement_program_start {}, *statement_program_end {};
1737d62b00eSchristos 
174*6881a400Schristos   /* Return the most "complete" file name for FILE possible.
1757d62b00eSchristos 
176*6881a400Schristos      This means prepending the directory and compilation directory, as needed,
177*6881a400Schristos      until we get an absolute path.  */
178*6881a400Schristos   std::string file_file_name (const file_entry &fe) const;
179*6881a400Schristos 
180*6881a400Schristos   /* Return the compilation directory of the compilation unit in the context of
181*6881a400Schristos      which this line header is read.  Return nullptr if non applicable.  */
182*6881a400Schristos   const char *comp_dir () const
183*6881a400Schristos   { return m_comp_dir; }
1847d62b00eSchristos 
1857d62b00eSchristos  private:
1867d62b00eSchristos   /* The include_directories table.  Note these are observing
1877d62b00eSchristos      pointers.  The memory is owned by debug_line_buffer.  */
1887d62b00eSchristos   std::vector<const char *> m_include_dirs;
1897d62b00eSchristos 
1907d62b00eSchristos   /* The file_names table. This is private because the meaning of indexes
1917d62b00eSchristos      differs among DWARF versions (The first valid index is 1 in DWARF 4 and
1927d62b00eSchristos      before, and is 0 in DWARF 5 and later).  So the client should use
1937d62b00eSchristos      file_name_at method for access.  */
1947d62b00eSchristos   std::vector<file_entry> m_file_names;
195*6881a400Schristos 
196*6881a400Schristos   /* Compilation directory of the compilation unit in the context of which this
197*6881a400Schristos      line header is read.  nullptr if unknown or not applicable.  */
198*6881a400Schristos   const char *m_comp_dir = nullptr;
1997d62b00eSchristos };
2007d62b00eSchristos 
2017d62b00eSchristos typedef std::unique_ptr<line_header> line_header_up;
2027d62b00eSchristos 
2037d62b00eSchristos inline const char *
2047d62b00eSchristos file_entry::include_dir (const line_header *lh) const
2057d62b00eSchristos {
2067d62b00eSchristos   return lh->include_dir_at (d_index);
2077d62b00eSchristos }
2087d62b00eSchristos 
2097d62b00eSchristos /* Read the statement program header starting at SECT_OFF in SECTION.
2107d62b00eSchristos    Return line_header.  Returns nullptr if there is a problem reading
2117d62b00eSchristos    the header, e.g., if it has a version we don't understand.
2127d62b00eSchristos 
2137d62b00eSchristos    NOTE: the strings in the include directory and file name tables of
2147d62b00eSchristos    the returned object point into the dwarf line section buffer,
2157d62b00eSchristos    and must not be freed.  */
2167d62b00eSchristos 
2177d62b00eSchristos extern line_header_up dwarf_decode_line_header
2187d62b00eSchristos   (sect_offset sect_off, bool is_dwz, dwarf2_per_objfile *per_objfile,
219*6881a400Schristos    struct dwarf2_section_info *section, const struct comp_unit_head *cu_header,
220*6881a400Schristos    const char *comp_dir);
2217d62b00eSchristos 
2227d62b00eSchristos #endif /* DWARF2_LINE_HEADER_H */
223