From 2c86cff96f47cdc7fe16e231f29566b3da2f756b Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Sat, 8 Feb 2020 13:40:54 -0700 Subject: [PATCH] Create dwarf2/section.[ch] This moves some section-handling code from dwarf2read.c into new files, dwarf2/section.[ch]. gdb/ChangeLog 2020-02-08 Tom Tromey * dwarf2read.h (struct dwarf2_section_info, dwarf2_read_section): Move to dwarf2/section.h. * dwarf2read.c (get_containing_section, get_section_bfd_owner) (get_section_bfd_section, get_section_name) (get_section_file_name, get_section_id, get_section_flags) (dwarf2_section_empty_p, dwarf2_read_section): Moe to dwarf2/section.c. * dwarf2/section.h: New file. * dwarf2/section.c: New file, from dwarf2read.c. * Makefile.in (COMMON_SFILES): Add dwarf2/section.c. Change-Id: I9f8498094cf99d9521e9481622ce8adbd453daf4 --- gdb/ChangeLog | 13 ++++ gdb/Makefile.in | 1 + gdb/dwarf2/section.c | 179 +++++++++++++++++++++++++++++++++++++++++++ gdb/dwarf2/section.h | 121 +++++++++++++++++++++++++++++ gdb/dwarf2read.c | 175 ------------------------------------------ gdb/dwarf2read.h | 49 +----------- 6 files changed, 315 insertions(+), 223 deletions(-) create mode 100644 gdb/dwarf2/section.c create mode 100644 gdb/dwarf2/section.h diff --git a/gdb/ChangeLog b/gdb/ChangeLog index d0c5d4a0fde..82dce890776 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,16 @@ +2020-02-08 Tom Tromey + + * dwarf2read.h (struct dwarf2_section_info, dwarf2_read_section): + Move to dwarf2/section.h. + * dwarf2read.c (get_containing_section, get_section_bfd_owner) + (get_section_bfd_section, get_section_name) + (get_section_file_name, get_section_id, get_section_flags) + (dwarf2_section_empty_p, dwarf2_read_section): Moe to + dwarf2/section.c. + * dwarf2/section.h: New file. + * dwarf2/section.c: New file, from dwarf2read.c. + * Makefile.in (COMMON_SFILES): Add dwarf2/section.c. + 2020-02-08 Tom Tromey * dwarf2read.h (read_unsigned_leb128): Don't declare. diff --git a/gdb/Makefile.in b/gdb/Makefile.in index b30ab54afa7..f560f1bd136 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -1003,6 +1003,7 @@ COMMON_SFILES = \ dwarf2loc.c \ dwarf2read.c \ dwarf2/leb.c \ + dwarf2/section.c \ eval.c \ event-loop.c \ event-top.c \ diff --git a/gdb/dwarf2/section.c b/gdb/dwarf2/section.c new file mode 100644 index 00000000000..618ab9adf12 --- /dev/null +++ b/gdb/dwarf2/section.c @@ -0,0 +1,179 @@ +/* DWARF 2 low-level section 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 . */ + +#include "defs.h" +#include "dwarf2/section.h" +#include "gdb_bfd.h" +#include "objfiles.h" + +struct dwarf2_section_info * +get_containing_section (const struct dwarf2_section_info *section) +{ + gdb_assert (section->is_virtual); + return section->s.containing_section; +} + +struct bfd * +get_section_bfd_owner (const struct dwarf2_section_info *section) +{ + if (section->is_virtual) + { + section = get_containing_section (section); + gdb_assert (!section->is_virtual); + } + return section->s.section->owner; +} + +asection * +get_section_bfd_section (const struct dwarf2_section_info *section) +{ + if (section->is_virtual) + { + section = get_containing_section (section); + gdb_assert (!section->is_virtual); + } + return section->s.section; +} + +const char * +get_section_name (const struct dwarf2_section_info *section) +{ + asection *sectp = get_section_bfd_section (section); + + gdb_assert (sectp != NULL); + return bfd_section_name (sectp); +} + +const char * +get_section_file_name (const struct dwarf2_section_info *section) +{ + bfd *abfd = get_section_bfd_owner (section); + + return bfd_get_filename (abfd); +} + +int +get_section_id (const struct dwarf2_section_info *section) +{ + asection *sectp = get_section_bfd_section (section); + + if (sectp == NULL) + return 0; + return sectp->id; +} + +int +get_section_flags (const struct dwarf2_section_info *section) +{ + asection *sectp = get_section_bfd_section (section); + + gdb_assert (sectp != NULL); + return bfd_section_flags (sectp); +} + +int +dwarf2_section_empty_p (const struct dwarf2_section_info *section) +{ + if (section->is_virtual) + return section->size == 0; + return section->s.section == NULL || section->size == 0; +} + +void +dwarf2_read_section (struct objfile *objfile, dwarf2_section_info *info) +{ + asection *sectp; + bfd *abfd; + gdb_byte *buf, *retbuf; + + if (info->readin) + return; + info->buffer = NULL; + info->readin = true; + + if (dwarf2_section_empty_p (info)) + return; + + sectp = get_section_bfd_section (info); + + /* If this is a virtual section we need to read in the real one first. */ + if (info->is_virtual) + { + struct dwarf2_section_info *containing_section = + get_containing_section (info); + + gdb_assert (sectp != NULL); + if ((sectp->flags & SEC_RELOC) != 0) + { + error (_("Dwarf Error: DWP format V2 with relocations is not" + " supported in section %s [in module %s]"), + get_section_name (info), get_section_file_name (info)); + } + dwarf2_read_section (objfile, containing_section); + /* Other code should have already caught virtual sections that don't + fit. */ + gdb_assert (info->virtual_offset + info->size + <= containing_section->size); + /* If the real section is empty or there was a problem reading the + section we shouldn't get here. */ + gdb_assert (containing_section->buffer != NULL); + info->buffer = containing_section->buffer + info->virtual_offset; + return; + } + + /* If the section has relocations, we must read it ourselves. + Otherwise we attach it to the BFD. */ + if ((sectp->flags & SEC_RELOC) == 0) + { + info->buffer = gdb_bfd_map_section (sectp, &info->size); + return; + } + + buf = (gdb_byte *) obstack_alloc (&objfile->objfile_obstack, info->size); + info->buffer = buf; + + /* When debugging .o files, we may need to apply relocations; see + http://sourceware.org/ml/gdb-patches/2002-04/msg00136.html . + We never compress sections in .o files, so we only need to + try this when the section is not compressed. */ + retbuf = symfile_relocate_debug_section (objfile, sectp, buf); + if (retbuf != NULL) + { + info->buffer = retbuf; + return; + } + + abfd = get_section_bfd_owner (info); + gdb_assert (abfd != NULL); + + if (bfd_seek (abfd, sectp->filepos, SEEK_SET) != 0 + || bfd_bread (buf, info->size, abfd) != info->size) + { + error (_("Dwarf Error: Can't read DWARF data" + " in section %s [in module %s]"), + bfd_section_name (sectp), bfd_get_filename (abfd)); + } +} diff --git a/gdb/dwarf2/section.h b/gdb/dwarf2/section.h new file mode 100644 index 00000000000..a1acc5f9e66 --- /dev/null +++ b/gdb/dwarf2/section.h @@ -0,0 +1,121 @@ +/* DWARF 2 low-level section 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 . */ + +#ifndef GDB_DWARF2_SECTION_H +#define GDB_DWARF2_SECTION_H + +/* A descriptor for dwarf sections. + + S.ASECTION, SIZE are typically initialized when the objfile is first + scanned. BUFFER, READIN are filled in later when the section is read. + If the section contained compressed data then SIZE is updated to record + the uncompressed size of the section. + + DWP file format V2 introduces a wrinkle that is easiest to handle by + creating the concept of virtual sections contained within a real section. + In DWP V2 the sections of the input DWO files are concatenated together + into one section, but section offsets are kept relative to the original + input section. + If this is a virtual dwp-v2 section, S.CONTAINING_SECTION is a backlink to + the real section this "virtual" section is contained in, and BUFFER,SIZE + describe the virtual section. */ + +struct dwarf2_section_info +{ + union + { + /* If this is a real section, the bfd section. */ + asection *section; + /* If this is a virtual section, pointer to the containing ("real") + section. */ + struct dwarf2_section_info *containing_section; + } s; + /* Pointer to section data, only valid if readin. */ + const gdb_byte *buffer; + /* The size of the section, real or virtual. */ + bfd_size_type size; + /* If this is a virtual section, the offset in the real section. + Only valid if is_virtual. */ + bfd_size_type virtual_offset; + /* True if we have tried to read this section. */ + bool readin; + /* True if this is a virtual section, False otherwise. + This specifies which of s.section and s.containing_section to use. */ + bool is_virtual; +}; + +/* Read the contents of the section INFO. + OBJFILE is the main object file, but not necessarily the file where + the section comes from. E.g., for DWO files the bfd of INFO is the bfd + of the DWO file. + If the section is compressed, uncompress it before returning. */ + +extern void dwarf2_read_section (struct objfile *objfile, + dwarf2_section_info *info); + +extern const char *get_section_name (const struct dwarf2_section_info *); + +extern const char *get_section_file_name (const struct dwarf2_section_info *); + +/* Return the containing section of virtual section SECTION. */ + +extern struct dwarf2_section_info *get_containing_section + (const struct dwarf2_section_info *section); + +/* Return the bfd owner of SECTION. */ + +extern struct bfd *get_section_bfd_owner + (const struct dwarf2_section_info *section); + +/* Return the bfd section of SECTION. + Returns NULL if the section is not present. */ + +extern asection *get_section_bfd_section + (const struct dwarf2_section_info *section); + +/* Return the name of SECTION. */ + +extern const char *get_section_name + (const struct dwarf2_section_info *section); + +/* Return the name of the file SECTION is in. */ + +extern const char *get_section_file_name + (const struct dwarf2_section_info *section); + +/* Return the id of SECTION. + Returns 0 if SECTION doesn't exist. */ + +extern int get_section_id (const struct dwarf2_section_info *section); + +/* Return the flags of SECTION. + SECTION (or containing section if this is a virtual section) must exist. */ + +extern int get_section_flags (const struct dwarf2_section_info *section); + +extern int dwarf2_section_empty_p (const struct dwarf2_section_info *section); + +#endif /* GDB_DWARF2_SECTION_H */ diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index fe26fc33d6e..760e1290731 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -1474,10 +1474,6 @@ show_dwarf_max_cache_age (struct ui_file *file, int from_tty, /* local function prototypes */ -static const char *get_section_name (const struct dwarf2_section_info *); - -static const char *get_section_file_name (const struct dwarf2_section_info *); - static void dwarf2_find_base_address (struct die_info *die, struct dwarf2_cu *cu); @@ -2264,88 +2260,6 @@ dwarf2_has_info (struct objfile *objfile, && dwarf2_per_objfile->abbrev.s.section != NULL); } -/* Return the containing section of virtual section SECTION. */ - -static struct dwarf2_section_info * -get_containing_section (const struct dwarf2_section_info *section) -{ - gdb_assert (section->is_virtual); - return section->s.containing_section; -} - -/* Return the bfd owner of SECTION. */ - -static struct bfd * -get_section_bfd_owner (const struct dwarf2_section_info *section) -{ - if (section->is_virtual) - { - section = get_containing_section (section); - gdb_assert (!section->is_virtual); - } - return section->s.section->owner; -} - -/* Return the bfd section of SECTION. - Returns NULL if the section is not present. */ - -static asection * -get_section_bfd_section (const struct dwarf2_section_info *section) -{ - if (section->is_virtual) - { - section = get_containing_section (section); - gdb_assert (!section->is_virtual); - } - return section->s.section; -} - -/* Return the name of SECTION. */ - -static const char * -get_section_name (const struct dwarf2_section_info *section) -{ - asection *sectp = get_section_bfd_section (section); - - gdb_assert (sectp != NULL); - return bfd_section_name (sectp); -} - -/* Return the name of the file SECTION is in. */ - -static const char * -get_section_file_name (const struct dwarf2_section_info *section) -{ - bfd *abfd = get_section_bfd_owner (section); - - return bfd_get_filename (abfd); -} - -/* Return the id of SECTION. - Returns 0 if SECTION doesn't exist. */ - -static int -get_section_id (const struct dwarf2_section_info *section) -{ - asection *sectp = get_section_bfd_section (section); - - if (sectp == NULL) - return 0; - return sectp->id; -} - -/* Return the flags of SECTION. - SECTION (or containing section if this is a virtual section) must exist. */ - -static int -get_section_flags (const struct dwarf2_section_info *section) -{ - asection *sectp = get_section_bfd_section (section); - - gdb_assert (sectp != NULL); - return bfd_section_flags (sectp); -} - /* When loading sections, we look either for uncompressed section or for compressed section names. */ @@ -2488,95 +2402,6 @@ dwarf2_per_objfile::locate_sections (bfd *abfd, asection *sectp, this->has_section_at_zero = true; } -/* A helper function that decides whether a section is empty, - or not present. */ - -static int -dwarf2_section_empty_p (const struct dwarf2_section_info *section) -{ - if (section->is_virtual) - return section->size == 0; - return section->s.section == NULL || section->size == 0; -} - -/* See dwarf2read.h. */ - -void -dwarf2_read_section (struct objfile *objfile, dwarf2_section_info *info) -{ - asection *sectp; - bfd *abfd; - gdb_byte *buf, *retbuf; - - if (info->readin) - return; - info->buffer = NULL; - info->readin = true; - - if (dwarf2_section_empty_p (info)) - return; - - sectp = get_section_bfd_section (info); - - /* If this is a virtual section we need to read in the real one first. */ - if (info->is_virtual) - { - struct dwarf2_section_info *containing_section = - get_containing_section (info); - - gdb_assert (sectp != NULL); - if ((sectp->flags & SEC_RELOC) != 0) - { - error (_("Dwarf Error: DWP format V2 with relocations is not" - " supported in section %s [in module %s]"), - get_section_name (info), get_section_file_name (info)); - } - dwarf2_read_section (objfile, containing_section); - /* Other code should have already caught virtual sections that don't - fit. */ - gdb_assert (info->virtual_offset + info->size - <= containing_section->size); - /* If the real section is empty or there was a problem reading the - section we shouldn't get here. */ - gdb_assert (containing_section->buffer != NULL); - info->buffer = containing_section->buffer + info->virtual_offset; - return; - } - - /* If the section has relocations, we must read it ourselves. - Otherwise we attach it to the BFD. */ - if ((sectp->flags & SEC_RELOC) == 0) - { - info->buffer = gdb_bfd_map_section (sectp, &info->size); - return; - } - - buf = (gdb_byte *) obstack_alloc (&objfile->objfile_obstack, info->size); - info->buffer = buf; - - /* When debugging .o files, we may need to apply relocations; see - http://sourceware.org/ml/gdb-patches/2002-04/msg00136.html . - We never compress sections in .o files, so we only need to - try this when the section is not compressed. */ - retbuf = symfile_relocate_debug_section (objfile, sectp, buf); - if (retbuf != NULL) - { - info->buffer = retbuf; - return; - } - - abfd = get_section_bfd_owner (info); - gdb_assert (abfd != NULL); - - if (bfd_seek (abfd, sectp->filepos, SEEK_SET) != 0 - || bfd_bread (buf, info->size, abfd) != info->size) - { - error (_("Dwarf Error: Can't read DWARF data" - " in section %s [in module %s]"), - bfd_section_name (sectp), bfd_get_filename (abfd)); - } -} - /* A helper function that returns the size of a section in a safe way. If you are positive that the section has been read before using the size, then it is safe to refer to the dwarf2_section_info object's diff --git a/gdb/dwarf2read.h b/gdb/dwarf2read.h index 5aa9421bbe5..62a7600a799 100644 --- a/gdb/dwarf2read.h +++ b/gdb/dwarf2read.h @@ -22,6 +22,7 @@ #include #include "dwarf-index-cache.h" +#include "dwarf2/section.h" #include "filename-seen-cache.h" #include "gdb_obstack.h" #include "gdbsupport/hash_enum.h" @@ -33,54 +34,6 @@ extern struct cmd_list_element *show_dwarf_cmdlist; extern bool dwarf_always_disassemble; -/* A descriptor for dwarf sections. - - S.ASECTION, SIZE are typically initialized when the objfile is first - scanned. BUFFER, READIN are filled in later when the section is read. - If the section contained compressed data then SIZE is updated to record - the uncompressed size of the section. - - DWP file format V2 introduces a wrinkle that is easiest to handle by - creating the concept of virtual sections contained within a real section. - In DWP V2 the sections of the input DWO files are concatenated together - into one section, but section offsets are kept relative to the original - input section. - If this is a virtual dwp-v2 section, S.CONTAINING_SECTION is a backlink to - the real section this "virtual" section is contained in, and BUFFER,SIZE - describe the virtual section. */ - -struct dwarf2_section_info -{ - union - { - /* If this is a real section, the bfd section. */ - asection *section; - /* If this is a virtual section, pointer to the containing ("real") - section. */ - struct dwarf2_section_info *containing_section; - } s; - /* Pointer to section data, only valid if readin. */ - const gdb_byte *buffer; - /* The size of the section, real or virtual. */ - bfd_size_type size; - /* If this is a virtual section, the offset in the real section. - Only valid if is_virtual. */ - bfd_size_type virtual_offset; - /* True if we have tried to read this section. */ - bool readin; - /* True if this is a virtual section, False otherwise. - This specifies which of s.section and s.containing_section to use. */ - bool is_virtual; -}; - -/* Read the contents of the section INFO. - OBJFILE is the main object file, but not necessarily the file where - the section comes from. E.g., for DWO files the bfd of INFO is the bfd - of the DWO file. - If the section is compressed, uncompress it before returning. */ - -void dwarf2_read_section (struct objfile *objfile, dwarf2_section_info *info); - struct tu_stats { int nr_uniq_abbrev_tables; -- 2.30.2