| /* DWARF 2 low-level section code | |
| Copyright (C) 1994-2021 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); | |
| } | |
| 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 (); | |
| 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) | |
| 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); | |
| } |