File: | src/gnu/usr.bin/binutils-2.17/binutils/rdcoff.c |
Warning: | line 437, column 12 Assigned value is garbage or undefined |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* stabs.c -- Parse COFF debugging information | |||
2 | Copyright 1996, 1999, 2000, 2002, 2003 Free Software Foundation, Inc. | |||
3 | Written by Ian Lance Taylor <ian@cygnus.com>. | |||
4 | ||||
5 | This file is part of GNU Binutils. | |||
6 | ||||
7 | This program is free software; you can redistribute it and/or modify | |||
8 | it under the terms of the GNU General Public License as published by | |||
9 | the Free Software Foundation; either version 2 of the License, or | |||
10 | (at your option) any later version. | |||
11 | ||||
12 | This program is distributed in the hope that it will be useful, | |||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
15 | GNU General Public License for more details. | |||
16 | ||||
17 | You should have received a copy of the GNU General Public License | |||
18 | along with this program; if not, write to the Free Software | |||
19 | Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA | |||
20 | 02110-1301, USA. */ | |||
21 | ||||
22 | /* This file contains code which parses COFF debugging information. */ | |||
23 | ||||
24 | #include "bfd.h" | |||
25 | #include "coff/internal.h" | |||
26 | #include "bucomm.h" | |||
27 | #include "libiberty.h" | |||
28 | #include "debug.h" | |||
29 | #include "budbg.h" | |||
30 | ||||
31 | /* FIXME: We should not need this BFD internal file. We need it for | |||
32 | the N_BTMASK, etc., values. */ | |||
33 | #include "libcoff.h" | |||
34 | ||||
35 | /* These macros extract the right mask and shifts for this BFD. They | |||
36 | assume that there is a local variable named ABFD. This is so that | |||
37 | macros like ISFCN and DECREF, from coff/internal.h, will work | |||
38 | without modification. */ | |||
39 | #define N_BTMASK(((abfd)->tdata.coff_obj_data)->local_n_btmask) (coff_data (abfd)((abfd)->tdata.coff_obj_data)->local_n_btmask) | |||
40 | #define N_BTSHFT(((abfd)->tdata.coff_obj_data)->local_n_btshft) (coff_data (abfd)((abfd)->tdata.coff_obj_data)->local_n_btshft) | |||
41 | #define N_TMASK(((abfd)->tdata.coff_obj_data)->local_n_tmask) (coff_data (abfd)((abfd)->tdata.coff_obj_data)->local_n_tmask) | |||
42 | #define N_TSHIFT(((abfd)->tdata.coff_obj_data)->local_n_tshift) (coff_data (abfd)((abfd)->tdata.coff_obj_data)->local_n_tshift) | |||
43 | ||||
44 | /* This structure is used to hold the symbols, as well as the current | |||
45 | location within the symbols. */ | |||
46 | ||||
47 | struct coff_symbols | |||
48 | { | |||
49 | /* The symbols. */ | |||
50 | asymbol **syms; | |||
51 | /* The number of symbols. */ | |||
52 | long symcount; | |||
53 | /* The index of the current symbol. */ | |||
54 | long symno; | |||
55 | /* The index of the current symbol in the COFF symbol table (where | |||
56 | each auxent counts as a symbol). */ | |||
57 | long coff_symno; | |||
58 | }; | |||
59 | ||||
60 | /* The largest basic type we are prepared to handle. */ | |||
61 | ||||
62 | #define T_MAX(16) (T_LNGDBL16) | |||
63 | ||||
64 | /* This structure is used to hold slots. */ | |||
65 | ||||
66 | struct coff_slots | |||
67 | { | |||
68 | /* Next set of slots. */ | |||
69 | struct coff_slots *next; | |||
70 | /* Slots. */ | |||
71 | #define COFF_SLOTS(16) (16) | |||
72 | debug_type slots[COFF_SLOTS(16)]; | |||
73 | }; | |||
74 | ||||
75 | /* This structure is used to map symbol indices to types. */ | |||
76 | ||||
77 | struct coff_types | |||
78 | { | |||
79 | /* Slots. */ | |||
80 | struct coff_slots *slots; | |||
81 | /* Basic types. */ | |||
82 | debug_type basic[T_MAX(16) + 1]; | |||
83 | }; | |||
84 | ||||
85 | static debug_type *coff_get_slot (struct coff_types *, int); | |||
86 | static debug_type parse_coff_type | |||
87 | (bfd *, struct coff_symbols *, struct coff_types *, long, int, | |||
88 | union internal_auxent *, bfd_boolean, void *); | |||
89 | static debug_type parse_coff_base_type | |||
90 | (bfd *, struct coff_symbols *, struct coff_types *, long, int, | |||
91 | union internal_auxent *, void *); | |||
92 | static debug_type parse_coff_struct_type | |||
93 | (bfd *, struct coff_symbols *, struct coff_types *, int, | |||
94 | union internal_auxent *, void *); | |||
95 | static debug_type parse_coff_enum_type | |||
96 | (bfd *, struct coff_symbols *, struct coff_types *, | |||
97 | union internal_auxent *, void *); | |||
98 | static bfd_boolean parse_coff_symbol | |||
99 | (bfd *, struct coff_types *, asymbol *, long, struct internal_syment *, | |||
100 | void *, debug_type, bfd_boolean); | |||
101 | static bfd_boolean external_coff_symbol_p (int sym_class); | |||
102 | ||||
103 | /* Return the slot for a type. */ | |||
104 | ||||
105 | static debug_type * | |||
106 | coff_get_slot (struct coff_types *types, int indx) | |||
107 | { | |||
108 | struct coff_slots **pps; | |||
109 | ||||
110 | pps = &types->slots; | |||
111 | ||||
112 | while (indx >= COFF_SLOTS(16)) | |||
113 | { | |||
114 | if (*pps == NULL((void*)0)) | |||
115 | { | |||
116 | *pps = (struct coff_slots *) xmalloc (sizeof **pps); | |||
117 | memset (*pps, 0, sizeof **pps); | |||
118 | } | |||
119 | pps = &(*pps)->next; | |||
120 | indx -= COFF_SLOTS(16); | |||
121 | } | |||
122 | ||||
123 | if (*pps == NULL((void*)0)) | |||
124 | { | |||
125 | *pps = (struct coff_slots *) xmalloc (sizeof **pps); | |||
126 | memset (*pps, 0, sizeof **pps); | |||
127 | } | |||
128 | ||||
129 | return (*pps)->slots + indx; | |||
130 | } | |||
131 | ||||
132 | /* Parse a COFF type code in NTYPE. */ | |||
133 | ||||
134 | static debug_type | |||
135 | parse_coff_type (bfd *abfd, struct coff_symbols *symbols, | |||
136 | struct coff_types *types, long coff_symno, int ntype, | |||
137 | union internal_auxent *pauxent, bfd_boolean useaux, | |||
138 | void *dhandle) | |||
139 | { | |||
140 | debug_type type; | |||
141 | ||||
142 | if ((ntype & ~N_BTMASK(((abfd)->tdata.coff_obj_data)->local_n_btmask)) != 0) | |||
143 | { | |||
144 | int newtype; | |||
145 | ||||
146 | newtype = DECREF (ntype)((((ntype) >> (((abfd)->tdata.coff_obj_data)->local_n_tshift )) & ~ (((abfd)->tdata.coff_obj_data)->local_n_btmask )) | ((ntype) & (((abfd)->tdata.coff_obj_data)->local_n_btmask ))); | |||
147 | ||||
148 | if (ISPTR (ntype)(((unsigned long) (ntype) & (((abfd)->tdata.coff_obj_data )->local_n_tmask)) == ((unsigned long) (1) << (((abfd )->tdata.coff_obj_data)->local_n_btshft)))) | |||
149 | { | |||
150 | type = parse_coff_type (abfd, symbols, types, coff_symno, newtype, | |||
151 | pauxent, useaux, dhandle); | |||
152 | type = debug_make_pointer_type (dhandle, type); | |||
153 | } | |||
154 | else if (ISFCN (ntype)(((unsigned long) (ntype) & (((abfd)->tdata.coff_obj_data )->local_n_tmask)) == ((unsigned long) (2) << (((abfd )->tdata.coff_obj_data)->local_n_btshft)))) | |||
155 | { | |||
156 | type = parse_coff_type (abfd, symbols, types, coff_symno, newtype, | |||
157 | pauxent, useaux, dhandle); | |||
158 | type = debug_make_function_type (dhandle, type, (debug_type *) NULL((void*)0), | |||
159 | FALSE0); | |||
160 | } | |||
161 | else if (ISARY (ntype)(((unsigned long) (ntype) & (((abfd)->tdata.coff_obj_data )->local_n_tmask)) == ((unsigned long) (3) << (((abfd )->tdata.coff_obj_data)->local_n_btshft)))) | |||
162 | { | |||
163 | int n; | |||
164 | ||||
165 | if (pauxent == NULL((void*)0)) | |||
166 | n = 0; | |||
167 | else | |||
168 | { | |||
169 | unsigned short *dim; | |||
170 | int i; | |||
171 | ||||
172 | /* FIXME: If pauxent->x_sym.x_tagndx.l == 0, gdb sets | |||
173 | the c_naux field of the syment to 0. */ | |||
174 | ||||
175 | /* Move the dimensions down, so that the next array | |||
176 | picks up the next one. */ | |||
177 | dim = pauxent->x_sym.x_fcnary.x_ary.x_dimen; | |||
178 | n = dim[0]; | |||
179 | for (i = 0; *dim != 0 && i < DIMNUM4 - 1; i++, dim++) | |||
180 | *dim = *(dim + 1); | |||
181 | *dim = 0; | |||
182 | } | |||
183 | ||||
184 | type = parse_coff_type (abfd, symbols, types, coff_symno, newtype, | |||
185 | pauxent, FALSE0, dhandle); | |||
186 | type = debug_make_array_type (dhandle, type, | |||
187 | parse_coff_base_type (abfd, symbols, | |||
188 | types, | |||
189 | coff_symno, | |||
190 | T_INT4, | |||
191 | NULL((void*)0), dhandle), | |||
192 | 0, n - 1, FALSE0); | |||
193 | } | |||
194 | else | |||
195 | { | |||
196 | non_fatal (_("parse_coff_type: Bad type code 0x%x")("parse_coff_type: Bad type code 0x%x"), ntype); | |||
197 | return DEBUG_TYPE_NULL((debug_type) ((void*)0)); | |||
198 | } | |||
199 | ||||
200 | return type; | |||
201 | } | |||
202 | ||||
203 | if (pauxent != NULL((void*)0) && pauxent->x_sym.x_tagndx.l > 0) | |||
204 | { | |||
205 | debug_type *slot; | |||
206 | ||||
207 | /* This is a reference to an existing type. FIXME: gdb checks | |||
208 | that the class is not C_STRTAG, nor C_UNTAG, nor C_ENTAG. */ | |||
209 | slot = coff_get_slot (types, pauxent->x_sym.x_tagndx.l); | |||
210 | if (*slot != DEBUG_TYPE_NULL((debug_type) ((void*)0))) | |||
211 | return *slot; | |||
212 | else | |||
213 | return debug_make_indirect_type (dhandle, slot, (const char *) NULL((void*)0)); | |||
214 | } | |||
215 | ||||
216 | /* If the aux entry has already been used for something, useaux will | |||
217 | have been set to false, indicating that parse_coff_base_type | |||
218 | should not use it. We need to do it this way, rather than simply | |||
219 | passing pauxent as NULL, because we need to be able handle | |||
220 | multiple array dimensions while still discarding pauxent after | |||
221 | having handled all of them. */ | |||
222 | if (! useaux) | |||
223 | pauxent = NULL((void*)0); | |||
224 | ||||
225 | return parse_coff_base_type (abfd, symbols, types, coff_symno, ntype, | |||
226 | pauxent, dhandle); | |||
227 | } | |||
228 | ||||
229 | /* Parse a basic COFF type in NTYPE. */ | |||
230 | ||||
231 | static debug_type | |||
232 | parse_coff_base_type (bfd *abfd, struct coff_symbols *symbols, | |||
233 | struct coff_types *types, long coff_symno, int ntype, | |||
234 | union internal_auxent *pauxent, void *dhandle) | |||
235 | { | |||
236 | debug_type ret; | |||
237 | bfd_boolean set_basic; | |||
238 | const char *name; | |||
239 | debug_type *slot; | |||
240 | ||||
241 | if (ntype >= 0 | |||
242 | && ntype <= T_MAX(16) | |||
243 | && types->basic[ntype] != DEBUG_TYPE_NULL((debug_type) ((void*)0))) | |||
244 | return types->basic[ntype]; | |||
245 | ||||
246 | set_basic = TRUE1; | |||
247 | name = NULL((void*)0); | |||
248 | ||||
249 | switch (ntype) | |||
250 | { | |||
251 | default: | |||
252 | ret = debug_make_void_type (dhandle); | |||
253 | break; | |||
254 | ||||
255 | case T_NULL0: | |||
256 | case T_VOID1: | |||
257 | ret = debug_make_void_type (dhandle); | |||
258 | name = "void"; | |||
259 | break; | |||
260 | ||||
261 | case T_CHAR2: | |||
262 | ret = debug_make_int_type (dhandle, 1, FALSE0); | |||
263 | name = "char"; | |||
264 | break; | |||
265 | ||||
266 | case T_SHORT3: | |||
267 | ret = debug_make_int_type (dhandle, 2, FALSE0); | |||
268 | name = "short"; | |||
269 | break; | |||
270 | ||||
271 | case T_INT4: | |||
272 | /* FIXME: Perhaps the size should depend upon the architecture. */ | |||
273 | ret = debug_make_int_type (dhandle, 4, FALSE0); | |||
274 | name = "int"; | |||
275 | break; | |||
276 | ||||
277 | case T_LONG5: | |||
278 | ret = debug_make_int_type (dhandle, 4, FALSE0); | |||
279 | name = "long"; | |||
280 | break; | |||
281 | ||||
282 | case T_FLOAT6: | |||
283 | ret = debug_make_float_type (dhandle, 4); | |||
284 | name = "float"; | |||
285 | break; | |||
286 | ||||
287 | case T_DOUBLE7: | |||
288 | ret = debug_make_float_type (dhandle, 8); | |||
289 | name = "double"; | |||
290 | break; | |||
291 | ||||
292 | case T_LNGDBL16: | |||
293 | ret = debug_make_float_type (dhandle, 12); | |||
294 | name = "long double"; | |||
295 | break; | |||
296 | ||||
297 | case T_UCHAR12: | |||
298 | ret = debug_make_int_type (dhandle, 1, TRUE1); | |||
299 | name = "unsigned char"; | |||
300 | break; | |||
301 | ||||
302 | case T_USHORT13: | |||
303 | ret = debug_make_int_type (dhandle, 2, TRUE1); | |||
304 | name = "unsigned short"; | |||
305 | break; | |||
306 | ||||
307 | case T_UINT14: | |||
308 | ret = debug_make_int_type (dhandle, 4, TRUE1); | |||
309 | name = "unsigned int"; | |||
310 | break; | |||
311 | ||||
312 | case T_ULONG15: | |||
313 | ret = debug_make_int_type (dhandle, 4, TRUE1); | |||
314 | name = "unsigned long"; | |||
315 | break; | |||
316 | ||||
317 | case T_STRUCT8: | |||
318 | if (pauxent == NULL((void*)0)) | |||
319 | ret = debug_make_struct_type (dhandle, TRUE1, 0, | |||
320 | (debug_field *) NULL((void*)0)); | |||
321 | else | |||
322 | ret = parse_coff_struct_type (abfd, symbols, types, ntype, pauxent, | |||
323 | dhandle); | |||
324 | ||||
325 | slot = coff_get_slot (types, coff_symno); | |||
326 | *slot = ret; | |||
327 | ||||
328 | set_basic = FALSE0; | |||
329 | break; | |||
330 | ||||
331 | case T_UNION9: | |||
332 | if (pauxent == NULL((void*)0)) | |||
333 | ret = debug_make_struct_type (dhandle, FALSE0, 0, (debug_field *) NULL((void*)0)); | |||
334 | else | |||
335 | ret = parse_coff_struct_type (abfd, symbols, types, ntype, pauxent, | |||
336 | dhandle); | |||
337 | ||||
338 | slot = coff_get_slot (types, coff_symno); | |||
339 | *slot = ret; | |||
340 | ||||
341 | set_basic = FALSE0; | |||
342 | break; | |||
343 | ||||
344 | case T_ENUM10: | |||
345 | if (pauxent == NULL((void*)0)) | |||
346 | ret = debug_make_enum_type (dhandle, (const char **) NULL((void*)0), | |||
347 | (bfd_signed_vma *) NULL((void*)0)); | |||
348 | else | |||
349 | ret = parse_coff_enum_type (abfd, symbols, types, pauxent, dhandle); | |||
350 | ||||
351 | slot = coff_get_slot (types, coff_symno); | |||
352 | *slot = ret; | |||
353 | ||||
354 | set_basic = FALSE0; | |||
355 | break; | |||
356 | } | |||
357 | ||||
358 | if (name != NULL((void*)0)) | |||
359 | ret = debug_name_type (dhandle, name, ret); | |||
360 | ||||
361 | if (set_basic | |||
362 | && ntype >= 0 | |||
363 | && ntype <= T_MAX(16)) | |||
364 | types->basic[ntype] = ret; | |||
365 | ||||
366 | return ret; | |||
367 | } | |||
368 | ||||
369 | /* Parse a struct type. */ | |||
370 | ||||
371 | static debug_type | |||
372 | parse_coff_struct_type (bfd *abfd, struct coff_symbols *symbols, | |||
373 | struct coff_types *types, int ntype, | |||
374 | union internal_auxent *pauxent, void *dhandle) | |||
375 | { | |||
376 | long symend; | |||
377 | int alloc; | |||
378 | debug_field *fields; | |||
379 | int count; | |||
380 | bfd_boolean done; | |||
381 | ||||
382 | symend = pauxent->x_sym.x_fcnary.x_fcn.x_endndx.l; | |||
383 | ||||
384 | alloc = 10; | |||
385 | fields = (debug_field *) xmalloc (alloc * sizeof *fields); | |||
386 | count = 0; | |||
387 | ||||
388 | done = FALSE0; | |||
389 | while (! done |
0.1 | 'done' is 0 |
1 | Assuming 'symend' is > field 'coff_symno' |
9 | Assigned value is garbage or undefined |