| 1 | /* DWARF 2 debugging format support for GDB. |
| 2 | |
| 3 | Copyright (C) 1994-2020 Free Software Foundation, Inc. |
| 4 | |
| 5 | Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology, |
| 6 | Inc. with support from Florida State University (under contract |
| 7 | with the Ada Joint Program Office), and Silicon Graphics, Inc. |
| 8 | Initial contribution by Brent Benson, Harris Computer Systems, Inc., |
| 9 | based on Fred Fish's (Cygnus Support) implementation of DWARF 1 |
| 10 | support. |
| 11 | |
| 12 | This file is part of GDB. |
| 13 | |
| 14 | This program is free software; you can redistribute it and/or modify |
| 15 | it under the terms of the GNU General Public License as published by |
| 16 | the Free Software Foundation; either version 3 of the License, or |
| 17 | (at your option) any later version. |
| 18 | |
| 19 | This program is distributed in the hope that it will be useful, |
| 20 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 21 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 22 | GNU General Public License for more details. |
| 23 | |
| 24 | You should have received a copy of the GNU General Public License |
| 25 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
| 26 | |
| 27 | #include "defs.h" |
| 28 | #include "dwarf2/comp-unit.h" |
| 29 | #include "dwarf2/leb.h" |
| 30 | #include "dwarf2/read.h" |
| 31 | #include "dwarf2/section.h" |
| 32 | |
| 33 | /* Convert a unit type to corresponding DW_UT name. */ |
| 34 | |
| 35 | static const char * |
| 36 | dwarf_unit_type_name (int unit_type) |
| 37 | { |
| 38 | switch (unit_type) |
| 39 | { |
| 40 | case 0x01: |
| 41 | return "DW_UT_compile (0x01)"; |
| 42 | case 0x02: |
| 43 | return "DW_UT_type (0x02)"; |
| 44 | case 0x03: |
| 45 | return "DW_UT_partial (0x03)"; |
| 46 | case 0x04: |
| 47 | return "DW_UT_skeleton (0x04)"; |
| 48 | case 0x05: |
| 49 | return "DW_UT_split_compile (0x05)"; |
| 50 | case 0x06: |
| 51 | return "DW_UT_split_type (0x06)"; |
| 52 | case 0x80: |
| 53 | return "DW_UT_lo_user (0x80)"; |
| 54 | case 0xff: |
| 55 | return "DW_UT_hi_user (0xff)"; |
| 56 | default: |
| 57 | return nullptr; |
| 58 | } |
| 59 | } |
| 60 | |
| 61 | /* See comp-unit.h. */ |
| 62 | |
| 63 | const gdb_byte * |
| 64 | read_comp_unit_head (struct comp_unit_head *cu_header, |
| 65 | const gdb_byte *info_ptr, |
| 66 | struct dwarf2_section_info *section, |
| 67 | rcuh_kind section_kind) |
| 68 | { |
| 69 | int signed_addr; |
| 70 | unsigned int bytes_read; |
| 71 | const char *filename = section->get_file_name (); |
| 72 | bfd *abfd = section->get_bfd_owner (); |
| 73 | |
| 74 | cu_header->length = read_initial_length (abfd, info_ptr, &bytes_read); |
| 75 | cu_header->initial_length_size = bytes_read; |
| 76 | cu_header->offset_size = (bytes_read == 4) ? 4 : 8; |
| 77 | info_ptr += bytes_read; |
| 78 | cu_header->version = read_2_bytes (abfd, info_ptr); |
| 79 | if (cu_header->version < 2 || cu_header->version > 5) |
| 80 | error (_("Dwarf Error: wrong version in compilation unit header " |
| 81 | "(is %d, should be 2, 3, 4 or 5) [in module %s]"), |
| 82 | cu_header->version, filename); |
| 83 | info_ptr += 2; |
| 84 | if (cu_header->version < 5) |
| 85 | switch (section_kind) |
| 86 | { |
| 87 | case rcuh_kind::COMPILE: |
| 88 | cu_header->unit_type = DW_UT_compile; |
| 89 | break; |
| 90 | case rcuh_kind::TYPE: |
| 91 | cu_header->unit_type = DW_UT_type; |
| 92 | break; |
| 93 | default: |
| 94 | internal_error (__FILE__, __LINE__, |
| 95 | _("read_comp_unit_head: invalid section_kind")); |
| 96 | } |
| 97 | else |
| 98 | { |
| 99 | cu_header->unit_type = static_cast<enum dwarf_unit_type> |
| 100 | (read_1_byte (abfd, info_ptr)); |
| 101 | info_ptr += 1; |
| 102 | switch (cu_header->unit_type) |
| 103 | { |
| 104 | case DW_UT_compile: |
| 105 | case DW_UT_partial: |
| 106 | case DW_UT_skeleton: |
| 107 | case DW_UT_split_compile: |
| 108 | if (section_kind != rcuh_kind::COMPILE) |
| 109 | error (_("Dwarf Error: wrong unit_type in compilation unit header " |
| 110 | "(is %s, should be %s) [in module %s]"), |
| 111 | dwarf_unit_type_name (cu_header->unit_type), |
| 112 | dwarf_unit_type_name (DW_UT_type), filename); |
| 113 | break; |
| 114 | case DW_UT_type: |
| 115 | case DW_UT_split_type: |
| 116 | section_kind = rcuh_kind::TYPE; |
| 117 | break; |
| 118 | default: |
| 119 | error (_("Dwarf Error: wrong unit_type in compilation unit header " |
| 120 | "(is %#04x, should be one of: %s, %s, %s, %s or %s) " |
| 121 | "[in module %s]"), cu_header->unit_type, |
| 122 | dwarf_unit_type_name (DW_UT_compile), |
| 123 | dwarf_unit_type_name (DW_UT_skeleton), |
| 124 | dwarf_unit_type_name (DW_UT_split_compile), |
| 125 | dwarf_unit_type_name (DW_UT_type), |
| 126 | dwarf_unit_type_name (DW_UT_split_type), filename); |
| 127 | } |
| 128 | |
| 129 | cu_header->addr_size = read_1_byte (abfd, info_ptr); |
| 130 | info_ptr += 1; |
| 131 | } |
| 132 | cu_header->abbrev_sect_off |
| 133 | = (sect_offset) cu_header->read_offset (abfd, info_ptr, &bytes_read); |
| 134 | info_ptr += bytes_read; |
| 135 | if (cu_header->version < 5) |
| 136 | { |
| 137 | cu_header->addr_size = read_1_byte (abfd, info_ptr); |
| 138 | info_ptr += 1; |
| 139 | } |
| 140 | signed_addr = bfd_get_sign_extend_vma (abfd); |
| 141 | if (signed_addr < 0) |
| 142 | internal_error (__FILE__, __LINE__, |
| 143 | _("read_comp_unit_head: dwarf from non elf file")); |
| 144 | cu_header->signed_addr_p = signed_addr; |
| 145 | |
| 146 | bool header_has_signature = section_kind == rcuh_kind::TYPE |
| 147 | || cu_header->unit_type == DW_UT_skeleton |
| 148 | || cu_header->unit_type == DW_UT_split_compile; |
| 149 | |
| 150 | if (header_has_signature) |
| 151 | { |
| 152 | cu_header->signature = read_8_bytes (abfd, info_ptr); |
| 153 | info_ptr += 8; |
| 154 | } |
| 155 | |
| 156 | if (section_kind == rcuh_kind::TYPE) |
| 157 | { |
| 158 | LONGEST type_offset; |
| 159 | type_offset = cu_header->read_offset (abfd, info_ptr, &bytes_read); |
| 160 | info_ptr += bytes_read; |
| 161 | cu_header->type_cu_offset_in_tu = (cu_offset) type_offset; |
| 162 | if (to_underlying (cu_header->type_cu_offset_in_tu) != type_offset) |
| 163 | error (_("Dwarf Error: Too big type_offset in compilation unit " |
| 164 | "header (is %s) [in module %s]"), plongest (type_offset), |
| 165 | filename); |
| 166 | } |
| 167 | |
| 168 | return info_ptr; |
| 169 | } |
| 170 | |
| 171 | /* Subroutine of read_and_check_comp_unit_head and |
| 172 | read_and_check_type_unit_head to simplify them. |
| 173 | Perform various error checking on the header. */ |
| 174 | |
| 175 | static void |
| 176 | error_check_comp_unit_head (dwarf2_per_objfile *per_objfile, |
| 177 | struct comp_unit_head *header, |
| 178 | struct dwarf2_section_info *section, |
| 179 | struct dwarf2_section_info *abbrev_section) |
| 180 | { |
| 181 | const char *filename = section->get_file_name (); |
| 182 | |
| 183 | if (to_underlying (header->abbrev_sect_off) |
| 184 | >= abbrev_section->get_size (per_objfile->objfile)) |
| 185 | error (_("Dwarf Error: bad offset (%s) in compilation unit header " |
| 186 | "(offset %s + 6) [in module %s]"), |
| 187 | sect_offset_str (header->abbrev_sect_off), |
| 188 | sect_offset_str (header->sect_off), |
| 189 | filename); |
| 190 | |
| 191 | /* Cast to ULONGEST to use 64-bit arithmetic when possible to |
| 192 | avoid potential 32-bit overflow. */ |
| 193 | if (((ULONGEST) header->sect_off + header->get_length ()) |
| 194 | > section->size) |
| 195 | error (_("Dwarf Error: bad length (0x%x) in compilation unit header " |
| 196 | "(offset %s + 0) [in module %s]"), |
| 197 | header->length, sect_offset_str (header->sect_off), |
| 198 | filename); |
| 199 | } |
| 200 | |
| 201 | /* See comp-unit.h. */ |
| 202 | |
| 203 | const gdb_byte * |
| 204 | read_and_check_comp_unit_head (dwarf2_per_objfile *per_objfile, |
| 205 | struct comp_unit_head *header, |
| 206 | struct dwarf2_section_info *section, |
| 207 | struct dwarf2_section_info *abbrev_section, |
| 208 | const gdb_byte *info_ptr, |
| 209 | rcuh_kind section_kind) |
| 210 | { |
| 211 | const gdb_byte *beg_of_comp_unit = info_ptr; |
| 212 | |
| 213 | header->sect_off = (sect_offset) (beg_of_comp_unit - section->buffer); |
| 214 | |
| 215 | info_ptr = read_comp_unit_head (header, info_ptr, section, section_kind); |
| 216 | |
| 217 | header->first_die_cu_offset = (cu_offset) (info_ptr - beg_of_comp_unit); |
| 218 | |
| 219 | error_check_comp_unit_head (per_objfile, header, section, abbrev_section); |
| 220 | |
| 221 | return info_ptr; |
| 222 | } |
| 223 | |
| 224 | CORE_ADDR |
| 225 | comp_unit_head::read_address (bfd *abfd, const gdb_byte *buf, |
| 226 | unsigned int *bytes_read) const |
| 227 | { |
| 228 | CORE_ADDR retval = 0; |
| 229 | |
| 230 | if (signed_addr_p) |
| 231 | { |
| 232 | switch (addr_size) |
| 233 | { |
| 234 | case 2: |
| 235 | retval = bfd_get_signed_16 (abfd, buf); |
| 236 | break; |
| 237 | case 4: |
| 238 | retval = bfd_get_signed_32 (abfd, buf); |
| 239 | break; |
| 240 | case 8: |
| 241 | retval = bfd_get_signed_64 (abfd, buf); |
| 242 | break; |
| 243 | default: |
| 244 | internal_error (__FILE__, __LINE__, |
| 245 | _("read_address: bad switch, signed [in module %s]"), |
| 246 | bfd_get_filename (abfd)); |
| 247 | } |
| 248 | } |
| 249 | else |
| 250 | { |
| 251 | switch (addr_size) |
| 252 | { |
| 253 | case 2: |
| 254 | retval = bfd_get_16 (abfd, buf); |
| 255 | break; |
| 256 | case 4: |
| 257 | retval = bfd_get_32 (abfd, buf); |
| 258 | break; |
| 259 | case 8: |
| 260 | retval = bfd_get_64 (abfd, buf); |
| 261 | break; |
| 262 | default: |
| 263 | internal_error (__FILE__, __LINE__, |
| 264 | _("read_address: bad switch, " |
| 265 | "unsigned [in module %s]"), |
| 266 | bfd_get_filename (abfd)); |
| 267 | } |
| 268 | } |
| 269 | |
| 270 | *bytes_read = addr_size; |
| 271 | return retval; |
| 272 | } |