214 lines
5.6 KiB
C
214 lines
5.6 KiB
C
/* DWARF 2 low-level section code
|
|
|
|
Copyright (C) 1994-2022 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"
|
|
#include "complaints.h"
|
|
|
|
void
|
|
dwarf2_section_info::overflow_complaint () const
|
|
{
|
|
complaint (_("debug info runs off end of %s section"
|
|
" [in module %s]"),
|
|
get_name (), get_file_name ());
|
|
}
|
|
|
|
struct dwarf2_section_info *
|
|
dwarf2_section_info::get_containing_section () const
|
|
{
|
|
gdb_assert (is_virtual);
|
|
return s.containing_section;
|
|
}
|
|
|
|
struct bfd *
|
|
dwarf2_section_info::get_bfd_owner () const
|
|
{
|
|
const dwarf2_section_info *section = this;
|
|
if (is_virtual)
|
|
{
|
|
section = get_containing_section ();
|
|
gdb_assert (!section->is_virtual);
|
|
}
|
|
gdb_assert (section->s.section != nullptr);
|
|
return section->s.section->owner;
|
|
}
|
|
|
|
asection *
|
|
dwarf2_section_info::get_bfd_section () const
|
|
{
|
|
const dwarf2_section_info *section = this;
|
|
if (section->is_virtual)
|
|
{
|
|
section = get_containing_section ();
|
|
gdb_assert (!section->is_virtual);
|
|
}
|
|
return section->s.section;
|
|
}
|
|
|
|
const char *
|
|
dwarf2_section_info::get_name () const
|
|
{
|
|
asection *sectp = get_bfd_section ();
|
|
|
|
gdb_assert (sectp != NULL);
|
|
return bfd_section_name (sectp);
|
|
}
|
|
|
|
const char *
|
|
dwarf2_section_info::get_file_name () const
|
|
{
|
|
bfd *abfd = get_bfd_owner ();
|
|
|
|
gdb_assert (abfd != nullptr);
|
|
return bfd_get_filename (abfd);
|
|
}
|
|
|
|
int
|
|
dwarf2_section_info::get_id () const
|
|
{
|
|
asection *sectp = get_bfd_section ();
|
|
|
|
if (sectp == NULL)
|
|
return 0;
|
|
return sectp->id;
|
|
}
|
|
|
|
int
|
|
dwarf2_section_info::get_flags () const
|
|
{
|
|
asection *sectp = get_bfd_section ();
|
|
|
|
gdb_assert (sectp != NULL);
|
|
return bfd_section_flags (sectp);
|
|
}
|
|
|
|
bool
|
|
dwarf2_section_info::empty () const
|
|
{
|
|
if (is_virtual)
|
|
return size == 0;
|
|
return s.section == NULL || size == 0;
|
|
}
|
|
|
|
void
|
|
dwarf2_section_info::read (struct objfile *objfile)
|
|
{
|
|
asection *sectp;
|
|
bfd *abfd;
|
|
gdb_byte *buf, *retbuf;
|
|
|
|
if (readin)
|
|
return;
|
|
buffer = NULL;
|
|
readin = true;
|
|
|
|
if (empty ())
|
|
return;
|
|
|
|
sectp = get_bfd_section ();
|
|
|
|
/* If this is a virtual section we need to read in the real one first. */
|
|
if (is_virtual)
|
|
{
|
|
struct dwarf2_section_info *containing_section =
|
|
get_containing_section ();
|
|
|
|
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_name (), get_file_name ());
|
|
}
|
|
containing_section->read (objfile);
|
|
/* Other code should have already caught virtual sections that don't
|
|
fit. */
|
|
gdb_assert (virtual_offset + 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);
|
|
buffer = containing_section->buffer + 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)
|
|
{
|
|
buffer = gdb_bfd_map_section (sectp, &size);
|
|
return;
|
|
}
|
|
|
|
buf = (gdb_byte *) obstack_alloc (&objfile->objfile_obstack, size);
|
|
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)
|
|
{
|
|
buffer = retbuf;
|
|
return;
|
|
}
|
|
|
|
abfd = get_bfd_owner ();
|
|
gdb_assert (abfd != NULL);
|
|
|
|
if (bfd_seek (abfd, sectp->filepos, SEEK_SET) != 0
|
|
|| bfd_bread (buf, size, abfd) != size)
|
|
{
|
|
error (_("Dwarf Error: Can't read DWARF data"
|
|
" in section %s [in module %s]"),
|
|
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)
|
|
{
|
|
if (get_bfd_section () == nullptr)
|
|
error (_("Dwarf Error: %s used without required section"),
|
|
form_name);
|
|
else
|
|
error (_("Dwarf 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);
|
|
}
|