* [PATCH 00/22] More splitting of dwarf2/read.c
@ 2020-03-22 18:45 Tom Tromey
2020-03-22 18:45 ` [PATCH 01/22] Introduce dwarf2/dwz.h Tom Tromey
` (22 more replies)
0 siblings, 23 replies; 32+ messages in thread
From: Tom Tromey @ 2020-03-22 18:45 UTC (permalink / raw)
To: gdb-patches
One goal of mine is to split up the DWARF reader code into many
smaller, more self-contained files. I think this will make the code
easier to read and to work on; and also let us tease out (and repair)
hidden dependencies. This latter part is desirable because, in the
longer run, I'd like to parallelize DWARF reading.
So, here is round 2 of splitting.
The main change here is that the macro-reading code is moved to its
own file. It's almost possible, after this, to scan macros in a
worker thread. (However, dwz file handling, and the recent move to
sharing a bcache, interfere with this.)
Some smaller utility functions are also moved into other files as
well.
Let me know what you think,
Tom
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 01/22] Introduce dwarf2/dwz.h
2020-03-22 18:45 [PATCH 00/22] More splitting of dwarf2/read.c Tom Tromey
@ 2020-03-22 18:45 ` Tom Tromey
2020-03-22 18:45 ` [PATCH 02/22] Add dwz.c and dwz_file::read_string Tom Tromey
` (21 subsequent siblings)
22 siblings, 0 replies; 32+ messages in thread
From: Tom Tromey @ 2020-03-22 18:45 UTC (permalink / raw)
To: gdb-patches; +Cc: Tom Tromey
This moves "struct dwz_file" to a new header file, dwarf2/dwz.h.
gdb/ChangeLog
2020-03-22 Tom Tromey <tom@tromey.com>
* dwarf2/read.h (struct dwz_file): Move to dwz.h.
* dwarf2/read.c: Add include.
* dwarf2/index-write.c: Add include.
* dwarf2/index-cache.c: Add include.
* dwarf2/dwz.h: New file.
---
gdb/ChangeLog | 8 ++++++
gdb/dwarf2/dwz.h | 58 ++++++++++++++++++++++++++++++++++++++++
gdb/dwarf2/index-cache.c | 1 +
gdb/dwarf2/index-write.c | 1 +
gdb/dwarf2/read.c | 1 +
gdb/dwarf2/read.h | 31 ---------------------
6 files changed, 69 insertions(+), 31 deletions(-)
create mode 100644 gdb/dwarf2/dwz.h
diff --git a/gdb/dwarf2/dwz.h b/gdb/dwarf2/dwz.h
new file mode 100644
index 00000000000..94b84ebf3d9
--- /dev/null
+++ b/gdb/dwarf2/dwz.h
@@ -0,0 +1,58 @@
+/* DWARF DWZ handling for GDB.
+
+ Copyright (C) 2003-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 <http://www.gnu.org/licenses/>. */
+
+#ifndef GDB_DWARF2_DWZ_H
+#define GDB_DWARF2_DWZ_H
+
+#include "gdb_bfd.h"
+#include "dwarf2/index-cache.h"
+#include "dwarf2/section.h"
+
+/* This represents a '.dwz' file. */
+
+struct dwz_file
+{
+ dwz_file (gdb_bfd_ref_ptr &&bfd)
+ : dwz_bfd (std::move (bfd))
+ {
+ }
+
+ const char *filename () const
+ {
+ return bfd_get_filename (this->dwz_bfd.get ());
+ }
+
+ /* A dwz file can only contain a few sections. */
+ struct dwarf2_section_info abbrev {};
+ struct dwarf2_section_info info {};
+ struct dwarf2_section_info str {};
+ struct dwarf2_section_info line {};
+ struct dwarf2_section_info macro {};
+ struct dwarf2_section_info gdb_index {};
+ struct dwarf2_section_info debug_names {};
+
+ /* The dwz's BFD. */
+ gdb_bfd_ref_ptr dwz_bfd;
+
+ /* If we loaded the index from an external file, this contains the
+ resources associated to the open file, memory mapping, etc. */
+ std::unique_ptr<index_cache_resource> index_cache_res;
+};
+
+#endif /* GDB_DWARF2_DWZ_H */
diff --git a/gdb/dwarf2/index-cache.c b/gdb/dwarf2/index-cache.c
index 7b4d9975905..62fbe2a0b4d 100644
--- a/gdb/dwarf2/index-cache.c
+++ b/gdb/dwarf2/index-cache.c
@@ -27,6 +27,7 @@
#include "gdbsupport/pathstuff.h"
#include "dwarf2/index-write.h"
#include "dwarf2/read.h"
+#include "dwarf2/dwz.h"
#include "objfiles.h"
#include "gdbsupport/selftest.h"
#include <string>
diff --git a/gdb/dwarf2/index-write.c b/gdb/dwarf2/index-write.c
index 4b711d0d29a..8c933dc63b7 100644
--- a/gdb/dwarf2/index-write.c
+++ b/gdb/dwarf2/index-write.c
@@ -32,6 +32,7 @@
#include "dwarf2/index-common.h"
#include "dwarf2.h"
#include "dwarf2/read.h"
+#include "dwarf2/dwz.h"
#include "gdb/gdb-index.h"
#include "gdbcmd.h"
#include "objfiles.h"
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 0e879e08a0c..57ef2428c02 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -37,6 +37,7 @@
#include "dwarf2/index-common.h"
#include "dwarf2/leb.h"
#include "dwarf2/line-header.h"
+#include "dwarf2/dwz.h"
#include "bfd.h"
#include "elf-bfd.h"
#include "symtab.h"
diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h
index f0e3d6bb723..c5a8ecf8a6a 100644
--- a/gdb/dwarf2/read.h
+++ b/gdb/dwarf2/read.h
@@ -491,37 +491,6 @@ struct signatured_type
struct dwo_unit *dwo_unit;
};
-/* This represents a '.dwz' file. */
-
-struct dwz_file
-{
- dwz_file (gdb_bfd_ref_ptr &&bfd)
- : dwz_bfd (std::move (bfd))
- {
- }
-
- const char *filename () const
- {
- return bfd_get_filename (this->dwz_bfd.get ());
- }
-
- /* A dwz file can only contain a few sections. */
- struct dwarf2_section_info abbrev {};
- struct dwarf2_section_info info {};
- struct dwarf2_section_info str {};
- struct dwarf2_section_info line {};
- struct dwarf2_section_info macro {};
- struct dwarf2_section_info gdb_index {};
- struct dwarf2_section_info debug_names {};
-
- /* The dwz's BFD. */
- gdb_bfd_ref_ptr dwz_bfd;
-
- /* If we loaded the index from an external file, this contains the
- resources associated to the open file, memory mapping, etc. */
- std::unique_ptr<index_cache_resource> index_cache_res;
-};
-
/* Open the separate '.dwz' debug file, if needed. Return NULL if
there is no .gnu_debugaltlink section in the file. Error if there
is such a section but the file cannot be found. */
--
2.17.2
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 02/22] Add dwz.c and dwz_file::read_string
2020-03-22 18:45 [PATCH 00/22] More splitting of dwarf2/read.c Tom Tromey
2020-03-22 18:45 ` [PATCH 01/22] Introduce dwarf2/dwz.h Tom Tromey
@ 2020-03-22 18:45 ` Tom Tromey
2020-03-22 18:45 ` [PATCH 03/22] Change dwarf_decode_macro_bytes calling convention Tom Tromey
` (20 subsequent siblings)
22 siblings, 0 replies; 32+ messages in thread
From: Tom Tromey @ 2020-03-22 18:45 UTC (permalink / raw)
To: gdb-patches; +Cc: Tom Tromey
This changes read_indirect_string_from_dwz to be a method on the
dwz_file, and adds a new dwarf2/dwz.c file.
gdb/ChangeLog
2020-03-22 Tom Tromey <tom@tromey.com>
* dwarf2/read.c (read_attribute_value): Update.
(read_indirect_string_from_dwz): Move to dwz.c; change into
method.
(dwarf_decode_macro_bytes): Update.
* dwarf2/dwz.h (struct dwz_file) <read_string>: Declare method.
* dwarf2/dwz.c: New file.
* Makefile.in (COMMON_SFILES): Add dwz.c.
---
gdb/ChangeLog | 10 ++++++++++
gdb/Makefile.in | 1 +
gdb/dwarf2/dwz.c | 40 ++++++++++++++++++++++++++++++++++++++++
gdb/dwarf2/dwz.h | 7 +++++++
gdb/dwarf2/read.c | 34 ++--------------------------------
5 files changed, 60 insertions(+), 32 deletions(-)
create mode 100644 gdb/dwarf2/dwz.c
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 0c331af4bff..c9450ce7b52 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -1003,6 +1003,7 @@ COMMON_SFILES = \
dwarf2/abbrev.c \
dwarf2/attribute.c \
dwarf2/comp-unit.c \
+ dwarf2/dwz.c \
dwarf2/expr.c \
dwarf2/frame-tailcall.c \
dwarf2/frame.c \
diff --git a/gdb/dwarf2/dwz.c b/gdb/dwarf2/dwz.c
new file mode 100644
index 00000000000..a7143738194
--- /dev/null
+++ b/gdb/dwarf2/dwz.c
@@ -0,0 +1,40 @@
+/* DWARF DWZ handling for GDB.
+
+ Copyright (C) 2003-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 <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "dwarf2/dwz.h"
+
+const char *
+dwz_file::read_string (struct objfile *objfile, LONGEST str_offset)
+{
+ str.read (objfile);
+
+ if (str.buffer == NULL)
+ error (_("DW_FORM_GNU_strp_alt used without .debug_str "
+ "section [in module %s]"),
+ bfd_get_filename (dwz_bfd.get ()));
+ if (str_offset >= str.size)
+ error (_("DW_FORM_GNU_strp_alt pointing outside of "
+ ".debug_str section [in module %s]"),
+ bfd_get_filename (dwz_bfd.get ()));
+ gdb_assert (HOST_CHAR_BIT == 8);
+ if (str.buffer[str_offset] == '\0')
+ return NULL;
+ return (const char *) (str.buffer + str_offset);
+}
diff --git a/gdb/dwarf2/dwz.h b/gdb/dwarf2/dwz.h
index 94b84ebf3d9..54e60612a3f 100644
--- a/gdb/dwarf2/dwz.h
+++ b/gdb/dwarf2/dwz.h
@@ -53,6 +53,13 @@ struct dwz_file
/* If we loaded the index from an external file, this contains the
resources associated to the open file, memory mapping, etc. */
std::unique_ptr<index_cache_resource> index_cache_res;
+
+ /* Read a string at offset STR_OFFSET in the .debug_str section from
+ this dwz file. Throw an error if the offset is too large. If
+ the string consists of a single NUL byte, return NULL; otherwise
+ return a pointer to the string. */
+
+ const char *read_string (struct objfile *objfile, LONGEST str_offset);
};
#endif /* GDB_DWARF2_DWZ_H */
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 57ef2428c02..23b3fab1be5 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -1259,9 +1259,6 @@ static const char *read_indirect_string_at_offset
(struct dwarf2_per_objfile *dwarf2_per_objfile, bfd *abfd,
LONGEST str_offset);
-static const char *read_indirect_string_from_dwz
- (struct objfile *objfile, struct dwz_file *, LONGEST);
-
static CORE_ADDR read_addr_index_from_leb128 (struct dwarf2_cu *,
const gdb_byte *,
unsigned int *);
@@ -18585,8 +18582,7 @@ read_attribute_value (const struct die_reader_specs *reader,
LONGEST str_offset = cu_header->read_offset (abfd, info_ptr,
&bytes_read);
- DW_STRING (attr) = read_indirect_string_from_dwz (objfile,
- dwz, str_offset);
+ DW_STRING (attr) = dwz->read_string (objfile, str_offset);
DW_STRING_IS_CANONICAL (attr) = 0;
info_ptr += bytes_read;
}
@@ -18831,31 +18827,6 @@ read_indirect_line_string_at_offset (struct dwarf2_per_objfile *dwarf2_per_objfi
".debug_line_str");
}
-/* Read a string at offset STR_OFFSET in the .debug_str section from
- the .dwz file DWZ. Throw an error if the offset is too large. If
- the string consists of a single NUL byte, return NULL; otherwise
- return a pointer to the string. */
-
-static const char *
-read_indirect_string_from_dwz (struct objfile *objfile, struct dwz_file *dwz,
- LONGEST str_offset)
-{
- dwz->str.read (objfile);
-
- if (dwz->str.buffer == NULL)
- error (_("DW_FORM_GNU_strp_alt used without .debug_str "
- "section [in module %s]"),
- bfd_get_filename (dwz->dwz_bfd.get ()));
- if (str_offset >= dwz->str.size)
- error (_("DW_FORM_GNU_strp_alt pointing outside of "
- ".debug_str section [in module %s]"),
- bfd_get_filename (dwz->dwz_bfd.get ()));
- gdb_assert (HOST_CHAR_BIT == 8);
- if (dwz->str.buffer[str_offset] == '\0')
- return NULL;
- return (const char *) (dwz->str.buffer + str_offset);
-}
-
/* Return pointer to string at .debug_str offset as read from BUF.
BUF is assumed to be in a compilation unit described by CU_HEADER.
Return *BYTES_READ_PTR count of bytes read from BUF. */
@@ -23584,8 +23555,7 @@ dwarf_decode_macro_bytes (struct dwarf2_cu *cu,
struct dwz_file *dwz
= dwarf2_get_dwz_file (dwarf2_per_objfile);
- body = read_indirect_string_from_dwz (objfile,
- dwz, str_offset);
+ body = dwz->read_string (objfile, str_offset);
}
else
body = read_indirect_string_at_offset (dwarf2_per_objfile,
--
2.17.2
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 03/22] Change dwarf_decode_macro_bytes calling convention
2020-03-22 18:45 [PATCH 00/22] More splitting of dwarf2/read.c Tom Tromey
2020-03-22 18:45 ` [PATCH 01/22] Introduce dwarf2/dwz.h Tom Tromey
2020-03-22 18:45 ` [PATCH 02/22] Add dwz.c and dwz_file::read_string Tom Tromey
@ 2020-03-22 18:45 ` Tom Tromey
2020-03-22 18:45 ` [PATCH 04/22] Split dwarf_decode_macros into two overloads Tom Tromey
` (19 subsequent siblings)
22 siblings, 0 replies; 32+ messages in thread
From: Tom Tromey @ 2020-03-22 18:45 UTC (permalink / raw)
To: gdb-patches; +Cc: Tom Tromey
This changes dwarf_decode_macro_bytes to accept a buildsym_compunit
rather than a dwarf2_cu. This enables some subsequent changes; and
also makes the function accept a "more specific" parameter.
gdb/ChangeLog
2020-03-22 Tom Tromey <tom@tromey.com>
* dwarf2/read.c (macro_start_file): Change "cu" parameter to
"builder".
(dwarf_decode_macro_bytes): Likewise. Add dwarf2_per_objfile
parameter.
(dwarf_decode_macros): Update.
---
gdb/ChangeLog | 8 ++++++++
gdb/dwarf2/read.c | 23 +++++++++++++----------
2 files changed, 21 insertions(+), 10 deletions(-)
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 23b3fab1be5..1410dd48a2f 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -23090,7 +23090,7 @@ dwarf_alloc_die (struct dwarf2_cu *cu, int num_attrs)
/* Macro support. */
static struct macro_source_file *
-macro_start_file (struct dwarf2_cu *cu,
+macro_start_file (buildsym_compunit *builder,
int file, int line,
struct macro_source_file *current_file,
struct line_header *lh)
@@ -23102,7 +23102,7 @@ macro_start_file (struct dwarf2_cu *cu,
{
/* Note: We don't create a macro table for this compilation unit
at all until we actually get a filename. */
- struct macro_table *macro_table = cu->get_builder ()->get_macro_table ();
+ struct macro_table *macro_table = builder->get_macro_table ();
/* If we have no current file, then this must be the start_file
directive for the compilation unit's main source file. */
@@ -23463,7 +23463,8 @@ dwarf_parse_macro_header (const gdb_byte **opcode_definitions,
including DW_MACRO_import. */
static void
-dwarf_decode_macro_bytes (struct dwarf2_cu *cu,
+dwarf_decode_macro_bytes (struct dwarf2_per_objfile *dwarf2_per_objfile,
+ buildsym_compunit *builder,
bfd *abfd,
const gdb_byte *mac_ptr, const gdb_byte *mac_end,
struct macro_source_file *current_file,
@@ -23473,8 +23474,6 @@ dwarf_decode_macro_bytes (struct dwarf2_cu *cu,
unsigned int offset_size,
htab_t include_hash)
{
- struct dwarf2_per_objfile *dwarf2_per_objfile
- = cu->per_cu->dwarf2_per_objfile;
struct objfile *objfile = dwarf2_per_objfile->objfile;
enum dwarf_macro_record_type macinfo_type;
int at_commandline;
@@ -23631,8 +23630,8 @@ dwarf_decode_macro_bytes (struct dwarf2_cu *cu,
at_commandline = 0;
}
else
- current_file = macro_start_file (cu, file, line, current_file,
- lh);
+ current_file = macro_start_file (builder, file, line,
+ current_file, lh);
}
break;
@@ -23713,7 +23712,8 @@ dwarf_decode_macro_bytes (struct dwarf2_cu *cu,
{
*slot = (void *) new_mac_ptr;
- dwarf_decode_macro_bytes (cu, include_bfd, new_mac_ptr,
+ dwarf_decode_macro_bytes (dwarf2_per_objfile, builder,
+ include_bfd, new_mac_ptr,
include_mac_end, current_file, lh,
section, section_is_gnu, is_dwz,
offset_size, include_hash);
@@ -23827,6 +23827,7 @@ dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
return;
}
+ buildsym_compunit *builder = cu->get_builder ();
do
{
/* Do we at least have room for a macinfo type byte? */
@@ -23875,7 +23876,8 @@ dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
file = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
mac_ptr += bytes_read;
- current_file = macro_start_file (cu, file, line, current_file, lh);
+ current_file = macro_start_file (builder, file, line,
+ current_file, lh);
}
break;
@@ -23940,7 +23942,8 @@ dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
mac_ptr = section->buffer + offset;
slot = htab_find_slot (include_hash.get (), mac_ptr, INSERT);
*slot = (void *) mac_ptr;
- dwarf_decode_macro_bytes (cu, abfd, mac_ptr, mac_end,
+ dwarf_decode_macro_bytes (dwarf2_per_objfile, builder,
+ abfd, mac_ptr, mac_end,
current_file, lh, section,
section_is_gnu, 0, offset_size,
include_hash.get ());
--
2.17.2
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 04/22] Split dwarf_decode_macros into two overloads
2020-03-22 18:45 [PATCH 00/22] More splitting of dwarf2/read.c Tom Tromey
` (2 preceding siblings ...)
2020-03-22 18:45 ` [PATCH 03/22] Change dwarf_decode_macro_bytes calling convention Tom Tromey
@ 2020-03-22 18:45 ` Tom Tromey
2020-03-23 16:13 ` Christian Biesinger
2020-03-24 1:58 ` Simon Marchi
2020-03-22 18:45 ` [PATCH 05/22] Move dwarf2_section_buffer_overflow_complaint to dwarf2/section.c Tom Tromey
` (18 subsequent siblings)
22 siblings, 2 replies; 32+ messages in thread
From: Tom Tromey @ 2020-03-22 18:45 UTC (permalink / raw)
To: gdb-patches; +Cc: Tom Tromey
This splits dwarf_decode_macros into two overloads -- one that's
suitable for splitting into a separate file, and one that finds the
correct section and should remain in dwarf2/read.c.
gdb/ChangeLog
2020-03-22 Tom Tromey <tom@tromey.com>
* dwarf2/read.c (dwarf_decode_macros): Split into two overloads.
---
gdb/ChangeLog | 4 ++
gdb/dwarf2/read.c | 102 +++++++++++++++++++++++++++-------------------
2 files changed, 63 insertions(+), 43 deletions(-)
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 1410dd48a2f..2d126461c74 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -23753,56 +23753,18 @@ dwarf_decode_macro_bytes (struct dwarf2_per_objfile *dwarf2_per_objfile,
}
static void
-dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
- int section_is_gnu)
+dwarf_decode_macros (struct dwarf2_per_objfile *dwarf2_per_objfile,
+ buildsym_compunit *builder, dwarf2_section_info *section,
+ struct line_header *lh, unsigned int offset_size,
+ unsigned int offset, int section_is_gnu)
{
- struct dwarf2_per_objfile *dwarf2_per_objfile
- = cu->per_cu->dwarf2_per_objfile;
- struct objfile *objfile = dwarf2_per_objfile->objfile;
- struct line_header *lh = cu->line_header;
bfd *abfd;
const gdb_byte *mac_ptr, *mac_end;
struct macro_source_file *current_file = 0;
enum dwarf_macro_record_type macinfo_type;
- unsigned int offset_size = cu->header.offset_size;
const gdb_byte *opcode_definitions[256];
void **slot;
- struct dwarf2_section_info *section;
- const char *section_name;
- if (cu->dwo_unit != NULL)
- {
- if (section_is_gnu)
- {
- section = &cu->dwo_unit->dwo_file->sections.macro;
- section_name = ".debug_macro.dwo";
- }
- else
- {
- section = &cu->dwo_unit->dwo_file->sections.macinfo;
- section_name = ".debug_macinfo.dwo";
- }
- }
- else
- {
- if (section_is_gnu)
- {
- section = &dwarf2_per_objfile->macro;
- section_name = ".debug_macro";
- }
- else
- {
- section = &dwarf2_per_objfile->macinfo;
- section_name = ".debug_macinfo";
- }
- }
-
- section->read (objfile);
- if (section->buffer == NULL)
- {
- complaint (_("missing %s section"), section_name);
- return;
- }
abfd = section->get_bfd_owner ();
/* First pass: Find the name of the base filename.
@@ -23827,7 +23789,6 @@ dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
return;
}
- buildsym_compunit *builder = cu->get_builder ();
do
{
/* Do we at least have room for a macinfo type byte? */
@@ -23949,6 +23910,61 @@ dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
include_hash.get ());
}
+/* An overload of dwarf_decode_macros that finds the correct section
+ and ensures it is read in before calling the other overload. */
+
+static void
+dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
+ int section_is_gnu)
+{
+ struct dwarf2_per_objfile *dwarf2_per_objfile
+ = cu->per_cu->dwarf2_per_objfile;
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ struct line_header *lh = cu->line_header;
+ unsigned int offset_size = cu->header.offset_size;
+ struct dwarf2_section_info *section;
+ const char *section_name;
+
+ if (cu->dwo_unit != NULL)
+ {
+ if (section_is_gnu)
+ {
+ section = &cu->dwo_unit->dwo_file->sections.macro;
+ section_name = ".debug_macro.dwo";
+ }
+ else
+ {
+ section = &cu->dwo_unit->dwo_file->sections.macinfo;
+ section_name = ".debug_macinfo.dwo";
+ }
+ }
+ else
+ {
+ if (section_is_gnu)
+ {
+ section = &dwarf2_per_objfile->macro;
+ section_name = ".debug_macro";
+ }
+ else
+ {
+ section = &dwarf2_per_objfile->macinfo;
+ section_name = ".debug_macinfo";
+ }
+ }
+
+ section->read (objfile);
+ if (section->buffer == NULL)
+ {
+ complaint (_("missing %s section"), section_name);
+ return;
+ }
+
+ buildsym_compunit *builder = cu->get_builder ();
+
+ dwarf_decode_macros (dwarf2_per_objfile, builder, section, lh,
+ offset_size, offset, section_is_gnu);
+}
+
/* Return the .debug_loc section to use for CU.
For DWO files use .debug_loc.dwo. */
--
2.17.2
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 05/22] Move dwarf2_section_buffer_overflow_complaint to dwarf2/section.c
2020-03-22 18:45 [PATCH 00/22] More splitting of dwarf2/read.c Tom Tromey
` (3 preceding siblings ...)
2020-03-22 18:45 ` [PATCH 04/22] Split dwarf_decode_macros into two overloads Tom Tromey
@ 2020-03-22 18:45 ` Tom Tromey
2020-03-22 18:45 ` [PATCH 06/22] Convert dwarf2_section_buffer_overflow_complaint to a method Tom Tromey
` (17 subsequent siblings)
22 siblings, 0 replies; 32+ messages in thread
From: Tom Tromey @ 2020-03-22 18:45 UTC (permalink / raw)
To: gdb-patches; +Cc: Tom Tromey
This moves dwarf2_section_buffer_overflow_complaint to
dwarf2/section.c.
gdb/ChangeLog
2020-03-22 Tom Tromey <tom@tromey.com>
* dwarf2/section.h (dwarf2_section_buffer_overflow_complaint):
Declare.
* dwarf2/section.c (dwarf2_section_buffer_overflow_complaint):
Move from read.c.
* dwarf2/read.c (dwarf2_section_buffer_overflow_complaint): Move
to section.c.
---
gdb/ChangeLog | 9 +++++++++
gdb/dwarf2/read.c | 9 ---------
gdb/dwarf2/section.c | 10 ++++++++++
gdb/dwarf2/section.h | 3 +++
4 files changed, 22 insertions(+), 9 deletions(-)
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 2d126461c74..2b4f693c38a 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -1711,15 +1711,6 @@ dwarf2_const_value_length_mismatch_complaint (const char *arg1, int arg2,
arg1, arg2, arg3);
}
-static void
-dwarf2_section_buffer_overflow_complaint (struct dwarf2_section_info *section)
-{
- complaint (_("debug info runs off end of %s section"
- " [in module %s]"),
- section->get_name (),
- section->get_file_name ());
-}
-
static void
dwarf2_macro_malformed_definition_complaint (const char *arg1)
{
diff --git a/gdb/dwarf2/section.c b/gdb/dwarf2/section.c
index 5e33809117d..31cb8b9b2e7 100644
--- a/gdb/dwarf2/section.c
+++ b/gdb/dwarf2/section.c
@@ -28,6 +28,16 @@
#include "dwarf2/section.h"
#include "gdb_bfd.h"
#include "objfiles.h"
+#include "complaints.h"
+
+void
+dwarf2_section_buffer_overflow_complaint (struct dwarf2_section_info *section)
+{
+ complaint (_("debug info runs off end of %s section"
+ " [in module %s]"),
+ section->get_name (),
+ section->get_file_name ());
+}
struct dwarf2_section_info *
dwarf2_section_info::get_containing_section () const
diff --git a/gdb/dwarf2/section.h b/gdb/dwarf2/section.h
index 8ddedcaf761..f4ac9af311e 100644
--- a/gdb/dwarf2/section.h
+++ b/gdb/dwarf2/section.h
@@ -116,4 +116,7 @@ struct dwarf2_section_info
bool is_virtual;
};
+extern void dwarf2_section_buffer_overflow_complaint
+ (struct dwarf2_section_info *section);
+
#endif /* GDB_DWARF2_SECTION_H */
--
2.17.2
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 06/22] Convert dwarf2_section_buffer_overflow_complaint to a method
2020-03-22 18:45 [PATCH 00/22] More splitting of dwarf2/read.c Tom Tromey
` (4 preceding siblings ...)
2020-03-22 18:45 ` [PATCH 05/22] Move dwarf2_section_buffer_overflow_complaint to dwarf2/section.c Tom Tromey
@ 2020-03-22 18:45 ` Tom Tromey
2020-03-22 18:45 ` [PATCH 07/22] Add dwarf2_section_info::read_string method Tom Tromey
` (16 subsequent siblings)
22 siblings, 0 replies; 32+ messages in thread
From: Tom Tromey @ 2020-03-22 18:45 UTC (permalink / raw)
To: gdb-patches; +Cc: Tom Tromey
This changes dwarf2_section_buffer_overflow_complaint to be a method
on dwarf2_section_info.
gdb/ChangeLog
2020-03-22 Tom Tromey <tom@tromey.com>
* dwarf2/section.h (struct dwarf2_section_info)
<overload_complaint>: Declare.
(dwarf2_section_buffer_overflow_complaint): Don't declare.
* dwarf2/section.c (dwarf2_section_info::overflow_complaint):
Rename from dwarf2_section_buffer_overflow_complaint.
* dwarf2/read.c (skip_one_die, partial_die_info::read)
(skip_form_bytes, dwarf_decode_macro_bytes): Update.
---
gdb/ChangeLog | 10 ++++++++++
gdb/dwarf2/read.c | 10 +++++-----
gdb/dwarf2/section.c | 5 ++---
gdb/dwarf2/section.h | 7 ++++---
4 files changed, 21 insertions(+), 11 deletions(-)
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 2b4f693c38a..52a53428d5b 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -8595,7 +8595,7 @@ skip_one_die (const struct die_reader_specs *reader, const gdb_byte *info_ptr,
if (sibling_ptr < info_ptr)
complaint (_("DW_AT_sibling points backwards"));
else if (sibling_ptr > reader->buffer_end)
- dwarf2_section_buffer_overflow_complaint (reader->die_section);
+ reader->die_section->overflow_complaint ();
else
return sibling_ptr;
}
@@ -18079,7 +18079,7 @@ partial_die_info::read (const struct die_reader_specs *reader,
if (sibling_ptr < info_ptr)
complaint (_("DW_AT_sibling points backwards"));
else if (sibling_ptr > reader->buffer_end)
- dwarf2_section_buffer_overflow_complaint (reader->die_section);
+ reader->die_section->overflow_complaint ();
else
sibling = sibling_ptr;
}
@@ -23329,7 +23329,7 @@ skip_form_bytes (bfd *abfd, const gdb_byte *bytes, const gdb_byte *buffer_end,
bytes = gdb_skip_leb128 (bytes, buffer_end);
if (bytes == NULL)
{
- dwarf2_section_buffer_overflow_complaint (section);
+ section->overflow_complaint ();
return NULL;
}
break;
@@ -23492,7 +23492,7 @@ dwarf_decode_macro_bytes (struct dwarf2_per_objfile *dwarf2_per_objfile,
/* Do we at least have room for a macinfo type byte? */
if (mac_ptr >= mac_end)
{
- dwarf2_section_buffer_overflow_complaint (section);
+ section->overflow_complaint ();
break;
}
@@ -23645,7 +23645,7 @@ dwarf_decode_macro_bytes (struct dwarf2_per_objfile *dwarf2_per_objfile,
/* Do we at least have room for a macinfo type byte? */
if (mac_ptr >= mac_end)
{
- dwarf2_section_buffer_overflow_complaint (section);
+ section->overflow_complaint ();
return;
}
diff --git a/gdb/dwarf2/section.c b/gdb/dwarf2/section.c
index 31cb8b9b2e7..9714368a5d2 100644
--- a/gdb/dwarf2/section.c
+++ b/gdb/dwarf2/section.c
@@ -31,12 +31,11 @@
#include "complaints.h"
void
-dwarf2_section_buffer_overflow_complaint (struct dwarf2_section_info *section)
+dwarf2_section_info::overflow_complaint () const
{
complaint (_("debug info runs off end of %s section"
" [in module %s]"),
- section->get_name (),
- section->get_file_name ());
+ get_name (), get_file_name ());
}
struct dwarf2_section_info *
diff --git a/gdb/dwarf2/section.h b/gdb/dwarf2/section.h
index f4ac9af311e..555efecacd6 100644
--- a/gdb/dwarf2/section.h
+++ b/gdb/dwarf2/section.h
@@ -94,6 +94,10 @@ struct dwarf2_section_info
return size;
}
+ /* Issue a complaint that something was outside the bounds of this
+ buffer. */
+ void overflow_complaint () const;
+
union
{
/* If this is a real section, the bfd section. */
@@ -116,7 +120,4 @@ struct dwarf2_section_info
bool is_virtual;
};
-extern void dwarf2_section_buffer_overflow_complaint
- (struct dwarf2_section_info *section);
-
#endif /* GDB_DWARF2_SECTION_H */
--
2.17.2
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 07/22] Add dwarf2_section_info::read_string method
2020-03-22 18:45 [PATCH 00/22] More splitting of dwarf2/read.c Tom Tromey
` (5 preceding siblings ...)
2020-03-22 18:45 ` [PATCH 06/22] Convert dwarf2_section_buffer_overflow_complaint to a method Tom Tromey
@ 2020-03-22 18:45 ` Tom Tromey
2020-03-22 18:45 ` [PATCH 08/22] Move code to new file dwarf2/macro.c Tom Tromey
` (15 subsequent siblings)
22 siblings, 0 replies; 32+ messages in thread
From: Tom Tromey @ 2020-03-22 18:45 UTC (permalink / raw)
To: gdb-patches; +Cc: Tom Tromey
This moves a string-reading function to be a method on
dwarf2_section_info, and then updates the users.
gdb/ChangeLog
2020-03-22 Tom Tromey <tom@tromey.com>
* dwarf2/section.h (struct dwarf2_section_info) <read_string>: New
method.
* dwarf2/section.c: New method. From
read_indirect_string_at_offset_from.
* dwarf2/read.c (mapped_debug_names::namei_to_name): Update.
(read_indirect_string_at_offset_from): Move to section.c.
(read_indirect_string_at_offset): Rewrite.
(read_indirect_line_string_at_offset): Remove.
(read_indirect_string, read_indirect_line_string)
(dwarf_decode_macro_bytes): Update.
---
gdb/ChangeLog | 13 ++++++++++
gdb/dwarf2/read.c | 60 ++++++++------------------------------------
gdb/dwarf2/section.c | 17 +++++++++++++
gdb/dwarf2/section.h | 5 ++++
4 files changed, 46 insertions(+), 49 deletions(-)
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 52a53428d5b..75d028d95b1 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -1256,8 +1256,7 @@ static const char *read_indirect_line_string
const struct comp_unit_head *, unsigned int *);
static const char *read_indirect_string_at_offset
- (struct dwarf2_per_objfile *dwarf2_per_objfile, bfd *abfd,
- LONGEST str_offset);
+ (struct dwarf2_per_objfile *dwarf2_per_objfile, LONGEST str_offset);
static CORE_ADDR read_addr_index_from_leb128 (struct dwarf2_cu *,
const gdb_byte *,
@@ -5171,8 +5170,8 @@ mapped_debug_names::namei_to_name (uint32_t namei) const
+ namei * offset_size),
offset_size,
dwarf5_byte_order);
- return read_indirect_string_at_offset
- (dwarf2_per_objfile, dwarf2_per_objfile->objfile->obfd, namei_string_offs);
+ return read_indirect_string_at_offset (dwarf2_per_objfile,
+ namei_string_offs);
}
/* Find a slot in .debug_names for the object named NAME. If NAME is
@@ -18770,52 +18769,14 @@ read_checked_initial_length_and_offset (bfd *abfd, const gdb_byte *buf,
return length;
}
-/* Return pointer to string at section SECT offset STR_OFFSET with error
- reporting strings FORM_NAME and SECT_NAME. */
-
-static const char *
-read_indirect_string_at_offset_from (struct objfile *objfile,
- bfd *abfd, LONGEST str_offset,
- struct dwarf2_section_info *sect,
- const char *form_name,
- const char *sect_name)
-{
- sect->read (objfile);
- if (sect->buffer == NULL)
- error (_("%s used without %s section [in module %s]"),
- form_name, sect_name, bfd_get_filename (abfd));
- if (str_offset >= sect->size)
- error (_("%s pointing outside of %s section [in module %s]"),
- form_name, sect_name, bfd_get_filename (abfd));
- gdb_assert (HOST_CHAR_BIT == 8);
- if (sect->buffer[str_offset] == '\0')
- return NULL;
- return (const char *) (sect->buffer + str_offset);
-}
-
/* Return pointer to string at .debug_str offset STR_OFFSET. */
static const char *
read_indirect_string_at_offset (struct dwarf2_per_objfile *dwarf2_per_objfile,
- bfd *abfd, LONGEST str_offset)
-{
- return read_indirect_string_at_offset_from (dwarf2_per_objfile->objfile,
- abfd, str_offset,
- &dwarf2_per_objfile->str,
- "DW_FORM_strp", ".debug_str");
-}
-
-/* Return pointer to string at .debug_line_str offset STR_OFFSET. */
-
-static const char *
-read_indirect_line_string_at_offset (struct dwarf2_per_objfile *dwarf2_per_objfile,
- bfd *abfd, LONGEST str_offset)
+ LONGEST str_offset)
{
- return read_indirect_string_at_offset_from (dwarf2_per_objfile->objfile,
- abfd, str_offset,
- &dwarf2_per_objfile->line_str,
- "DW_FORM_line_strp",
- ".debug_line_str");
+ return dwarf2_per_objfile->str.read_string (dwarf2_per_objfile->objfile,
+ str_offset, "DW_FORM_strp");
}
/* Return pointer to string at .debug_str offset as read from BUF.
@@ -18830,7 +18791,7 @@ read_indirect_string (struct dwarf2_per_objfile *dwarf2_per_objfile, bfd *abfd,
{
LONGEST str_offset = cu_header->read_offset (abfd, buf, bytes_read_ptr);
- return read_indirect_string_at_offset (dwarf2_per_objfile, abfd, str_offset);
+ return read_indirect_string_at_offset (dwarf2_per_objfile, str_offset);
}
/* Return pointer to string at .debug_line_str offset as read from BUF.
@@ -18845,8 +18806,9 @@ read_indirect_line_string (struct dwarf2_per_objfile *dwarf2_per_objfile,
{
LONGEST str_offset = cu_header->read_offset (abfd, buf, bytes_read_ptr);
- return read_indirect_line_string_at_offset (dwarf2_per_objfile, abfd,
- str_offset);
+ return dwarf2_per_objfile->line_str.read_string (dwarf2_per_objfile->objfile,
+ str_offset,
+ "DW_FORM_line_strp");
}
/* Given index ADDR_INDEX in .debug_addr, fetch the value.
@@ -23549,7 +23511,7 @@ dwarf_decode_macro_bytes (struct dwarf2_per_objfile *dwarf2_per_objfile,
}
else
body = read_indirect_string_at_offset (dwarf2_per_objfile,
- abfd, str_offset);
+ str_offset);
}
is_define = (macinfo_type == DW_MACRO_define
diff --git a/gdb/dwarf2/section.c b/gdb/dwarf2/section.c
index 9714368a5d2..776617911a2 100644
--- a/gdb/dwarf2/section.c
+++ b/gdb/dwarf2/section.c
@@ -187,3 +187,20 @@ dwarf2_section_info::read (struct objfile *objfile)
bfd_section_name (sectp), bfd_get_filename (abfd));
}
}
+
+const char *
+dwarf2_section_info::read_string (struct objfile *objfile, LONGEST str_offset,
+ const char *form_name)
+{
+ read (objfile);
+ if (buffer == NULL)
+ error (_("%s used without %s section [in module %s]"),
+ form_name, get_name (), get_file_name ());
+ if (str_offset >= size)
+ error (_("%s pointing outside of %s section [in module %s]"),
+ form_name, get_name (), get_file_name ());
+ gdb_assert (HOST_CHAR_BIT == 8);
+ if (buffer[str_offset] == '\0')
+ return NULL;
+ return (const char *) (buffer + str_offset);
+}
diff --git a/gdb/dwarf2/section.h b/gdb/dwarf2/section.h
index 555efecacd6..02f42df78c6 100644
--- a/gdb/dwarf2/section.h
+++ b/gdb/dwarf2/section.h
@@ -98,6 +98,11 @@ struct dwarf2_section_info
buffer. */
void overflow_complaint () const;
+ /* Return pointer to string in this section at offset STR_OFFSET
+ with error reporting string FORM_NAME. */
+ const char *read_string (struct objfile *objfile, LONGEST str_offset,
+ const char *form_name);
+
union
{
/* If this is a real section, the bfd section. */
--
2.17.2
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 08/22] Move code to new file dwarf2/macro.c
2020-03-22 18:45 [PATCH 00/22] More splitting of dwarf2/read.c Tom Tromey
` (6 preceding siblings ...)
2020-03-22 18:45 ` [PATCH 07/22] Add dwarf2_section_info::read_string method Tom Tromey
@ 2020-03-22 18:45 ` Tom Tromey
2020-03-22 18:45 ` [PATCH 09/22] Make some line_header methods const Tom Tromey
` (14 subsequent siblings)
22 siblings, 0 replies; 32+ messages in thread
From: Tom Tromey @ 2020-03-22 18:45 UTC (permalink / raw)
To: gdb-patches; +Cc: Tom Tromey
This moves some more code out of dwarf2/read.c, introducing new files
dwarf2/macro.c and dwarf2/macro.h.
gdb/ChangeLog
2020-03-22 Tom Tromey <tom@tromey.com>
* dwarf2/read.c (dwarf2_macro_malformed_definition_complaint)
(macro_start_file, consume_improper_spaces)
(parse_macro_definition, skip_form_bytes, skip_unknown_opcode)
(dwarf_parse_macro_header, dwarf_decode_macro_bytes)
(dwarf_decode_macros): Move to macro.c.
* dwarf2/macro.c: New file.
* dwarf2/macro.h: New file.
* Makefile.in (COMMON_SFILES): Add dwarf2/macro.c.
---
gdb/ChangeLog | 11 +
gdb/Makefile.in | 1 +
gdb/dwarf2/macro.c | 867 +++++++++++++++++++++++++++++++++++++++++++++
gdb/dwarf2/macro.h | 33 ++
gdb/dwarf2/read.c | 832 +------------------------------------------
5 files changed, 914 insertions(+), 830 deletions(-)
create mode 100644 gdb/dwarf2/macro.c
create mode 100644 gdb/dwarf2/macro.h
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index c9450ce7b52..f66affd3e5f 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -1013,6 +1013,7 @@ COMMON_SFILES = \
dwarf2/leb.c \
dwarf2/line-header.c \
dwarf2/loc.c \
+ dwarf2/macro.c \
dwarf2/read.c \
dwarf2/section.c \
eval.c \
diff --git a/gdb/dwarf2/macro.c b/gdb/dwarf2/macro.c
new file mode 100644
index 00000000000..1f1cca858c1
--- /dev/null
+++ b/gdb/dwarf2/macro.c
@@ -0,0 +1,867 @@
+/* Read DWARF macro information
+
+ Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+ Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology,
+ Inc. with support from Florida State University (under contract
+ with the Ada Joint Program Office), and Silicon Graphics, Inc.
+ Initial contribution by Brent Benson, Harris Computer Systems, Inc.,
+ based on Fred Fish's (Cygnus Support) implementation of DWARF 1
+ support.
+
+ 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/>. */
+
+#include "defs.h"
+#include "dwarf2/read.h"
+#include "dwarf2/leb.h"
+#include "dwarf2/expr.h"
+#include "dwarf2/line-header.h"
+#include "dwarf2/section.h"
+#include "dwarf2/macro.h"
+#include "dwarf2/dwz.h"
+#include "buildsym.h"
+#include "macrotab.h"
+#include "complaints.h"
+
+static void
+dwarf2_macro_malformed_definition_complaint (const char *arg1)
+{
+ complaint (_("macro debug info contains a "
+ "malformed macro definition:\n`%s'"),
+ arg1);
+}
+
+static struct macro_source_file *
+macro_start_file (buildsym_compunit *builder,
+ int file, int line,
+ struct macro_source_file *current_file,
+ struct line_header *lh)
+{
+ /* File name relative to the compilation directory of this source file. */
+ gdb::unique_xmalloc_ptr<char> file_name = lh->file_file_name (file);
+
+ if (! current_file)
+ {
+ /* Note: We don't create a macro table for this compilation unit
+ at all until we actually get a filename. */
+ struct macro_table *macro_table = builder->get_macro_table ();
+
+ /* If we have no current file, then this must be the start_file
+ directive for the compilation unit's main source file. */
+ current_file = macro_set_main (macro_table, file_name.get ());
+ macro_define_special (macro_table);
+ }
+ else
+ current_file = macro_include (current_file, line, file_name.get ());
+
+ return current_file;
+}
+
+static const char *
+consume_improper_spaces (const char *p, const char *body)
+{
+ if (*p == ' ')
+ {
+ complaint (_("macro definition contains spaces "
+ "in formal argument list:\n`%s'"),
+ body);
+
+ while (*p == ' ')
+ p++;
+ }
+
+ return p;
+}
+
+
+static void
+parse_macro_definition (struct macro_source_file *file, int line,
+ const char *body)
+{
+ const char *p;
+
+ /* The body string takes one of two forms. For object-like macro
+ definitions, it should be:
+
+ <macro name> " " <definition>
+
+ For function-like macro definitions, it should be:
+
+ <macro name> "() " <definition>
+ or
+ <macro name> "(" <arg name> ( "," <arg name> ) * ") " <definition>
+
+ Spaces may appear only where explicitly indicated, and in the
+ <definition>.
+
+ The Dwarf 2 spec says that an object-like macro's name is always
+ followed by a space, but versions of GCC around March 2002 omit
+ the space when the macro's definition is the empty string.
+
+ The Dwarf 2 spec says that there should be no spaces between the
+ formal arguments in a function-like macro's formal argument list,
+ but versions of GCC around March 2002 include spaces after the
+ commas. */
+
+
+ /* Find the extent of the macro name. The macro name is terminated
+ by either a space or null character (for an object-like macro) or
+ an opening paren (for a function-like macro). */
+ for (p = body; *p; p++)
+ if (*p == ' ' || *p == '(')
+ break;
+
+ if (*p == ' ' || *p == '\0')
+ {
+ /* It's an object-like macro. */
+ int name_len = p - body;
+ std::string name (body, name_len);
+ const char *replacement;
+
+ if (*p == ' ')
+ replacement = body + name_len + 1;
+ else
+ {
+ dwarf2_macro_malformed_definition_complaint (body);
+ replacement = body + name_len;
+ }
+
+ macro_define_object (file, line, name.c_str (), replacement);
+ }
+ else if (*p == '(')
+ {
+ /* It's a function-like macro. */
+ std::string name (body, p - body);
+ int argc = 0;
+ int argv_size = 1;
+ char **argv = XNEWVEC (char *, argv_size);
+
+ p++;
+
+ p = consume_improper_spaces (p, body);
+
+ /* Parse the formal argument list. */
+ while (*p && *p != ')')
+ {
+ /* Find the extent of the current argument name. */
+ const char *arg_start = p;
+
+ while (*p && *p != ',' && *p != ')' && *p != ' ')
+ p++;
+
+ if (! *p || p == arg_start)
+ dwarf2_macro_malformed_definition_complaint (body);
+ else
+ {
+ /* Make sure argv has room for the new argument. */
+ if (argc >= argv_size)
+ {
+ argv_size *= 2;
+ argv = XRESIZEVEC (char *, argv, argv_size);
+ }
+
+ argv[argc++] = savestring (arg_start, p - arg_start);
+ }
+
+ p = consume_improper_spaces (p, body);
+
+ /* Consume the comma, if present. */
+ if (*p == ',')
+ {
+ p++;
+
+ p = consume_improper_spaces (p, body);
+ }
+ }
+
+ if (*p == ')')
+ {
+ p++;
+
+ if (*p == ' ')
+ /* Perfectly formed definition, no complaints. */
+ macro_define_function (file, line, name.c_str (),
+ argc, (const char **) argv,
+ p + 1);
+ else if (*p == '\0')
+ {
+ /* Complain, but do define it. */
+ dwarf2_macro_malformed_definition_complaint (body);
+ macro_define_function (file, line, name.c_str (),
+ argc, (const char **) argv,
+ p);
+ }
+ else
+ /* Just complain. */
+ dwarf2_macro_malformed_definition_complaint (body);
+ }
+ else
+ /* Just complain. */
+ dwarf2_macro_malformed_definition_complaint (body);
+
+ {
+ int i;
+
+ for (i = 0; i < argc; i++)
+ xfree (argv[i]);
+ }
+ xfree (argv);
+ }
+ else
+ dwarf2_macro_malformed_definition_complaint (body);
+}
+
+/* Skip some bytes from BYTES according to the form given in FORM.
+ Returns the new pointer. */
+
+static const gdb_byte *
+skip_form_bytes (bfd *abfd, const gdb_byte *bytes, const gdb_byte *buffer_end,
+ enum dwarf_form form,
+ unsigned int offset_size,
+ struct dwarf2_section_info *section)
+{
+ unsigned int bytes_read;
+
+ switch (form)
+ {
+ case DW_FORM_data1:
+ case DW_FORM_flag:
+ ++bytes;
+ break;
+
+ case DW_FORM_data2:
+ bytes += 2;
+ break;
+
+ case DW_FORM_data4:
+ bytes += 4;
+ break;
+
+ case DW_FORM_data8:
+ bytes += 8;
+ break;
+
+ case DW_FORM_data16:
+ bytes += 16;
+ break;
+
+ case DW_FORM_string:
+ read_direct_string (abfd, bytes, &bytes_read);
+ bytes += bytes_read;
+ break;
+
+ case DW_FORM_sec_offset:
+ case DW_FORM_strp:
+ case DW_FORM_GNU_strp_alt:
+ bytes += offset_size;
+ break;
+
+ case DW_FORM_block:
+ bytes += read_unsigned_leb128 (abfd, bytes, &bytes_read);
+ bytes += bytes_read;
+ break;
+
+ case DW_FORM_block1:
+ bytes += 1 + read_1_byte (abfd, bytes);
+ break;
+ case DW_FORM_block2:
+ bytes += 2 + read_2_bytes (abfd, bytes);
+ break;
+ case DW_FORM_block4:
+ bytes += 4 + read_4_bytes (abfd, bytes);
+ break;
+
+ case DW_FORM_addrx:
+ case DW_FORM_sdata:
+ case DW_FORM_strx:
+ case DW_FORM_udata:
+ case DW_FORM_GNU_addr_index:
+ case DW_FORM_GNU_str_index:
+ bytes = gdb_skip_leb128 (bytes, buffer_end);
+ if (bytes == NULL)
+ {
+ section->overflow_complaint ();
+ return NULL;
+ }
+ break;
+
+ case DW_FORM_implicit_const:
+ break;
+
+ default:
+ {
+ complaint (_("invalid form 0x%x in `%s'"),
+ form, section->get_name ());
+ return NULL;
+ }
+ }
+
+ return bytes;
+}
+
+/* A helper for dwarf_decode_macros that handles skipping an unknown
+ opcode. Returns an updated pointer to the macro data buffer; or,
+ on error, issues a complaint and returns NULL. */
+
+static const gdb_byte *
+skip_unknown_opcode (unsigned int opcode,
+ const gdb_byte **opcode_definitions,
+ const gdb_byte *mac_ptr, const gdb_byte *mac_end,
+ bfd *abfd,
+ unsigned int offset_size,
+ struct dwarf2_section_info *section)
+{
+ unsigned int bytes_read, i;
+ unsigned long arg;
+ const gdb_byte *defn;
+
+ if (opcode_definitions[opcode] == NULL)
+ {
+ complaint (_("unrecognized DW_MACFINO opcode 0x%x"),
+ opcode);
+ return NULL;
+ }
+
+ defn = opcode_definitions[opcode];
+ arg = read_unsigned_leb128 (abfd, defn, &bytes_read);
+ defn += bytes_read;
+
+ for (i = 0; i < arg; ++i)
+ {
+ mac_ptr = skip_form_bytes (abfd, mac_ptr, mac_end,
+ (enum dwarf_form) defn[i], offset_size,
+ section);
+ if (mac_ptr == NULL)
+ {
+ /* skip_form_bytes already issued the complaint. */
+ return NULL;
+ }
+ }
+
+ return mac_ptr;
+}
+
+/* A helper function which parses the header of a macro section.
+ If the macro section is the extended (for now called "GNU") type,
+ then this updates *OFFSET_SIZE. Returns a pointer to just after
+ the header, or issues a complaint and returns NULL on error. */
+
+static const gdb_byte *
+dwarf_parse_macro_header (const gdb_byte **opcode_definitions,
+ bfd *abfd,
+ const gdb_byte *mac_ptr,
+ unsigned int *offset_size,
+ int section_is_gnu)
+{
+ memset (opcode_definitions, 0, 256 * sizeof (gdb_byte *));
+
+ if (section_is_gnu)
+ {
+ unsigned int version, flags;
+
+ version = read_2_bytes (abfd, mac_ptr);
+ if (version != 4 && version != 5)
+ {
+ complaint (_("unrecognized version `%d' in .debug_macro section"),
+ version);
+ return NULL;
+ }
+ mac_ptr += 2;
+
+ flags = read_1_byte (abfd, mac_ptr);
+ ++mac_ptr;
+ *offset_size = (flags & 1) ? 8 : 4;
+
+ if ((flags & 2) != 0)
+ /* We don't need the line table offset. */
+ mac_ptr += *offset_size;
+
+ /* Vendor opcode descriptions. */
+ if ((flags & 4) != 0)
+ {
+ unsigned int i, count;
+
+ count = read_1_byte (abfd, mac_ptr);
+ ++mac_ptr;
+ for (i = 0; i < count; ++i)
+ {
+ unsigned int opcode, bytes_read;
+ unsigned long arg;
+
+ opcode = read_1_byte (abfd, mac_ptr);
+ ++mac_ptr;
+ opcode_definitions[opcode] = mac_ptr;
+ arg = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
+ mac_ptr += bytes_read;
+ mac_ptr += arg;
+ }
+ }
+ }
+
+ return mac_ptr;
+}
+
+/* A helper for dwarf_decode_macros that handles the GNU extensions,
+ including DW_MACRO_import. */
+
+static void
+dwarf_decode_macro_bytes (struct dwarf2_per_objfile *dwarf2_per_objfile,
+ buildsym_compunit *builder,
+ bfd *abfd,
+ const gdb_byte *mac_ptr, const gdb_byte *mac_end,
+ struct macro_source_file *current_file,
+ struct line_header *lh,
+ struct dwarf2_section_info *section,
+ int section_is_gnu, int section_is_dwz,
+ unsigned int offset_size,
+ htab_t include_hash)
+{
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ enum dwarf_macro_record_type macinfo_type;
+ int at_commandline;
+ const gdb_byte *opcode_definitions[256];
+
+ mac_ptr = dwarf_parse_macro_header (opcode_definitions, abfd, mac_ptr,
+ &offset_size, section_is_gnu);
+ if (mac_ptr == NULL)
+ {
+ /* We already issued a complaint. */
+ return;
+ }
+
+ /* Determines if GDB is still before first DW_MACINFO_start_file. If true
+ GDB is still reading the definitions from command line. First
+ DW_MACINFO_start_file will need to be ignored as it was already executed
+ to create CURRENT_FILE for the main source holding also the command line
+ definitions. On first met DW_MACINFO_start_file this flag is reset to
+ normally execute all the remaining DW_MACINFO_start_file macinfos. */
+
+ at_commandline = 1;
+
+ do
+ {
+ /* Do we at least have room for a macinfo type byte? */
+ if (mac_ptr >= mac_end)
+ {
+ section->overflow_complaint ();
+ break;
+ }
+
+ macinfo_type = (enum dwarf_macro_record_type) read_1_byte (abfd, mac_ptr);
+ mac_ptr++;
+
+ /* Note that we rely on the fact that the corresponding GNU and
+ DWARF constants are the same. */
+ DIAGNOSTIC_PUSH
+ DIAGNOSTIC_IGNORE_SWITCH_DIFFERENT_ENUM_TYPES
+ switch (macinfo_type)
+ {
+ /* A zero macinfo type indicates the end of the macro
+ information. */
+ case 0:
+ break;
+
+ case DW_MACRO_define:
+ case DW_MACRO_undef:
+ case DW_MACRO_define_strp:
+ case DW_MACRO_undef_strp:
+ case DW_MACRO_define_sup:
+ case DW_MACRO_undef_sup:
+ {
+ unsigned int bytes_read;
+ int line;
+ const char *body;
+ int is_define;
+
+ line = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
+ mac_ptr += bytes_read;
+
+ if (macinfo_type == DW_MACRO_define
+ || macinfo_type == DW_MACRO_undef)
+ {
+ body = read_direct_string (abfd, mac_ptr, &bytes_read);
+ mac_ptr += bytes_read;
+ }
+ else
+ {
+ LONGEST str_offset;
+
+ str_offset = read_offset (abfd, mac_ptr, offset_size);
+ mac_ptr += offset_size;
+
+ if (macinfo_type == DW_MACRO_define_sup
+ || macinfo_type == DW_MACRO_undef_sup
+ || section_is_dwz)
+ {
+ struct dwz_file *dwz
+ = dwarf2_get_dwz_file (dwarf2_per_objfile);
+
+ body = dwz->read_string (objfile, str_offset);
+ }
+ else
+ body = (dwarf2_per_objfile->str.read_string
+ (dwarf2_per_objfile->objfile,
+ str_offset, "DW_FORM_strp"));
+ }
+
+ is_define = (macinfo_type == DW_MACRO_define
+ || macinfo_type == DW_MACRO_define_strp
+ || macinfo_type == DW_MACRO_define_sup);
+ if (! current_file)
+ {
+ /* DWARF violation as no main source is present. */
+ complaint (_("debug info with no main source gives macro %s "
+ "on line %d: %s"),
+ is_define ? _("definition") : _("undefinition"),
+ line, body);
+ break;
+ }
+ if ((line == 0 && !at_commandline)
+ || (line != 0 && at_commandline))
+ complaint (_("debug info gives %s macro %s with %s line %d: %s"),
+ at_commandline ? _("command-line") : _("in-file"),
+ is_define ? _("definition") : _("undefinition"),
+ line == 0 ? _("zero") : _("non-zero"), line, body);
+
+ if (body == NULL)
+ {
+ /* Fedora's rpm-build's "debugedit" binary
+ corrupted .debug_macro sections.
+
+ For more info, see
+ https://bugzilla.redhat.com/show_bug.cgi?id=1708786 */
+ complaint (_("debug info gives %s invalid macro %s "
+ "without body (corrupted?) at line %d "
+ "on file %s"),
+ at_commandline ? _("command-line") : _("in-file"),
+ is_define ? _("definition") : _("undefinition"),
+ line, current_file->filename);
+ }
+ else if (is_define)
+ parse_macro_definition (current_file, line, body);
+ else
+ {
+ gdb_assert (macinfo_type == DW_MACRO_undef
+ || macinfo_type == DW_MACRO_undef_strp
+ || macinfo_type == DW_MACRO_undef_sup);
+ macro_undef (current_file, line, body);
+ }
+ }
+ break;
+
+ case DW_MACRO_start_file:
+ {
+ unsigned int bytes_read;
+ int line, file;
+
+ line = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
+ mac_ptr += bytes_read;
+ file = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
+ mac_ptr += bytes_read;
+
+ if ((line == 0 && !at_commandline)
+ || (line != 0 && at_commandline))
+ complaint (_("debug info gives source %d included "
+ "from %s at %s line %d"),
+ file, at_commandline ? _("command-line") : _("file"),
+ line == 0 ? _("zero") : _("non-zero"), line);
+
+ if (at_commandline)
+ {
+ /* This DW_MACRO_start_file was executed in the
+ pass one. */
+ at_commandline = 0;
+ }
+ else
+ current_file = macro_start_file (builder, file, line,
+ current_file, lh);
+ }
+ break;
+
+ case DW_MACRO_end_file:
+ if (! current_file)
+ complaint (_("macro debug info has an unmatched "
+ "`close_file' directive"));
+ else
+ {
+ current_file = current_file->included_by;
+ if (! current_file)
+ {
+ enum dwarf_macro_record_type next_type;
+
+ /* GCC circa March 2002 doesn't produce the zero
+ type byte marking the end of the compilation
+ unit. Complain if it's not there, but exit no
+ matter what. */
+
+ /* Do we at least have room for a macinfo type byte? */
+ if (mac_ptr >= mac_end)
+ {
+ section->overflow_complaint ();
+ return;
+ }
+
+ /* We don't increment mac_ptr here, so this is just
+ a look-ahead. */
+ next_type
+ = (enum dwarf_macro_record_type) read_1_byte (abfd,
+ mac_ptr);
+ if (next_type != 0)
+ complaint (_("no terminating 0-type entry for "
+ "macros in `.debug_macinfo' section"));
+
+ return;
+ }
+ }
+ break;
+
+ case DW_MACRO_import:
+ case DW_MACRO_import_sup:
+ {
+ LONGEST offset;
+ void **slot;
+ bfd *include_bfd = abfd;
+ struct dwarf2_section_info *include_section = section;
+ const gdb_byte *include_mac_end = mac_end;
+ int is_dwz = section_is_dwz;
+ const gdb_byte *new_mac_ptr;
+
+ offset = read_offset (abfd, mac_ptr, offset_size);
+ mac_ptr += offset_size;
+
+ if (macinfo_type == DW_MACRO_import_sup)
+ {
+ struct dwz_file *dwz = dwarf2_get_dwz_file (dwarf2_per_objfile);
+
+ dwz->macro.read (objfile);
+
+ include_section = &dwz->macro;
+ include_bfd = include_section->get_bfd_owner ();
+ include_mac_end = dwz->macro.buffer + dwz->macro.size;
+ is_dwz = 1;
+ }
+
+ new_mac_ptr = include_section->buffer + offset;
+ slot = htab_find_slot (include_hash, new_mac_ptr, INSERT);
+
+ if (*slot != NULL)
+ {
+ /* This has actually happened; see
+ http://sourceware.org/bugzilla/show_bug.cgi?id=13568. */
+ complaint (_("recursive DW_MACRO_import in "
+ ".debug_macro section"));
+ }
+ else
+ {
+ *slot = (void *) new_mac_ptr;
+
+ dwarf_decode_macro_bytes (dwarf2_per_objfile, builder,
+ include_bfd, new_mac_ptr,
+ include_mac_end, current_file, lh,
+ section, section_is_gnu, is_dwz,
+ offset_size, include_hash);
+
+ htab_remove_elt (include_hash, (void *) new_mac_ptr);
+ }
+ }
+ break;
+
+ case DW_MACINFO_vendor_ext:
+ if (!section_is_gnu)
+ {
+ unsigned int bytes_read;
+
+ /* This reads the constant, but since we don't recognize
+ any vendor extensions, we ignore it. */
+ read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
+ mac_ptr += bytes_read;
+ read_direct_string (abfd, mac_ptr, &bytes_read);
+ mac_ptr += bytes_read;
+
+ /* We don't recognize any vendor extensions. */
+ break;
+ }
+ /* FALLTHROUGH */
+
+ default:
+ mac_ptr = skip_unknown_opcode (macinfo_type, opcode_definitions,
+ mac_ptr, mac_end, abfd, offset_size,
+ section);
+ if (mac_ptr == NULL)
+ return;
+ break;
+ }
+ DIAGNOSTIC_POP
+ } while (macinfo_type != 0);
+}
+
+void
+dwarf_decode_macros (struct dwarf2_per_objfile *dwarf2_per_objfile,
+ buildsym_compunit *builder, dwarf2_section_info *section,
+ struct line_header *lh, unsigned int offset_size,
+ unsigned int offset, int section_is_gnu)
+{
+ bfd *abfd;
+ const gdb_byte *mac_ptr, *mac_end;
+ struct macro_source_file *current_file = 0;
+ enum dwarf_macro_record_type macinfo_type;
+ const gdb_byte *opcode_definitions[256];
+ void **slot;
+
+ abfd = section->get_bfd_owner ();
+
+ /* First pass: Find the name of the base filename.
+ This filename is needed in order to process all macros whose definition
+ (or undefinition) comes from the command line. These macros are defined
+ before the first DW_MACINFO_start_file entry, and yet still need to be
+ associated to the base file.
+
+ To determine the base file name, we scan the macro definitions until we
+ reach the first DW_MACINFO_start_file entry. We then initialize
+ CURRENT_FILE accordingly so that any macro definition found before the
+ first DW_MACINFO_start_file can still be associated to the base file. */
+
+ mac_ptr = section->buffer + offset;
+ mac_end = section->buffer + section->size;
+
+ mac_ptr = dwarf_parse_macro_header (opcode_definitions, abfd, mac_ptr,
+ &offset_size, section_is_gnu);
+ if (mac_ptr == NULL)
+ {
+ /* We already issued a complaint. */
+ return;
+ }
+
+ do
+ {
+ /* Do we at least have room for a macinfo type byte? */
+ if (mac_ptr >= mac_end)
+ {
+ /* Complaint is printed during the second pass as GDB will probably
+ stop the first pass earlier upon finding
+ DW_MACINFO_start_file. */
+ break;
+ }
+
+ macinfo_type = (enum dwarf_macro_record_type) read_1_byte (abfd, mac_ptr);
+ mac_ptr++;
+
+ /* Note that we rely on the fact that the corresponding GNU and
+ DWARF constants are the same. */
+ DIAGNOSTIC_PUSH
+ DIAGNOSTIC_IGNORE_SWITCH_DIFFERENT_ENUM_TYPES
+ switch (macinfo_type)
+ {
+ /* A zero macinfo type indicates the end of the macro
+ information. */
+ case 0:
+ break;
+
+ case DW_MACRO_define:
+ case DW_MACRO_undef:
+ /* Only skip the data by MAC_PTR. */
+ {
+ unsigned int bytes_read;
+
+ read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
+ mac_ptr += bytes_read;
+ read_direct_string (abfd, mac_ptr, &bytes_read);
+ mac_ptr += bytes_read;
+ }
+ break;
+
+ case DW_MACRO_start_file:
+ {
+ unsigned int bytes_read;
+ int line, file;
+
+ line = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
+ mac_ptr += bytes_read;
+ file = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
+ mac_ptr += bytes_read;
+
+ current_file = macro_start_file (builder, file, line,
+ current_file, lh);
+ }
+ break;
+
+ case DW_MACRO_end_file:
+ /* No data to skip by MAC_PTR. */
+ break;
+
+ case DW_MACRO_define_strp:
+ case DW_MACRO_undef_strp:
+ case DW_MACRO_define_sup:
+ case DW_MACRO_undef_sup:
+ {
+ unsigned int bytes_read;
+
+ read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
+ mac_ptr += bytes_read;
+ mac_ptr += offset_size;
+ }
+ break;
+
+ case DW_MACRO_import:
+ case DW_MACRO_import_sup:
+ /* Note that, according to the spec, a transparent include
+ chain cannot call DW_MACRO_start_file. So, we can just
+ skip this opcode. */
+ mac_ptr += offset_size;
+ break;
+
+ case DW_MACINFO_vendor_ext:
+ /* Only skip the data by MAC_PTR. */
+ if (!section_is_gnu)
+ {
+ unsigned int bytes_read;
+
+ read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
+ mac_ptr += bytes_read;
+ read_direct_string (abfd, mac_ptr, &bytes_read);
+ mac_ptr += bytes_read;
+ }
+ /* FALLTHROUGH */
+
+ default:
+ mac_ptr = skip_unknown_opcode (macinfo_type, opcode_definitions,
+ mac_ptr, mac_end, abfd, offset_size,
+ section);
+ if (mac_ptr == NULL)
+ return;
+ break;
+ }
+ DIAGNOSTIC_POP
+ } while (macinfo_type != 0 && current_file == NULL);
+
+ /* Second pass: Process all entries.
+
+ Use the AT_COMMAND_LINE flag to determine whether we are still processing
+ command-line macro definitions/undefinitions. This flag is unset when we
+ reach the first DW_MACINFO_start_file entry. */
+
+ htab_up include_hash (htab_create_alloc (1, htab_hash_pointer,
+ htab_eq_pointer,
+ NULL, xcalloc, xfree));
+ mac_ptr = section->buffer + offset;
+ slot = htab_find_slot (include_hash.get (), mac_ptr, INSERT);
+ *slot = (void *) mac_ptr;
+ dwarf_decode_macro_bytes (dwarf2_per_objfile, builder,
+ abfd, mac_ptr, mac_end,
+ current_file, lh, section,
+ section_is_gnu, 0, offset_size,
+ include_hash.get ());
+}
diff --git a/gdb/dwarf2/macro.h b/gdb/dwarf2/macro.h
new file mode 100644
index 00000000000..3937c550088
--- /dev/null
+++ b/gdb/dwarf2/macro.h
@@ -0,0 +1,33 @@
+/* DWARF macro support for GDB.
+
+ Copyright (C) 2003-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 <http://www.gnu.org/licenses/>. */
+
+#ifndef GDB_DWARF2_MACRO_H
+#define GDB_DWARF2_MACRO_H
+
+struct buildsym_compunit;
+
+extern void dwarf_decode_macros (struct dwarf2_per_objfile *dwarf2_per_objfile,
+ buildsym_compunit *builder,
+ dwarf2_section_info *section,
+ struct line_header *lh,
+ unsigned int offset_size,
+ unsigned int offset,
+ int section_is_gnu);
+
+#endif /* GDB_DWARF2_MACRO_H */
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 75d028d95b1..ca90418e45e 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -38,6 +38,7 @@
#include "dwarf2/leb.h"
#include "dwarf2/line-header.h"
#include "dwarf2/dwz.h"
+#include "dwarf2/macro.h"
#include "bfd.h"
#include "elf-bfd.h"
#include "symtab.h"
@@ -48,7 +49,6 @@
#include "demangle.h"
#include "gdb-demangle.h"
#include "filenames.h" /* for DOSish file names */
-#include "macrotab.h"
#include "language.h"
#include "complaints.h"
#include "dwarf2/expr.h"
@@ -1710,14 +1710,6 @@ dwarf2_const_value_length_mismatch_complaint (const char *arg1, int arg2,
arg1, arg2, arg3);
}
-static void
-dwarf2_macro_malformed_definition_complaint (const char *arg1)
-{
- complaint (_("macro debug info contains a "
- "malformed macro definition:\n`%s'"),
- arg1);
-}
-
static void
dwarf2_invalid_attrib_class_complaint (const char *arg1, const char *arg2)
{
@@ -23040,828 +23032,8 @@ dwarf_alloc_die (struct dwarf2_cu *cu, int num_attrs)
}
\f
-/* Macro support. */
-
-static struct macro_source_file *
-macro_start_file (buildsym_compunit *builder,
- int file, int line,
- struct macro_source_file *current_file,
- struct line_header *lh)
-{
- /* File name relative to the compilation directory of this source file. */
- gdb::unique_xmalloc_ptr<char> file_name = lh->file_file_name (file);
-
- if (! current_file)
- {
- /* Note: We don't create a macro table for this compilation unit
- at all until we actually get a filename. */
- struct macro_table *macro_table = builder->get_macro_table ();
-
- /* If we have no current file, then this must be the start_file
- directive for the compilation unit's main source file. */
- current_file = macro_set_main (macro_table, file_name.get ());
- macro_define_special (macro_table);
- }
- else
- current_file = macro_include (current_file, line, file_name.get ());
-
- return current_file;
-}
-
-static const char *
-consume_improper_spaces (const char *p, const char *body)
-{
- if (*p == ' ')
- {
- complaint (_("macro definition contains spaces "
- "in formal argument list:\n`%s'"),
- body);
-
- while (*p == ' ')
- p++;
- }
-
- return p;
-}
-
-
-static void
-parse_macro_definition (struct macro_source_file *file, int line,
- const char *body)
-{
- const char *p;
-
- /* The body string takes one of two forms. For object-like macro
- definitions, it should be:
-
- <macro name> " " <definition>
-
- For function-like macro definitions, it should be:
-
- <macro name> "() " <definition>
- or
- <macro name> "(" <arg name> ( "," <arg name> ) * ") " <definition>
-
- Spaces may appear only where explicitly indicated, and in the
- <definition>.
-
- The Dwarf 2 spec says that an object-like macro's name is always
- followed by a space, but versions of GCC around March 2002 omit
- the space when the macro's definition is the empty string.
-
- The Dwarf 2 spec says that there should be no spaces between the
- formal arguments in a function-like macro's formal argument list,
- but versions of GCC around March 2002 include spaces after the
- commas. */
-
-
- /* Find the extent of the macro name. The macro name is terminated
- by either a space or null character (for an object-like macro) or
- an opening paren (for a function-like macro). */
- for (p = body; *p; p++)
- if (*p == ' ' || *p == '(')
- break;
-
- if (*p == ' ' || *p == '\0')
- {
- /* It's an object-like macro. */
- int name_len = p - body;
- std::string name (body, name_len);
- const char *replacement;
-
- if (*p == ' ')
- replacement = body + name_len + 1;
- else
- {
- dwarf2_macro_malformed_definition_complaint (body);
- replacement = body + name_len;
- }
-
- macro_define_object (file, line, name.c_str (), replacement);
- }
- else if (*p == '(')
- {
- /* It's a function-like macro. */
- std::string name (body, p - body);
- int argc = 0;
- int argv_size = 1;
- char **argv = XNEWVEC (char *, argv_size);
-
- p++;
-
- p = consume_improper_spaces (p, body);
-
- /* Parse the formal argument list. */
- while (*p && *p != ')')
- {
- /* Find the extent of the current argument name. */
- const char *arg_start = p;
-
- while (*p && *p != ',' && *p != ')' && *p != ' ')
- p++;
-
- if (! *p || p == arg_start)
- dwarf2_macro_malformed_definition_complaint (body);
- else
- {
- /* Make sure argv has room for the new argument. */
- if (argc >= argv_size)
- {
- argv_size *= 2;
- argv = XRESIZEVEC (char *, argv, argv_size);
- }
-
- argv[argc++] = savestring (arg_start, p - arg_start);
- }
-
- p = consume_improper_spaces (p, body);
-
- /* Consume the comma, if present. */
- if (*p == ',')
- {
- p++;
-
- p = consume_improper_spaces (p, body);
- }
- }
-
- if (*p == ')')
- {
- p++;
-
- if (*p == ' ')
- /* Perfectly formed definition, no complaints. */
- macro_define_function (file, line, name.c_str (),
- argc, (const char **) argv,
- p + 1);
- else if (*p == '\0')
- {
- /* Complain, but do define it. */
- dwarf2_macro_malformed_definition_complaint (body);
- macro_define_function (file, line, name.c_str (),
- argc, (const char **) argv,
- p);
- }
- else
- /* Just complain. */
- dwarf2_macro_malformed_definition_complaint (body);
- }
- else
- /* Just complain. */
- dwarf2_macro_malformed_definition_complaint (body);
-
- {
- int i;
-
- for (i = 0; i < argc; i++)
- xfree (argv[i]);
- }
- xfree (argv);
- }
- else
- dwarf2_macro_malformed_definition_complaint (body);
-}
-
-/* Skip some bytes from BYTES according to the form given in FORM.
- Returns the new pointer. */
-
-static const gdb_byte *
-skip_form_bytes (bfd *abfd, const gdb_byte *bytes, const gdb_byte *buffer_end,
- enum dwarf_form form,
- unsigned int offset_size,
- struct dwarf2_section_info *section)
-{
- unsigned int bytes_read;
-
- switch (form)
- {
- case DW_FORM_data1:
- case DW_FORM_flag:
- ++bytes;
- break;
-
- case DW_FORM_data2:
- bytes += 2;
- break;
-
- case DW_FORM_data4:
- bytes += 4;
- break;
-
- case DW_FORM_data8:
- bytes += 8;
- break;
-
- case DW_FORM_data16:
- bytes += 16;
- break;
-
- case DW_FORM_string:
- read_direct_string (abfd, bytes, &bytes_read);
- bytes += bytes_read;
- break;
-
- case DW_FORM_sec_offset:
- case DW_FORM_strp:
- case DW_FORM_GNU_strp_alt:
- bytes += offset_size;
- break;
-
- case DW_FORM_block:
- bytes += read_unsigned_leb128 (abfd, bytes, &bytes_read);
- bytes += bytes_read;
- break;
-
- case DW_FORM_block1:
- bytes += 1 + read_1_byte (abfd, bytes);
- break;
- case DW_FORM_block2:
- bytes += 2 + read_2_bytes (abfd, bytes);
- break;
- case DW_FORM_block4:
- bytes += 4 + read_4_bytes (abfd, bytes);
- break;
-
- case DW_FORM_addrx:
- case DW_FORM_sdata:
- case DW_FORM_strx:
- case DW_FORM_udata:
- case DW_FORM_GNU_addr_index:
- case DW_FORM_GNU_str_index:
- bytes = gdb_skip_leb128 (bytes, buffer_end);
- if (bytes == NULL)
- {
- section->overflow_complaint ();
- return NULL;
- }
- break;
-
- case DW_FORM_implicit_const:
- break;
-
- default:
- {
- complaint (_("invalid form 0x%x in `%s'"),
- form, section->get_name ());
- return NULL;
- }
- }
-
- return bytes;
-}
-
-/* A helper for dwarf_decode_macros that handles skipping an unknown
- opcode. Returns an updated pointer to the macro data buffer; or,
- on error, issues a complaint and returns NULL. */
-
-static const gdb_byte *
-skip_unknown_opcode (unsigned int opcode,
- const gdb_byte **opcode_definitions,
- const gdb_byte *mac_ptr, const gdb_byte *mac_end,
- bfd *abfd,
- unsigned int offset_size,
- struct dwarf2_section_info *section)
-{
- unsigned int bytes_read, i;
- unsigned long arg;
- const gdb_byte *defn;
-
- if (opcode_definitions[opcode] == NULL)
- {
- complaint (_("unrecognized DW_MACFINO opcode 0x%x"),
- opcode);
- return NULL;
- }
-
- defn = opcode_definitions[opcode];
- arg = read_unsigned_leb128 (abfd, defn, &bytes_read);
- defn += bytes_read;
-
- for (i = 0; i < arg; ++i)
- {
- mac_ptr = skip_form_bytes (abfd, mac_ptr, mac_end,
- (enum dwarf_form) defn[i], offset_size,
- section);
- if (mac_ptr == NULL)
- {
- /* skip_form_bytes already issued the complaint. */
- return NULL;
- }
- }
-
- return mac_ptr;
-}
-
-/* A helper function which parses the header of a macro section.
- If the macro section is the extended (for now called "GNU") type,
- then this updates *OFFSET_SIZE. Returns a pointer to just after
- the header, or issues a complaint and returns NULL on error. */
-
-static const gdb_byte *
-dwarf_parse_macro_header (const gdb_byte **opcode_definitions,
- bfd *abfd,
- const gdb_byte *mac_ptr,
- unsigned int *offset_size,
- int section_is_gnu)
-{
- memset (opcode_definitions, 0, 256 * sizeof (gdb_byte *));
-
- if (section_is_gnu)
- {
- unsigned int version, flags;
-
- version = read_2_bytes (abfd, mac_ptr);
- if (version != 4 && version != 5)
- {
- complaint (_("unrecognized version `%d' in .debug_macro section"),
- version);
- return NULL;
- }
- mac_ptr += 2;
-
- flags = read_1_byte (abfd, mac_ptr);
- ++mac_ptr;
- *offset_size = (flags & 1) ? 8 : 4;
-
- if ((flags & 2) != 0)
- /* We don't need the line table offset. */
- mac_ptr += *offset_size;
-
- /* Vendor opcode descriptions. */
- if ((flags & 4) != 0)
- {
- unsigned int i, count;
-
- count = read_1_byte (abfd, mac_ptr);
- ++mac_ptr;
- for (i = 0; i < count; ++i)
- {
- unsigned int opcode, bytes_read;
- unsigned long arg;
-
- opcode = read_1_byte (abfd, mac_ptr);
- ++mac_ptr;
- opcode_definitions[opcode] = mac_ptr;
- arg = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
- mac_ptr += bytes_read;
- mac_ptr += arg;
- }
- }
- }
-
- return mac_ptr;
-}
-
-/* A helper for dwarf_decode_macros that handles the GNU extensions,
- including DW_MACRO_import. */
-
-static void
-dwarf_decode_macro_bytes (struct dwarf2_per_objfile *dwarf2_per_objfile,
- buildsym_compunit *builder,
- bfd *abfd,
- const gdb_byte *mac_ptr, const gdb_byte *mac_end,
- struct macro_source_file *current_file,
- struct line_header *lh,
- struct dwarf2_section_info *section,
- int section_is_gnu, int section_is_dwz,
- unsigned int offset_size,
- htab_t include_hash)
-{
- struct objfile *objfile = dwarf2_per_objfile->objfile;
- enum dwarf_macro_record_type macinfo_type;
- int at_commandline;
- const gdb_byte *opcode_definitions[256];
-
- mac_ptr = dwarf_parse_macro_header (opcode_definitions, abfd, mac_ptr,
- &offset_size, section_is_gnu);
- if (mac_ptr == NULL)
- {
- /* We already issued a complaint. */
- return;
- }
-
- /* Determines if GDB is still before first DW_MACINFO_start_file. If true
- GDB is still reading the definitions from command line. First
- DW_MACINFO_start_file will need to be ignored as it was already executed
- to create CURRENT_FILE for the main source holding also the command line
- definitions. On first met DW_MACINFO_start_file this flag is reset to
- normally execute all the remaining DW_MACINFO_start_file macinfos. */
-
- at_commandline = 1;
-
- do
- {
- /* Do we at least have room for a macinfo type byte? */
- if (mac_ptr >= mac_end)
- {
- section->overflow_complaint ();
- break;
- }
-
- macinfo_type = (enum dwarf_macro_record_type) read_1_byte (abfd, mac_ptr);
- mac_ptr++;
-
- /* Note that we rely on the fact that the corresponding GNU and
- DWARF constants are the same. */
- DIAGNOSTIC_PUSH
- DIAGNOSTIC_IGNORE_SWITCH_DIFFERENT_ENUM_TYPES
- switch (macinfo_type)
- {
- /* A zero macinfo type indicates the end of the macro
- information. */
- case 0:
- break;
-
- case DW_MACRO_define:
- case DW_MACRO_undef:
- case DW_MACRO_define_strp:
- case DW_MACRO_undef_strp:
- case DW_MACRO_define_sup:
- case DW_MACRO_undef_sup:
- {
- unsigned int bytes_read;
- int line;
- const char *body;
- int is_define;
-
- line = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
- mac_ptr += bytes_read;
-
- if (macinfo_type == DW_MACRO_define
- || macinfo_type == DW_MACRO_undef)
- {
- body = read_direct_string (abfd, mac_ptr, &bytes_read);
- mac_ptr += bytes_read;
- }
- else
- {
- LONGEST str_offset;
-
- str_offset = read_offset (abfd, mac_ptr, offset_size);
- mac_ptr += offset_size;
-
- if (macinfo_type == DW_MACRO_define_sup
- || macinfo_type == DW_MACRO_undef_sup
- || section_is_dwz)
- {
- struct dwz_file *dwz
- = dwarf2_get_dwz_file (dwarf2_per_objfile);
-
- body = dwz->read_string (objfile, str_offset);
- }
- else
- body = read_indirect_string_at_offset (dwarf2_per_objfile,
- str_offset);
- }
-
- is_define = (macinfo_type == DW_MACRO_define
- || macinfo_type == DW_MACRO_define_strp
- || macinfo_type == DW_MACRO_define_sup);
- if (! current_file)
- {
- /* DWARF violation as no main source is present. */
- complaint (_("debug info with no main source gives macro %s "
- "on line %d: %s"),
- is_define ? _("definition") : _("undefinition"),
- line, body);
- break;
- }
- if ((line == 0 && !at_commandline)
- || (line != 0 && at_commandline))
- complaint (_("debug info gives %s macro %s with %s line %d: %s"),
- at_commandline ? _("command-line") : _("in-file"),
- is_define ? _("definition") : _("undefinition"),
- line == 0 ? _("zero") : _("non-zero"), line, body);
-
- if (body == NULL)
- {
- /* Fedora's rpm-build's "debugedit" binary
- corrupted .debug_macro sections.
-
- For more info, see
- https://bugzilla.redhat.com/show_bug.cgi?id=1708786 */
- complaint (_("debug info gives %s invalid macro %s "
- "without body (corrupted?) at line %d "
- "on file %s"),
- at_commandline ? _("command-line") : _("in-file"),
- is_define ? _("definition") : _("undefinition"),
- line, current_file->filename);
- }
- else if (is_define)
- parse_macro_definition (current_file, line, body);
- else
- {
- gdb_assert (macinfo_type == DW_MACRO_undef
- || macinfo_type == DW_MACRO_undef_strp
- || macinfo_type == DW_MACRO_undef_sup);
- macro_undef (current_file, line, body);
- }
- }
- break;
-
- case DW_MACRO_start_file:
- {
- unsigned int bytes_read;
- int line, file;
-
- line = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
- mac_ptr += bytes_read;
- file = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
- mac_ptr += bytes_read;
-
- if ((line == 0 && !at_commandline)
- || (line != 0 && at_commandline))
- complaint (_("debug info gives source %d included "
- "from %s at %s line %d"),
- file, at_commandline ? _("command-line") : _("file"),
- line == 0 ? _("zero") : _("non-zero"), line);
-
- if (at_commandline)
- {
- /* This DW_MACRO_start_file was executed in the
- pass one. */
- at_commandline = 0;
- }
- else
- current_file = macro_start_file (builder, file, line,
- current_file, lh);
- }
- break;
-
- case DW_MACRO_end_file:
- if (! current_file)
- complaint (_("macro debug info has an unmatched "
- "`close_file' directive"));
- else
- {
- current_file = current_file->included_by;
- if (! current_file)
- {
- enum dwarf_macro_record_type next_type;
-
- /* GCC circa March 2002 doesn't produce the zero
- type byte marking the end of the compilation
- unit. Complain if it's not there, but exit no
- matter what. */
-
- /* Do we at least have room for a macinfo type byte? */
- if (mac_ptr >= mac_end)
- {
- section->overflow_complaint ();
- return;
- }
-
- /* We don't increment mac_ptr here, so this is just
- a look-ahead. */
- next_type
- = (enum dwarf_macro_record_type) read_1_byte (abfd,
- mac_ptr);
- if (next_type != 0)
- complaint (_("no terminating 0-type entry for "
- "macros in `.debug_macinfo' section"));
-
- return;
- }
- }
- break;
-
- case DW_MACRO_import:
- case DW_MACRO_import_sup:
- {
- LONGEST offset;
- void **slot;
- bfd *include_bfd = abfd;
- struct dwarf2_section_info *include_section = section;
- const gdb_byte *include_mac_end = mac_end;
- int is_dwz = section_is_dwz;
- const gdb_byte *new_mac_ptr;
-
- offset = read_offset (abfd, mac_ptr, offset_size);
- mac_ptr += offset_size;
-
- if (macinfo_type == DW_MACRO_import_sup)
- {
- struct dwz_file *dwz = dwarf2_get_dwz_file (dwarf2_per_objfile);
-
- dwz->macro.read (objfile);
-
- include_section = &dwz->macro;
- include_bfd = include_section->get_bfd_owner ();
- include_mac_end = dwz->macro.buffer + dwz->macro.size;
- is_dwz = 1;
- }
- new_mac_ptr = include_section->buffer + offset;
- slot = htab_find_slot (include_hash, new_mac_ptr, INSERT);
-
- if (*slot != NULL)
- {
- /* This has actually happened; see
- http://sourceware.org/bugzilla/show_bug.cgi?id=13568. */
- complaint (_("recursive DW_MACRO_import in "
- ".debug_macro section"));
- }
- else
- {
- *slot = (void *) new_mac_ptr;
-
- dwarf_decode_macro_bytes (dwarf2_per_objfile, builder,
- include_bfd, new_mac_ptr,
- include_mac_end, current_file, lh,
- section, section_is_gnu, is_dwz,
- offset_size, include_hash);
-
- htab_remove_elt (include_hash, (void *) new_mac_ptr);
- }
- }
- break;
-
- case DW_MACINFO_vendor_ext:
- if (!section_is_gnu)
- {
- unsigned int bytes_read;
-
- /* This reads the constant, but since we don't recognize
- any vendor extensions, we ignore it. */
- read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
- mac_ptr += bytes_read;
- read_direct_string (abfd, mac_ptr, &bytes_read);
- mac_ptr += bytes_read;
-
- /* We don't recognize any vendor extensions. */
- break;
- }
- /* FALLTHROUGH */
-
- default:
- mac_ptr = skip_unknown_opcode (macinfo_type, opcode_definitions,
- mac_ptr, mac_end, abfd, offset_size,
- section);
- if (mac_ptr == NULL)
- return;
- break;
- }
- DIAGNOSTIC_POP
- } while (macinfo_type != 0);
-}
-
-static void
-dwarf_decode_macros (struct dwarf2_per_objfile *dwarf2_per_objfile,
- buildsym_compunit *builder, dwarf2_section_info *section,
- struct line_header *lh, unsigned int offset_size,
- unsigned int offset, int section_is_gnu)
-{
- bfd *abfd;
- const gdb_byte *mac_ptr, *mac_end;
- struct macro_source_file *current_file = 0;
- enum dwarf_macro_record_type macinfo_type;
- const gdb_byte *opcode_definitions[256];
- void **slot;
-
- abfd = section->get_bfd_owner ();
-
- /* First pass: Find the name of the base filename.
- This filename is needed in order to process all macros whose definition
- (or undefinition) comes from the command line. These macros are defined
- before the first DW_MACINFO_start_file entry, and yet still need to be
- associated to the base file.
-
- To determine the base file name, we scan the macro definitions until we
- reach the first DW_MACINFO_start_file entry. We then initialize
- CURRENT_FILE accordingly so that any macro definition found before the
- first DW_MACINFO_start_file can still be associated to the base file. */
-
- mac_ptr = section->buffer + offset;
- mac_end = section->buffer + section->size;
-
- mac_ptr = dwarf_parse_macro_header (opcode_definitions, abfd, mac_ptr,
- &offset_size, section_is_gnu);
- if (mac_ptr == NULL)
- {
- /* We already issued a complaint. */
- return;
- }
-
- do
- {
- /* Do we at least have room for a macinfo type byte? */
- if (mac_ptr >= mac_end)
- {
- /* Complaint is printed during the second pass as GDB will probably
- stop the first pass earlier upon finding
- DW_MACINFO_start_file. */
- break;
- }
-
- macinfo_type = (enum dwarf_macro_record_type) read_1_byte (abfd, mac_ptr);
- mac_ptr++;
-
- /* Note that we rely on the fact that the corresponding GNU and
- DWARF constants are the same. */
- DIAGNOSTIC_PUSH
- DIAGNOSTIC_IGNORE_SWITCH_DIFFERENT_ENUM_TYPES
- switch (macinfo_type)
- {
- /* A zero macinfo type indicates the end of the macro
- information. */
- case 0:
- break;
-
- case DW_MACRO_define:
- case DW_MACRO_undef:
- /* Only skip the data by MAC_PTR. */
- {
- unsigned int bytes_read;
-
- read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
- mac_ptr += bytes_read;
- read_direct_string (abfd, mac_ptr, &bytes_read);
- mac_ptr += bytes_read;
- }
- break;
-
- case DW_MACRO_start_file:
- {
- unsigned int bytes_read;
- int line, file;
-
- line = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
- mac_ptr += bytes_read;
- file = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
- mac_ptr += bytes_read;
-
- current_file = macro_start_file (builder, file, line,
- current_file, lh);
- }
- break;
-
- case DW_MACRO_end_file:
- /* No data to skip by MAC_PTR. */
- break;
-
- case DW_MACRO_define_strp:
- case DW_MACRO_undef_strp:
- case DW_MACRO_define_sup:
- case DW_MACRO_undef_sup:
- {
- unsigned int bytes_read;
-
- read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
- mac_ptr += bytes_read;
- mac_ptr += offset_size;
- }
- break;
-
- case DW_MACRO_import:
- case DW_MACRO_import_sup:
- /* Note that, according to the spec, a transparent include
- chain cannot call DW_MACRO_start_file. So, we can just
- skip this opcode. */
- mac_ptr += offset_size;
- break;
-
- case DW_MACINFO_vendor_ext:
- /* Only skip the data by MAC_PTR. */
- if (!section_is_gnu)
- {
- unsigned int bytes_read;
-
- read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
- mac_ptr += bytes_read;
- read_direct_string (abfd, mac_ptr, &bytes_read);
- mac_ptr += bytes_read;
- }
- /* FALLTHROUGH */
-
- default:
- mac_ptr = skip_unknown_opcode (macinfo_type, opcode_definitions,
- mac_ptr, mac_end, abfd, offset_size,
- section);
- if (mac_ptr == NULL)
- return;
- break;
- }
- DIAGNOSTIC_POP
- } while (macinfo_type != 0 && current_file == NULL);
-
- /* Second pass: Process all entries.
-
- Use the AT_COMMAND_LINE flag to determine whether we are still processing
- command-line macro definitions/undefinitions. This flag is unset when we
- reach the first DW_MACINFO_start_file entry. */
-
- htab_up include_hash (htab_create_alloc (1, htab_hash_pointer,
- htab_eq_pointer,
- NULL, xcalloc, xfree));
- mac_ptr = section->buffer + offset;
- slot = htab_find_slot (include_hash.get (), mac_ptr, INSERT);
- *slot = (void *) mac_ptr;
- dwarf_decode_macro_bytes (dwarf2_per_objfile, builder,
- abfd, mac_ptr, mac_end,
- current_file, lh, section,
- section_is_gnu, 0, offset_size,
- include_hash.get ());
-}
+/* Macro support. */
/* An overload of dwarf_decode_macros that finds the correct section
and ensures it is read in before calling the other overload. */
--
2.17.2
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 09/22] Make some line_header methods const
2020-03-22 18:45 [PATCH 00/22] More splitting of dwarf2/read.c Tom Tromey
` (7 preceding siblings ...)
2020-03-22 18:45 ` [PATCH 08/22] Move code to new file dwarf2/macro.c Tom Tromey
@ 2020-03-22 18:45 ` Tom Tromey
2020-03-22 18:45 ` [PATCH 10/22] Use a const line_header in macro reader Tom Tromey
` (13 subsequent siblings)
22 siblings, 0 replies; 32+ messages in thread
From: Tom Tromey @ 2020-03-22 18:45 UTC (permalink / raw)
To: gdb-patches; +Cc: Tom Tromey
This changes a few line_header methods to be const. In some cases, a
const overload is added.
gdb/ChangeLog
2020-03-22 Tom Tromey <tom@tromey.com>
* dwarf2/line-header.h (struct line_header) <is_valid_file_index,
file_names_size, file_full_name, file_file_name>: Use const.
<file_name_at, file_names>: Add const overload.
* dwarf2/line-header.c (line_header::file_file_name)
(line_header::file_full_name): Update.
---
gdb/ChangeLog | 8 ++++++++
| 4 ++--
| 18 ++++++++++++++----
3 files changed, 24 insertions(+), 6 deletions(-)
--git a/gdb/dwarf2/line-header.c b/gdb/dwarf2/line-header.c
index 56dfb5c2dd2..f417f2d0fae 100644
--- a/gdb/dwarf2/line-header.c
+++ b/gdb/dwarf2/line-header.c
@@ -59,7 +59,7 @@ line_header::add_file_name (const char *name,
}
gdb::unique_xmalloc_ptr<char>
-line_header::file_file_name (int file)
+line_header::file_file_name (int file) const
{
/* Is the file number a valid index into the line header's file name
table? Remember that file numbers start with one, not zero. */
@@ -95,7 +95,7 @@ line_header::file_file_name (int file)
}
gdb::unique_xmalloc_ptr<char>
-line_header::file_full_name (int file, const char *comp_dir)
+line_header::file_full_name (int file, const char *comp_dir) const
{
/* Is the file number a valid index into the line header's file name
table? Remember that file numbers start with one, not zero. */
--git a/gdb/dwarf2/line-header.h b/gdb/dwarf2/line-header.h
index 08cf7b0810f..30bc37fb85a 100644
--- a/gdb/dwarf2/line-header.h
+++ b/gdb/dwarf2/line-header.h
@@ -96,7 +96,7 @@ struct line_header
return m_include_dirs[vec_index];
}
- bool is_valid_file_index (int file_index)
+ bool is_valid_file_index (int file_index) const
{
if (version >= 5)
return 0 <= file_index && file_index < file_names_size ();
@@ -117,11 +117,21 @@ struct line_header
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 {};
@@ -145,7 +155,7 @@ struct line_header
element is standard_opcode_lengths[opcode_base - 1]. */
std::unique_ptr<unsigned char[]> standard_opcode_lengths;
- int file_names_size ()
+ int file_names_size () const
{ return m_file_names.size(); }
/* The start and end of the statement program following this
@@ -157,13 +167,13 @@ struct line_header
compilation. The result is allocated using xmalloc; the caller
is responsible for freeing it. */
gdb::unique_xmalloc_ptr<char> file_full_name (int file,
- const char *comp_dir);
+ const char *comp_dir) const;
/* 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);
+ gdb::unique_xmalloc_ptr<char> file_file_name (int file) const;
private:
/* The include_directories table. Note these are observing
--
2.17.2
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 10/22] Use a const line_header in macro reader
2020-03-22 18:45 [PATCH 00/22] More splitting of dwarf2/read.c Tom Tromey
` (8 preceding siblings ...)
2020-03-22 18:45 ` [PATCH 09/22] Make some line_header methods const Tom Tromey
@ 2020-03-22 18:45 ` Tom Tromey
2020-03-22 18:45 ` [PATCH 11/22] Use a const dwarf2_section_info " Tom Tromey
` (12 subsequent siblings)
22 siblings, 0 replies; 32+ messages in thread
From: Tom Tromey @ 2020-03-22 18:45 UTC (permalink / raw)
To: gdb-patches; +Cc: Tom Tromey
This changes the DWARF macro reader to use a const line_header.
gdb/ChangeLog
2020-03-22 Tom Tromey <tom@tromey.com>
* dwarf2/read.c (dwarf_decode_macros): Make "lh" const.
* dwarf2/macro.h (dwarf_decode_macros): Constify "lh" parameter.
* dwarf2/macro.c (macro_start_file): Constify "lh" parameter.
(dwarf_decode_macro_bytes, dwarf_decode_macros): Likewise.
---
gdb/ChangeLog | 7 +++++++
gdb/dwarf2/macro.c | 6 +++---
gdb/dwarf2/macro.h | 2 +-
gdb/dwarf2/read.c | 2 +-
4 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/gdb/dwarf2/macro.c b/gdb/dwarf2/macro.c
index 1f1cca858c1..01af58de29f 100644
--- a/gdb/dwarf2/macro.c
+++ b/gdb/dwarf2/macro.c
@@ -48,7 +48,7 @@ static struct macro_source_file *
macro_start_file (buildsym_compunit *builder,
int file, int line,
struct macro_source_file *current_file,
- struct line_header *lh)
+ const struct line_header *lh)
{
/* File name relative to the compilation directory of this source file. */
gdb::unique_xmalloc_ptr<char> file_name = lh->file_file_name (file);
@@ -423,7 +423,7 @@ dwarf_decode_macro_bytes (struct dwarf2_per_objfile *dwarf2_per_objfile,
bfd *abfd,
const gdb_byte *mac_ptr, const gdb_byte *mac_end,
struct macro_source_file *current_file,
- struct line_header *lh,
+ const struct line_header *lh,
struct dwarf2_section_info *section,
int section_is_gnu, int section_is_dwz,
unsigned int offset_size,
@@ -711,7 +711,7 @@ dwarf_decode_macro_bytes (struct dwarf2_per_objfile *dwarf2_per_objfile,
void
dwarf_decode_macros (struct dwarf2_per_objfile *dwarf2_per_objfile,
buildsym_compunit *builder, dwarf2_section_info *section,
- struct line_header *lh, unsigned int offset_size,
+ const struct line_header *lh, unsigned int offset_size,
unsigned int offset, int section_is_gnu)
{
bfd *abfd;
diff --git a/gdb/dwarf2/macro.h b/gdb/dwarf2/macro.h
index 3937c550088..b92987cf0d1 100644
--- a/gdb/dwarf2/macro.h
+++ b/gdb/dwarf2/macro.h
@@ -25,7 +25,7 @@ struct buildsym_compunit;
extern void dwarf_decode_macros (struct dwarf2_per_objfile *dwarf2_per_objfile,
buildsym_compunit *builder,
dwarf2_section_info *section,
- struct line_header *lh,
+ const struct line_header *lh,
unsigned int offset_size,
unsigned int offset,
int section_is_gnu);
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index ca90418e45e..13fa63bff57 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -23045,7 +23045,7 @@ dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
struct dwarf2_per_objfile *dwarf2_per_objfile
= cu->per_cu->dwarf2_per_objfile;
struct objfile *objfile = dwarf2_per_objfile->objfile;
- struct line_header *lh = cu->line_header;
+ const struct line_header *lh = cu->line_header;
unsigned int offset_size = cu->header.offset_size;
struct dwarf2_section_info *section;
const char *section_name;
--
2.17.2
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 11/22] Use a const dwarf2_section_info in macro reader
2020-03-22 18:45 [PATCH 00/22] More splitting of dwarf2/read.c Tom Tromey
` (9 preceding siblings ...)
2020-03-22 18:45 ` [PATCH 10/22] Use a const line_header in macro reader Tom Tromey
@ 2020-03-22 18:45 ` Tom Tromey
2020-03-22 18:45 ` [PATCH 12/22] Trivial fix in dwarf_decode_macro_bytes Tom Tromey
` (11 subsequent siblings)
22 siblings, 0 replies; 32+ messages in thread
From: Tom Tromey @ 2020-03-22 18:45 UTC (permalink / raw)
To: gdb-patches; +Cc: Tom Tromey
This changes the DWARF macro reader to use a const dwarf2_section_info.
gdb/ChangeLog
2020-03-22 Tom Tromey <tom@tromey.com>
* dwarf2/macro.h (dwarf_decode_macros): Make section parameter
const.
* dwarf2/macro.c (skip_form_bytes, skip_unknown_opcode)
(dwarf_decode_macro_bytes, dwarf_decode_macros): Make section
parameter const.
---
gdb/ChangeLog | 8 ++++++++
gdb/dwarf2/macro.c | 11 ++++++-----
gdb/dwarf2/macro.h | 2 +-
3 files changed, 15 insertions(+), 6 deletions(-)
diff --git a/gdb/dwarf2/macro.c b/gdb/dwarf2/macro.c
index 01af58de29f..49586399673 100644
--- a/gdb/dwarf2/macro.c
+++ b/gdb/dwarf2/macro.c
@@ -231,7 +231,7 @@ static const gdb_byte *
skip_form_bytes (bfd *abfd, const gdb_byte *bytes, const gdb_byte *buffer_end,
enum dwarf_form form,
unsigned int offset_size,
- struct dwarf2_section_info *section)
+ const struct dwarf2_section_info *section)
{
unsigned int bytes_read;
@@ -322,7 +322,7 @@ skip_unknown_opcode (unsigned int opcode,
const gdb_byte *mac_ptr, const gdb_byte *mac_end,
bfd *abfd,
unsigned int offset_size,
- struct dwarf2_section_info *section)
+ const struct dwarf2_section_info *section)
{
unsigned int bytes_read, i;
unsigned long arg;
@@ -424,7 +424,7 @@ dwarf_decode_macro_bytes (struct dwarf2_per_objfile *dwarf2_per_objfile,
const gdb_byte *mac_ptr, const gdb_byte *mac_end,
struct macro_source_file *current_file,
const struct line_header *lh,
- struct dwarf2_section_info *section,
+ const struct dwarf2_section_info *section,
int section_is_gnu, int section_is_dwz,
unsigned int offset_size,
htab_t include_hash)
@@ -634,7 +634,7 @@ dwarf_decode_macro_bytes (struct dwarf2_per_objfile *dwarf2_per_objfile,
LONGEST offset;
void **slot;
bfd *include_bfd = abfd;
- struct dwarf2_section_info *include_section = section;
+ const struct dwarf2_section_info *include_section = section;
const gdb_byte *include_mac_end = mac_end;
int is_dwz = section_is_dwz;
const gdb_byte *new_mac_ptr;
@@ -710,7 +710,8 @@ dwarf_decode_macro_bytes (struct dwarf2_per_objfile *dwarf2_per_objfile,
void
dwarf_decode_macros (struct dwarf2_per_objfile *dwarf2_per_objfile,
- buildsym_compunit *builder, dwarf2_section_info *section,
+ buildsym_compunit *builder,
+ const dwarf2_section_info *section,
const struct line_header *lh, unsigned int offset_size,
unsigned int offset, int section_is_gnu)
{
diff --git a/gdb/dwarf2/macro.h b/gdb/dwarf2/macro.h
index b92987cf0d1..cb66a6f50cd 100644
--- a/gdb/dwarf2/macro.h
+++ b/gdb/dwarf2/macro.h
@@ -24,7 +24,7 @@ struct buildsym_compunit;
extern void dwarf_decode_macros (struct dwarf2_per_objfile *dwarf2_per_objfile,
buildsym_compunit *builder,
- dwarf2_section_info *section,
+ const dwarf2_section_info *section,
const struct line_header *lh,
unsigned int offset_size,
unsigned int offset,
--
2.17.2
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 12/22] Trivial fix in dwarf_decode_macro_bytes
2020-03-22 18:45 [PATCH 00/22] More splitting of dwarf2/read.c Tom Tromey
` (10 preceding siblings ...)
2020-03-22 18:45 ` [PATCH 11/22] Use a const dwarf2_section_info " Tom Tromey
@ 2020-03-22 18:45 ` Tom Tromey
2020-03-22 18:45 ` [PATCH 13/22] Convert read_indirect_line_string to a method Tom Tromey
` (10 subsequent siblings)
22 siblings, 0 replies; 32+ messages in thread
From: Tom Tromey @ 2020-03-22 18:45 UTC (permalink / raw)
To: gdb-patches; +Cc: Tom Tromey
One spot in dwarf_decode_macro_bytes could use the existing "objfile"
local variable.
gdb/ChangeLog
2020-03-22 Tom Tromey <tom@tromey.com>
* dwarf2/macro.c (dwarf_decode_macro_bytes): Use objfile local
variable.
---
gdb/ChangeLog | 5 +++++
gdb/dwarf2/macro.c | 6 +++---
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/gdb/dwarf2/macro.c b/gdb/dwarf2/macro.c
index 49586399673..6c2d2514652 100644
--- a/gdb/dwarf2/macro.c
+++ b/gdb/dwarf2/macro.c
@@ -512,9 +512,9 @@ dwarf_decode_macro_bytes (struct dwarf2_per_objfile *dwarf2_per_objfile,
body = dwz->read_string (objfile, str_offset);
}
else
- body = (dwarf2_per_objfile->str.read_string
- (dwarf2_per_objfile->objfile,
- str_offset, "DW_FORM_strp"));
+ body = dwarf2_per_objfile->str.read_string (objfile,
+ str_offset,
+ "DW_FORM_strp");
}
is_define = (macinfo_type == DW_MACRO_define
--
2.17.2
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 13/22] Convert read_indirect_line_string to a method
2020-03-22 18:45 [PATCH 00/22] More splitting of dwarf2/read.c Tom Tromey
` (11 preceding siblings ...)
2020-03-22 18:45 ` [PATCH 12/22] Trivial fix in dwarf_decode_macro_bytes Tom Tromey
@ 2020-03-22 18:45 ` Tom Tromey
2020-03-24 2:49 ` Simon Marchi
2020-03-22 18:45 ` [PATCH 14/22] Move more code to line-header.c Tom Tromey
` (9 subsequent siblings)
22 siblings, 1 reply; 32+ messages in thread
From: Tom Tromey @ 2020-03-22 18:45 UTC (permalink / raw)
To: gdb-patches; +Cc: Tom Tromey
This changes read_indirect_line_string to be a method on
dwarf2_per_objfile. This makes it a bit simpler to share between
files.
gdb/ChangeLog
2020-03-22 Tom Tromey <tom@tromey.com>
* dwarf2/read.h (struct dwarf2_per_objfile) <read_line_string>:
Declare method.
* dwarf2/read.c (read_attribute_value): Update.
(dwarf2_per_objfile::read_line_string): Rename from
read_indirect_line_string.
(read_formatted_entries): Update.
---
gdb/ChangeLog | 9 +++++++++
gdb/dwarf2/read.c | 28 +++++++++++-----------------
gdb/dwarf2/read.h | 8 ++++++++
3 files changed, 28 insertions(+), 17 deletions(-)
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 13fa63bff57..001030b31c0 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -1251,10 +1251,6 @@ static const char *read_indirect_string
(struct dwarf2_per_objfile *dwarf2_per_objfile, bfd *, const gdb_byte *,
const struct comp_unit_head *, unsigned int *);
-static const char *read_indirect_line_string
- (struct dwarf2_per_objfile *dwarf2_per_objfile, bfd *, const gdb_byte *,
- const struct comp_unit_head *, unsigned int *);
-
static const char *read_indirect_string_at_offset
(struct dwarf2_per_objfile *dwarf2_per_objfile, LONGEST str_offset);
@@ -18550,9 +18546,9 @@ read_attribute_value (const struct die_reader_specs *reader,
case DW_FORM_line_strp:
if (!cu->per_cu->is_dwz)
{
- DW_STRING (attr) = read_indirect_line_string (dwarf2_per_objfile,
- abfd, info_ptr,
- cu_header, &bytes_read);
+ DW_STRING (attr)
+ = dwarf2_per_objfile->read_line_string (info_ptr, cu_header,
+ &bytes_read);
DW_STRING_IS_CANONICAL (attr) = 0;
info_ptr += bytes_read;
break;
@@ -18790,17 +18786,15 @@ read_indirect_string (struct dwarf2_per_objfile *dwarf2_per_objfile, bfd *abfd,
BUF is assumed to be in a compilation unit described by CU_HEADER.
Return *BYTES_READ_PTR count of bytes read from BUF. */
-static const char *
-read_indirect_line_string (struct dwarf2_per_objfile *dwarf2_per_objfile,
- bfd *abfd, const gdb_byte *buf,
+const char *
+dwarf2_per_objfile::read_line_string (const gdb_byte *buf,
const struct comp_unit_head *cu_header,
unsigned int *bytes_read_ptr)
{
+ bfd *abfd = objfile->obfd;
LONGEST str_offset = cu_header->read_offset (abfd, buf, bytes_read_ptr);
- return dwarf2_per_objfile->line_str.read_string (dwarf2_per_objfile->objfile,
- str_offset,
- "DW_FORM_line_strp");
+ return line_str.read_string (objfile, str_offset, "DW_FORM_line_strp");
}
/* Given index ADDR_INDEX in .debug_addr, fetch the value.
@@ -19284,10 +19278,10 @@ read_formatted_entries (struct dwarf2_per_objfile *dwarf2_per_objfile,
break;
case DW_FORM_line_strp:
- string.emplace (read_indirect_line_string (dwarf2_per_objfile,
- abfd, buf,
- cu_header,
- &bytes_read));
+ string.emplace
+ (dwarf2_per_objfile->read_line_string (buf,
+ cu_header,
+ &bytes_read));
buf += bytes_read;
break;
diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h
index c5a8ecf8a6a..039113f87e9 100644
--- a/gdb/dwarf2/read.h
+++ b/gdb/dwarf2/read.h
@@ -110,6 +110,14 @@ struct dwarf2_per_objfile
/* Free all cached compilation units. */
void free_cached_comp_units ();
+
+ /* Return pointer to string at .debug_line_str offset as read from BUF.
+ BUF is assumed to be in a compilation unit described by CU_HEADER.
+ Return *BYTES_READ_PTR count of bytes read from BUF. */
+ const char *read_line_string (const gdb_byte *buf,
+ const struct comp_unit_head *cu_header,
+ unsigned int *bytes_read_ptr);
+
private:
/* This function is mapped across the sections and remembers the
offset and size of each of the debugging sections we are
--
2.17.2
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 14/22] Move more code to line-header.c
2020-03-22 18:45 [PATCH 00/22] More splitting of dwarf2/read.c Tom Tromey
` (12 preceding siblings ...)
2020-03-22 18:45 ` [PATCH 13/22] Convert read_indirect_line_string to a method Tom Tromey
@ 2020-03-22 18:45 ` Tom Tromey
2020-03-22 18:45 ` [PATCH 15/22] Move die_info to new header Tom Tromey
` (8 subsequent siblings)
22 siblings, 0 replies; 32+ messages in thread
From: Tom Tromey @ 2020-03-22 18:45 UTC (permalink / raw)
To: gdb-patches; +Cc: Tom Tromey
This moves some more code out of read.c and into line-header.c.
dwarf_decode_line_header is split into two -- the part remaining in
read.c handles interfacing to the dwarf2_cu; while the part in
line-header.c (more or less) purely handles the actual decoding.
gdb/ChangeLog
2020-03-22 Tom Tromey <tom@tromey.com>
* dwarf2/line-header.h (dwarf_decode_line_header): Declare.
* dwarf2/read.c
(dwarf2_statement_list_fits_in_line_number_section_complaint):
Move to line-header.c.
(read_checked_initial_length_and_offset, read_formatted_entries):
Likewise.
(dwarf_decode_line_header): Split into two.
* dwarf2/line-header.c
(dwarf2_statement_list_fits_in_line_number_section_complaint):
Move from read.c.
(read_checked_initial_length_and_offset, read_formatted_entries):
Likewise.
(dwarf_decode_line_header): New function, split from read.c.
---
gdb/ChangeLog | 16 ++
| 335 +++++++++++++++++++++++++++++++++++++++
| 14 ++
gdb/dwarf2/read.c | 332 +-------------------------------------
4 files changed, 368 insertions(+), 329 deletions(-)
--git a/gdb/dwarf2/line-header.c b/gdb/dwarf2/line-header.c
index f417f2d0fae..58749e9594b 100644
--- a/gdb/dwarf2/line-header.c
+++ b/gdb/dwarf2/line-header.c
@@ -18,6 +18,8 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
+#include "dwarf2/comp-unit.h"
+#include "dwarf2/leb.h"
#include "dwarf2/line-header.h"
#include "dwarf2/read.h"
#include "complaints.h"
@@ -112,3 +114,336 @@ line_header::file_full_name (int file, const char *comp_dir) const
else
return file_file_name (file);
}
+
+static void
+dwarf2_statement_list_fits_in_line_number_section_complaint (void)
+{
+ complaint (_("statement list doesn't fit in .debug_line section"));
+}
+
+/* Cover function for read_initial_length.
+ Returns the length of the object at BUF, and stores the size of the
+ initial length in *BYTES_READ and stores the size that offsets will be in
+ *OFFSET_SIZE.
+ If the initial length size is not equivalent to that specified in
+ CU_HEADER then issue a complaint.
+ This is useful when reading non-comp-unit headers. */
+
+static LONGEST
+read_checked_initial_length_and_offset (bfd *abfd, const gdb_byte *buf,
+ const struct comp_unit_head *cu_header,
+ unsigned int *bytes_read,
+ unsigned int *offset_size)
+{
+ LONGEST length = read_initial_length (abfd, buf, bytes_read);
+
+ gdb_assert (cu_header->initial_length_size == 4
+ || cu_header->initial_length_size == 8
+ || cu_header->initial_length_size == 12);
+
+ if (cu_header->initial_length_size != *bytes_read)
+ complaint (_("intermixed 32-bit and 64-bit DWARF sections"));
+
+ *offset_size = (*bytes_read == 4) ? 4 : 8;
+ return length;
+}
+
+/* Read directory or file name entry format, starting with byte of
+ format count entries, ULEB128 pairs of entry formats, ULEB128 of
+ entries count and the entries themselves in the described entry
+ format. */
+
+static void
+read_formatted_entries (struct dwarf2_per_objfile *dwarf2_per_objfile,
+ bfd *abfd, const gdb_byte **bufp,
+ struct line_header *lh,
+ const struct comp_unit_head *cu_header,
+ void (*callback) (struct line_header *lh,
+ const char *name,
+ dir_index d_index,
+ unsigned int mod_time,
+ unsigned int length))
+{
+ gdb_byte format_count, formati;
+ ULONGEST data_count, datai;
+ const gdb_byte *buf = *bufp;
+ const gdb_byte *format_header_data;
+ unsigned int bytes_read;
+
+ format_count = read_1_byte (abfd, buf);
+ buf += 1;
+ format_header_data = buf;
+ for (formati = 0; formati < format_count; formati++)
+ {
+ read_unsigned_leb128 (abfd, buf, &bytes_read);
+ buf += bytes_read;
+ read_unsigned_leb128 (abfd, buf, &bytes_read);
+ buf += bytes_read;
+ }
+
+ data_count = read_unsigned_leb128 (abfd, buf, &bytes_read);
+ buf += bytes_read;
+ for (datai = 0; datai < data_count; datai++)
+ {
+ const gdb_byte *format = format_header_data;
+ struct file_entry fe;
+
+ for (formati = 0; formati < format_count; formati++)
+ {
+ ULONGEST content_type = read_unsigned_leb128 (abfd, format, &bytes_read);
+ format += bytes_read;
+
+ ULONGEST form = read_unsigned_leb128 (abfd, format, &bytes_read);
+ format += bytes_read;
+
+ gdb::optional<const char *> string;
+ gdb::optional<unsigned int> uint;
+
+ switch (form)
+ {
+ case DW_FORM_string:
+ string.emplace (read_direct_string (abfd, buf, &bytes_read));
+ buf += bytes_read;
+ break;
+
+ case DW_FORM_line_strp:
+ string.emplace
+ (dwarf2_per_objfile->read_line_string (buf,
+ cu_header,
+ &bytes_read));
+ buf += bytes_read;
+ break;
+
+ case DW_FORM_data1:
+ uint.emplace (read_1_byte (abfd, buf));
+ buf += 1;
+ break;
+
+ case DW_FORM_data2:
+ uint.emplace (read_2_bytes (abfd, buf));
+ buf += 2;
+ break;
+
+ case DW_FORM_data4:
+ uint.emplace (read_4_bytes (abfd, buf));
+ buf += 4;
+ break;
+
+ case DW_FORM_data8:
+ uint.emplace (read_8_bytes (abfd, buf));
+ buf += 8;
+ break;
+
+ case DW_FORM_data16:
+ /* This is used for MD5, but file_entry does not record MD5s. */
+ buf += 16;
+ break;
+
+ case DW_FORM_udata:
+ uint.emplace (read_unsigned_leb128 (abfd, buf, &bytes_read));
+ buf += bytes_read;
+ break;
+
+ case DW_FORM_block:
+ /* It is valid only for DW_LNCT_timestamp which is ignored by
+ 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 (_("Unknown format content type %s"),
+ pulongest (content_type));
+ }
+ }
+
+ callback (lh, fe.name, fe.d_index, fe.mod_time, fe.length);
+ }
+
+ *bufp = buf;
+}
+
+/* See line-header.h. */
+
+line_header_up
+dwarf_decode_line_header (sect_offset sect_off, bool is_dwz,
+ struct dwarf2_per_objfile *dwarf2_per_objfile,
+ struct dwarf2_section_info *section,
+ const struct comp_unit_head *cu_header)
+{
+ const gdb_byte *line_ptr;
+ unsigned int bytes_read, offset_size;
+ int i;
+ const char *cur_dir, *cur_file;
+
+ bfd *abfd = section->get_bfd_owner ();
+
+ /* Make sure that at least there's room for the total_length field.
+ That could be 12 bytes long, but we're just going to fudge that. */
+ if (to_underlying (sect_off) + 4 >= section->size)
+ {
+ dwarf2_statement_list_fits_in_line_number_section_complaint ();
+ return 0;
+ }
+
+ line_header_up lh (new line_header ());
+
+ lh->sect_off = sect_off;
+ lh->offset_in_dwz = is_dwz;
+
+ line_ptr = section->buffer + to_underlying (sect_off);
+
+ /* Read in the header. */
+ lh->total_length =
+ 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 = start_here + lh->total_length;
+ lh->version = read_2_bytes (abfd, line_ptr);
+ line_ptr += 2;
+ if (lh->version > 5)
+ {
+ /* This is a version we don't understand. The format could have
+ changed in ways we don't handle properly so just punt. */
+ complaint (_("unsupported version in .debug_line section"));
+ return NULL;
+ }
+ if (lh->version >= 5)
+ {
+ gdb_byte segment_selector_size;
+
+ /* Skip address size. */
+ read_1_byte (abfd, line_ptr);
+ line_ptr += 1;
+
+ segment_selector_size = read_1_byte (abfd, line_ptr);
+ line_ptr += 1;
+ if (segment_selector_size != 0)
+ {
+ complaint (_("unsupported segment selector size %u "
+ "in .debug_line section"),
+ segment_selector_size);
+ return NULL;
+ }
+ }
+ lh->header_length = read_offset (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)
+ {
+ lh->maximum_ops_per_instruction = read_1_byte (abfd, line_ptr);
+ line_ptr += 1;
+ }
+ else
+ lh->maximum_ops_per_instruction = 1;
+
+ if (lh->maximum_ops_per_instruction == 0)
+ {
+ lh->maximum_ops_per_instruction = 1;
+ complaint (_("invalid maximum_ops_per_instruction "
+ "in `.debug_line' section"));
+ }
+
+ lh->default_is_stmt = read_1_byte (abfd, line_ptr);
+ line_ptr += 1;
+ lh->line_base = read_1_signed_byte (abfd, line_ptr);
+ line_ptr += 1;
+ lh->line_range = read_1_byte (abfd, line_ptr);
+ line_ptr += 1;
+ lh->opcode_base = read_1_byte (abfd, line_ptr);
+ line_ptr += 1;
+ lh->standard_opcode_lengths.reset (new unsigned char[lh->opcode_base]);
+
+ lh->standard_opcode_lengths[0] = 1; /* This should never be used anyway. */
+ for (i = 1; i < lh->opcode_base; ++i)
+ {
+ lh->standard_opcode_lengths[i] = read_1_byte (abfd, line_ptr);
+ line_ptr += 1;
+ }
+
+ if (lh->version >= 5)
+ {
+ /* Read directory table. */
+ read_formatted_entries (dwarf2_per_objfile, abfd, &line_ptr, lh.get (),
+ cu_header,
+ [] (struct line_header *header, const char *name,
+ dir_index d_index, unsigned int mod_time,
+ unsigned int length)
+ {
+ header->add_include_dir (name);
+ });
+
+ /* Read file name table. */
+ read_formatted_entries (dwarf2_per_objfile, abfd, &line_ptr, lh.get (),
+ cu_header,
+ [] (struct line_header *header, const char *name,
+ dir_index d_index, unsigned int mod_time,
+ unsigned int length)
+ {
+ header->add_file_name (name, d_index, mod_time, length);
+ });
+ }
+ else
+ {
+ /* Read directory table. */
+ while ((cur_dir = read_direct_string (abfd, line_ptr, &bytes_read)) != NULL)
+ {
+ line_ptr += bytes_read;
+ lh->add_include_dir (cur_dir);
+ }
+ line_ptr += bytes_read;
+
+ /* Read file name table. */
+ while ((cur_file = read_direct_string (abfd, line_ptr, &bytes_read)) != NULL)
+ {
+ unsigned int mod_time, length;
+ dir_index d_index;
+
+ 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, d_index, mod_time, length);
+ }
+ line_ptr += bytes_read;
+ }
+
+ if (line_ptr > (section->buffer + section->size))
+ complaint (_("line number info header doesn't "
+ "fit in `.debug_line' section"));
+
+ return lh;
+}
--git a/gdb/dwarf2/line-header.h b/gdb/dwarf2/line-header.h
index 30bc37fb85a..700aaddacf7 100644
--- a/gdb/dwarf2/line-header.h
+++ b/gdb/dwarf2/line-header.h
@@ -195,4 +195,18 @@ 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,
+ struct dwarf2_per_objfile *dwarf2_per_objfile,
+ struct dwarf2_section_info *section,
+ const struct comp_unit_head *cu_header);
+
#endif /* DWARF2_LINE_HEADER_H */
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 001030b31c0..5d9fed2d827 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -1239,10 +1239,6 @@ static void read_attribute_reprocess (const struct die_reader_specs *reader,
static CORE_ADDR read_addr_index (struct dwarf2_cu *cu, unsigned int addr_index);
-static LONGEST read_checked_initial_length_and_offset
- (bfd *, const gdb_byte *, const struct comp_unit_head *,
- unsigned int *, unsigned int *);
-
static sect_offset read_abbrev_offset
(struct dwarf2_per_objfile *dwarf2_per_objfile,
struct dwarf2_section_info *, sect_offset);
@@ -1673,12 +1669,6 @@ static void free_line_header_voidp (void *arg);
\f
/* Various complaints about symbol reading that don't abort the process. */
-static void
-dwarf2_statement_list_fits_in_line_number_section_complaint (void)
-{
- complaint (_("statement list doesn't fit in .debug_line section"));
-}
-
static void
dwarf2_debug_line_missing_file_complaint (void)
{
@@ -18730,33 +18720,6 @@ read_attribute (const struct die_reader_specs *reader,
need_reprocess);
}
-/* Cover function for read_initial_length.
- Returns the length of the object at BUF, and stores the size of the
- initial length in *BYTES_READ and stores the size that offsets will be in
- *OFFSET_SIZE.
- If the initial length size is not equivalent to that specified in
- CU_HEADER then issue a complaint.
- This is useful when reading non-comp-unit headers. */
-
-static LONGEST
-read_checked_initial_length_and_offset (bfd *abfd, const gdb_byte *buf,
- const struct comp_unit_head *cu_header,
- unsigned int *bytes_read,
- unsigned int *offset_size)
-{
- LONGEST length = read_initial_length (abfd, buf, bytes_read);
-
- gdb_assert (cu_header->initial_length_size == 4
- || cu_header->initial_length_size == 8
- || cu_header->initial_length_size == 12);
-
- if (cu_header->initial_length_size != *bytes_read)
- complaint (_("intermixed 32-bit and 64-bit DWARF sections"));
-
- *offset_size = (*bytes_read == 4) ? 4 : 8;
- return length;
-}
-
/* Return pointer to string at .debug_str offset STR_OFFSET. */
static const char *
@@ -19219,140 +19182,6 @@ get_debug_line_section (struct dwarf2_cu *cu)
return section;
}
-/* Read directory or file name entry format, starting with byte of
- format count entries, ULEB128 pairs of entry formats, ULEB128 of
- entries count and the entries themselves in the described entry
- format. */
-
-static void
-read_formatted_entries (struct dwarf2_per_objfile *dwarf2_per_objfile,
- bfd *abfd, const gdb_byte **bufp,
- struct line_header *lh,
- const struct comp_unit_head *cu_header,
- void (*callback) (struct line_header *lh,
- const char *name,
- dir_index d_index,
- unsigned int mod_time,
- unsigned int length))
-{
- gdb_byte format_count, formati;
- ULONGEST data_count, datai;
- const gdb_byte *buf = *bufp;
- const gdb_byte *format_header_data;
- unsigned int bytes_read;
-
- format_count = read_1_byte (abfd, buf);
- buf += 1;
- format_header_data = buf;
- for (formati = 0; formati < format_count; formati++)
- {
- read_unsigned_leb128 (abfd, buf, &bytes_read);
- buf += bytes_read;
- read_unsigned_leb128 (abfd, buf, &bytes_read);
- buf += bytes_read;
- }
-
- data_count = read_unsigned_leb128 (abfd, buf, &bytes_read);
- buf += bytes_read;
- for (datai = 0; datai < data_count; datai++)
- {
- const gdb_byte *format = format_header_data;
- struct file_entry fe;
-
- for (formati = 0; formati < format_count; formati++)
- {
- ULONGEST content_type = read_unsigned_leb128 (abfd, format, &bytes_read);
- format += bytes_read;
-
- ULONGEST form = read_unsigned_leb128 (abfd, format, &bytes_read);
- format += bytes_read;
-
- gdb::optional<const char *> string;
- gdb::optional<unsigned int> uint;
-
- switch (form)
- {
- case DW_FORM_string:
- string.emplace (read_direct_string (abfd, buf, &bytes_read));
- buf += bytes_read;
- break;
-
- case DW_FORM_line_strp:
- string.emplace
- (dwarf2_per_objfile->read_line_string (buf,
- cu_header,
- &bytes_read));
- buf += bytes_read;
- break;
-
- case DW_FORM_data1:
- uint.emplace (read_1_byte (abfd, buf));
- buf += 1;
- break;
-
- case DW_FORM_data2:
- uint.emplace (read_2_bytes (abfd, buf));
- buf += 2;
- break;
-
- case DW_FORM_data4:
- uint.emplace (read_4_bytes (abfd, buf));
- buf += 4;
- break;
-
- case DW_FORM_data8:
- uint.emplace (read_8_bytes (abfd, buf));
- buf += 8;
- break;
-
- case DW_FORM_data16:
- /* This is used for MD5, but file_entry does not record MD5s. */
- buf += 16;
- break;
-
- case DW_FORM_udata:
- uint.emplace (read_unsigned_leb128 (abfd, buf, &bytes_read));
- buf += bytes_read;
- break;
-
- case DW_FORM_block:
- /* It is valid only for DW_LNCT_timestamp which is ignored by
- 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 (_("Unknown format content type %s"),
- pulongest (content_type));
- }
- }
-
- callback (lh, fe.name, fe.d_index, fe.mod_time, fe.length);
- }
-
- *bufp = buf;
-}
-
/* Read the statement program header starting at OFFSET in
.debug_line, or .debug_line.dwo. Return a pointer
to a struct line_header, allocated using xmalloc.
@@ -19366,12 +19195,7 @@ read_formatted_entries (struct dwarf2_per_objfile *dwarf2_per_objfile,
static line_header_up
dwarf_decode_line_header (sect_offset sect_off, struct dwarf2_cu *cu)
{
- const gdb_byte *line_ptr;
- unsigned int bytes_read, offset_size;
- int i;
- const char *cur_dir, *cur_file;
struct dwarf2_section_info *section;
- bfd *abfd;
struct dwarf2_per_objfile *dwarf2_per_objfile
= cu->per_cu->dwarf2_per_objfile;
@@ -19386,159 +19210,9 @@ dwarf_decode_line_header (sect_offset sect_off, struct dwarf2_cu *cu)
return 0;
}
- /* We can't do this until we know the section is non-empty.
- Only then do we know we have such a section. */
- abfd = section->get_bfd_owner ();
-
- /* Make sure that at least there's room for the total_length field.
- That could be 12 bytes long, but we're just going to fudge that. */
- if (to_underlying (sect_off) + 4 >= section->size)
- {
- dwarf2_statement_list_fits_in_line_number_section_complaint ();
- return 0;
- }
-
- line_header_up lh (new line_header ());
-
- lh->sect_off = sect_off;
- lh->offset_in_dwz = cu->per_cu->is_dwz;
-
- line_ptr = section->buffer + to_underlying (sect_off);
-
- /* Read in the header. */
- lh->total_length =
- 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 = start_here + lh->total_length;
- lh->version = read_2_bytes (abfd, line_ptr);
- line_ptr += 2;
- if (lh->version > 5)
- {
- /* This is a version we don't understand. The format could have
- changed in ways we don't handle properly so just punt. */
- complaint (_("unsupported version in .debug_line section"));
- return NULL;
- }
- if (lh->version >= 5)
- {
- gdb_byte segment_selector_size;
-
- /* Skip address size. */
- read_1_byte (abfd, line_ptr);
- line_ptr += 1;
-
- segment_selector_size = read_1_byte (abfd, line_ptr);
- line_ptr += 1;
- if (segment_selector_size != 0)
- {
- complaint (_("unsupported segment selector size %u "
- "in .debug_line section"),
- segment_selector_size);
- return NULL;
- }
- }
- lh->header_length = read_offset (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)
- {
- lh->maximum_ops_per_instruction = read_1_byte (abfd, line_ptr);
- line_ptr += 1;
- }
- else
- lh->maximum_ops_per_instruction = 1;
-
- if (lh->maximum_ops_per_instruction == 0)
- {
- lh->maximum_ops_per_instruction = 1;
- complaint (_("invalid maximum_ops_per_instruction "
- "in `.debug_line' section"));
- }
-
- lh->default_is_stmt = read_1_byte (abfd, line_ptr);
- line_ptr += 1;
- lh->line_base = read_1_signed_byte (abfd, line_ptr);
- line_ptr += 1;
- lh->line_range = read_1_byte (abfd, line_ptr);
- line_ptr += 1;
- lh->opcode_base = read_1_byte (abfd, line_ptr);
- line_ptr += 1;
- lh->standard_opcode_lengths.reset (new unsigned char[lh->opcode_base]);
-
- lh->standard_opcode_lengths[0] = 1; /* This should never be used anyway. */
- for (i = 1; i < lh->opcode_base; ++i)
- {
- lh->standard_opcode_lengths[i] = read_1_byte (abfd, line_ptr);
- line_ptr += 1;
- }
-
- if (lh->version >= 5)
- {
- /* Read directory table. */
- read_formatted_entries (dwarf2_per_objfile, abfd, &line_ptr, lh.get (),
- &cu->header,
- [] (struct line_header *header, const char *name,
- dir_index d_index, unsigned int mod_time,
- unsigned int length)
- {
- header->add_include_dir (name);
- });
-
- /* Read file name table. */
- read_formatted_entries (dwarf2_per_objfile, abfd, &line_ptr, lh.get (),
- &cu->header,
- [] (struct line_header *header, const char *name,
- dir_index d_index, unsigned int mod_time,
- unsigned int length)
- {
- header->add_file_name (name, d_index, mod_time, length);
- });
- }
- else
- {
- /* Read directory table. */
- while ((cur_dir = read_direct_string (abfd, line_ptr, &bytes_read)) != NULL)
- {
- line_ptr += bytes_read;
- lh->add_include_dir (cur_dir);
- }
- line_ptr += bytes_read;
-
- /* Read file name table. */
- while ((cur_file = read_direct_string (abfd, line_ptr, &bytes_read)) != NULL)
- {
- unsigned int mod_time, length;
- dir_index d_index;
-
- 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, d_index, mod_time, length);
- }
- line_ptr += bytes_read;
- }
-
- if (line_ptr > (section->buffer + section->size))
- complaint (_("line number info header doesn't "
- "fit in `.debug_line' section"));
-
- return lh;
+ return dwarf_decode_line_header (sect_off, cu->per_cu->is_dwz,
+ dwarf2_per_objfile, section,
+ &cu->header);
}
/* Subroutine of dwarf_decode_lines to simplify it.
--
2.17.2
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 15/22] Move die_info to new header
2020-03-22 18:45 [PATCH 00/22] More splitting of dwarf2/read.c Tom Tromey
` (13 preceding siblings ...)
2020-03-22 18:45 ` [PATCH 14/22] Move more code to line-header.c Tom Tromey
@ 2020-03-22 18:45 ` Tom Tromey
2020-03-22 18:45 ` [PATCH 16/22] Remove dwarf2_cu::base_known Tom Tromey
` (7 subsequent siblings)
22 siblings, 0 replies; 32+ messages in thread
From: Tom Tromey @ 2020-03-22 18:45 UTC (permalink / raw)
To: gdb-patches; +Cc: Tom Tromey
This moves struct die_info to a new header, dwarf2/die.h.
gdb/ChangeLog
2020-03-22 Tom Tromey <tom@tromey.com>
* dwarf2/read.c (struct die_info): Move to die.h.
* dwarf2/die.h: New file.
---
gdb/ChangeLog | 5 ++++
gdb/dwarf2/die.h | 62 +++++++++++++++++++++++++++++++++++++++++++++++
gdb/dwarf2/read.c | 40 +-----------------------------
3 files changed, 68 insertions(+), 39 deletions(-)
create mode 100644 gdb/dwarf2/die.h
diff --git a/gdb/dwarf2/die.h b/gdb/dwarf2/die.h
new file mode 100644
index 00000000000..f8826a276e8
--- /dev/null
+++ b/gdb/dwarf2/die.h
@@ -0,0 +1,62 @@
+/* DWARF DIEs
+
+ Copyright (C) 2003-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 <http://www.gnu.org/licenses/>. */
+
+#ifndef GDB_DWARF2_DIE_H
+#define GDB_DWARF2_DIE_H
+
+/* This data structure holds a complete die structure. */
+struct die_info
+{
+ /* DWARF-2 tag for this DIE. */
+ ENUM_BITFIELD(dwarf_tag) tag : 16;
+
+ /* Number of attributes */
+ unsigned char num_attrs;
+
+ /* True if we're presently building the full type name for the
+ type derived from this DIE. */
+ unsigned char building_fullname : 1;
+
+ /* True if this die is in process. PR 16581. */
+ unsigned char in_process : 1;
+
+ /* True if this DIE has children. */
+ unsigned char has_children : 1;
+
+ /* Abbrev number */
+ unsigned int abbrev;
+
+ /* Offset in .debug_info or .debug_types section. */
+ sect_offset sect_off;
+
+ /* The dies in a compilation unit form an n-ary tree. PARENT
+ points to this die's parent; CHILD points to the first child of
+ this node; and all the children of a given node are chained
+ together via their SIBLING fields. */
+ struct die_info *child; /* Its first child, if any. */
+ struct die_info *sibling; /* Its next sibling, if any. */
+ struct die_info *parent; /* Its parent, if any. */
+
+ /* An array of attributes, with NUM_ATTRS elements. There may be
+ zero, but it's not common and zero-sized arrays are not
+ sufficiently portable C. */
+ struct attribute attrs[1];
+};
+
+#endif /* GDB_DWARF2_DIE_H */
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 5d9fed2d827..8b9b6bc3ea0 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -39,6 +39,7 @@
#include "dwarf2/line-header.h"
#include "dwarf2/dwz.h"
#include "dwarf2/macro.h"
+#include "dwarf2/die.h"
#include "bfd.h"
#include "elf-bfd.h"
#include "symtab.h"
@@ -1045,45 +1046,6 @@ struct partial_die_info : public allocate_on_obstack
}
};
-/* This data structure holds a complete die structure. */
-struct die_info
- {
- /* DWARF-2 tag for this DIE. */
- ENUM_BITFIELD(dwarf_tag) tag : 16;
-
- /* Number of attributes */
- unsigned char num_attrs;
-
- /* True if we're presently building the full type name for the
- type derived from this DIE. */
- unsigned char building_fullname : 1;
-
- /* True if this die is in process. PR 16581. */
- unsigned char in_process : 1;
-
- /* True if this DIE has children. */
- unsigned char has_children : 1;
-
- /* Abbrev number */
- unsigned int abbrev;
-
- /* Offset in .debug_info or .debug_types section. */
- sect_offset sect_off;
-
- /* The dies in a compilation unit form an n-ary tree. PARENT
- points to this die's parent; CHILD points to the first child of
- this node; and all the children of a given node are chained
- together via their SIBLING fields. */
- struct die_info *child; /* Its first child, if any. */
- struct die_info *sibling; /* Its next sibling, if any. */
- struct die_info *parent; /* Its parent, if any. */
-
- /* An array of attributes, with NUM_ATTRS elements. There may be
- zero, but it's not common and zero-sized arrays are not
- sufficiently portable C. */
- struct attribute attrs[1];
- };
-
/* FIXME: We might want to set this from BFD via bfd_arch_bits_per_byte,
but this would require a corresponding change in unpack_field_as_long
and friends. */
--
2.17.2
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 16/22] Remove dwarf2_cu::base_known
2020-03-22 18:45 [PATCH 00/22] More splitting of dwarf2/read.c Tom Tromey
` (14 preceding siblings ...)
2020-03-22 18:45 ` [PATCH 15/22] Move die_info to new header Tom Tromey
@ 2020-03-22 18:45 ` Tom Tromey
2020-03-22 18:45 ` [PATCH 17/22] Change dwarf2_attr_no_follow to be a method Tom Tromey
` (6 subsequent siblings)
22 siblings, 0 replies; 32+ messages in thread
From: Tom Tromey @ 2020-03-22 18:45 UTC (permalink / raw)
To: gdb-patches; +Cc: Tom Tromey
This removes dwarf2_cu::base_known, changing base_address to be a
gdb::optional.
gdb/ChangeLog
2020-03-22 Tom Tromey <tom@tromey.com>
* dwarf2/read.c (struct dwarf2_cu) <base_known>: Remove.
<base_address>: Now an optional.
(dwarf2_find_base_address, dwarf2_rnglists_process)
(dwarf2_ranges_process, fill_in_loclist_baton)
(dwarf2_symbol_mark_computed): Update.
---
gdb/ChangeLog | 8 ++++++++
gdb/dwarf2/read.c | 47 +++++++++++++++++------------------------------
2 files changed, 25 insertions(+), 30 deletions(-)
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 8b9b6bc3ea0..3479cd55a2e 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -393,10 +393,7 @@ struct dwarf2_cu
struct comp_unit_head header {};
/* Base address of this compilation unit. */
- CORE_ADDR base_address = 0;
-
- /* Non-zero if base_address has been set. */
- int base_known = 0;
+ gdb::optional<CORE_ADDR> base_address;
/* The language we are debugging. */
enum language language = language_unknown;
@@ -5783,23 +5780,16 @@ dwarf2_find_base_address (struct die_info *die, struct dwarf2_cu *cu)
{
struct attribute *attr;
- cu->base_known = 0;
- cu->base_address = 0;
+ cu->base_address.reset ();
attr = dwarf2_attr (die, DW_AT_entry_pc, cu);
if (attr != nullptr)
- {
- cu->base_address = attr->value_as_address ();
- cu->base_known = 1;
- }
+ cu->base_address = attr->value_as_address ();
else
{
attr = dwarf2_attr (die, DW_AT_low_pc, cu);
if (attr != nullptr)
- {
- cu->base_address = attr->value_as_address ();
- cu->base_known = 1;
- }
+ cu->base_address = attr->value_as_address ();
}
}
@@ -13441,13 +13431,11 @@ dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
struct objfile *objfile = dwarf2_per_objfile->objfile;
bfd *obfd = objfile->obfd;
/* Base address selection entry. */
- CORE_ADDR base;
- int found_base;
+ gdb::optional<CORE_ADDR> base;
const gdb_byte *buffer;
CORE_ADDR baseaddr;
bool overflow = false;
- found_base = cu->base_known;
base = cu->base_address;
dwarf2_per_objfile->rnglists.read (objfile);
@@ -13486,7 +13474,6 @@ dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
break;
}
base = cu->header.read_address (obfd, buffer, &bytes_read);
- found_base = 1;
buffer += bytes_read;
break;
case DW_RLE_start_length:
@@ -13544,7 +13531,7 @@ dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
if (rlet == DW_RLE_base_address)
continue;
- if (!found_base)
+ if (!base.has_value ())
{
/* We have no valid base address for the ranges
data. */
@@ -13563,8 +13550,8 @@ dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
if (range_beginning == range_end)
continue;
- range_beginning += base;
- range_end += base;
+ range_beginning += *base;
+ range_end += *base;
/* A not-uncommon case of bad debug info.
Don't pollute the addrmap with bad data. */
@@ -13608,8 +13595,7 @@ dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu,
unsigned int addr_size = cu_header->addr_size;
CORE_ADDR mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1));
/* Base address selection entry. */
- CORE_ADDR base;
- int found_base;
+ gdb::optional<CORE_ADDR> base;
unsigned int dummy;
const gdb_byte *buffer;
CORE_ADDR baseaddr;
@@ -13617,7 +13603,6 @@ dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu,
if (cu_header->version >= 5)
return dwarf2_rnglists_process (offset, cu, callback);
- found_base = cu->base_known;
base = cu->base_address;
dwarf2_per_objfile->ranges.read (objfile);
@@ -13654,11 +13639,10 @@ dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu,
/* If we found the largest possible address, then we already
have the base address in range_end. */
base = range_end;
- found_base = 1;
continue;
}
- if (!found_base)
+ if (!base.has_value ())
{
/* We have no valid base address for the ranges
data. */
@@ -13677,8 +13661,8 @@ dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu,
if (range_beginning == range_end)
continue;
- range_beginning += base;
- range_end += base;
+ range_beginning += *base;
+ range_end += *base;
/* A not-uncommon case of bad debug info.
Don't pollute the addrmap with bad data. */
@@ -22758,7 +22742,10 @@ fill_in_loclist_baton (struct dwarf2_cu *cu,
don't run off the edge of the section. */
baton->size = section->size - DW_UNSND (attr);
baton->data = section->buffer + DW_UNSND (attr);
- baton->base_address = cu->base_address;
+ if (cu->base_address.has_value ())
+ baton->base_address = *cu->base_address;
+ else
+ baton->base_address = 0;
baton->from_dwo = cu->dwo_unit != NULL;
}
@@ -22783,7 +22770,7 @@ dwarf2_symbol_mark_computed (const struct attribute *attr, struct symbol *sym,
fill_in_loclist_baton (cu, baton, attr);
- if (cu->base_known == 0)
+ if (!cu->base_address.has_value ())
complaint (_("Location list used without "
"specifying the CU base address."));
--
2.17.2
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 17/22] Change dwarf2_attr_no_follow to be a method
2020-03-22 18:45 [PATCH 00/22] More splitting of dwarf2/read.c Tom Tromey
` (15 preceding siblings ...)
2020-03-22 18:45 ` [PATCH 16/22] Remove dwarf2_cu::base_known Tom Tromey
@ 2020-03-22 18:45 ` Tom Tromey
2020-03-22 18:45 ` [PATCH 18/22] Remove sibling_die Tom Tromey
` (5 subsequent siblings)
22 siblings, 0 replies; 32+ messages in thread
From: Tom Tromey @ 2020-03-22 18:45 UTC (permalink / raw)
To: gdb-patches; +Cc: Tom Tromey
This changes dwarf2_attr_no_follow to be a method on die_info.
gdb/ChangeLog
2020-03-22 Tom Tromey <tom@tromey.com>
* dwarf2/read.c (lookup_addr_base, lookup_ranges_base)
(build_type_psymtabs_reader, read_structure_type)
(read_enumeration_type, read_full_die_1): Update.
(dwarf2_attr_no_follow): Move to die.h.
* dwarf2/die.h (struct die_info) <attr>: New method.
---
gdb/ChangeLog | 8 ++++++++
gdb/dwarf2/die.h | 11 +++++++++++
gdb/dwarf2/read.c | 37 ++++++++-----------------------------
3 files changed, 27 insertions(+), 29 deletions(-)
diff --git a/gdb/dwarf2/die.h b/gdb/dwarf2/die.h
index f8826a276e8..3a265b7df03 100644
--- a/gdb/dwarf2/die.h
+++ b/gdb/dwarf2/die.h
@@ -23,6 +23,17 @@
/* This data structure holds a complete die structure. */
struct die_info
{
+ /* Return the named attribute or NULL if not there, but do not
+ follow DW_AT_specification, etc. */
+ struct attribute *attr (dwarf_attribute name)
+ {
+ for (unsigned i = 0; i < num_attrs; ++i)
+ if (attrs[i].name == name)
+ return &attrs[i];
+ return NULL;
+ }
+
+
/* DWARF-2 tag for this DIE. */
ENUM_BITFIELD(dwarf_tag) tag : 16;
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 3479cd55a2e..87c4cae9b01 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -1224,9 +1224,6 @@ static void set_cu_language (unsigned int, struct dwarf2_cu *);
static struct attribute *dwarf2_attr (struct die_info *, unsigned int,
struct dwarf2_cu *);
-static struct attribute *dwarf2_attr_no_follow (struct die_info *,
- unsigned int);
-
static const char *dwarf2_string_attr (struct die_info *die, unsigned int name,
struct dwarf2_cu *cu);
@@ -6397,9 +6394,9 @@ static gdb::optional<ULONGEST>
lookup_addr_base (struct die_info *comp_unit_die)
{
struct attribute *attr;
- attr = dwarf2_attr_no_follow (comp_unit_die, DW_AT_addr_base);
+ attr = comp_unit_die->attr (DW_AT_addr_base);
if (attr == nullptr)
- attr = dwarf2_attr_no_follow (comp_unit_die, DW_AT_GNU_addr_base);
+ attr = comp_unit_die->attr (DW_AT_GNU_addr_base);
if (attr == nullptr)
return gdb::optional<ULONGEST> ();
return DW_UNSND (attr);
@@ -6411,9 +6408,9 @@ static ULONGEST
lookup_ranges_base (struct die_info *comp_unit_die)
{
struct attribute *attr;
- attr = dwarf2_attr_no_follow (comp_unit_die, DW_AT_rnglists_base);
+ attr = comp_unit_die->attr (DW_AT_rnglists_base);
if (attr == nullptr)
- attr = dwarf2_attr_no_follow (comp_unit_die, DW_AT_GNU_ranges_base);
+ attr = comp_unit_die->attr (DW_AT_GNU_ranges_base);
if (attr == nullptr)
return 0;
return DW_UNSND (attr);
@@ -7399,7 +7396,7 @@ build_type_psymtabs_reader (const struct die_reader_specs *reader,
if (! type_unit_die->has_children)
return;
- attr = dwarf2_attr_no_follow (type_unit_die, DW_AT_stmt_list);
+ attr = type_unit_die->attr (DW_AT_stmt_list);
tu_group = get_type_unit_group (cu, attr);
if (tu_group->tus == nullptr)
@@ -14977,7 +14974,7 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
/* If the definition of this type lives in .debug_types, read that type.
Don't follow DW_AT_specification though, that will take us back up
the chain and we want to go down. */
- attr = dwarf2_attr_no_follow (die, DW_AT_signature);
+ attr = die->attr (DW_AT_signature);
if (attr != nullptr)
{
type = get_DW_AT_signature_type (die, attr, cu);
@@ -15513,7 +15510,7 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu)
/* If the definition of this type lives in .debug_types, read that type.
Don't follow DW_AT_specification though, that will take us back up
the chain and we want to go down. */
- attr = dwarf2_attr_no_follow (die, DW_AT_signature);
+ attr = die->attr (DW_AT_signature);
if (attr != nullptr)
{
type = get_DW_AT_signature_type (die, attr, cu);
@@ -17539,7 +17536,7 @@ read_full_die_1 (const struct die_reader_specs *reader,
indexes_that_need_reprocess.push_back (i);
}
- struct attribute *attr = dwarf2_attr_no_follow (die, DW_AT_str_offsets_base);
+ struct attribute *attr = die->attr (DW_AT_str_offsets_base);
if (attr != nullptr)
cu->str_offsets_base = DW_UNSND (attr);
@@ -18984,24 +18981,6 @@ dwarf2_attr (struct die_info *die, unsigned int name, struct dwarf2_cu *cu)
return NULL;
}
-/* Return the named attribute or NULL if not there,
- but do not follow DW_AT_specification, etc.
- This is for use in contexts where we're reading .debug_types dies.
- Following DW_AT_specification, DW_AT_abstract_origin will take us
- back up the chain, and we want to go down. */
-
-static struct attribute *
-dwarf2_attr_no_follow (struct die_info *die, unsigned int name)
-{
- unsigned int i;
-
- for (i = 0; i < die->num_attrs; ++i)
- if (die->attrs[i].name == name)
- return &die->attrs[i];
-
- return NULL;
-}
-
/* Return the string associated with a string-typed attribute, or NULL if it
is either not found or is of an incorrect type. */
--
2.17.2
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 18/22] Remove sibling_die
2020-03-22 18:45 [PATCH 00/22] More splitting of dwarf2/read.c Tom Tromey
` (16 preceding siblings ...)
2020-03-22 18:45 ` [PATCH 17/22] Change dwarf2_attr_no_follow to be a method Tom Tromey
@ 2020-03-22 18:45 ` Tom Tromey
2020-03-22 18:45 ` [PATCH 19/22] Change two more functions to be methods on die_info Tom Tromey
` (4 subsequent siblings)
22 siblings, 0 replies; 32+ messages in thread
From: Tom Tromey @ 2020-03-22 18:45 UTC (permalink / raw)
To: gdb-patches; +Cc: Tom Tromey
The sibling_die helper function does not seem to add much value,
considering that many other fields of die_info are directly accessed.
So, this removes it.
gdb/ChangeLog
2020-03-22 Tom Tromey <tom@tromey.com>
* dwarf2/read.c (read_import_statement, read_file_scope)
(read_type_unit_scope, inherit_abstract_dies, read_func_scope)
(read_lexical_block_scope, read_call_site_scope)
(dwarf2_get_subprogram_pc_bounds, get_scope_pc_bounds)
(handle_struct_member_die, process_structure_scope)
(update_enumeration_type_from_children)
(process_enumeration_scope, read_array_type, read_common_block)
(read_namespace, read_module, read_subroutine_type): Update.
(sibling_die): Remove.
---
gdb/ChangeLog | 12 +++++++++
gdb/dwarf2/read.c | 62 ++++++++++++++++++++---------------------------
2 files changed, 38 insertions(+), 36 deletions(-)
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 87c4cae9b01..9d744ab0825 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -1416,8 +1416,6 @@ static const char *dwarf_bool_name (unsigned int);
static const char *dwarf_type_encoding_name (unsigned int);
-static struct die_info *sibling_die (struct die_info *);
-
static void dump_die_shallow (struct ui_file *, int indent, struct die_info *);
static void dump_die_for_error (struct die_info *);
@@ -10461,7 +10459,7 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
if (die->tag == DW_TAG_imported_module && cu->language == language_fortran)
for (child_die = die->child; child_die && child_die->tag;
- child_die = sibling_die (child_die))
+ child_die = child_die->sibling)
{
/* DWARF-4: A Fortran use statement with a “rename list” may be
represented by an imported module entry with an import attribute
@@ -10739,7 +10737,7 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
while (child_die && child_die->tag)
{
process_die (child_die, cu);
- child_die = sibling_die (child_die);
+ child_die = child_die->sibling;
}
}
@@ -10907,7 +10905,7 @@ read_type_unit_scope (struct die_info *die, struct dwarf2_cu *cu)
while (child_die && child_die->tag)
{
process_die (child_die, cu);
- child_die = sibling_die (child_die);
+ child_die = child_die->sibling;
}
}
}
@@ -12680,7 +12678,7 @@ inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu)
for (child_die = die->child;
child_die && child_die->tag;
- child_die = sibling_die (child_die))
+ child_die = child_die->sibling)
{
struct die_info *child_origin_die;
struct dwarf2_cu *child_origin_cu;
@@ -12757,7 +12755,7 @@ inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu)
if (!origin_child_die->in_process)
process_die (origin_child_die, origin_cu);
}
- origin_child_die = sibling_die (origin_child_die);
+ origin_child_die = origin_child_die->sibling;
}
origin_cu->list_in_scope = origin_previous_list_in_scope;
@@ -12826,7 +12824,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
/* If we have any template arguments, then we must allocate a
different sort of symbol. */
- for (child_die = die->child; child_die; child_die = sibling_die (child_die))
+ for (child_die = die->child; child_die; child_die = child_die->sibling)
{
if (child_die->tag == DW_TAG_template_type_param
|| child_die->tag == DW_TAG_template_value_param)
@@ -12879,7 +12877,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
}
else
process_die (child_die, cu);
- child_die = sibling_die (child_die);
+ child_die = child_die->sibling;
}
}
@@ -12901,7 +12899,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
{
if (child_die->tag == DW_TAG_imported_module)
process_die (child_die, spec_cu);
- child_die = sibling_die (child_die);
+ child_die = child_die->sibling;
}
/* In some cases, GCC generates specification DIEs that
@@ -12990,7 +12988,7 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu)
GCC does no longer produces such DWARF since GCC r224161. */
for (child_die = die->child;
child_die != NULL && child_die->tag;
- child_die = sibling_die (child_die))
+ child_die = child_die->sibling)
process_die (child_die, cu);
return;
case PC_BOUNDS_INVALID:
@@ -13006,7 +13004,7 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu)
while (child_die && child_die->tag)
{
process_die (child_die, cu);
- child_die = sibling_die (child_die);
+ child_die = child_die->sibling;
}
}
inherit_abstract_dies (die, cu);
@@ -13087,7 +13085,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
nparams = 0;
for (child_die = die->child; child_die && child_die->tag;
- child_die = sibling_die (child_die))
+ child_die = child_die->sibling)
{
if (child_die->tag != DW_TAG_call_site_parameter
&& child_die->tag != DW_TAG_GNU_call_site_parameter)
@@ -13232,7 +13230,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
for (child_die = die->child;
child_die && child_die->tag;
- child_die = sibling_die (child_die))
+ child_die = child_die->sibling)
{
struct call_site_parameter *parameter;
struct attribute *loc, *origin;
@@ -13859,7 +13857,7 @@ dwarf2_get_subprogram_pc_bounds (struct die_info *die,
if (child->tag == DW_TAG_subprogram
|| child->tag == DW_TAG_lexical_block)
dwarf2_get_subprogram_pc_bounds (child, lowpc, highpc, cu);
- child = sibling_die (child);
+ child = child->sibling;
}
}
@@ -13915,7 +13913,7 @@ get_scope_pc_bounds (struct die_info *die,
break;
}
- child = sibling_die (child);
+ child = child->sibling;
}
}
@@ -15153,7 +15151,7 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
for (die_info *variant_child = child_die->child;
variant_child != NULL;
- variant_child = sibling_die (variant_child))
+ variant_child = variant_child->sibling)
{
if (variant_child->tag == DW_TAG_member)
{
@@ -15243,7 +15241,7 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
if (is_variant_part && discr_offset == child_die->sect_off)
fi.fields.back ().variant.is_discriminant = true;
- child_die = sibling_die (child_die);
+ child_die = child_die->sibling;
}
/* Attach template arguments to type. */
@@ -15391,7 +15389,7 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
else
process_die (child_die, cu);
- child_die = sibling_die (child_die);
+ child_die = child_die->sibling;
}
/* Do not consider external references. According to the DWARF standard,
@@ -15452,7 +15450,7 @@ update_enumeration_type_from_children (struct die_info *die,
for (child_die = die->child;
child_die != NULL && child_die->tag;
- child_die = sibling_die (child_die))
+ child_die = child_die->sibling)
{
struct attribute *attr;
LONGEST value;
@@ -15628,7 +15626,7 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu)
}
}
- child_die = sibling_die (child_die);
+ child_die = child_die->sibling;
}
if (!fields.empty ())
@@ -15739,7 +15737,7 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
range_types.push_back (child_type);
}
}
- child_die = sibling_die (child_die);
+ child_die = child_die->sibling;
}
/* Dwarf2 dimensions are output from left to right, create the
@@ -15976,7 +15974,7 @@ read_common_block (struct die_info *die, struct dwarf2_cu *cu)
for (child_die = die->child;
child_die && child_die->tag;
- child_die = sibling_die (child_die))
+ child_die = child_die->sibling)
++n_entries;
size = (sizeof (struct common_block)
@@ -15989,7 +15987,7 @@ read_common_block (struct die_info *die, struct dwarf2_cu *cu)
for (child_die = die->child;
child_die && child_die->tag;
- child_die = sibling_die (child_die))
+ child_die = child_die->sibling)
{
/* Create the symbol in the DW_TAG_common_block block in the current
symbol scope. */
@@ -16111,7 +16109,7 @@ read_namespace (struct die_info *die, struct dwarf2_cu *cu)
while (child_die && child_die->tag)
{
process_die (child_die, cu);
- child_die = sibling_die (child_die);
+ child_die = child_die->sibling;
}
}
}
@@ -16147,7 +16145,7 @@ read_module (struct die_info *die, struct dwarf2_cu *cu)
while (child_die && child_die->tag)
{
process_die (child_die, cu);
- child_die = sibling_die (child_die);
+ child_die = child_die->sibling;
}
}
@@ -16646,7 +16644,7 @@ read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu)
nparams++;
else if (child_die->tag == DW_TAG_unspecified_parameters)
TYPE_VARARGS (ftype) = 1;
- child_die = sibling_die (child_die);
+ child_die = child_die->sibling;
}
/* Allocate storage for parameters and fill them in. */
@@ -16717,7 +16715,7 @@ read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu)
TYPE_FIELD_TYPE (ftype, iparams) = arg_type;
iparams++;
}
- child_die = sibling_die (child_die);
+ child_die = child_die->sibling;
}
}
@@ -21238,14 +21236,6 @@ typename_concat (struct obstack *obs, const char *prefix, const char *suffix,
}
}
-/* Return sibling of die, NULL if no sibling. */
-
-static struct die_info *
-sibling_die (struct die_info *die)
-{
- return die->sibling;
-}
-
/* Get name of a die, return NULL if not found. */
static const char *
--
2.17.2
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 19/22] Change two more functions to be methods on die_info
2020-03-22 18:45 [PATCH 00/22] More splitting of dwarf2/read.c Tom Tromey
` (17 preceding siblings ...)
2020-03-22 18:45 ` [PATCH 18/22] Remove sibling_die Tom Tromey
@ 2020-03-22 18:45 ` Tom Tromey
2020-03-23 19:07 ` Christian Biesinger
2020-03-22 18:45 ` [PATCH 20/22] Rewrite new die_info methods Tom Tromey
` (3 subsequent siblings)
22 siblings, 1 reply; 32+ messages in thread
From: Tom Tromey @ 2020-03-22 18:45 UTC (permalink / raw)
To: gdb-patches; +Cc: Tom Tromey
This changes lookup_addr_base and lookup_ranges_base to be methods on
die_info.
gdb/ChangeLog
2020-03-22 Tom Tromey <tom@tromey.com>
* dwarf2/die.h (struct die_info) <addr_base, ranges_base>: New
methods.
* dwarf2/read.c (lookup_addr_base): Move to die.h.
(lookup_ranges_base): Likewise.
(read_cutu_die_from_dwo, read_full_die_1): Update.
---
gdb/ChangeLog | 8 ++++++++
gdb/dwarf2/die.h | 28 ++++++++++++++++++++++++++++
gdb/dwarf2/read.c | 34 +++-------------------------------
3 files changed, 39 insertions(+), 31 deletions(-)
diff --git a/gdb/dwarf2/die.h b/gdb/dwarf2/die.h
index 3a265b7df03..5673ae261ac 100644
--- a/gdb/dwarf2/die.h
+++ b/gdb/dwarf2/die.h
@@ -33,6 +33,34 @@ struct die_info
return NULL;
}
+ /* Return the address base of the compile unit, which, if exists, is
+ stored either at the attribute DW_AT_GNU_addr_base, or
+ DW_AT_addr_base. */
+ gdb::optional<ULONGEST> addr_base ()
+ {
+ struct attribute *attr;
+ attr = attr (DW_AT_addr_base);
+ if (attr == nullptr)
+ attr = attr (DW_AT_GNU_addr_base);
+ if (attr == nullptr)
+ return gdb::optional<ULONGEST> ();
+ return DW_UNSND (attr);
+ }
+
+ /* Return range lists base of the compile unit, which, if exists, is
+ stored either at the attribute DW_AT_rnglists_base or
+ DW_AT_GNU_ranges_base. */
+ ULONGEST ranges_base ()
+ {
+ struct attribute *attr;
+ attr = attr (DW_AT_rnglists_base);
+ if (attr == nullptr)
+ attr = attr (DW_AT_GNU_ranges_base);
+ if (attr == nullptr)
+ return 0;
+ return DW_UNSND (attr);
+ }
+
/* DWARF-2 tag for this DIE. */
ENUM_BITFIELD(dwarf_tag) tag : 16;
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 9d744ab0825..9e7152d03e6 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -6386,34 +6386,6 @@ lookup_signatured_type (struct dwarf2_cu *cu, ULONGEST sig)
}
}
-/* Return the address base of the compile unit, which, if exists, is stored
- either at the attribute DW_AT_GNU_addr_base, or DW_AT_addr_base. */
-static gdb::optional<ULONGEST>
-lookup_addr_base (struct die_info *comp_unit_die)
-{
- struct attribute *attr;
- attr = comp_unit_die->attr (DW_AT_addr_base);
- if (attr == nullptr)
- attr = comp_unit_die->attr (DW_AT_GNU_addr_base);
- if (attr == nullptr)
- return gdb::optional<ULONGEST> ();
- return DW_UNSND (attr);
-}
-
-/* Return range lists base of the compile unit, which, if exists, is stored
- either at the attribute DW_AT_rnglists_base or DW_AT_GNU_ranges_base. */
-static ULONGEST
-lookup_ranges_base (struct die_info *comp_unit_die)
-{
- struct attribute *attr;
- attr = comp_unit_die->attr (DW_AT_rnglists_base);
- if (attr == nullptr)
- attr = comp_unit_die->attr (DW_AT_GNU_ranges_base);
- if (attr == nullptr)
- return 0;
- return DW_UNSND (attr);
-}
-
/* Low level DIE reading support. */
/* Initialize a die_reader_specs struct from a dwarf2_cu struct. */
@@ -6502,12 +6474,12 @@ read_cutu_die_from_dwo (struct dwarf2_per_cu_data *this_cu,
ranges = dwarf2_attr (stub_comp_unit_die, DW_AT_ranges, cu);
comp_dir = dwarf2_attr (stub_comp_unit_die, DW_AT_comp_dir, cu);
- cu->addr_base = lookup_addr_base (stub_comp_unit_die);
+ cu->addr_base = stub_comp_unit_die->addr_base ();
/* There should be a DW_AT_rnglists_base (DW_AT_GNU_ranges_base) attribute
here (if needed). We need the value before we can process
DW_AT_ranges. */
- cu->ranges_base = lookup_ranges_base (stub_comp_unit_die);
+ cu->ranges_base = stub_comp_unit_die->ranges_base ();
}
else if (stub_comp_dir != NULL)
{
@@ -17538,7 +17510,7 @@ read_full_die_1 (const struct die_reader_specs *reader,
if (attr != nullptr)
cu->str_offsets_base = DW_UNSND (attr);
- auto maybe_addr_base = lookup_addr_base(die);
+ auto maybe_addr_base = die->addr_base ();
if (maybe_addr_base.has_value ())
cu->addr_base = *maybe_addr_base;
for (int index : indexes_that_need_reprocess)
--
2.17.2
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 20/22] Rewrite new die_info methods
2020-03-22 18:45 [PATCH 00/22] More splitting of dwarf2/read.c Tom Tromey
` (18 preceding siblings ...)
2020-03-22 18:45 ` [PATCH 19/22] Change two more functions to be methods on die_info Tom Tromey
@ 2020-03-22 18:45 ` Tom Tromey
2020-03-22 18:45 ` [PATCH 21/22] Move DWARF-constant stringifying code to new file Tom Tromey
` (2 subsequent siblings)
22 siblings, 0 replies; 32+ messages in thread
From: Tom Tromey @ 2020-03-22 18:45 UTC (permalink / raw)
To: gdb-patches; +Cc: Tom Tromey
This rewrites the two new die_info to iterate over attributes rather
than to do two separate searches.
gdb/ChangeLog
2020-03-22 Tom Tromey <tom@tromey.com>
* dwarf2/die.h (struct die_info) <addr_base, ranges_base>:
Rewrite.
---
gdb/ChangeLog | 5 +++++
gdb/dwarf2/die.h | 30 ++++++++++++++++--------------
2 files changed, 21 insertions(+), 14 deletions(-)
diff --git a/gdb/dwarf2/die.h b/gdb/dwarf2/die.h
index 5673ae261ac..5522ebdf311 100644
--- a/gdb/dwarf2/die.h
+++ b/gdb/dwarf2/die.h
@@ -38,13 +38,14 @@ struct die_info
DW_AT_addr_base. */
gdb::optional<ULONGEST> addr_base ()
{
- struct attribute *attr;
- attr = attr (DW_AT_addr_base);
- if (attr == nullptr)
- attr = attr (DW_AT_GNU_addr_base);
- if (attr == nullptr)
- return gdb::optional<ULONGEST> ();
- return DW_UNSND (attr);
+ for (unsigned i = 0; i < num_attrs; ++i)
+ if (attrs[i].name == DW_AT_addr_base
+ || attrs[i].name == DW_AT_GNU_addr_base)
+ {
+ /* If both exist, just use the first one. */
+ return DW_UNSND (&attrs[i]);
+ }
+ return gdb::optional<ULONGEST> ();
}
/* Return range lists base of the compile unit, which, if exists, is
@@ -52,13 +53,14 @@ struct die_info
DW_AT_GNU_ranges_base. */
ULONGEST ranges_base ()
{
- struct attribute *attr;
- attr = attr (DW_AT_rnglists_base);
- if (attr == nullptr)
- attr = attr (DW_AT_GNU_ranges_base);
- if (attr == nullptr)
- return 0;
- return DW_UNSND (attr);
+ for (unsigned i = 0; i < num_attrs; ++i)
+ if (attrs[i].name == DW_AT_rnglists_base
+ || attrs[i].name == DW_AT_GNU_ranges_base)
+ {
+ /* If both exist, just use the first one. */
+ return DW_UNSND (&attrs[i]);
+ }
+ return 0;
}
--
2.17.2
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 21/22] Move DWARF-constant stringifying code to new file
2020-03-22 18:45 [PATCH 00/22] More splitting of dwarf2/read.c Tom Tromey
` (19 preceding siblings ...)
2020-03-22 18:45 ` [PATCH 20/22] Rewrite new die_info methods Tom Tromey
@ 2020-03-22 18:45 ` Tom Tromey
2020-03-22 18:45 ` [PATCH 22/22] Change two functions to be methods on struct attribute Tom Tromey
2020-03-24 13:34 ` [PATCH 00/22] More splitting of dwarf2/read.c Simon Marchi
22 siblings, 0 replies; 32+ messages in thread
From: Tom Tromey @ 2020-03-22 18:45 UTC (permalink / raw)
To: gdb-patches; +Cc: Tom Tromey
This moves the DWARF debugging functions that stringify various
constants to a new file, dwarf2/stringify.c.
gdb/ChangeLog
2020-03-22 Tom Tromey <tom@tromey.com>
* dwarf2/read.c (dwarf_unit_type_name, dwarf_tag_name)
(dwarf_attr_name, dwarf_form_name, dwarf_bool_name)
(dwarf_type_encoding_name): Move to stringify.c.
* Makefile.in (COMMON_SFILES): Add dwarf2/stringify.c.
* dwarf2/stringify.c: New file.
* dwarf2/stringify.h: New file.
---
gdb/ChangeLog | 9 ++++
gdb/Makefile.in | 1 +
gdb/dwarf2/read.c | 94 +--------------------------------
gdb/dwarf2/stringify.c | 114 +++++++++++++++++++++++++++++++++++++++++
gdb/dwarf2/stringify.h | 38 ++++++++++++++
5 files changed, 163 insertions(+), 93 deletions(-)
create mode 100644 gdb/dwarf2/stringify.c
create mode 100644 gdb/dwarf2/stringify.h
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index f66affd3e5f..bc3ef695bbd 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -1016,6 +1016,7 @@ COMMON_SFILES = \
dwarf2/macro.c \
dwarf2/read.c \
dwarf2/section.c \
+ dwarf2/stringify.c \
eval.c \
event-loop.c \
event-top.c \
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 9e7152d03e6..87305ec3688 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -40,6 +40,7 @@
#include "dwarf2/dwz.h"
#include "dwarf2/macro.h"
#include "dwarf2/die.h"
+#include "dwarf2/stringify.h"
#include "bfd.h"
#include "elf-bfd.h"
#include "symtab.h"
@@ -1406,16 +1407,6 @@ static const char *dwarf2_physname (const char *name, struct die_info *die,
static struct die_info *dwarf2_extension (struct die_info *die,
struct dwarf2_cu **);
-static const char *dwarf_tag_name (unsigned int);
-
-static const char *dwarf_attr_name (unsigned int);
-
-static const char *dwarf_form_name (unsigned int);
-
-static const char *dwarf_bool_name (unsigned int);
-
-static const char *dwarf_type_encoding_name (unsigned int);
-
static void dump_die_shallow (struct ui_file *, int indent, struct die_info *);
static void dump_die_for_error (struct die_info *);
@@ -21336,89 +21327,6 @@ dwarf2_extension (struct die_info *die, struct dwarf2_cu **ext_cu)
return follow_die_ref (die, attr, ext_cu);
}
-/* A convenience function that returns an "unknown" DWARF name,
- including the value of V. STR is the name of the entity being
- printed, e.g., "TAG". */
-
-static const char *
-dwarf_unknown (const char *str, unsigned v)
-{
- char *cell = get_print_cell ();
- xsnprintf (cell, PRINT_CELL_SIZE, "DW_%s_<unknown: %u>", str, v);
- return cell;
-}
-
-/* Convert a DIE tag into its string name. */
-
-static const char *
-dwarf_tag_name (unsigned tag)
-{
- const char *name = get_DW_TAG_name (tag);
-
- if (name == NULL)
- return dwarf_unknown ("TAG", tag);
-
- return name;
-}
-
-/* Convert a DWARF attribute code into its string name. */
-
-static const char *
-dwarf_attr_name (unsigned attr)
-{
- const char *name;
-
-#ifdef MIPS /* collides with DW_AT_HP_block_index */
- if (attr == DW_AT_MIPS_fde)
- return "DW_AT_MIPS_fde";
-#else
- if (attr == DW_AT_HP_block_index)
- return "DW_AT_HP_block_index";
-#endif
-
- name = get_DW_AT_name (attr);
-
- if (name == NULL)
- return dwarf_unknown ("AT", attr);
-
- return name;
-}
-
-/* Convert a DWARF value form code into its string name. */
-
-static const char *
-dwarf_form_name (unsigned form)
-{
- const char *name = get_DW_FORM_name (form);
-
- if (name == NULL)
- return dwarf_unknown ("FORM", form);
-
- return name;
-}
-
-static const char *
-dwarf_bool_name (unsigned mybool)
-{
- if (mybool)
- return "TRUE";
- else
- return "FALSE";
-}
-
-/* Convert a DWARF type code into its string name. */
-
-static const char *
-dwarf_type_encoding_name (unsigned enc)
-{
- const char *name = get_DW_ATE_name (enc);
-
- if (name == NULL)
- return dwarf_unknown ("ATE", enc);
-
- return name;
-}
-
static void
dump_die_shallow (struct ui_file *f, int indent, struct die_info *die)
{
diff --git a/gdb/dwarf2/stringify.c b/gdb/dwarf2/stringify.c
new file mode 100644
index 00000000000..0cdefe81081
--- /dev/null
+++ b/gdb/dwarf2/stringify.c
@@ -0,0 +1,114 @@
+/* DWARF stringify code
+
+ Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+ Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology,
+ Inc. with support from Florida State University (under contract
+ with the Ada Joint Program Office), and Silicon Graphics, Inc.
+ Initial contribution by Brent Benson, Harris Computer Systems, Inc.,
+ based on Fred Fish's (Cygnus Support) implementation of DWARF 1
+ support.
+
+ 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/>. */
+
+#include "defs.h"
+#include "dwarf2.h"
+#include "dwarf2/stringify.h"
+
+/* A convenience function that returns an "unknown" DWARF name,
+ including the value of V. STR is the name of the entity being
+ printed, e.g., "TAG". */
+
+static const char *
+dwarf_unknown (const char *str, unsigned v)
+{
+ char *cell = get_print_cell ();
+ xsnprintf (cell, PRINT_CELL_SIZE, "DW_%s_<unknown: %u>", str, v);
+ return cell;
+}
+
+/* See stringify.h. */
+
+const char *
+dwarf_tag_name (unsigned tag)
+{
+ const char *name = get_DW_TAG_name (tag);
+
+ if (name == NULL)
+ return dwarf_unknown ("TAG", tag);
+
+ return name;
+}
+
+/* See stringify.h. */
+
+const char *
+dwarf_attr_name (unsigned attr)
+{
+ const char *name;
+
+#ifdef MIPS /* collides with DW_AT_HP_block_index */
+ if (attr == DW_AT_MIPS_fde)
+ return "DW_AT_MIPS_fde";
+#else
+ if (attr == DW_AT_HP_block_index)
+ return "DW_AT_HP_block_index";
+#endif
+
+ name = get_DW_AT_name (attr);
+
+ if (name == NULL)
+ return dwarf_unknown ("AT", attr);
+
+ return name;
+}
+
+/* See stringify.h. */
+
+const char *
+dwarf_form_name (unsigned form)
+{
+ const char *name = get_DW_FORM_name (form);
+
+ if (name == NULL)
+ return dwarf_unknown ("FORM", form);
+
+ return name;
+}
+
+/* See stringify.h. */
+
+const char *
+dwarf_bool_name (unsigned mybool)
+{
+ if (mybool)
+ return "TRUE";
+ else
+ return "FALSE";
+}
+
+/* See stringify.h. */
+
+const char *
+dwarf_type_encoding_name (unsigned enc)
+{
+ const char *name = get_DW_ATE_name (enc);
+
+ if (name == NULL)
+ return dwarf_unknown ("ATE", enc);
+
+ return name;
+}
diff --git a/gdb/dwarf2/stringify.h b/gdb/dwarf2/stringify.h
new file mode 100644
index 00000000000..d3b3d2c191a
--- /dev/null
+++ b/gdb/dwarf2/stringify.h
@@ -0,0 +1,38 @@
+/* DWARF stringify code
+
+ Copyright (C) 2003-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 <http://www.gnu.org/licenses/>. */
+
+#ifndef GDB_DWARF2_STRINGIFY_H
+#define GDB_DWARF2_STRINGIFY_H
+
+/* Convert a DIE tag into its string name. */
+extern const char *dwarf_tag_name (unsigned tag);
+
+/* Convert a DWARF attribute code into its string name. */
+extern const char *dwarf_attr_name (unsigned attr);
+
+/* Convert a DWARF value form code into its string name. */
+extern const char *dwarf_form_name (unsigned form);
+
+/* Convert a boolean to a string form. */
+extern const char *dwarf_bool_name (unsigned mybool);
+
+/* Convert a DWARF type code into its string name. */
+extern const char *dwarf_type_encoding_name (unsigned enc);
+
+#endif /* GDB_DWARF2_STRINGIFY_H */
--
2.17.2
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 22/22] Change two functions to be methods on struct attribute
2020-03-22 18:45 [PATCH 00/22] More splitting of dwarf2/read.c Tom Tromey
` (20 preceding siblings ...)
2020-03-22 18:45 ` [PATCH 21/22] Move DWARF-constant stringifying code to new file Tom Tromey
@ 2020-03-22 18:45 ` Tom Tromey
2020-03-24 13:34 ` [PATCH 00/22] More splitting of dwarf2/read.c Simon Marchi
22 siblings, 0 replies; 32+ messages in thread
From: Tom Tromey @ 2020-03-22 18:45 UTC (permalink / raw)
To: gdb-patches; +Cc: Tom Tromey
This changes dwarf2_get_ref_die_offset and
dwarf2_get_attr_constant_value to be methods on struct attribute.
2020-03-22 Tom Tromey <tom@tromey.com>
* dwarf2/read.c (handle_data_member_location, dwarf2_add_field)
(mark_common_block_symbol_computed, read_tag_string_type)
(attr_to_dynamic_prop, read_subrange_type): Update.
(dwarf2_get_ref_die_offset, dwarf2_get_attr_constant_value): Move
to be methods on struct attribute.
(skip_one_die, process_imported_unit_die, read_namespace_alias)
(read_call_site_scope, partial_die_info::read)
(partial_die_info::read, lookup_die_type, follow_die_ref):
Update.
* dwarf2/attribute.c (attribute::get_ref_die_offset): New method,
from dwarf2_get_ref_die_offset.
(attribute::constant_value): New method, from
dwarf2_get_attr_constant_value.
* dwarf2/attribute.h (struct attribute) <get_ref_die_offset>:
Declare method.
<constant_value>: New method.
---
gdb/ChangeLog | 19 ++++++++++
gdb/dwarf2/attribute.c | 37 ++++++++++++++++++++
gdb/dwarf2/attribute.h | 12 +++++++
gdb/dwarf2/read.c | 78 ++++++++++--------------------------------
4 files changed, 86 insertions(+), 60 deletions(-)
diff --git a/gdb/dwarf2/attribute.c b/gdb/dwarf2/attribute.c
index 6efff3e2c0a..0e5a8c8f536 100644
--- a/gdb/dwarf2/attribute.c
+++ b/gdb/dwarf2/attribute.c
@@ -26,6 +26,8 @@
#include "defs.h"
#include "dwarf2/attribute.h"
+#include "dwarf2/stringify.h"
+#include "complaints.h"
/* See attribute.h. */
@@ -119,3 +121,38 @@ attribute::form_is_ref () const
return false;
}
}
+
+/* See attribute.h. */
+
+sect_offset
+attribute::get_ref_die_offset () const
+{
+ if (form_is_ref ())
+ return (sect_offset) DW_UNSND (this);
+
+ complaint (_("unsupported die ref attribute form: '%s'"),
+ dwarf_form_name (form));
+ return {};
+}
+
+/* See attribute.h. */
+
+LONGEST
+attribute::constant_value (int default_value) const
+{
+ if (form == DW_FORM_sdata || form == DW_FORM_implicit_const)
+ return DW_SND (this);
+ else if (form == DW_FORM_udata
+ || form == DW_FORM_data1
+ || form == DW_FORM_data2
+ || form == DW_FORM_data4
+ || form == DW_FORM_data8)
+ return DW_UNSND (this);
+ else
+ {
+ /* For DW_FORM_data16 see attribute::form_is_constant. */
+ complaint (_("Attribute value is not a constant (%s)"),
+ dwarf_form_name (form));
+ return default_value;
+ }
+}
diff --git a/gdb/dwarf2/attribute.h b/gdb/dwarf2/attribute.h
index c2602310715..483b805433b 100644
--- a/gdb/dwarf2/attribute.h
+++ b/gdb/dwarf2/attribute.h
@@ -28,6 +28,7 @@
#define GDB_DWARF2_ATTRIBUTE_H
#include "dwarf2.h"
+#include "gdbtypes.h"
/* Blocks are a bunch of untyped bytes. */
struct dwarf_block
@@ -84,6 +85,17 @@ struct attribute
bool form_is_block () const;
+ /* Return DIE offset of this attribute. Return 0 with complaint if
+ the attribute is not of the required kind. */
+
+ sect_offset get_ref_die_offset () const;
+
+ /* Return the constant value held by this attribute. Return
+ DEFAULT_VALUE if the value held by the attribute is not
+ constant. */
+
+ LONGEST constant_value (int default_value) const;
+
ENUM_BITFIELD(dwarf_attribute) name : 16;
ENUM_BITFIELD(dwarf_form) form : 15;
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 87305ec3688..73df64d15fd 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -1419,10 +1419,6 @@ static void dump_die_1 (struct ui_file *, int level, int max_level,
static void store_in_ref_table (struct die_info *,
struct dwarf2_cu *);
-static sect_offset dwarf2_get_ref_die_offset (const struct attribute *);
-
-static LONGEST dwarf2_get_attr_constant_value (const struct attribute *, int);
-
static struct die_info *follow_die_ref_or_sig (struct die_info *,
const struct attribute *,
struct dwarf2_cu **);
@@ -8476,7 +8472,7 @@ skip_one_die (const struct die_reader_specs *reader, const gdb_byte *info_ptr,
complaint (_("ignoring absolute DW_AT_sibling"));
else
{
- sect_offset off = dwarf2_get_ref_die_offset (&attr);
+ sect_offset off = attr.get_ref_die_offset ();
const gdb_byte *sibling_ptr = buffer + to_underlying (off);
if (sibling_ptr < info_ptr)
@@ -9643,7 +9639,7 @@ process_imported_unit_die (struct die_info *die, struct dwarf2_cu *cu)
attr = dwarf2_attr (die, DW_AT_import, cu);
if (attr != NULL)
{
- sect_offset sect_off = dwarf2_get_ref_die_offset (attr);
+ sect_offset sect_off = attr->get_ref_die_offset ();
bool is_dwz = (attr->form == DW_FORM_GNU_ref_alt || cu->per_cu->is_dwz);
dwarf2_per_cu_data *per_cu
= dwarf2_find_containing_comp_unit (sect_off, is_dwz,
@@ -10296,7 +10292,7 @@ read_namespace_alias (struct die_info *die, struct dwarf2_cu *cu)
if (attr != NULL)
{
struct type *type;
- sect_offset sect_off = dwarf2_get_ref_die_offset (attr);
+ sect_offset sect_off = attr->get_ref_die_offset ();
type = get_die_type_at_offset (sect_off, cu->per_cu);
if (type != NULL && TYPE_CODE (type) == TYPE_CODE_NAMESPACE)
@@ -13224,8 +13220,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
{
parameter->kind = CALL_SITE_PARAMETER_PARAM_OFFSET;
- sect_offset sect_off
- = (sect_offset) dwarf2_get_ref_die_offset (origin);
+ sect_offset sect_off = origin->get_ref_die_offset ();
if (!cu->header.offset_in_cu_p (sect_off))
{
/* As DW_OP_GNU_parameter_ref uses CU-relative offset this
@@ -14059,7 +14054,7 @@ handle_data_member_location (struct die_info *die, struct dwarf2_cu *cu,
so if we see it, we can assume that a constant form is really
a constant and not a section offset. */
if (attr->form_is_constant ())
- *offset = dwarf2_get_attr_constant_value (attr, 0);
+ *offset = attr->constant_value (0);
else if (attr->form_is_section_offset ())
dwarf2_complex_location_expr_complaint ();
else if (attr->form_is_block ())
@@ -14186,7 +14181,7 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
attr = dwarf2_attr (die, DW_AT_data_bit_offset, cu);
if (attr != NULL)
SET_FIELD_BITPOS (*fp, (FIELD_BITPOS (*fp)
- + dwarf2_get_attr_constant_value (attr, 0)));
+ + attr->constant_value (0)));
/* Get name of field. */
fieldname = dwarf2_name (die, cu);
@@ -15860,7 +15855,7 @@ mark_common_block_symbol_computed (struct symbol *sym,
if (member_loc->form_is_constant ())
{
- offset = dwarf2_get_attr_constant_value (member_loc, 0);
+ offset = member_loc->constant_value (0);
baton->size += 1 /* DW_OP_addr */ + cu->header.addr_size;
}
else
@@ -16452,7 +16447,7 @@ read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu)
{
/* Pass 0 as the default as we know this attribute is constant
and the default value will not be returned. */
- LONGEST sz = dwarf2_get_attr_constant_value (len, 0);
+ LONGEST sz = len->constant_value (0);
prop_type = cu->per_cu->int_type (sz, true);
}
else
@@ -16474,12 +16469,12 @@ read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu)
indirection. There's no need to create a dynamic property in this
case. Pass 0 for the default value as we know it will not be
returned in this case. */
- length = dwarf2_get_attr_constant_value (attr, 0);
+ length = attr->constant_value (0);
}
else if ((attr = dwarf2_attr (die, DW_AT_byte_size, cu)) != nullptr)
{
/* We don't currently support non-constant byte sizes for strings. */
- length = dwarf2_get_attr_constant_value (attr, 1);
+ length = attr->constant_value (1);
}
else
{
@@ -17058,7 +17053,7 @@ attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die,
}
else if (attr->form_is_constant ())
{
- prop->data.const_val = dwarf2_get_attr_constant_value (attr, 0);
+ prop->data.const_val = attr->constant_value (0);
prop->kind = PROP_CONST;
}
else
@@ -17236,7 +17231,7 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
LONGEST bias = 0;
struct attribute *bias_attr = dwarf2_attr (die, DW_AT_GNU_bias, cu);
if (bias_attr != nullptr && bias_attr->form_is_constant ())
- bias = dwarf2_get_attr_constant_value (bias_attr, 0);
+ bias = bias_attr->constant_value (0);
/* Normally, the DWARF producers are expected to use a signed
constant form (Eg. DW_FORM_sdata) to express negative bounds.
@@ -17942,7 +17937,7 @@ partial_die_info::read (const struct die_reader_specs *reader,
case DW_AT_specification:
case DW_AT_extension:
has_specification = 1;
- spec_offset = dwarf2_get_ref_die_offset (&attr);
+ spec_offset = attr.get_ref_die_offset ();
spec_is_dwz = (attr.form == DW_FORM_GNU_ref_alt
|| cu->per_cu->is_dwz);
break;
@@ -17954,7 +17949,7 @@ partial_die_info::read (const struct die_reader_specs *reader,
else
{
const gdb_byte *buffer = reader->buffer;
- sect_offset off = dwarf2_get_ref_die_offset (&attr);
+ sect_offset off = attr.get_ref_die_offset ();
const gdb_byte *sibling_ptr = buffer + to_underlying (off);
if (sibling_ptr < info_ptr)
@@ -17999,7 +17994,7 @@ partial_die_info::read (const struct die_reader_specs *reader,
case DW_AT_import:
if (tag == DW_TAG_imported_unit)
{
- d.sect_off = dwarf2_get_ref_die_offset (&attr);
+ d.sect_off = attr.get_ref_die_offset ();
is_dwz = (attr.form == DW_FORM_GNU_ref_alt
|| cu->per_cu->is_dwz);
}
@@ -20703,7 +20698,7 @@ lookup_die_type (struct die_info *die, const struct attribute *attr,
if (attr->form == DW_FORM_GNU_ref_alt)
{
struct dwarf2_per_cu_data *per_cu;
- sect_offset sect_off = dwarf2_get_ref_die_offset (attr);
+ sect_offset sect_off = attr->get_ref_die_offset ();
per_cu = dwarf2_find_containing_comp_unit (sect_off, 1,
dwarf2_per_objfile);
@@ -20711,7 +20706,7 @@ lookup_die_type (struct die_info *die, const struct attribute *attr,
}
else if (attr->form_is_ref ())
{
- sect_offset sect_off = dwarf2_get_ref_die_offset (attr);
+ sect_offset sect_off = attr->get_ref_die_offset ();
this_type = get_die_type_at_offset (sect_off, cu->per_cu);
}
@@ -21513,43 +21508,6 @@ store_in_ref_table (struct die_info *die, struct dwarf2_cu *cu)
*slot = die;
}
-/* Return DIE offset of ATTR. Return 0 with complaint if ATTR is not of the
- required kind. */
-
-static sect_offset
-dwarf2_get_ref_die_offset (const struct attribute *attr)
-{
- if (attr->form_is_ref ())
- return (sect_offset) DW_UNSND (attr);
-
- complaint (_("unsupported die ref attribute form: '%s'"),
- dwarf_form_name (attr->form));
- return {};
-}
-
-/* Return the constant value held by ATTR. Return DEFAULT_VALUE if
- * the value held by the attribute is not constant. */
-
-static LONGEST
-dwarf2_get_attr_constant_value (const struct attribute *attr, int default_value)
-{
- if (attr->form == DW_FORM_sdata || attr->form == DW_FORM_implicit_const)
- return DW_SND (attr);
- else if (attr->form == DW_FORM_udata
- || attr->form == DW_FORM_data1
- || attr->form == DW_FORM_data2
- || attr->form == DW_FORM_data4
- || attr->form == DW_FORM_data8)
- return DW_UNSND (attr);
- else
- {
- /* For DW_FORM_data16 see attribute::form_is_constant. */
- complaint (_("Attribute value is not a constant (%s)"),
- dwarf_form_name (attr->form));
- return default_value;
- }
-}
-
/* Follow reference or signature attribute ATTR of SRC_DIE.
On entry *REF_CU is the CU of SRC_DIE.
On exit *REF_CU is the CU of the result. */
@@ -21640,7 +21598,7 @@ static struct die_info *
follow_die_ref (struct die_info *src_die, const struct attribute *attr,
struct dwarf2_cu **ref_cu)
{
- sect_offset sect_off = dwarf2_get_ref_die_offset (attr);
+ sect_offset sect_off = attr->get_ref_die_offset ();
struct dwarf2_cu *cu = *ref_cu;
struct die_info *die;
--
2.17.2
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 04/22] Split dwarf_decode_macros into two overloads
2020-03-22 18:45 ` [PATCH 04/22] Split dwarf_decode_macros into two overloads Tom Tromey
@ 2020-03-23 16:13 ` Christian Biesinger
2020-03-26 2:09 ` Tom Tromey
2020-03-24 1:58 ` Simon Marchi
1 sibling, 1 reply; 32+ messages in thread
From: Christian Biesinger @ 2020-03-23 16:13 UTC (permalink / raw)
To: Tom Tromey; +Cc: gdb-patches
On Sun, Mar 22, 2020 at 1:45 PM Tom Tromey <tom@tromey.com> wrote:
>
> This splits dwarf_decode_macros into two overloads -- one that's
> suitable for splitting into a separate file, and one that finds the
> correct section and should remain in dwarf2/read.c.
>
> gdb/ChangeLog
> 2020-03-22 Tom Tromey <tom@tromey.com>
>
> * dwarf2/read.c (dwarf_decode_macros): Split into two overloads.
> ---
> gdb/ChangeLog | 4 ++
> gdb/dwarf2/read.c | 102 +++++++++++++++++++++++++++-------------------
> 2 files changed, 63 insertions(+), 43 deletions(-)
>
> diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
> index 1410dd48a2f..2d126461c74 100644
> --- a/gdb/dwarf2/read.c
> +++ b/gdb/dwarf2/read.c
> @@ -23753,56 +23753,18 @@ dwarf_decode_macro_bytes (struct dwarf2_per_objfile *dwarf2_per_objfile,
> }
>
> static void
> -dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
> - int section_is_gnu)
> +dwarf_decode_macros (struct dwarf2_per_objfile *dwarf2_per_objfile,
> + buildsym_compunit *builder, dwarf2_section_info *section,
> + struct line_header *lh, unsigned int offset_size,
> + unsigned int offset, int section_is_gnu)
> {
> - struct dwarf2_per_objfile *dwarf2_per_objfile
> - = cu->per_cu->dwarf2_per_objfile;
> - struct objfile *objfile = dwarf2_per_objfile->objfile;
> - struct line_header *lh = cu->line_header;
> bfd *abfd;
> const gdb_byte *mac_ptr, *mac_end;
> struct macro_source_file *current_file = 0;
> enum dwarf_macro_record_type macinfo_type;
> - unsigned int offset_size = cu->header.offset_size;
> const gdb_byte *opcode_definitions[256];
> void **slot;
> - struct dwarf2_section_info *section;
> - const char *section_name;
>
> - if (cu->dwo_unit != NULL)
> - {
> - if (section_is_gnu)
> - {
> - section = &cu->dwo_unit->dwo_file->sections.macro;
> - section_name = ".debug_macro.dwo";
> - }
> - else
> - {
> - section = &cu->dwo_unit->dwo_file->sections.macinfo;
> - section_name = ".debug_macinfo.dwo";
> - }
> - }
> - else
> - {
> - if (section_is_gnu)
> - {
> - section = &dwarf2_per_objfile->macro;
> - section_name = ".debug_macro";
> - }
> - else
> - {
> - section = &dwarf2_per_objfile->macinfo;
> - section_name = ".debug_macinfo";
> - }
> - }
> -
> - section->read (objfile);
> - if (section->buffer == NULL)
> - {
> - complaint (_("missing %s section"), section_name);
> - return;
> - }
> abfd = section->get_bfd_owner ();
>
> /* First pass: Find the name of the base filename.
> @@ -23827,7 +23789,6 @@ dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
> return;
> }
>
> - buildsym_compunit *builder = cu->get_builder ();
> do
> {
> /* Do we at least have room for a macinfo type byte? */
> @@ -23949,6 +23910,61 @@ dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
> include_hash.get ());
> }
>
> +/* An overload of dwarf_decode_macros that finds the correct section
> + and ensures it is read in before calling the other overload. */
> +
> +static void
> +dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
> + int section_is_gnu)
> +{
> + struct dwarf2_per_objfile *dwarf2_per_objfile
> + = cu->per_cu->dwarf2_per_objfile;
> + struct objfile *objfile = dwarf2_per_objfile->objfile;
> + struct line_header *lh = cu->line_header;
> + unsigned int offset_size = cu->header.offset_size;
> + struct dwarf2_section_info *section;
> + const char *section_name;
> +
> + if (cu->dwo_unit != NULL)
Since you're touching these lines, want to change NULL to nullptr? (in
a few places)
Christian
> + {
> + if (section_is_gnu)
> + {
> + section = &cu->dwo_unit->dwo_file->sections.macro;
> + section_name = ".debug_macro.dwo";
> + }
> + else
> + {
> + section = &cu->dwo_unit->dwo_file->sections.macinfo;
> + section_name = ".debug_macinfo.dwo";
> + }
> + }
> + else
> + {
> + if (section_is_gnu)
> + {
> + section = &dwarf2_per_objfile->macro;
> + section_name = ".debug_macro";
> + }
> + else
> + {
> + section = &dwarf2_per_objfile->macinfo;
> + section_name = ".debug_macinfo";
> + }
> + }
> +
> + section->read (objfile);
> + if (section->buffer == NULL)
> + {
> + complaint (_("missing %s section"), section_name);
> + return;
> + }
> +
> + buildsym_compunit *builder = cu->get_builder ();
> +
> + dwarf_decode_macros (dwarf2_per_objfile, builder, section, lh,
> + offset_size, offset, section_is_gnu);
> +}
> +
> /* Return the .debug_loc section to use for CU.
> For DWO files use .debug_loc.dwo. */
>
> --
> 2.17.2
>
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 19/22] Change two more functions to be methods on die_info
2020-03-22 18:45 ` [PATCH 19/22] Change two more functions to be methods on die_info Tom Tromey
@ 2020-03-23 19:07 ` Christian Biesinger
2020-03-26 2:17 ` Tom Tromey
0 siblings, 1 reply; 32+ messages in thread
From: Christian Biesinger @ 2020-03-23 19:07 UTC (permalink / raw)
To: Tom Tromey; +Cc: gdb-patches
On Sun, Mar 22, 2020 at 1:46 PM Tom Tromey <tom@tromey.com> wrote:
>
> This changes lookup_addr_base and lookup_ranges_base to be methods on
> die_info.
>
> gdb/ChangeLog
> 2020-03-22 Tom Tromey <tom@tromey.com>
>
> * dwarf2/die.h (struct die_info) <addr_base, ranges_base>: New
> methods.
> * dwarf2/read.c (lookup_addr_base): Move to die.h.
> (lookup_ranges_base): Likewise.
> (read_cutu_die_from_dwo, read_full_die_1): Update.
> ---
> gdb/ChangeLog | 8 ++++++++
> gdb/dwarf2/die.h | 28 ++++++++++++++++++++++++++++
> gdb/dwarf2/read.c | 34 +++-------------------------------
> 3 files changed, 39 insertions(+), 31 deletions(-)
>
> diff --git a/gdb/dwarf2/die.h b/gdb/dwarf2/die.h
> index 3a265b7df03..5673ae261ac 100644
> --- a/gdb/dwarf2/die.h
> +++ b/gdb/dwarf2/die.h
> @@ -33,6 +33,34 @@ struct die_info
> return NULL;
> }
>
> + /* Return the address base of the compile unit, which, if exists, is
> + stored either at the attribute DW_AT_GNU_addr_base, or
> + DW_AT_addr_base. */
> + gdb::optional<ULONGEST> addr_base ()
> + {
> + struct attribute *attr;
> + attr = attr (DW_AT_addr_base);
I get that you want to avoid making code changes while moving code but
I would really suggest merging these two lines at least (similar in
the next function)
> + if (attr == nullptr)
> + attr = attr (DW_AT_GNU_addr_base);
> + if (attr == nullptr)
> + return gdb::optional<ULONGEST> ();
> + return DW_UNSND (attr);
> + }
> +
> + /* Return range lists base of the compile unit, which, if exists, is
> + stored either at the attribute DW_AT_rnglists_base or
> + DW_AT_GNU_ranges_base. */
> + ULONGEST ranges_base ()
> + {
> + struct attribute *attr;
> + attr = attr (DW_AT_rnglists_base);
> + if (attr == nullptr)
> + attr = attr (DW_AT_GNU_ranges_base);
> + if (attr == nullptr)
> + return 0;
> + return DW_UNSND (attr);
> + }
> +
>
> /* DWARF-2 tag for this DIE. */
> ENUM_BITFIELD(dwarf_tag) tag : 16;
> diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
> index 9d744ab0825..9e7152d03e6 100644
> --- a/gdb/dwarf2/read.c
> +++ b/gdb/dwarf2/read.c
> @@ -6386,34 +6386,6 @@ lookup_signatured_type (struct dwarf2_cu *cu, ULONGEST sig)
> }
> }
>
> -/* Return the address base of the compile unit, which, if exists, is stored
> - either at the attribute DW_AT_GNU_addr_base, or DW_AT_addr_base. */
> -static gdb::optional<ULONGEST>
> -lookup_addr_base (struct die_info *comp_unit_die)
> -{
> - struct attribute *attr;
> - attr = comp_unit_die->attr (DW_AT_addr_base);
> - if (attr == nullptr)
> - attr = comp_unit_die->attr (DW_AT_GNU_addr_base);
> - if (attr == nullptr)
> - return gdb::optional<ULONGEST> ();
> - return DW_UNSND (attr);
> -}
> -
> -/* Return range lists base of the compile unit, which, if exists, is stored
> - either at the attribute DW_AT_rnglists_base or DW_AT_GNU_ranges_base. */
> -static ULONGEST
> -lookup_ranges_base (struct die_info *comp_unit_die)
> -{
> - struct attribute *attr;
> - attr = comp_unit_die->attr (DW_AT_rnglists_base);
> - if (attr == nullptr)
> - attr = comp_unit_die->attr (DW_AT_GNU_ranges_base);
> - if (attr == nullptr)
> - return 0;
> - return DW_UNSND (attr);
> -}
> -
> /* Low level DIE reading support. */
>
> /* Initialize a die_reader_specs struct from a dwarf2_cu struct. */
> @@ -6502,12 +6474,12 @@ read_cutu_die_from_dwo (struct dwarf2_per_cu_data *this_cu,
> ranges = dwarf2_attr (stub_comp_unit_die, DW_AT_ranges, cu);
> comp_dir = dwarf2_attr (stub_comp_unit_die, DW_AT_comp_dir, cu);
>
> - cu->addr_base = lookup_addr_base (stub_comp_unit_die);
> + cu->addr_base = stub_comp_unit_die->addr_base ();
>
> /* There should be a DW_AT_rnglists_base (DW_AT_GNU_ranges_base) attribute
> here (if needed). We need the value before we can process
> DW_AT_ranges. */
> - cu->ranges_base = lookup_ranges_base (stub_comp_unit_die);
> + cu->ranges_base = stub_comp_unit_die->ranges_base ();
> }
> else if (stub_comp_dir != NULL)
> {
> @@ -17538,7 +17510,7 @@ read_full_die_1 (const struct die_reader_specs *reader,
> if (attr != nullptr)
> cu->str_offsets_base = DW_UNSND (attr);
>
> - auto maybe_addr_base = lookup_addr_base(die);
> + auto maybe_addr_base = die->addr_base ();
> if (maybe_addr_base.has_value ())
> cu->addr_base = *maybe_addr_base;
> for (int index : indexes_that_need_reprocess)
> --
> 2.17.2
>
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 04/22] Split dwarf_decode_macros into two overloads
2020-03-22 18:45 ` [PATCH 04/22] Split dwarf_decode_macros into two overloads Tom Tromey
2020-03-23 16:13 ` Christian Biesinger
@ 2020-03-24 1:58 ` Simon Marchi
2020-03-26 2:10 ` Tom Tromey
1 sibling, 1 reply; 32+ messages in thread
From: Simon Marchi @ 2020-03-24 1:58 UTC (permalink / raw)
To: Tom Tromey, gdb-patches
On 2020-03-22 2:45 p.m., Tom Tromey wrote:
> @@ -23949,6 +23910,61 @@ dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
> include_hash.get ());
> }
>
> +/* An overload of dwarf_decode_macros that finds the correct section
> + and ensures it is read in before calling the other overload. */
> +
> +static void
> +dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
> + int section_is_gnu)
Spaces -> tabs.
Simon
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 13/22] Convert read_indirect_line_string to a method
2020-03-22 18:45 ` [PATCH 13/22] Convert read_indirect_line_string to a method Tom Tromey
@ 2020-03-24 2:49 ` Simon Marchi
0 siblings, 0 replies; 32+ messages in thread
From: Simon Marchi @ 2020-03-24 2:49 UTC (permalink / raw)
To: Tom Tromey, gdb-patches
On 2020-03-22 2:45 p.m., Tom Tromey wrote:
> @@ -18790,17 +18786,15 @@ read_indirect_string (struct dwarf2_per_objfile *dwarf2_per_objfile, bfd *abfd,
> BUF is assumed to be in a compilation unit described by CU_HEADER.
> Return *BYTES_READ_PTR count of bytes read from BUF. */
>
> -static const char *
> -read_indirect_line_string (struct dwarf2_per_objfile *dwarf2_per_objfile,
> - bfd *abfd, const gdb_byte *buf,
> +const char *
> +dwarf2_per_objfile::read_line_string (const gdb_byte *buf,
> const struct comp_unit_head *cu_header,
> unsigned int *bytes_read_ptr)
The comment above this definition should become
/* See read.h. */
Simon
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 00/22] More splitting of dwarf2/read.c
2020-03-22 18:45 [PATCH 00/22] More splitting of dwarf2/read.c Tom Tromey
` (21 preceding siblings ...)
2020-03-22 18:45 ` [PATCH 22/22] Change two functions to be methods on struct attribute Tom Tromey
@ 2020-03-24 13:34 ` Simon Marchi
2020-03-26 15:32 ` Tom Tromey
22 siblings, 1 reply; 32+ messages in thread
From: Simon Marchi @ 2020-03-24 13:34 UTC (permalink / raw)
To: Tom Tromey, gdb-patches
On 2020-03-22 2:45 p.m., Tom Tromey wrote:
> One goal of mine is to split up the DWARF reader code into many
> smaller, more self-contained files. I think this will make the code
> easier to read and to work on; and also let us tease out (and repair)
> hidden dependencies. This latter part is desirable because, in the
> longer run, I'd like to parallelize DWARF reading.
>
> So, here is round 2 of splitting.
>
> The main change here is that the macro-reading code is moved to its
> own file. It's almost possible, after this, to scan macros in a
> worker thread. (However, dwz file handling, and the recent move to
> sharing a bcache, interfere with this.)
>
> Some smaller utility functions are also moved into other files as
> well.
>
> Let me know what you think,
> Tom
>
>
Other than the little nits I pointed out, this all looks good to me,
thanks for doing this!
Simon
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 04/22] Split dwarf_decode_macros into two overloads
2020-03-23 16:13 ` Christian Biesinger
@ 2020-03-26 2:09 ` Tom Tromey
0 siblings, 0 replies; 32+ messages in thread
From: Tom Tromey @ 2020-03-26 2:09 UTC (permalink / raw)
To: Christian Biesinger; +Cc: Tom Tromey, gdb-patches
>>>>> "Christian" == Christian Biesinger <cbiesinger@google.com> writes:
>> + if (cu->dwo_unit != NULL)
Christian> Since you're touching these lines, want to change NULL to nullptr? (in
Christian> a few places)
I made this change.
Tom
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 04/22] Split dwarf_decode_macros into two overloads
2020-03-24 1:58 ` Simon Marchi
@ 2020-03-26 2:10 ` Tom Tromey
0 siblings, 0 replies; 32+ messages in thread
From: Tom Tromey @ 2020-03-26 2:10 UTC (permalink / raw)
To: Simon Marchi; +Cc: Tom Tromey, gdb-patches
>>>>> "Simon" == Simon Marchi <simark@simark.ca> writes:
>> +static void
>> +dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
>> + int section_is_gnu)
Simon> Spaces -> tabs.
Done.
Tom
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 19/22] Change two more functions to be methods on die_info
2020-03-23 19:07 ` Christian Biesinger
@ 2020-03-26 2:17 ` Tom Tromey
0 siblings, 0 replies; 32+ messages in thread
From: Tom Tromey @ 2020-03-26 2:17 UTC (permalink / raw)
To: Christian Biesinger; +Cc: Tom Tromey, gdb-patches
>>>>> "Christian" == Christian Biesinger <cbiesinger@google.com> writes:
>> + attr = attr (DW_AT_addr_base);
Christian> I get that you want to avoid making code changes while moving code but
Christian> I would really suggest merging these two lines at least (similar in
Christian> the next function)
This line doesn't even compile actually.
I must have only built this after writing the next patch? Ugh.
Anyway I changed it as you suggest and used this->attr, which I normally
wouldn't do, but thought was ok since this patch is just a transition.
Tom
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 00/22] More splitting of dwarf2/read.c
2020-03-24 13:34 ` [PATCH 00/22] More splitting of dwarf2/read.c Simon Marchi
@ 2020-03-26 15:32 ` Tom Tromey
0 siblings, 0 replies; 32+ messages in thread
From: Tom Tromey @ 2020-03-26 15:32 UTC (permalink / raw)
To: Simon Marchi; +Cc: Tom Tromey, gdb-patches
>>>>> "Simon" == Simon Marchi <simark@simark.ca> writes:
Simon> Other than the little nits I pointed out, this all looks good to me,
Simon> thanks for doing this!
Thanks. I fixed all of those, and I re-regression-tested the series on
x86-64 Fedora 28. I'm checking it in now.
Tom
^ permalink raw reply [flat|nested] 32+ messages in thread
end of thread, other threads:[~2020-03-26 15:48 UTC | newest]
Thread overview: 32+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-22 18:45 [PATCH 00/22] More splitting of dwarf2/read.c Tom Tromey
2020-03-22 18:45 ` [PATCH 01/22] Introduce dwarf2/dwz.h Tom Tromey
2020-03-22 18:45 ` [PATCH 02/22] Add dwz.c and dwz_file::read_string Tom Tromey
2020-03-22 18:45 ` [PATCH 03/22] Change dwarf_decode_macro_bytes calling convention Tom Tromey
2020-03-22 18:45 ` [PATCH 04/22] Split dwarf_decode_macros into two overloads Tom Tromey
2020-03-23 16:13 ` Christian Biesinger
2020-03-26 2:09 ` Tom Tromey
2020-03-24 1:58 ` Simon Marchi
2020-03-26 2:10 ` Tom Tromey
2020-03-22 18:45 ` [PATCH 05/22] Move dwarf2_section_buffer_overflow_complaint to dwarf2/section.c Tom Tromey
2020-03-22 18:45 ` [PATCH 06/22] Convert dwarf2_section_buffer_overflow_complaint to a method Tom Tromey
2020-03-22 18:45 ` [PATCH 07/22] Add dwarf2_section_info::read_string method Tom Tromey
2020-03-22 18:45 ` [PATCH 08/22] Move code to new file dwarf2/macro.c Tom Tromey
2020-03-22 18:45 ` [PATCH 09/22] Make some line_header methods const Tom Tromey
2020-03-22 18:45 ` [PATCH 10/22] Use a const line_header in macro reader Tom Tromey
2020-03-22 18:45 ` [PATCH 11/22] Use a const dwarf2_section_info " Tom Tromey
2020-03-22 18:45 ` [PATCH 12/22] Trivial fix in dwarf_decode_macro_bytes Tom Tromey
2020-03-22 18:45 ` [PATCH 13/22] Convert read_indirect_line_string to a method Tom Tromey
2020-03-24 2:49 ` Simon Marchi
2020-03-22 18:45 ` [PATCH 14/22] Move more code to line-header.c Tom Tromey
2020-03-22 18:45 ` [PATCH 15/22] Move die_info to new header Tom Tromey
2020-03-22 18:45 ` [PATCH 16/22] Remove dwarf2_cu::base_known Tom Tromey
2020-03-22 18:45 ` [PATCH 17/22] Change dwarf2_attr_no_follow to be a method Tom Tromey
2020-03-22 18:45 ` [PATCH 18/22] Remove sibling_die Tom Tromey
2020-03-22 18:45 ` [PATCH 19/22] Change two more functions to be methods on die_info Tom Tromey
2020-03-23 19:07 ` Christian Biesinger
2020-03-26 2:17 ` Tom Tromey
2020-03-22 18:45 ` [PATCH 20/22] Rewrite new die_info methods Tom Tromey
2020-03-22 18:45 ` [PATCH 21/22] Move DWARF-constant stringifying code to new file Tom Tromey
2020-03-22 18:45 ` [PATCH 22/22] Change two functions to be methods on struct attribute Tom Tromey
2020-03-24 13:34 ` [PATCH 00/22] More splitting of dwarf2/read.c Simon Marchi
2020-03-26 15:32 ` Tom Tromey
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).