diff options
author | Tom Tromey <tom@tromey.com> | 2021-05-17 14:16:06 -0600 |
---|---|---|
committer | Tom Tromey <tom@tromey.com> | 2021-05-17 14:16:07 -0600 |
commit | cd53fa40d480468bdcfc2992cf9753fb59bc7a23 (patch) | |
tree | bb1e16517c217f9815b833a9d1cfe6c3fb902081 /gdb/dwarf2/comp-unit-head.c | |
parent | 347212b81930f9afb9e2885656f897cf3821881c (diff) | |
download | binutils-cd53fa40d480468bdcfc2992cf9753fb59bc7a23.zip binutils-cd53fa40d480468bdcfc2992cf9753fb59bc7a23.tar.gz binutils-cd53fa40d480468bdcfc2992cf9753fb59bc7a23.tar.bz2 |
Rename dwarf2/comp-unit.h
Simon pointed out that dwarf2/cu.h and dwarf2/comp-unit.h seemingly
mean the same thing. He suggested renaming the latter to
comp-unit-head.h, which is what this patch does.
gdb/ChangeLog
2021-05-17 Tom Tromey <tom@tromey.com>
* dwarf2/read.h: Update include.
* dwarf2/read.c: Update include.
* dwarf2/line-header.c: Update include.
* dwarf2/cu.h: Update include.
* dwarf2/comp-unit-head.h: Rename from comp-unit.h.
* dwarf2/comp-unit-head.c: Rename from comp-unit.c.
* Makefile.in (COMMON_SFILES): Update.
Diffstat (limited to 'gdb/dwarf2/comp-unit-head.c')
-rw-r--r-- | gdb/dwarf2/comp-unit-head.c | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/gdb/dwarf2/comp-unit-head.c b/gdb/dwarf2/comp-unit-head.c new file mode 100644 index 0000000..8cc741d --- /dev/null +++ b/gdb/dwarf2/comp-unit-head.c @@ -0,0 +1,246 @@ +/* DWARF 2 debugging format support for GDB. + + 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/comp-unit-head.h" +#include "dwarf2/leb.h" +#include "dwarf2/read.h" +#include "dwarf2/section.h" +#include "dwarf2/stringify.h" + +/* See comp-unit-head.h. */ + +const gdb_byte * +read_comp_unit_head (struct comp_unit_head *cu_header, + const gdb_byte *info_ptr, + struct dwarf2_section_info *section, + rcuh_kind section_kind) +{ + int signed_addr; + unsigned int bytes_read; + const char *filename = section->get_file_name (); + bfd *abfd = section->get_bfd_owner (); + + cu_header->length = read_initial_length (abfd, info_ptr, &bytes_read); + cu_header->initial_length_size = bytes_read; + cu_header->offset_size = (bytes_read == 4) ? 4 : 8; + info_ptr += bytes_read; + unsigned version = read_2_bytes (abfd, info_ptr); + if (version < 2 || version > 5) + error (_("Dwarf Error: wrong version in compilation unit header " + "(is %d, should be 2, 3, 4 or 5) [in module %s]"), + version, filename); + cu_header->version = version; + info_ptr += 2; + if (cu_header->version < 5) + switch (section_kind) + { + case rcuh_kind::COMPILE: + cu_header->unit_type = DW_UT_compile; + break; + case rcuh_kind::TYPE: + cu_header->unit_type = DW_UT_type; + break; + default: + internal_error (__FILE__, __LINE__, + _("read_comp_unit_head: invalid section_kind")); + } + else + { + cu_header->unit_type = static_cast<enum dwarf_unit_type> + (read_1_byte (abfd, info_ptr)); + info_ptr += 1; + switch (cu_header->unit_type) + { + case DW_UT_compile: + case DW_UT_partial: + case DW_UT_skeleton: + case DW_UT_split_compile: + if (section_kind != rcuh_kind::COMPILE) + error (_("Dwarf Error: wrong unit_type in compilation unit header " + "(is %s, should be %s) [in module %s]"), + dwarf_unit_type_name (cu_header->unit_type), + dwarf_unit_type_name (DW_UT_type), filename); + break; + case DW_UT_type: + case DW_UT_split_type: + section_kind = rcuh_kind::TYPE; + break; + default: + error (_("Dwarf Error: wrong unit_type in compilation unit header " + "(is %#04x, should be one of: %s, %s, %s, %s or %s) " + "[in module %s]"), cu_header->unit_type, + dwarf_unit_type_name (DW_UT_compile), + dwarf_unit_type_name (DW_UT_skeleton), + dwarf_unit_type_name (DW_UT_split_compile), + dwarf_unit_type_name (DW_UT_type), + dwarf_unit_type_name (DW_UT_split_type), filename); + } + + cu_header->addr_size = read_1_byte (abfd, info_ptr); + info_ptr += 1; + } + cu_header->abbrev_sect_off + = (sect_offset) cu_header->read_offset (abfd, info_ptr, &bytes_read); + info_ptr += bytes_read; + if (cu_header->version < 5) + { + cu_header->addr_size = read_1_byte (abfd, info_ptr); + info_ptr += 1; + } + signed_addr = bfd_get_sign_extend_vma (abfd); + if (signed_addr < 0) + internal_error (__FILE__, __LINE__, + _("read_comp_unit_head: dwarf from non elf file")); + cu_header->signed_addr_p = signed_addr; + + bool header_has_signature = section_kind == rcuh_kind::TYPE + || cu_header->unit_type == DW_UT_skeleton + || cu_header->unit_type == DW_UT_split_compile; + + if (header_has_signature) + { + cu_header->signature = read_8_bytes (abfd, info_ptr); + info_ptr += 8; + } + + if (section_kind == rcuh_kind::TYPE) + { + LONGEST type_offset; + type_offset = cu_header->read_offset (abfd, info_ptr, &bytes_read); + info_ptr += bytes_read; + cu_header->type_cu_offset_in_tu = (cu_offset) type_offset; + if (to_underlying (cu_header->type_cu_offset_in_tu) != type_offset) + error (_("Dwarf Error: Too big type_offset in compilation unit " + "header (is %s) [in module %s]"), plongest (type_offset), + filename); + } + + return info_ptr; +} + +/* Subroutine of read_and_check_comp_unit_head and + read_and_check_type_unit_head to simplify them. + Perform various error checking on the header. */ + +static void +error_check_comp_unit_head (dwarf2_per_objfile *per_objfile, + struct comp_unit_head *header, + struct dwarf2_section_info *section, + struct dwarf2_section_info *abbrev_section) +{ + const char *filename = section->get_file_name (); + + if (to_underlying (header->abbrev_sect_off) + >= abbrev_section->get_size (per_objfile->objfile)) + error (_("Dwarf Error: bad offset (%s) in compilation unit header " + "(offset %s + 6) [in module %s]"), + sect_offset_str (header->abbrev_sect_off), + sect_offset_str (header->sect_off), + filename); + + /* Cast to ULONGEST to use 64-bit arithmetic when possible to + avoid potential 32-bit overflow. */ + if (((ULONGEST) header->sect_off + header->get_length ()) + > section->size) + error (_("Dwarf Error: bad length (0x%x) in compilation unit header " + "(offset %s + 0) [in module %s]"), + header->length, sect_offset_str (header->sect_off), + filename); +} + +/* See comp-unit-head.h. */ + +const gdb_byte * +read_and_check_comp_unit_head (dwarf2_per_objfile *per_objfile, + struct comp_unit_head *header, + struct dwarf2_section_info *section, + struct dwarf2_section_info *abbrev_section, + const gdb_byte *info_ptr, + rcuh_kind section_kind) +{ + const gdb_byte *beg_of_comp_unit = info_ptr; + + header->sect_off = (sect_offset) (beg_of_comp_unit - section->buffer); + + info_ptr = read_comp_unit_head (header, info_ptr, section, section_kind); + + header->first_die_cu_offset = (cu_offset) (info_ptr - beg_of_comp_unit); + + error_check_comp_unit_head (per_objfile, header, section, abbrev_section); + + return info_ptr; +} + +CORE_ADDR +comp_unit_head::read_address (bfd *abfd, const gdb_byte *buf, + unsigned int *bytes_read) const +{ + CORE_ADDR retval = 0; + + if (signed_addr_p) + { + switch (addr_size) + { + case 2: + retval = bfd_get_signed_16 (abfd, buf); + break; + case 4: + retval = bfd_get_signed_32 (abfd, buf); + break; + case 8: + retval = bfd_get_signed_64 (abfd, buf); + break; + default: + internal_error (__FILE__, __LINE__, + _("read_address: bad switch, signed [in module %s]"), + bfd_get_filename (abfd)); + } + } + else + { + switch (addr_size) + { + case 2: + retval = bfd_get_16 (abfd, buf); + break; + case 4: + retval = bfd_get_32 (abfd, buf); + break; + case 8: + retval = bfd_get_64 (abfd, buf); + break; + default: + internal_error (__FILE__, __LINE__, + _("read_address: bad switch, " + "unsigned [in module %s]"), + bfd_get_filename (abfd)); + } + } + + *bytes_read = addr_size; + return retval; +} |