| /* DWARF 2 debugging format support for GDB. |
| |
| Copyright (C) 1994-2021 Free Software Foundation, Inc. |
| |
| This file is part of GDB. |
| |
| This program is free software; you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by |
| the Free Software Foundation; either version 3 of the License, or |
| (at your option) any later version. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
| |
| #ifndef DWARF2_LINE_HEADER_H |
| #define DWARF2_LINE_HEADER_H |
| |
| #include "gdbtypes.h" |
| |
| /* dir_index is 1-based in DWARF 4 and before, and is 0-based in DWARF 5 and |
| later. */ |
| typedef int dir_index; |
| |
| /* file_name_index is 1-based in DWARF 4 and before, and is 0-based in DWARF 5 |
| and later. */ |
| typedef int file_name_index; |
| |
| struct line_header; |
| |
| struct file_entry |
| { |
| file_entry () = default; |
| |
| file_entry (const char *name_, dir_index d_index_, |
| unsigned int mod_time_, unsigned int length_) |
| : name (name_), |
| d_index (d_index_), |
| mod_time (mod_time_), |
| length (length_) |
| {} |
| |
| /* Return the include directory at D_INDEX stored in LH. Returns |
| NULL if D_INDEX is out of bounds. */ |
| const char *include_dir (const line_header *lh) const; |
| |
| /* The file name. Note this is an observing pointer. The memory is |
| owned by debug_line_buffer. */ |
| const char *name {}; |
| |
| /* The directory index (1-based). */ |
| dir_index d_index {}; |
| |
| unsigned int mod_time {}; |
| |
| unsigned int length {}; |
| |
| /* True if referenced by the Line Number Program. */ |
| bool included_p {}; |
| |
| /* The associated symbol table, if any. */ |
| struct symtab *symtab {}; |
| }; |
| |
| /* The line number information for a compilation unit (found in the |
| .debug_line section) begins with a "statement program header", |
| which contains the following information. */ |
| struct line_header |
| { |
| line_header () |
| : offset_in_dwz {} |
| {} |
| |
| /* Add an entry to the include directory table. */ |
| void add_include_dir (const char *include_dir); |
| |
| /* Add an entry to the file name table. */ |
| void add_file_name (const char *name, dir_index d_index, |
| unsigned int mod_time, unsigned int length); |
| |
| /* Return the include dir at INDEX (0-based in DWARF 5 and 1-based before). |
| Returns NULL if INDEX is out of bounds. */ |
| const char *include_dir_at (dir_index index) const |
| { |
| int vec_index; |
| if (version >= 5) |
| vec_index = index; |
| else |
| vec_index = index - 1; |
| if (vec_index < 0 || vec_index >= m_include_dirs.size ()) |
| return NULL; |
| return m_include_dirs[vec_index]; |
| } |
| |
| bool is_valid_file_index (int file_index) const |
| { |
| if (version >= 5) |
| return 0 <= file_index && file_index < file_names_size (); |
| return 1 <= file_index && file_index <= file_names_size (); |
| } |
| |
| /* Return the file name at INDEX (0-based in DWARF 5 and 1-based before). |
| Returns NULL if INDEX is out of bounds. */ |
| file_entry *file_name_at (file_name_index index) |
| { |
| int vec_index; |
| if (version >= 5) |
| vec_index = index; |
| else |
| vec_index = index - 1; |
| if (vec_index < 0 || vec_index >= m_file_names.size ()) |
| return NULL; |
| return &m_file_names[vec_index]; |
| } |
| |
| /* A const overload of the same. */ |
| const file_entry *file_name_at (file_name_index index) const |
| { |
| line_header *lh = const_cast<line_header *> (this); |
| return lh->file_name_at (index); |
| } |
| |
| /* The indexes are 0-based in DWARF 5 and 1-based in DWARF 4. Therefore, |
| this method should only be used to iterate through all file entries in an |
| index-agnostic manner. */ |
| std::vector<file_entry> &file_names () |
| { return m_file_names; } |
| /* A const overload of the same. */ |
| const std::vector<file_entry> &file_names () const |
| { return m_file_names; } |
| |
| /* Offset of line number information in .debug_line section. */ |
| sect_offset sect_off {}; |
| |
| /* OFFSET is for struct dwz_file associated with dwarf2_per_objfile. */ |
| unsigned offset_in_dwz : 1; /* Can't initialize bitfields in-class. */ |
| |
| unsigned int total_length {}; |
| unsigned short version {}; |
| unsigned int header_length {}; |
| unsigned char minimum_instruction_length {}; |
| unsigned char maximum_ops_per_instruction {}; |
| unsigned char default_is_stmt {}; |
| int line_base {}; |
| unsigned char line_range {}; |
| unsigned char opcode_base {}; |
| |
| /* standard_opcode_lengths[i] is the number of operands for the |
| standard opcode whose value is i. This means that |
| standard_opcode_lengths[0] is unused, and the last meaningful |
| element is standard_opcode_lengths[opcode_base - 1]. */ |
| std::unique_ptr<unsigned char[]> standard_opcode_lengths; |
| |
| int file_names_size () const |
| { return m_file_names.size(); } |
| |
| /* The start and end of the statement program following this |
| header. These point into dwarf2_per_objfile->line_buffer. */ |
| const gdb_byte *statement_program_start {}, *statement_program_end {}; |
| |
| /* Return file name relative to the compilation directory of file |
| number I in this object's file name table. The result is |
| allocated using xmalloc; the caller is responsible for freeing |
| it. */ |
| gdb::unique_xmalloc_ptr<char> file_file_name (int file) const; |
| |
| private: |
| /* The include_directories table. Note these are observing |
| pointers. The memory is owned by debug_line_buffer. */ |
| std::vector<const char *> m_include_dirs; |
| |
| /* The file_names table. This is private because the meaning of indexes |
| differs among DWARF versions (The first valid index is 1 in DWARF 4 and |
| before, and is 0 in DWARF 5 and later). So the client should use |
| file_name_at method for access. */ |
| std::vector<file_entry> m_file_names; |
| }; |
| |
| typedef std::unique_ptr<line_header> line_header_up; |
| |
| inline const char * |
| file_entry::include_dir (const line_header *lh) const |
| { |
| return lh->include_dir_at (d_index); |
| } |
| |
| /* Read the statement program header starting at SECT_OFF in SECTION. |
| Return line_header. Returns nullptr if there is a problem reading |
| the header, e.g., if it has a version we don't understand. |
| |
| NOTE: the strings in the include directory and file name tables of |
| the returned object point into the dwarf line section buffer, |
| and must not be freed. */ |
| |
| extern line_header_up dwarf_decode_line_header |
| (sect_offset sect_off, bool is_dwz, dwarf2_per_objfile *per_objfile, |
| struct dwarf2_section_info *section, const struct comp_unit_head *cu_header); |
| |
| #endif /* DWARF2_LINE_HEADER_H */ |