1 /* stabs.c -- Parse COFF debugging information
2 Copyright (C) 1996-2023 Free Software Foundation, Inc.
3 Written by Ian Lance Taylor <ian@cygnus.com>.
5 This file is part of GNU Binutils.
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 3 of the License, or
10 (at your option) any later version.
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.
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
22 /* This file contains code which parses COFF debugging information. */
26 #include "coff/internal.h"
27 #include "libiberty.h"
32 /* FIXME: We should not need this BFD internal file. We need it for
33 the N_BTMASK, etc., values. */
36 /* These macros extract the right mask and shifts for this BFD. They
37 assume that there is a local variable named ABFD. This is so that
38 macros like ISFCN and DECREF, from coff/internal.h, will work
39 without modification. */
40 #define N_BTMASK (coff_data (abfd)->local_n_btmask)
41 #define N_BTSHFT (coff_data (abfd)->local_n_btshft)
42 #define N_TMASK (coff_data (abfd)->local_n_tmask)
43 #define N_TSHIFT (coff_data (abfd)->local_n_tshift)
45 /* This structure is used to hold the symbols, as well as the current
46 location within the symbols. */
52 /* The number of symbols. */
54 /* The index of the current symbol. */
56 /* The index of the current symbol in the COFF symbol table (where
57 each auxent counts as a symbol). */
61 /* This structure is used to map symbol indices to types. */
65 /* Next set of slots. */
66 struct coff_types
*next
;
67 /* Where the TYPES array starts. */
68 unsigned int base_index
;
70 #define COFF_SLOTS (16)
71 debug_type types
[COFF_SLOTS
];
74 static debug_type parse_coff_base_type
75 (bfd
*, struct coff_symbols
*, struct coff_types
**, long, int,
76 union internal_auxent
*, void *);
77 static debug_type parse_coff_struct_type
78 (bfd
*, struct coff_symbols
*, struct coff_types
**, int,
79 union internal_auxent
*, void *);
80 static debug_type parse_coff_enum_type
81 (bfd
*, struct coff_symbols
*, struct coff_types
**,
82 union internal_auxent
*, void *);
84 /* Return the slot for a type. */
87 coff_get_slot (void *dhandle
, struct coff_types
**types
, long indx
)
89 unsigned int base_index
;
91 base_index
= indx
/ COFF_SLOTS
* COFF_SLOTS
;
94 while (*types
&& (*types
)->base_index
< base_index
)
95 types
= &(*types
)->next
;
97 if (*types
== NULL
|| (*types
)->base_index
!= base_index
)
99 struct coff_types
*n
= debug_xzalloc (dhandle
, sizeof (*n
));
101 n
->base_index
= base_index
;
105 return (*types
)->types
+ indx
;
108 /* Parse a COFF type code in NTYPE. */
111 parse_coff_type (bfd
*abfd
, struct coff_symbols
*symbols
,
112 struct coff_types
**types
, long coff_symno
, int ntype
,
113 union internal_auxent
*pauxent
, bool useaux
,
118 if ((ntype
& ~N_BTMASK
) != 0)
122 newtype
= DECREF (ntype
);
126 type
= parse_coff_type (abfd
, symbols
, types
, coff_symno
, newtype
,
127 pauxent
, useaux
, dhandle
);
128 type
= debug_make_pointer_type (dhandle
, type
);
130 else if (ISFCN (ntype
))
132 type
= parse_coff_type (abfd
, symbols
, types
, coff_symno
, newtype
,
133 pauxent
, useaux
, dhandle
);
134 type
= debug_make_function_type (dhandle
, type
, (debug_type
*) NULL
,
137 else if (ISARY (ntype
))
148 /* FIXME: If pauxent->x_sym.x_tagndx.l == 0, gdb sets
149 the c_naux field of the syment to 0. */
151 /* Move the dimensions down, so that the next array
152 picks up the next one. */
153 dim
= pauxent
->x_sym
.x_fcnary
.x_ary
.x_dimen
;
155 for (i
= 0; *dim
!= 0 && i
< DIMNUM
- 1; i
++, dim
++)
160 type
= parse_coff_type (abfd
, symbols
, types
, coff_symno
, newtype
,
161 pauxent
, false, dhandle
);
162 type
= debug_make_array_type (dhandle
, type
,
163 parse_coff_base_type (abfd
, symbols
,
172 non_fatal (_("parse_coff_type: Bad type code 0x%x"), ntype
);
173 return DEBUG_TYPE_NULL
;
179 if (pauxent
!= NULL
&& (int32_t) pauxent
->x_sym
.x_tagndx
.u32
> 0)
183 /* This is a reference to an existing type. FIXME: gdb checks
184 that the class is not C_STRTAG, nor C_UNTAG, nor C_ENTAG. */
185 slot
= coff_get_slot (dhandle
, types
, pauxent
->x_sym
.x_tagndx
.u32
);
186 if (*slot
!= DEBUG_TYPE_NULL
)
189 return debug_make_indirect_type (dhandle
, slot
, (const char *) NULL
);
192 /* If the aux entry has already been used for something, useaux will
193 have been set to false, indicating that parse_coff_base_type
194 should not use it. We need to do it this way, rather than simply
195 passing pauxent as NULL, because we need to be able handle
196 multiple array dimensions while still discarding pauxent after
197 having handled all of them. */
201 return parse_coff_base_type (abfd
, symbols
, types
, coff_symno
, ntype
,
205 /* Parse a basic COFF type in NTYPE. */
208 parse_coff_base_type (bfd
*abfd
, struct coff_symbols
*symbols
,
209 struct coff_types
**types
, long coff_symno
, int ntype
,
210 union internal_auxent
*pauxent
, void *dhandle
)
213 const char *name
= NULL
;
218 ret
= debug_make_void_type (dhandle
);
223 ret
= debug_make_void_type (dhandle
);
228 ret
= debug_make_int_type (dhandle
, 1, false);
233 ret
= debug_make_int_type (dhandle
, 2, false);
238 /* FIXME: Perhaps the size should depend upon the architecture. */
239 ret
= debug_make_int_type (dhandle
, 4, false);
244 ret
= debug_make_int_type (dhandle
, 4, false);
249 ret
= debug_make_float_type (dhandle
, 4);
254 ret
= debug_make_float_type (dhandle
, 8);
259 ret
= debug_make_float_type (dhandle
, 12);
260 name
= "long double";
264 ret
= debug_make_int_type (dhandle
, 1, true);
265 name
= "unsigned char";
269 ret
= debug_make_int_type (dhandle
, 2, true);
270 name
= "unsigned short";
274 ret
= debug_make_int_type (dhandle
, 4, true);
275 name
= "unsigned int";
279 ret
= debug_make_int_type (dhandle
, 4, true);
280 name
= "unsigned long";
285 ret
= debug_make_struct_type (dhandle
, true, 0,
286 (debug_field
*) NULL
);
288 ret
= parse_coff_struct_type (abfd
, symbols
, types
, ntype
, pauxent
,
294 ret
= debug_make_struct_type (dhandle
, false, 0, (debug_field
*) NULL
);
296 ret
= parse_coff_struct_type (abfd
, symbols
, types
, ntype
, pauxent
,
302 ret
= debug_make_enum_type (dhandle
, (const char **) NULL
,
303 (bfd_signed_vma
*) NULL
);
305 ret
= parse_coff_enum_type (abfd
, symbols
, types
, pauxent
, dhandle
);
310 ret
= debug_name_type (dhandle
, name
, ret
);
312 debug_type
*slot
= coff_get_slot (dhandle
, types
, coff_symno
);
318 /* Parse a struct type. */
321 parse_coff_struct_type (bfd
*abfd
, struct coff_symbols
*symbols
,
322 struct coff_types
**types
, int ntype
,
323 union internal_auxent
*pauxent
, void *dhandle
)
327 debug_field
*fields
, *xfields
;
331 symend
= pauxent
->x_sym
.x_fcnary
.x_fcn
.x_endndx
.u32
;
334 fields
= (debug_field
*) xmalloc (alloc
* sizeof *fields
);
339 && symbols
->coff_symno
< symend
340 && symbols
->symno
< symbols
->symcount
)
343 long this_coff_symno
;
344 struct internal_syment syment
;
345 union internal_auxent auxent
;
346 union internal_auxent
*psubaux
;
347 bfd_vma bitpos
= 0, bitsize
= 0;
349 sym
= symbols
->syms
[symbols
->symno
];
351 if (! bfd_coff_get_syment (abfd
, sym
, &syment
))
353 non_fatal (_("bfd_coff_get_syment failed: %s"),
354 bfd_errmsg (bfd_get_error ()));
356 return DEBUG_TYPE_NULL
;
359 this_coff_symno
= symbols
->coff_symno
;
362 symbols
->coff_symno
+= 1 + syment
.n_numaux
;
364 if (syment
.n_numaux
== 0)
368 if (! bfd_coff_get_auxent (abfd
, sym
, 0, &auxent
))
370 non_fatal (_("bfd_coff_get_auxent failed: %s"),
371 bfd_errmsg (bfd_get_error ()));
373 return DEBUG_TYPE_NULL
;
378 switch (syment
.n_sclass
)
382 bitpos
= 8 * bfd_asymbol_value (sym
);
387 bitpos
= bfd_asymbol_value (sym
);
388 bitsize
= auxent
.x_sym
.x_misc
.x_lnsz
.x_size
;
401 ftype
= parse_coff_type (abfd
, symbols
, types
, this_coff_symno
,
402 syment
.n_type
, psubaux
, true, dhandle
);
403 f
= debug_make_field (dhandle
, bfd_asymbol_name (sym
), ftype
,
404 bitpos
, bitsize
, DEBUG_VISIBILITY_PUBLIC
);
405 if (f
== DEBUG_FIELD_NULL
)
408 return DEBUG_TYPE_NULL
;
411 if (count
+ 1 >= alloc
)
414 fields
= ((debug_field
*)
415 xrealloc (fields
, alloc
* sizeof *fields
));
423 fields
[count
] = DEBUG_FIELD_NULL
;
424 xfields
= debug_xalloc (dhandle
, (count
+ 1) * sizeof (*fields
));
425 memcpy (xfields
, fields
, (count
+ 1) * sizeof (*fields
));
428 return debug_make_struct_type (dhandle
, ntype
== T_STRUCT
,
429 pauxent
->x_sym
.x_misc
.x_lnsz
.x_size
,
433 /* Parse an enum type. */
436 parse_coff_enum_type (bfd
*abfd
, struct coff_symbols
*symbols
,
437 struct coff_types
**types ATTRIBUTE_UNUSED
,
438 union internal_auxent
*pauxent
, void *dhandle
)
442 const char **names
, **xnames
;
443 bfd_signed_vma
*vals
, *xvals
;
447 symend
= pauxent
->x_sym
.x_fcnary
.x_fcn
.x_endndx
.u32
;
450 names
= (const char **) xmalloc (alloc
* sizeof *names
);
451 vals
= (bfd_signed_vma
*) xmalloc (alloc
* sizeof *vals
);
456 && symbols
->coff_symno
< symend
457 && symbols
->symno
< symbols
->symcount
)
460 struct internal_syment syment
;
462 sym
= symbols
->syms
[symbols
->symno
];
464 if (! bfd_coff_get_syment (abfd
, sym
, &syment
))
466 non_fatal (_("bfd_coff_get_syment failed: %s"),
467 bfd_errmsg (bfd_get_error ()));
470 return DEBUG_TYPE_NULL
;
474 symbols
->coff_symno
+= 1 + syment
.n_numaux
;
476 switch (syment
.n_sclass
)
479 if (count
+ 1 >= alloc
)
482 names
= ((const char **)
483 xrealloc (names
, alloc
* sizeof *names
));
484 vals
= ((bfd_signed_vma
*)
485 xrealloc (vals
, alloc
* sizeof *vals
));
488 names
[count
] = bfd_asymbol_name (sym
);
489 vals
[count
] = bfd_asymbol_value (sym
);
501 xnames
= debug_xalloc (dhandle
, (count
+ 1) * sizeof (*names
));
502 memcpy (xnames
, names
, (count
+ 1) * sizeof (*names
));
504 xvals
= debug_xalloc (dhandle
, (count
+ 1) * sizeof (*vals
));
505 memcpy (xvals
, vals
, (count
+ 1) * sizeof (*vals
));
508 return debug_make_enum_type (dhandle
, xnames
, xvals
);
511 /* Handle a single COFF symbol. */
514 parse_coff_symbol (bfd
*abfd ATTRIBUTE_UNUSED
, struct coff_types
**types
,
515 asymbol
*sym
, long coff_symno
,
516 struct internal_syment
*psyment
, void *dhandle
,
517 debug_type type
, bool within_function
)
519 switch (psyment
->n_sclass
)
525 if (! debug_record_variable (dhandle
, bfd_asymbol_name (sym
), type
,
526 DEBUG_LOCAL
, bfd_asymbol_value (sym
)))
532 if (! debug_record_variable (dhandle
, bfd_asymbol_name (sym
), type
,
533 DEBUG_GLOBAL
, bfd_asymbol_value (sym
)))
538 if (! debug_record_variable (dhandle
, bfd_asymbol_name (sym
), type
,
542 bfd_asymbol_value (sym
)))
547 /* FIXME: We may need to convert the register number. */
548 if (! debug_record_variable (dhandle
, bfd_asymbol_name (sym
), type
,
549 DEBUG_REGISTER
, bfd_asymbol_value (sym
)))
557 if (! debug_record_parameter (dhandle
, bfd_asymbol_name (sym
), type
,
558 DEBUG_PARM_STACK
, bfd_asymbol_value (sym
)))
563 /* FIXME: We may need to convert the register number. */
564 if (! debug_record_parameter (dhandle
, bfd_asymbol_name (sym
), type
,
565 DEBUG_PARM_REG
, bfd_asymbol_value (sym
)))
570 type
= debug_name_type (dhandle
, bfd_asymbol_name (sym
), type
);
571 if (type
== DEBUG_TYPE_NULL
)
581 type
= debug_tag_type (dhandle
, bfd_asymbol_name (sym
), type
);
582 if (type
== DEBUG_TYPE_NULL
)
585 /* Store the named type into the slot, so that references get
587 slot
= coff_get_slot (dhandle
, types
, coff_symno
);
599 /* Determine if a symbol has external visibility. */
602 external_coff_symbol_p (int sym_class
)
615 /* This is the main routine. It looks through all the symbols and
619 parse_coff (bfd
*abfd
, asymbol
**syms
, long symcount
, void *dhandle
)
621 struct coff_symbols symbols
;
622 struct coff_types
*types
;
629 bool within_function
;
630 long this_coff_symno
;
633 symbols
.symcount
= symcount
;
635 symbols
.coff_symno
= 0;
645 within_function
= false;
647 while (symbols
.symno
< symcount
)
651 struct internal_syment syment
;
652 union internal_auxent auxent
;
653 union internal_auxent
*paux
;
656 sym
= syms
[symbols
.symno
];
658 if (! bfd_coff_get_syment (abfd
, sym
, &syment
))
660 non_fatal (_("bfd_coff_get_syment failed: %s"),
661 bfd_errmsg (bfd_get_error ()));
665 name
= bfd_asymbol_name (sym
);
667 this_coff_symno
= symbols
.coff_symno
;
670 symbols
.coff_symno
+= 1 + syment
.n_numaux
;
672 /* We only worry about the first auxent, because that is the
673 only one which is relevant for debugging information. */
674 if (syment
.n_numaux
== 0)
678 if (! bfd_coff_get_auxent (abfd
, sym
, 0, &auxent
))
680 non_fatal (_("bfd_coff_get_auxent failed: %s"),
681 bfd_errmsg (bfd_get_error ()));
687 if (this_coff_symno
== next_c_file
&& syment
.n_sclass
!= C_FILE
)
689 /* The last C_FILE symbol points to the first external
691 if (! debug_set_filename (dhandle
, "*globals*"))
695 switch (syment
.n_sclass
)
704 /* Just ignore these classes. */
708 next_c_file
= syment
.n_value
;
709 if (! debug_set_filename (dhandle
, name
))
714 /* Ignore static symbols with a type of T_NULL. These
715 represent section entries. */
716 if (syment
.n_type
== T_NULL
)
721 if (ISFCN (syment
.n_type
))
724 fnclass
= syment
.n_sclass
;
725 fntype
= syment
.n_type
;
726 if (syment
.n_numaux
> 0)
727 fnend
= bfd_asymbol_value (sym
) + auxent
.x_sym
.x_misc
.x_fsize
;
730 linenos
= BFD_SEND (abfd
, _get_lineno
, (abfd
, sym
));
733 type
= parse_coff_type (abfd
, &symbols
, &types
, this_coff_symno
,
734 syment
.n_type
, paux
, true, dhandle
);
735 if (type
== DEBUG_TYPE_NULL
)
737 if (! parse_coff_symbol (abfd
, &types
, sym
, this_coff_symno
, &syment
,
738 dhandle
, type
, within_function
))
743 if (strcmp (name
, ".bf") == 0)
747 non_fatal (_("%ld: .bf without preceding function"),
752 type
= parse_coff_type (abfd
, &symbols
, &types
, this_coff_symno
,
753 DECREF (fntype
), paux
, false, dhandle
);
754 if (type
== DEBUG_TYPE_NULL
)
757 if (! debug_record_function (dhandle
, fnname
, type
,
758 external_coff_symbol_p (fnclass
),
759 bfd_asymbol_value (sym
)))
767 if (syment
.n_numaux
== 0)
770 base
= auxent
.x_sym
.x_misc
.x_lnsz
.x_lnno
- 1;
772 addr
= bfd_section_vma (bfd_asymbol_section (sym
));
776 while (linenos
->line_number
!= 0)
778 if (! debug_record_line (dhandle
,
779 linenos
->line_number
+ base
,
780 linenos
->u
.offset
+ addr
))
791 within_function
= true;
793 else if (strcmp (name
, ".ef") == 0)
795 if (! within_function
)
797 non_fatal (_("%ld: unexpected .ef\n"), this_coff_symno
);
801 if (bfd_asymbol_value (sym
) > fnend
)
802 fnend
= bfd_asymbol_value (sym
);
803 if (! debug_end_function (dhandle
, fnend
))
807 within_function
= false;
812 if (strcmp (name
, ".bb") == 0)
814 if (! debug_start_block (dhandle
, bfd_asymbol_value (sym
)))
817 else if (strcmp (name
, ".eb") == 0)
819 if (! debug_end_block (dhandle
, bfd_asymbol_value (sym
)))
825 type
= parse_coff_type (abfd
, &symbols
, &types
, this_coff_symno
,
826 syment
.n_type
, paux
, true, dhandle
);
827 if (type
== DEBUG_TYPE_NULL
)
829 if (! parse_coff_symbol (abfd
, &types
, sym
, this_coff_symno
, &syment
,
830 dhandle
, type
, within_function
))