From patchwork Tue Aug 27 23:41:58 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Terekhov, Mikhail via Gdb-patches" X-Patchwork-Id: 34290 Received: (qmail 72252 invoked by alias); 27 Aug 2019 23:42:07 -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 72184 invoked by uid 89); 27 Aug 2019 23:42:06 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-22.9 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=qfn X-HELO: mail-qk1-f202.google.com Received: from mail-qk1-f202.google.com (HELO mail-qk1-f202.google.com) (209.85.222.202) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 27 Aug 2019 23:42:03 +0000 Received: by mail-qk1-f202.google.com with SMTP id q62so748291qkd.3 for ; Tue, 27 Aug 2019 16:42:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:message-id:mime-version:subject:from:to:cc; bh=sO8LMlD/QeB7+TJCLQJDJ1MM/npUD9IHV1V68vMz+OM=; b=uolqPdE08q6yIDl407OQTiu83txVfw8mPHqtIJgV1RjJSaBQCCsjh5TrgtcpAAuh1V 1Vww+SriRsAAbo+GTo91P5w0tks73AmOx20GY6z+7Q1VrTTQ1+E+m0uVcQ7jpGJoI2Jr rQvSwtdA2Dfu8/uHCKAwhyYEoRrAkdSxV+feSA486XaJc0S/WSU5/pdSWgBlKN6V8UV6 sOJgoU/ciWcVXUU2SySyOMBAwCrxpKY00nr/+5j2LvkYw1dFkppZe5W3CUO03MesqGIs 7P577776xfkK95Txjhpjh5ZQ/bIcYBNJDbDT3c83i71CTSdbo+kUya5UUmFlV/itEzDo YfGg== Date: Tue, 27 Aug 2019 16:41:58 -0700 Message-Id: <20190827234158.245283-1-tamur@google.com> Mime-Version: 1.0 Subject: [PATCH 3/4] Increasing support for dwarf 5. X-Patchwork-Original-From: "Ali Tamur via gdb-patches" From: "Terekhov, Mikhail via Gdb-patches" Reply-To: Ali Tamur To: gdb-patches@sourceware.org Cc: Ali Tamur X-IsSubscribed: yes * Line table header has new fields. * Fix handling of file and directory indexes in line tables; in dwarf 5 the indexes are zero-based. gdb/ChangeLog: 2019-08-26 Ali Tamur * gdb/dwarf2read.c (dir_index): Change definition and update comment. (file_name_index): Likewise. (line_header::include_dir_at): Allow for zero based indexes for dwarf 5. (line_header::file_name_at): Likewise. (line_header::file_names): Make the field private to abstract the fact that dwarf 4 and 5 use different index bases. (line_header::file_names_size): New method to let the clients use instead of accessing file_names directly. (line_header::first_file_index): Likewise. (file_full_name): Add parameter, is_zero_indexed. The file indexes in the line table is 1-based in dwarf 4, and 0 based in dwarf 5. (dw2_get_file_names_reader): Initialize variable, use added methods to access file names in the line table. (dwarf2_cu::setup_type_unit_groups): Use added methods to access file and directory names in line table. (process_structure_scope): Use added methods to access file names at the line table. (line_header::add_file_name): Reflect API change. (dwarf_decode_line_header): Fix statement_program boundry calculations. (psymtab_include_file_name): Reflect API changes. (lnp_state_machine::current_file): Likewise. (lnp_state_machine::record_line): Likewise. (lnp_state_machine::lnp_state_machine): Initialize m_file. (dwarf_decode_lines): Reflect API changes. (new_symbol): Likewise. (is_valid_file_index): New function. (file_file_name): Add parameter, is_zero_indexed. (file_full_name): Likewise. --- gdb/dwarf2read.c | 161 +++++++++++++++++++++++++++-------------------- 1 file changed, 93 insertions(+), 68 deletions(-) diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index b04993e9b6..73ec371af1 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -919,13 +919,13 @@ typedef void (die_reader_func_ftype) (const struct die_reader_specs *reader, int has_children, void *data); -/* A 1-based directory index. This is a strong typedef to prevent - accidentally using a directory index as a 0-based index into an - array/vector. */ -enum class dir_index : unsigned int {}; +/* dir_index is 1-based in dwarf 4 and before, and is 0-based in dwarf5 and + later. */ +typedef int dir_index; -/* Likewise, a 1-based file name index. */ -enum class file_name_index : unsigned int {}; +/* file_name_index is 1-based in dwarf 4 and before, and is 0-based in dwarf5 + and later. */ +typedef int file_name_index; struct file_entry { @@ -977,26 +977,30 @@ struct line_header void add_file_name (const char *name, dir_index d_index, unsigned int mod_time, unsigned int length); - /* Return the include dir at INDEX (1-based). Returns NULL if INDEX - is out of bounds. */ + /* Return the include dir at INDEX (0-based in dwarf5 and 1-based before). + Returns NULL if INDEX is out of bounds. */ const char *include_dir_at (dir_index index) const { - /* Convert directory index number (1-based) to vector index - (0-based). */ - size_t vec_index = to_underlying (index) - 1; + size_t vec_index; + if (version <= 4) + vec_index = index - 1; + else + vec_index = index; if (vec_index >= include_dirs.size ()) return NULL; return include_dirs[vec_index]; } - /* Return the file name at INDEX (1-based). Returns NULL if INDEX - is out of bounds. */ - file_entry *file_name_at (file_name_index index) + /* Return the file name at INDEX (0-based in dwarf5 and 1-based before). + Returns NULL if INDEX is out of bounds. */ + file_entry *file_name_at (file_name_index index, bool is_zero_indexed) { - /* Convert file name index number (1-based) to vector index - (0-based). */ - size_t vec_index = to_underlying (index) - 1; + size_t vec_index; + if (is_zero_indexed || version >= 5) + vec_index = index; + else + vec_index = index - 1; if (vec_index >= file_names.size ()) return NULL; @@ -1029,12 +1033,24 @@ struct line_header pointers. The memory is owned by debug_line_buffer. */ std::vector include_dirs; - /* The file_names table. */ - std::vector file_names; + int file_names_size() { + return file_names.size(); + } + + int first_file_index() { + return version >= 5 ? 0 : 1; + } /* 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 {}; + + private: + /* The file_names table. This is private because the meaning of indexes differ + 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_names; }; typedef std::unique_ptr line_header_up; @@ -1957,7 +1973,7 @@ static file_and_directory find_file_and_directory (struct die_info *die, struct dwarf2_cu *cu); static char *file_full_name (int file, struct line_header *lh, - const char *comp_dir); + const char *comp_dir, bool is_zero_indexed); /* Expected enum dwarf_unit_type for read_comp_unit_head. */ enum class rcuh_kind { COMPILE, TYPE }; @@ -3633,7 +3649,7 @@ dw2_get_file_names_reader (const struct die_reader_specs *reader, struct objfile *objfile = dwarf2_per_objfile->objfile; struct dwarf2_per_cu_data *lh_cu; struct attribute *attr; - int i; + int i = 0; void **slot; struct quick_file_names *qfn; @@ -3688,11 +3704,11 @@ dw2_get_file_names_reader (const struct die_reader_specs *reader, file_and_directory fnd = find_file_and_directory (comp_unit_die, cu); - qfn->num_file_names = lh->file_names.size (); + qfn->num_file_names = lh->file_names_size (); qfn->file_names = - XOBNEWVEC (&objfile->objfile_obstack, const char *, lh->file_names.size ()); - for (i = 0; i < lh->file_names.size (); ++i) - qfn->file_names[i] = file_full_name (i + 1, lh.get (), fnd.comp_dir); + XOBNEWVEC (&objfile->objfile_obstack, const char *, lh->file_names_size ()); + for (i = 0; i < lh->file_names_size (); ++i) + qfn->file_names[i] = file_full_name (i, lh.get (), fnd.comp_dir, true); qfn->real_names = NULL; lh_cu->v.quick->file_names = qfn; @@ -11648,16 +11664,16 @@ dwarf2_cu::setup_type_unit_groups (struct die_info *die) process_full_type_unit still needs to know if this is the first time. */ - tu_group->num_symtabs = line_header->file_names.size (); + tu_group->num_symtabs = line_header->file_names_size (); tu_group->symtabs = XNEWVEC (struct symtab *, - line_header->file_names.size ()); + line_header->file_names_size ()); - for (i = 0; i < line_header->file_names.size (); ++i) + for (i = 0; i < line_header->file_names_size (); ++i) { - file_entry &fe = line_header->file_names[i]; + file_entry *fe = line_header->file_name_at(i, true); - dwarf2_start_subfile (this, fe.name, - fe.include_dir (line_header)); + dwarf2_start_subfile (this, fe->name, + fe->include_dir (line_header)); buildsym_compunit *b = get_builder (); if (b->get_current_subfile ()->symtab == NULL) { @@ -11670,8 +11686,8 @@ dwarf2_cu::setup_type_unit_groups (struct die_info *die) = allocate_symtab (cust, b->get_current_subfile ()->name); } - fe.symtab = b->get_current_subfile ()->symtab; - tu_group->symtabs[i] = fe.symtab; + fe->symtab = b->get_current_subfile ()->symtab; + tu_group->symtabs[i] = fe->symtab; } } else @@ -11684,11 +11700,10 @@ dwarf2_cu::setup_type_unit_groups (struct die_info *die) compunit_language (cust), 0, cust)); - for (i = 0; i < line_header->file_names.size (); ++i) + for (i = 0; i < line_header->file_names_size (); ++i) { - file_entry &fe = line_header->file_names[i]; - - fe.symtab = tu_group->symtabs[i]; + file_entry *fe = line_header->file_name_at(i, true); + fe->symtab = tu_group->symtabs[i]; } } @@ -16161,7 +16176,7 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) { /* Any related symtab will do. */ symtab - = cu->line_header->file_name_at (file_name_index (1))->symtab; + = cu->line_header->file_name_at (0, true)->symtab; } else { @@ -20224,7 +20239,7 @@ line_header::add_file_name (const char *name, { if (dwarf_line_debug >= 2) fprintf_unfiltered (gdb_stdlog, "Adding file %u: %s\n", - (unsigned) file_names.size () + 1, name); + (unsigned) file_names_size () + 1, name); file_names.emplace_back (name, d_index, mod_time, length); } @@ -20440,12 +20455,15 @@ dwarf_decode_line_header (sect_offset sect_off, struct dwarf2_cu *cu) read_checked_initial_length_and_offset (abfd, line_ptr, &cu->header, &bytes_read, &offset_size); line_ptr += bytes_read; + + const gdb_byte *start_here = line_ptr; + if (line_ptr + lh->total_length > (section->buffer + section->size)) { dwarf2_statement_list_fits_in_line_number_section_complaint (); return 0; } - lh->statement_program_end = line_ptr + lh->total_length; + lh->statement_program_end = start_here + lh->total_length; lh->version = read_2_bytes (abfd, line_ptr); line_ptr += 2; if (lh->version > 5) @@ -20475,6 +20493,7 @@ dwarf_decode_line_header (sect_offset sect_off, struct dwarf2_cu *cu) } lh->header_length = read_offset_1 (abfd, line_ptr, offset_size); line_ptr += offset_size; + lh->statement_program_start = line_ptr + lh->header_length; lh->minimum_instruction_length = read_1_byte (abfd, line_ptr); line_ptr += 1; if (lh->version >= 4) @@ -20559,7 +20578,6 @@ dwarf_decode_line_header (sect_offset sect_off, struct dwarf2_cu *cu) } line_ptr += bytes_read; } - lh->statement_program_start = line_ptr; if (line_ptr > (section->buffer + section->size)) complaint (_("line number info header doesn't " @@ -20576,18 +20594,18 @@ dwarf_decode_line_header (sect_offset sect_off, struct dwarf2_cu *cu) Returns NULL if FILE_INDEX should be ignored, i.e., it is pst->filename. */ static const char * -psymtab_include_file_name (const struct line_header *lh, int file_index, +psymtab_include_file_name (struct line_header *lh, int file_index, const struct partial_symtab *pst, const char *comp_dir, gdb::unique_xmalloc_ptr *name_holder) { - const file_entry &fe = lh->file_names[file_index]; - const char *include_name = fe.name; + file_entry *fe = lh->file_name_at(file_index, true); + const char *include_name = fe->name; const char *include_name_to_compare = include_name; const char *pst_filename; int file_is_pst; - const char *dir_name = fe.include_dir (lh); + const char *dir_name = fe->include_dir (lh); gdb::unique_xmalloc_ptr hold_compare; if (!IS_ABSOLUTE_PATH (include_name) @@ -20659,7 +20677,7 @@ public: { /* lh->file_names is 0-based, but the file name numbers in the statement program are 1-based. */ - return m_line_header->file_name_at (m_file); + return m_line_header->file_name_at (m_file, false); } /* Record the line in the state machine. END_SEQUENCE is true if @@ -20756,12 +20774,11 @@ private: and initialized according to the DWARF spec. */ unsigned char m_op_index = 0; - /* The line table index (1-based) of the current file. */ - file_name_index m_file = (file_name_index) 1; unsigned int m_line = 1; /* These are initialized in the constructor. */ + file_name_index m_file; CORE_ADDR m_address; bool m_is_stmt; unsigned int m_discriminator; @@ -20949,7 +20966,7 @@ lnp_state_machine::record_line (bool end_sequence) fprintf_unfiltered (gdb_stdlog, "Processing actual line %u: file %u," " address %s, is_stmt %u, discrim %u\n", - m_line, to_underlying (m_file), + m_line, m_file, paddress (m_gdbarch, m_address), m_is_stmt, m_discriminator); } @@ -20999,6 +21016,7 @@ lnp_state_machine::lnp_state_machine (struct dwarf2_cu *cu, gdbarch *arch, m_gdbarch = arch; m_record_lines_p = record_lines_p; m_line_header = lh; + m_file = m_line_header->first_file_index(); m_currently_recording_lines = true; @@ -21292,8 +21310,8 @@ dwarf_decode_lines (struct line_header *lh, const char *comp_dir, /* Now that we're done scanning the Line Header Program, we can create the psymtab of each included file. */ - for (file_index = 0; file_index < lh->file_names.size (); file_index++) - if (lh->file_names[file_index].included_p == 1) + for (file_index = 0; file_index < lh->file_names_size (); file_index++) + if (lh->file_name_at(file_index, true)->included_p == 1) { gdb::unique_xmalloc_ptr name_holder; const char *include_name = @@ -21312,11 +21330,11 @@ dwarf_decode_lines (struct line_header *lh, const char *comp_dir, struct compunit_symtab *cust = builder->get_compunit_symtab (); int i; - for (i = 0; i < lh->file_names.size (); i++) + for (i = 0; i < lh->file_names_size (); i++) { - file_entry &fe = lh->file_names[i]; + file_entry *fe = lh->file_name_at(i, true); - dwarf2_start_subfile (cu, fe.name, fe.include_dir (lh)); + dwarf2_start_subfile (cu, fe->name, fe->include_dir (lh)); if (builder->get_current_subfile ()->symtab == NULL) { @@ -21324,7 +21342,7 @@ dwarf_decode_lines (struct line_header *lh, const char *comp_dir, = allocate_symtab (cust, builder->get_current_subfile ()->name); } - fe.symtab = builder->get_current_subfile ()->symtab; + fe->symtab = builder->get_current_subfile ()->symtab; } } } @@ -21543,7 +21561,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu, struct file_entry *fe; if (cu->line_header != NULL) - fe = cu->line_header->file_name_at (file_index); + fe = cu->line_header->file_name_at (file_index, false); else fe = NULL; @@ -24074,22 +24092,28 @@ dwarf_alloc_die (struct dwarf2_cu *cu, int num_attrs) *LH's file name table. The result is allocated using xmalloc; the caller is responsible for freeing it. */ +bool is_valid_file_index(int file_index, struct line_header *lh, bool is_zero_indexed) { + if (is_zero_indexed || lh->version >= 5) + return 0 <= file_index && file_index < lh->file_names_size (); + return 1 <= file_index && file_index <= lh->file_names_size (); +} + static char * -file_file_name (int file, struct line_header *lh) +file_file_name (int file, struct line_header *lh, bool is_zero_indexed) { /* 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 (1 <= file && file <= lh->file_names.size ()) + if (is_valid_file_index(file, lh, is_zero_indexed)) { - const file_entry &fe = lh->file_names[file - 1]; + const file_entry *fe = lh->file_name_at(file, is_zero_indexed); - if (!IS_ABSOLUTE_PATH (fe.name)) + if (!IS_ABSOLUTE_PATH (fe->name)) { - const char *dir = fe.include_dir (lh); + const char *dir = fe->include_dir (lh); if (dir != NULL) - return concat (dir, SLASH_STRING, fe.name, (char *) NULL); + return concat (dir, SLASH_STRING, fe->name, (char *) NULL); } - return xstrdup (fe.name); + return xstrdup (fe->name); } else { @@ -24113,13 +24137,14 @@ file_file_name (int file, struct line_header *lh) compilation. The result is allocated using xmalloc; the caller is responsible for freeing it. */ static char * -file_full_name (int file, struct line_header *lh, const char *comp_dir) +file_full_name (int file, struct line_header *lh, const char *comp_dir, + bool is_zero_indexed) { /* 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 (1 <= file && file <= lh->file_names.size ()) + if (is_valid_file_index(file, lh, is_zero_indexed)) { - char *relative = file_file_name (file, lh); + char *relative = file_file_name (file, lh, is_zero_indexed); if (IS_ABSOLUTE_PATH (relative) || comp_dir == NULL) return relative; @@ -24127,7 +24152,7 @@ file_full_name (int file, struct line_header *lh, const char *comp_dir) relative, (char *) NULL); } else - return file_file_name (file, lh); + return file_file_name (file, lh, is_zero_indexed); } @@ -24138,7 +24163,7 @@ macro_start_file (struct dwarf2_cu *cu, struct line_header *lh) { /* File name relative to the compilation directory of this source file. */ - char *file_name = file_file_name (file, lh); + char *file_name = file_file_name (file, lh, false); if (! current_file) {