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  <tom@tromey.com>

	* 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
This commit is contained in:
Tom Tromey 2020-02-08 13:40:54 -07:00
parent f4382c45a4
commit 2c86cff96f
6 changed files with 315 additions and 223 deletions

View File

@ -1,3 +1,16 @@
2020-02-08 Tom Tromey <tom@tromey.com>
* 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 <tom@tromey.com>
* dwarf2read.h (read_unsigned_leb128): Don't declare.

View File

@ -1003,6 +1003,7 @@ COMMON_SFILES = \
dwarf2loc.c \
dwarf2read.c \
dwarf2/leb.c \
dwarf2/section.c \
eval.c \
event-loop.c \
event-top.c \

179
gdb/dwarf2/section.c Normal file
View File

@ -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 <http://www.gnu.org/licenses/>. */
#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));
}
}

121
gdb/dwarf2/section.h Normal file
View File

@ -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 <http://www.gnu.org/licenses/>. */
#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 */

View File

@ -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

View File

@ -22,6 +22,7 @@
#include <unordered_map>
#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;