From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 128038 invoked by alias); 29 Mar 2017 02:25:08 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 126471 invoked by uid 89); 29 Mar 2017 02:25:05 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,RP_MATCHES_RCVD,SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=felt, mistakes, Processing, motivated X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 29 Mar 2017 02:25:02 +0000 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 2541461D07 for ; Wed, 29 Mar 2017 02:25:02 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 2541461D07 Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=palves@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 2541461D07 Received: from cascais.lan (ovpn04.gateway.prod.ext.phx2.redhat.com [10.5.9.4]) by smtp.corp.redhat.com (Postfix) with ESMTP id 8358E7FBCC for ; Wed, 29 Mar 2017 02:25:01 +0000 (UTC) From: Pedro Alves To: gdb-patches@sourceware.org Subject: [PATCH 3/5] dwarf2read.c: Make dir_index and file_name_index strong typedefs Date: Wed, 29 Mar 2017 02:25:00 -0000 Message-Id: <1490754298-9455-4-git-send-email-palves@redhat.com> In-Reply-To: <1490754298-9455-1-git-send-email-palves@redhat.com> References: <1490754298-9455-1-git-send-email-palves@redhat.com> X-SW-Source: 2017-03/txt/msg00497.txt.bz2 This should help catch mistakes related to mixing the 1-based DWARF indexes with 0-based std::vector indexes, since the new types do not implicitly convert to anything. The change in read_formatted_entries relates to the fact that doing the seemingly simpler: - uintp = &fe.dir_index; + uintp = (unsigned int *) &fe.dir_index; would be undefined C/C++. So to address that, I made the function extract the form before assigning to the file_entry. It felt natural to use gdb::optional for "do I have this value", and this is what motivated the previous patch that added the missing observer methods to gdb::optional. gdb/ChangeLog: yyyy-mm-dd Pedro Alves * common/underlying.h: New file. * dwarf2read.c: Include "common/gdb_optional.h" and "common/underlying.h". (dir_index, file_name_index): New types. (file_entry): Use them. (file_entry::include): Use to_underlying. (line_header::add_file_name): Use dir_index. (read_formatted_entries): Use gdb::optional. Read form before writting to file_entry. (dwarf_decode_line_header): Use dir_index. (lnp_state_machine::current_file): Use to_underlying. (lnp_state_machine::file): Change type to file_name_index. (dwarf_record_line): Use to_underlying. (init_lnp_state_machine): Use file_name_index. (dwarf_decode_lines_1): Use dir_index and file_name_index. --- gdb/common/underlying.h | 32 +++++++++++ gdb/dwarf2read.c | 141 +++++++++++++++++++++++++++--------------------- 2 files changed, 112 insertions(+), 61 deletions(-) create mode 100644 gdb/common/underlying.h diff --git a/gdb/common/underlying.h b/gdb/common/underlying.h new file mode 100644 index 0000000..41ff117 --- /dev/null +++ b/gdb/common/underlying.h @@ -0,0 +1,32 @@ +/* Copyright (C) 2017 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 COMMON_UNDERLYING_H +#define COMMON_UNDERLYING_H + +#include + +/* Convert an enum to its underlying value. */ + +template +constexpr typename std::underlying_type::type +to_underlying (E val) noexcept +{ + return static_cast::type> (val); +} + +#endif diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index e54e818..fddec86 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -71,6 +71,8 @@ #include "namespace.h" #include "common/gdb_unlinker.h" #include "common/function-view.h" +#include "common/gdb_optional.h" +#include "common/underlying.h" #include #include @@ -1052,20 +1054,28 @@ 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 {}; + +/* Likewise, a 1-based file name index. */ +enum class file_name_index : unsigned int {}; + struct file_entry { file_entry () = default; - file_entry (const char *name_, unsigned int dir_index_, + file_entry (const char *name_, dir_index d_index_, unsigned int mod_time_, unsigned int length_) : name (name_), - dir_index (dir_index_), + d_index (d_index_), mod_time (mod_time_), length (length_) {} - /* Return the include directory at DIR_INDEX stored in LH. Returns - NULL if DIR_INDEX is out of bounds. */ + /* 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 @@ -1073,7 +1083,7 @@ struct file_entry const char *name {}; /* The directory index (1-based). */ - unsigned int dir_index {}; + dir_index d_index {}; unsigned int mod_time {}; @@ -1099,7 +1109,7 @@ struct line_header void add_include_dir (const char *include_dir); /* Add an entry to the file name table. */ - void add_file_name (const char *name, unsigned int dir_index, + 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). Returns NULL if INDEX @@ -1169,7 +1179,7 @@ file_entry::include_dir (const line_header *lh) const { /* lh->include_dirs is 0-based, but the directory index numbers in the statement program are 1-based. */ - return lh->include_dir_at (dir_index - 1); + return lh->include_dir_at (to_underlying (d_index) - 1); } /* When we construct a partial symbol table entry we only @@ -17603,7 +17613,7 @@ line_header::add_include_dir (const char *include_dir) void line_header::add_file_name (const char *name, - unsigned int dir_index, + dir_index d_index, unsigned int mod_time, unsigned int length) { @@ -17611,7 +17621,7 @@ line_header::add_file_name (const char *name, fprintf_unfiltered (gdb_stdlog, "Adding file %u: %s\n", (unsigned) file_names.size () + 1, name); - file_names.emplace_back (name, dir_index, mod_time, length); + file_names.emplace_back (name, d_index, mod_time, length); } /* A convenience function to find the proper .debug_line section for a CU. */ @@ -17648,7 +17658,7 @@ read_formatted_entries (bfd *abfd, const gdb_byte **bufp, const struct comp_unit_head *cu_header, void (*callback) (struct line_header *lh, const char *name, - unsigned int dir_index, + dir_index d_index, unsigned int mod_time, unsigned int length)) { @@ -17679,71 +17689,51 @@ read_formatted_entries (bfd *abfd, const gdb_byte **bufp, for (formati = 0; formati < format_count; formati++) { - ULONGEST content_type, form; - const char *string_trash; - const char **stringp = &string_trash; - unsigned int uint_trash, *uintp = &uint_trash; - - content_type = read_unsigned_leb128 (abfd, format, &bytes_read); + ULONGEST content_type = read_unsigned_leb128 (abfd, format, &bytes_read); format += bytes_read; - switch (content_type) - { - case DW_LNCT_path: - stringp = &fe.name; - break; - case DW_LNCT_directory_index: - uintp = &fe.dir_index; - break; - case DW_LNCT_timestamp: - uintp = &fe.mod_time; - break; - case DW_LNCT_size: - uintp = &fe.length; - break; - case DW_LNCT_MD5: - break; - default: - complaint (&symfile_complaints, - _("Unknown format content type %s"), - pulongest (content_type)); - } - form = read_unsigned_leb128 (abfd, format, &bytes_read); + ULONGEST form = read_unsigned_leb128 (abfd, format, &bytes_read); format += bytes_read; + + gdb::optional string; + gdb::optional uint; + switch (form) { case DW_FORM_string: - *stringp = read_direct_string (abfd, buf, &bytes_read); + string.emplace (read_direct_string (abfd, buf, &bytes_read)); buf += bytes_read; break; case DW_FORM_line_strp: - *stringp = read_indirect_line_string (abfd, buf, cu_header, &bytes_read); + string.emplace (read_indirect_line_string (abfd, buf, + cu_header, + &bytes_read)); buf += bytes_read; break; case DW_FORM_data1: - *uintp = read_1_byte (abfd, buf); + uint.emplace (read_1_byte (abfd, buf)); buf += 1; break; case DW_FORM_data2: - *uintp = read_2_bytes (abfd, buf); + uint.emplace (read_2_bytes (abfd, buf)); buf += 2; break; case DW_FORM_data4: - *uintp = read_4_bytes (abfd, buf); + uint.emplace (read_4_bytes (abfd, buf)); buf += 4; break; case DW_FORM_data8: - *uintp = read_8_bytes (abfd, buf); + uint.emplace (read_8_bytes (abfd, buf)); buf += 8; break; case DW_FORM_udata: - *uintp = read_unsigned_leb128 (abfd, buf, &bytes_read); + uint.emplace (read_unsigned_leb128 (abfd, buf, &bytes_read)); buf += bytes_read; break; @@ -17752,9 +17742,35 @@ read_formatted_entries (bfd *abfd, const gdb_byte **bufp, current GDB. */ break; } + + switch (content_type) + { + case DW_LNCT_path: + if (string.has_value ()) + fe.name = *string; + break; + case DW_LNCT_directory_index: + if (uint.has_value ()) + fe.d_index = (dir_index) *uint; + break; + case DW_LNCT_timestamp: + if (uint.has_value ()) + fe.mod_time = *uint; + break; + case DW_LNCT_size: + if (uint.has_value ()) + fe.length = *uint; + break; + case DW_LNCT_MD5: + break; + default: + complaint (&symfile_complaints, + _("Unknown format content type %s"), + pulongest (content_type)); + } } - callback (lh, fe.name, fe.dir_index, fe.mod_time, fe.length); + callback (lh, fe.name, fe.d_index, fe.mod_time, fe.length); } *bufp = buf; @@ -17892,7 +17908,7 @@ dwarf_decode_line_header (unsigned int offset, struct dwarf2_cu *cu) /* Read directory table. */ read_formatted_entries (abfd, &line_ptr, lh.get (), &cu->header, [] (struct line_header *lh, const char *name, - unsigned int dir_index, unsigned int mod_time, + dir_index d_index, unsigned int mod_time, unsigned int length) { lh->add_include_dir (name); @@ -17901,10 +17917,10 @@ dwarf_decode_line_header (unsigned int offset, struct dwarf2_cu *cu) /* Read file name table. */ read_formatted_entries (abfd, &line_ptr, lh.get (), &cu->header, [] (struct line_header *lh, const char *name, - unsigned int dir_index, unsigned int mod_time, + dir_index d_index, unsigned int mod_time, unsigned int length) { - lh->add_file_name (name, dir_index, mod_time, length); + lh->add_file_name (name, d_index, mod_time, length); }); } else @@ -17920,17 +17936,18 @@ dwarf_decode_line_header (unsigned int offset, struct dwarf2_cu *cu) /* Read file name table. */ while ((cur_file = read_direct_string (abfd, line_ptr, &bytes_read)) != NULL) { - unsigned int dir_index, mod_time, length; + unsigned int mod_time, length; + dir_index d_index; line_ptr += bytes_read; - dir_index = read_unsigned_leb128 (abfd, line_ptr, &bytes_read); + d_index = (dir_index) read_unsigned_leb128 (abfd, line_ptr, &bytes_read); line_ptr += bytes_read; mod_time = read_unsigned_leb128 (abfd, line_ptr, &bytes_read); line_ptr += bytes_read; length = read_unsigned_leb128 (abfd, line_ptr, &bytes_read); line_ptr += bytes_read; - lh->add_file_name (cur_file, dir_index, mod_time, length); + lh->add_file_name (cur_file, d_index, mod_time, length); } line_ptr += bytes_read; } @@ -18036,7 +18053,7 @@ struct lnp_state_machine { /* lh->file_names is 0-based, but the file name numbers in the statement program are 1-based. */ - return the_line_header->file_name_at (file - 1); + return the_line_header->file_name_at (to_underlying (file) - 1); } /* The line number header. */ @@ -18046,7 +18063,7 @@ struct lnp_state_machine unsigned char op_index; /* The line table index (1-based) of the current file. */ - unsigned int file; + file_name_index file; unsigned int line; CORE_ADDR address; int is_stmt; @@ -18206,7 +18223,7 @@ dwarf_record_line (lnp_reader_state *reader, lnp_state_machine *state, fprintf_unfiltered (gdb_stdlog, "Processing actual line %u: file %u," " address %s, is_stmt %u, discrim %u\n", - line, state->file, + line, to_underlying (state->file), paddress (reader->gdbarch, state->address), is_stmt, discriminator); } @@ -18265,7 +18282,7 @@ init_lnp_state_machine (lnp_state_machine *state, /* Initialize these according to the DWARF spec. */ state->op_index = 0; - state->file = 1; + state->file = (file_name_index) 1; state->line = 1; /* Call `gdbarch_adjust_dwarf2_line' on the initial 0 address as if there was a line entry for it so that the backend has a chance to adjust it @@ -18423,12 +18440,13 @@ dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu, case DW_LNE_define_file: { const char *cur_file; - unsigned int dir_index, mod_time, length; + unsigned int mod_time, length; + dir_index dindex; cur_file = read_direct_string (abfd, line_ptr, &bytes_read); line_ptr += bytes_read; - dir_index = + dindex = (dir_index) read_unsigned_leb128 (abfd, line_ptr, &bytes_read); line_ptr += bytes_read; mod_time = @@ -18437,7 +18455,7 @@ dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu, length = read_unsigned_leb128 (abfd, line_ptr, &bytes_read); line_ptr += bytes_read; - lh->add_file_name (cur_file, dir_index, mod_time, length); + lh->add_file_name (cur_file, dindex, mod_time, length); } break; case DW_LNE_set_discriminator: @@ -18501,8 +18519,9 @@ dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu, break; case DW_LNS_set_file: { - state_machine.file = read_unsigned_leb128 (abfd, line_ptr, - &bytes_read); + state_machine.file + = (file_name_index) read_unsigned_leb128 (abfd, line_ptr, + &bytes_read); line_ptr += bytes_read; const file_entry *fe = state_machine.current_file (); -- 2.5.5