Commit | Line | Data |
---|---|---|
4057dfde TT |
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 | } | |
8266302d TT |
132 | cu_header->abbrev_sect_off |
133 | = (sect_offset) cu_header->read_offset (abfd, info_ptr, &bytes_read); | |
4057dfde TT |
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; | |
8266302d | 159 | type_offset = cu_header->read_offset (abfd, info_ptr, &bytes_read); |
4057dfde TT |
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 | |
976ca316 | 176 | error_check_comp_unit_head (dwarf2_per_objfile *per_objfile, |
4057dfde TT |
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) | |
976ca316 | 184 | >= abbrev_section->get_size (per_objfile->objfile)) |
4057dfde TT |
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 * | |
976ca316 | 204 | read_and_check_comp_unit_head (dwarf2_per_objfile *per_objfile, |
4057dfde TT |
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 | ||
976ca316 | 219 | error_check_comp_unit_head (per_objfile, header, section, abbrev_section); |
4057dfde TT |
220 | |
221 | return info_ptr; | |
222 | } | |
c8a7a66f TT |
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 | } |