From patchwork Thu Jan 23 00:56:59 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Tromey X-Patchwork-Id: 37505 Received: (qmail 83175 invoked by alias); 23 Jan 2020 00:57:56 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 81159 invoked by uid 89); 23 Jan 2020 00:57:40 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-21.2 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_PASS autolearn=ham version=3.3.1 spammy= X-HELO: gateway30.websitewelcome.com Received: from gateway30.websitewelcome.com (HELO gateway30.websitewelcome.com) (192.185.198.26) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 23 Jan 2020 00:57:27 +0000 Received: from cm16.websitewelcome.com (cm16.websitewelcome.com [100.42.49.19]) by gateway30.websitewelcome.com (Postfix) with ESMTP id 4F14D3EC7 for ; Wed, 22 Jan 2020 18:57:26 -0600 (CST) Received: from box5379.bluehost.com ([162.241.216.53]) by cmsmtp with SMTP id uQoIiPjts32AduQoIiZGP9; Wed, 22 Jan 2020 18:57:26 -0600 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=tromey.com; s=default; h=References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Sender:Reply-To:MIME-Version:Content-Type:Content-Transfer-Encoding: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=x4mWZXvxvKEPlfBQeKEfrRyzV0MhvfzBrWbUTFECHk0=; b=HZPFt+F2UslYexSvLBg8jmK+93 ZxDiKEEUF0tQGqcN8xVQQVZn8bxbHmYuJbU6diAoXpLa2aGH4C6wSYE5ggHSJpEkRMFrjHb+rpptN BUHIV+x0+7U3thYE188A/ca5M; Received: from 75-166-123-50.hlrn.qwest.net ([75.166.123.50]:40828 helo=bapiya.Home) by box5379.bluehost.com with esmtpa (Exim 4.92) (envelope-from ) id 1iuQoI-004Kmd-3e; Wed, 22 Jan 2020 17:57:26 -0700 From: Tom Tromey To: gdb-patches@sourceware.org Cc: Tom Tromey Subject: [PATCH 27/38] Move DWARF line_header to new file Date: Wed, 22 Jan 2020 17:56:59 -0700 Message-Id: <20200123005710.7978-28-tom@tromey.com> In-Reply-To: <20200123005710.7978-1-tom@tromey.com> References: <20200123005710.7978-1-tom@tromey.com> This moves the line_header class to a pair of new files, making dwarf2/read.c somewhat smaller. 2020-01-22 Tom Tromey * dwarf2/read.h (dwarf_line_debug): Declare. * Makefile.in (COMMON_SFILES): Add dwarf2/line-header.c. * dwarf2/read.c: Move line_header code to new files. (dwarf_line_debug): No longer static. * dwarf2/line-header.c: New file. * dwarf2/line-header.h: New file. Change-Id: I8d9d8a2398b4e888e20cc5dd68d041c28b5a06e3 --- gdb/ChangeLog | 9 ++ gdb/Makefile.in | 1 + gdb/dwarf2/line-header.c | 114 +++++++++++++++++ gdb/dwarf2/line-header.h | 188 +++++++++++++++++++++++++++++ gdb/dwarf2/read.c | 255 +-------------------------------------- gdb/dwarf2/read.h | 3 + 6 files changed, 317 insertions(+), 253 deletions(-) create mode 100644 gdb/dwarf2/line-header.c create mode 100644 gdb/dwarf2/line-header.h diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 37c5d250ff0..e4c2ebf968d 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -1003,6 +1003,7 @@ COMMON_SFILES = \ dwarf2/index-common.c \ dwarf2/index-write.c \ dwarf2/leb.c \ + dwarf2/line-header.c \ dwarf2/loc.c \ dwarf2/read.c \ dwarf2/section.c \ diff --git a/gdb/dwarf2/line-header.c b/gdb/dwarf2/line-header.c new file mode 100644 index 00000000000..56dfb5c2dd2 --- /dev/null +++ b/gdb/dwarf2/line-header.c @@ -0,0 +1,114 @@ +/* DWARF 2 debugging format support for GDB. + + Copyright (C) 1994-2020 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 . */ + +#include "defs.h" +#include "dwarf2/line-header.h" +#include "dwarf2/read.h" +#include "complaints.h" +#include "filenames.h" + +void +line_header::add_include_dir (const char *include_dir) +{ + if (dwarf_line_debug >= 2) + { + size_t new_size; + if (version >= 5) + new_size = m_include_dirs.size (); + else + new_size = m_include_dirs.size () + 1; + fprintf_unfiltered (gdb_stdlog, "Adding dir %zu: %s\n", + new_size, include_dir); + } + m_include_dirs.push_back (include_dir); +} + +void +line_header::add_file_name (const char *name, + dir_index d_index, + unsigned int mod_time, + unsigned int length) +{ + if (dwarf_line_debug >= 2) + { + size_t new_size; + if (version >= 5) + new_size = file_names_size (); + else + new_size = file_names_size () + 1; + fprintf_unfiltered (gdb_stdlog, "Adding file %zu: %s\n", + new_size, name); + } + m_file_names.emplace_back (name, d_index, mod_time, length); +} + +gdb::unique_xmalloc_ptr +line_header::file_file_name (int file) +{ + /* Is the file number a valid index into the line header's file name + table? Remember that file numbers start with one, not zero. */ + if (is_valid_file_index (file)) + { + const file_entry *fe = file_name_at (file); + + if (!IS_ABSOLUTE_PATH (fe->name)) + { + const char *dir = fe->include_dir (this); + if (dir != NULL) + return gdb::unique_xmalloc_ptr (concat (dir, SLASH_STRING, + fe->name, + (char *) NULL)); + } + return make_unique_xstrdup (fe->name); + } + else + { + /* The compiler produced a bogus file number. We can at least + record the macro definitions made in the file, even if we + won't be able to find the file by name. */ + char fake_name[80]; + + xsnprintf (fake_name, sizeof (fake_name), + "", file); + + complaint (_("bad file number in macro information (%d)"), + file); + + return make_unique_xstrdup (fake_name); + } +} + +gdb::unique_xmalloc_ptr +line_header::file_full_name (int file, const char *comp_dir) +{ + /* Is the file number a valid index into the line header's file name + table? Remember that file numbers start with one, not zero. */ + if (is_valid_file_index (file)) + { + gdb::unique_xmalloc_ptr relative = file_file_name (file); + + if (IS_ABSOLUTE_PATH (relative.get ()) || comp_dir == NULL) + return relative; + return gdb::unique_xmalloc_ptr (concat (comp_dir, SLASH_STRING, + relative.get (), + (char *) NULL)); + } + else + return file_file_name (file); +} diff --git a/gdb/dwarf2/line-header.h b/gdb/dwarf2/line-header.h new file mode 100644 index 00000000000..08cf7b0810f --- /dev/null +++ b/gdb/dwarf2/line-header.h @@ -0,0 +1,188 @@ +/* DWARF 2 debugging format support for GDB. + + Copyright (C) 1994-2020 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 . */ + +#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) + { + 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]; + } + + /* 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_names () + { 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 standard_opcode_lengths; + + int file_names_size () + { 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 the full name of file number I in this object's file name + table. Use COMP_DIR as the name of the current directory of the + compilation. The result is allocated using xmalloc; the caller + is responsible for freeing it. */ + gdb::unique_xmalloc_ptr file_full_name (int file, + const char *comp_dir); + + /* 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 file_file_name (int file); + + private: + /* The include_directories table. Note these are observing + pointers. The memory is owned by debug_line_buffer. */ + std::vector 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 m_file_names; +}; + +typedef std::unique_ptr line_header_up; + +inline const char * +file_entry::include_dir (const line_header *lh) const +{ + return lh->include_dir_at (d_index); +} + +#endif /* DWARF2_LINE_HEADER_H */ diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index b33f505362f..6a9a1a95012 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -35,6 +35,7 @@ #include "dwarf2/index-cache.h" #include "dwarf2/index-common.h" #include "dwarf2/leb.h" +#include "dwarf2/line-header.h" #include "bfd.h" #include "elf-bfd.h" #include "symtab.h" @@ -90,7 +91,7 @@ static unsigned int dwarf_read_debug = 0; static unsigned int dwarf_die_debug = 0; /* When non-zero, dump line number entries as they are read in. */ -static unsigned int dwarf_line_debug = 0; +unsigned int dwarf_line_debug = 0; /* When true, cross-check physname against demangler. */ static bool check_physname = false; @@ -946,167 +947,6 @@ private: abbrev_table_up m_dwo_abbrev_table; }; -/* 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 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) - { - 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]; - } - - /* 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_names () - { 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 standard_opcode_lengths; - - int file_names_size () - { 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 the full name of file number I in this object's file name - table. Use COMP_DIR as the name of the current directory of the - compilation. The result is allocated using xmalloc; the caller - is responsible for freeing it. */ - gdb::unique_xmalloc_ptr file_full_name (int file, - const char *comp_dir); - - /* 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 file_file_name (int file); - - private: - /* The include_directories table. Note these are observing - pointers. The memory is owned by debug_line_buffer. */ - std::vector 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 m_file_names; -}; - -typedef std::unique_ptr line_header_up; - -const char * -file_entry::include_dir (const line_header *lh) const -{ - return lh->include_dir_at (d_index); -} - /* When we construct a partial symbol table entry we only need this much information. */ struct partial_die_info : public allocate_on_obstack @@ -19895,41 +19735,6 @@ free_line_header_voidp (void *arg) delete lh; } -void -line_header::add_include_dir (const char *include_dir) -{ - if (dwarf_line_debug >= 2) - { - size_t new_size; - if (version >= 5) - new_size = m_include_dirs.size (); - else - new_size = m_include_dirs.size () + 1; - fprintf_unfiltered (gdb_stdlog, "Adding dir %zu: %s\n", - new_size, include_dir); - } - m_include_dirs.push_back (include_dir); -} - -void -line_header::add_file_name (const char *name, - dir_index d_index, - unsigned int mod_time, - unsigned int length) -{ - if (dwarf_line_debug >= 2) - { - size_t new_size; - if (version >= 5) - new_size = file_names_size (); - else - new_size = file_names_size () + 1; - fprintf_unfiltered (gdb_stdlog, "Adding file %zu: %s\n", - new_size, name); - } - m_file_names.emplace_back (name, d_index, mod_time, length); -} - /* A convenience function to find the proper .debug_line section for a CU. */ static struct dwarf2_section_info * @@ -23799,62 +23604,6 @@ dwarf_alloc_die (struct dwarf2_cu *cu, int num_attrs) /* Macro support. */ -gdb::unique_xmalloc_ptr -line_header::file_file_name (int file) -{ - /* Is the file number a valid index into the line header's file name - table? Remember that file numbers start with one, not zero. */ - if (is_valid_file_index (file)) - { - const file_entry *fe = file_name_at (file); - - if (!IS_ABSOLUTE_PATH (fe->name)) - { - const char *dir = fe->include_dir (this); - if (dir != NULL) - return gdb::unique_xmalloc_ptr (concat (dir, SLASH_STRING, - fe->name, - (char *) NULL)); - } - return make_unique_xstrdup (fe->name); - } - else - { - /* The compiler produced a bogus file number. We can at least - record the macro definitions made in the file, even if we - won't be able to find the file by name. */ - char fake_name[80]; - - xsnprintf (fake_name, sizeof (fake_name), - "", file); - - complaint (_("bad file number in macro information (%d)"), - file); - - return make_unique_xstrdup (fake_name); - } -} - -gdb::unique_xmalloc_ptr -line_header::file_full_name (int file, const char *comp_dir) -{ - /* Is the file number a valid index into the line header's file name - table? Remember that file numbers start with one, not zero. */ - if (is_valid_file_index (file)) - { - gdb::unique_xmalloc_ptr relative = file_file_name (file); - - if (IS_ABSOLUTE_PATH (relative.get ()) || comp_dir == NULL) - return relative; - return gdb::unique_xmalloc_ptr (concat (comp_dir, SLASH_STRING, - relative.get (), - (char *) NULL)); - } - else - return file_file_name (file); -} - - static struct macro_source_file * macro_start_file (struct dwarf2_cu *cu, int file, int line, diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h index b9d185d691c..9eab657e14a 100644 --- a/gdb/dwarf2/read.h +++ b/gdb/dwarf2/read.h @@ -452,4 +452,7 @@ struct dwz_file extern struct dwz_file *dwarf2_get_dwz_file (struct dwarf2_per_objfile *dwarf2_per_objfile); +/* When non-zero, dump line number entries as they are read in. */ +extern unsigned int dwarf_line_debug; + #endif /* DWARF2READ_H */