readelf/objdump: Handle DWARF info with mixed types of range section.
[binutils-gdb.git] / gas / stabs.c
blobf650a48ae88f2a3f184f79aa6e5c4d59c00da21e
1 /* Generic stabs parsing for gas.
2 Copyright (C) 1989-2023 Free Software Foundation, Inc.
4 This file is part of GAS, the GNU Assembler.
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as
8 published by the Free Software Foundation; either version 3,
9 or (at your option) any later version.
11 GAS is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
14 the GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING. If not, write to the Free
18 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
19 02110-1301, USA. */
21 #include "as.h"
22 #include "filenames.h"
23 #include "obstack.h"
24 #include "subsegs.h"
25 #include "ecoff.h"
27 /* We need this, despite the apparent object format dependency, since
28 it defines stab types, which all object formats can use now. */
30 #include "aout/stab_gnu.h"
32 /* Holds whether the assembler is generating stabs line debugging
33 information or not. Potentially used by md_cleanup function. */
35 int outputting_stabs_line_debug = 0;
37 static void generate_asm_file (int, const char *);
39 /* Allow backends to override the names used for the stab sections. */
40 #ifndef STAB_SECTION_NAME
41 #define STAB_SECTION_NAME ".stab"
42 #endif
44 #ifndef STAB_STRING_SECTION_NAME
45 #define STAB_STRING_SECTION_NAME ".stabstr"
46 #endif
48 /* Label at start of current function if we're in the middle of a
49 .func function, in which case stabs_generate_asm_lineno emits
50 function relative line number stabs. Otherwise it emits line
51 number stabs with absolute addresses. Note that both cases only
52 apply to assembler code assembled with -gstabs. */
53 static const char *current_function_label;
55 /* Current stab section when SEPARATE_STAB_SECTIONS. */
56 static segT cached_sec;
58 /* State used by generate_asm_file. */
59 static char *last_asm_file;
60 static int file_label_count;
62 /* State used by stabs_generate_asm_lineno. */
63 static int line_label_count;
64 static unsigned int prev_lineno;
65 static char *prev_line_file;
67 /* State used by stabs_generate_asm_func. */
68 static bool void_emitted_p;
70 /* State used by stabs_generate_asm_endfunc. */
71 static int endfunc_label_count;
74 * Handle .stabX directives, which used to be open-coded.
75 * So much creeping featurism overloaded the semantics that we decided
76 * to put all .stabX thinking in one place. Here.
78 * We try to make any .stabX directive legal. Other people's AS will often
79 * do assembly-time consistency checks: eg assigning meaning to n_type bits
80 * and "protecting" you from setting them to certain values. (They also zero
81 * certain bits before emitting symbols. Tut tut.)
83 * If an expression is not absolute we either gripe or use the relocation
84 * information. Other people's assemblers silently forget information they
85 * don't need and invent information they need that you didn't supply.
89 * Build a string dictionary entry for a .stabX symbol.
90 * The symbol is added to the .<secname>str section.
93 #ifndef SEPARATE_STAB_SECTIONS
94 #define SEPARATE_STAB_SECTIONS 0
95 #endif
97 unsigned int
98 get_stab_string_offset (const char *string, const char *stabstr_secname,
99 bool free_stabstr_secname)
101 unsigned int length;
102 unsigned int retval;
103 segT save_seg;
104 subsegT save_subseg;
105 segT seg;
106 char *p;
108 if (! SEPARATE_STAB_SECTIONS)
109 abort ();
111 length = strlen (string);
113 save_seg = now_seg;
114 save_subseg = now_subseg;
116 /* Create the stab string section, if it doesn't already exist. */
117 seg = subseg_new (stabstr_secname, 0);
118 if (free_stabstr_secname && seg->name != stabstr_secname)
119 free ((char *) stabstr_secname);
121 retval = seg_info (seg)->stabu.stab_string_size;
122 if (retval <= 0)
124 /* Make sure the first string is empty. */
125 p = frag_more (1);
126 *p = 0;
127 retval = seg_info (seg)->stabu.stab_string_size = 1;
128 bfd_set_section_flags (seg, SEC_READONLY | SEC_DEBUGGING);
131 if (length > 0)
132 { /* Ordinary case. */
133 p = frag_more (length + 1);
134 strcpy (p, string);
136 seg_info (seg)->stabu.stab_string_size += length + 1;
138 else
139 retval = 0;
141 subseg_set (save_seg, save_subseg);
143 return retval;
146 #ifdef AOUT_STABS
147 #ifndef OBJ_PROCESS_STAB
148 #define OBJ_PROCESS_STAB(SEG,W,S,T,O,D) aout_process_stab(W,S,T,O,D)
149 #endif
151 /* Here instead of obj-aout.c because other formats use it too. */
152 void
153 aout_process_stab (int what, const char *string, int type, int other, int desc)
155 /* Put the stab information in the symbol table. */
156 symbolS *symbol;
158 /* Create the symbol now, but only insert it into the symbol chain
159 after any symbols mentioned in the value expression get into the
160 symbol chain. This is to avoid "continuation symbols" (where one
161 ends in "\" and the debug info is continued in the next .stabs
162 directive) from being separated by other random symbols. */
163 symbol = symbol_create (string, undefined_section, &zero_address_frag, 0);
164 if (what == 's' || what == 'n')
166 /* Pick up the value from the input line. */
167 pseudo_set (symbol);
169 else
171 /* .stabd sets the name to NULL. Why? */
172 S_SET_NAME (symbol, NULL);
173 symbol_set_frag (symbol, frag_now);
174 S_SET_VALUE (symbol, (valueT) frag_now_fix ());
177 symbol_append (symbol, symbol_lastP, &symbol_rootP, &symbol_lastP);
179 symbol_get_bfdsym (symbol)->flags |= BSF_DEBUGGING;
181 S_SET_TYPE (symbol, type);
182 S_SET_OTHER (symbol, other);
183 S_SET_DESC (symbol, desc);
185 #endif
187 /* This can handle different kinds of stabs (s,n,d) and different
188 kinds of stab sections. If STAB_SECNAME_OBSTACK_END is non-NULL,
189 then STAB_SECNAME and STABSTR_SECNAME will be freed if possible
190 before this function returns (the former by obstack_free). */
192 static void
193 s_stab_generic (int what,
194 const char *stab_secname,
195 const char *stabstr_secname,
196 const char *stab_secname_obstack_end)
198 long longint;
199 const char *string;
200 char *saved_string_obstack_end;
201 int type;
202 int other;
203 int desc;
205 /* The general format is:
206 .stabs "STRING",TYPE,OTHER,DESC,VALUE
207 .stabn TYPE,OTHER,DESC,VALUE
208 .stabd TYPE,OTHER,DESC
209 At this point input_line_pointer points after the pseudo-op and
210 any trailing whitespace. The argument what is one of 's', 'n' or
211 'd' indicating which type of .stab this is. */
213 if (what != 's')
215 string = "";
216 saved_string_obstack_end = 0;
218 else
220 int length;
222 string = demand_copy_C_string (&length);
223 if (string == NULL)
225 as_warn (_(".stab%c: missing string"), what);
226 ignore_rest_of_line ();
227 return;
229 /* FIXME: We should probably find some other temporary storage
230 for string, rather than leaking memory if someone else
231 happens to use the notes obstack. */
232 saved_string_obstack_end = obstack_next_free (&notes);
233 SKIP_WHITESPACE ();
234 if (*input_line_pointer == ',')
235 input_line_pointer++;
236 else
238 as_warn (_(".stab%c: missing comma"), what);
239 ignore_rest_of_line ();
240 return;
244 if (get_absolute_expression_and_terminator (&longint) != ',')
246 as_warn (_(".stab%c: missing comma"), what);
247 ignore_rest_of_line ();
248 return;
250 type = longint;
252 if (get_absolute_expression_and_terminator (&longint) != ',')
254 as_warn (_(".stab%c: missing comma"), what);
255 ignore_rest_of_line ();
256 return;
258 other = longint;
260 desc = get_absolute_expression ();
262 if ((desc > 0xffff) || (desc < -0x8000))
263 /* This could happen for example with a source file with a huge
264 number of lines. The only cure is to use a different debug
265 format, probably DWARF. */
266 as_warn (_(".stab%c: description field '%x' too big, try a different debug format"),
267 what, desc);
269 if (what == 's' || what == 'n')
271 if (*input_line_pointer != ',')
273 as_warn (_(".stab%c: missing comma"), what);
274 ignore_rest_of_line ();
275 return;
277 input_line_pointer++;
278 SKIP_WHITESPACE ();
281 #ifdef TC_PPC
282 #ifdef OBJ_ELF
283 /* Solaris on PowerPC has decided that .stabd can take 4 arguments, so if we were
284 given 4 arguments, make it a .stabn */
285 else if (what == 'd')
287 char *save_location = input_line_pointer;
289 SKIP_WHITESPACE ();
290 if (*input_line_pointer == ',')
292 input_line_pointer++;
293 what = 'n';
295 else
296 input_line_pointer = save_location;
298 #endif /* OBJ_ELF */
299 #endif /* TC_PPC */
301 #ifndef NO_LISTING
302 if (listing)
304 switch (type)
306 case N_SLINE:
307 listing_source_line ((unsigned int) desc);
308 break;
309 case N_SO:
310 case N_SOL:
311 listing_source_file (string);
312 break;
315 #endif /* ! NO_LISTING */
317 /* We have now gathered the type, other, and desc information. For
318 .stabs or .stabn, input_line_pointer is now pointing at the
319 value. */
321 if (SEPARATE_STAB_SECTIONS)
322 /* Output the stab information in a separate section. This is used
323 at least for COFF and ELF. */
325 segT saved_seg = now_seg;
326 subsegT saved_subseg = now_subseg;
327 fragS *saved_frag = frag_now;
328 valueT dot;
329 segT seg;
330 unsigned int stroff;
331 char *p;
333 dot = frag_now_fix ();
335 #ifdef md_flush_pending_output
336 md_flush_pending_output ();
337 #endif
339 if (cached_sec && strcmp (cached_sec->name, stab_secname) == 0)
341 seg = cached_sec;
342 subseg_set (seg, 0);
344 else
346 seg = subseg_new (stab_secname, 0);
347 cached_sec = seg;
350 if (! seg_info (seg)->hadone)
352 bfd_set_section_flags (seg,
353 SEC_READONLY | SEC_RELOC | SEC_DEBUGGING);
354 #ifdef INIT_STAB_SECTION
355 INIT_STAB_SECTION (seg);
356 #endif
357 seg_info (seg)->hadone = 1;
360 stroff = get_stab_string_offset (string, stabstr_secname,
361 stab_secname_obstack_end != NULL);
363 /* Release the string, if nobody else has used the obstack. */
364 if (saved_string_obstack_end != NULL
365 && saved_string_obstack_end == obstack_next_free (&notes))
366 obstack_free (&notes, string);
367 /* Similarly for the section name. This must be done before
368 creating symbols below, which uses the notes obstack. */
369 if (seg->name != stab_secname
370 && stab_secname_obstack_end != NULL
371 && stab_secname_obstack_end == obstack_next_free (&notes))
372 obstack_free (&notes, stab_secname);
374 /* At least for now, stabs in a special stab section are always
375 output as 12 byte blocks of information. */
376 p = frag_more (8);
377 md_number_to_chars (p, (valueT) stroff, 4);
378 md_number_to_chars (p + 4, (valueT) type, 1);
379 md_number_to_chars (p + 5, (valueT) other, 1);
380 md_number_to_chars (p + 6, (valueT) desc, 2);
382 if (what == 's' || what == 'n')
384 /* Pick up the value from the input line. */
385 cons (4);
386 input_line_pointer--;
388 else
390 symbolS *symbol;
391 expressionS exp;
393 /* Arrange for a value representing the current location. */
394 symbol = symbol_temp_new (saved_seg, saved_frag, dot);
396 exp.X_op = O_symbol;
397 exp.X_add_symbol = symbol;
398 exp.X_add_number = 0;
400 emit_expr (&exp, 4);
403 #ifdef OBJ_PROCESS_STAB
404 OBJ_PROCESS_STAB (seg, what, string, type, other, desc);
405 #endif
407 subseg_set (saved_seg, saved_subseg);
409 else
411 if (stab_secname_obstack_end != NULL)
413 free ((char *) stabstr_secname);
414 if (stab_secname_obstack_end == obstack_next_free (&notes))
415 obstack_free (&notes, stab_secname);
417 #ifdef OBJ_PROCESS_STAB
418 OBJ_PROCESS_STAB (0, what, string, type, other, desc);
419 #else
420 abort ();
421 #endif
424 demand_empty_rest_of_line ();
427 /* Regular stab directive. */
429 void
430 s_stab (int what)
432 s_stab_generic (what, STAB_SECTION_NAME, STAB_STRING_SECTION_NAME, NULL);
435 /* "Extended stabs", used in Solaris only now. */
437 void
438 s_xstab (int what)
440 int length;
441 char *stab_secname, *stabstr_secname, *stab_secname_obstack_end;
443 stab_secname = demand_copy_C_string (&length);
444 stab_secname_obstack_end = obstack_next_free (&notes);
445 SKIP_WHITESPACE ();
446 if (*input_line_pointer == ',')
447 input_line_pointer++;
448 else
450 as_bad (_("comma missing in .xstabs"));
451 ignore_rest_of_line ();
452 return;
455 /* To get the name of the stab string section, simply add "str" to
456 the stab section name. */
457 stabstr_secname = concat (stab_secname, "str", (char *) NULL);
458 s_stab_generic (what, stab_secname, stabstr_secname,
459 stab_secname_obstack_end);
462 #ifdef S_SET_DESC
464 /* Frob invented at RMS' request. Set the n_desc of a symbol. */
466 void
467 s_desc (int ignore ATTRIBUTE_UNUSED)
469 char *name;
470 char c;
471 char *p;
472 symbolS *symbolP;
473 int temp;
475 c = get_symbol_name (&name);
476 p = input_line_pointer;
477 *p = c;
478 SKIP_WHITESPACE_AFTER_NAME ();
479 if (*input_line_pointer != ',')
481 *p = 0;
482 as_bad (_("expected comma after \"%s\""), name);
483 *p = c;
484 ignore_rest_of_line ();
486 else
488 input_line_pointer++;
489 temp = get_absolute_expression ();
490 *p = 0;
491 symbolP = symbol_find_or_make (name);
492 *p = c;
493 S_SET_DESC (symbolP, temp);
495 demand_empty_rest_of_line ();
496 } /* s_desc() */
498 #endif /* defined (S_SET_DESC) */
500 /* Generate stabs debugging information to denote the main source file. */
502 void
503 stabs_generate_asm_file (void)
505 const char *file;
506 unsigned int lineno;
508 file = as_where (&lineno);
509 if (use_gnu_debug_info_extensions)
511 char *dir;
512 char *dir2;
514 dir = remap_debug_filename (getpwd ());
515 dir2 = concat (dir, "/", NULL);
516 generate_asm_file (N_SO, dir2);
517 free (dir2);
518 free (dir);
520 generate_asm_file (N_SO, file);
523 /* Generate stabs debugging information to denote the source file.
524 TYPE is one of N_SO, N_SOL. */
526 static void
527 generate_asm_file (int type, const char *file)
529 char sym[30];
530 char *buf;
531 const char *tmp = file;
532 const char *file_endp = file + strlen (file);
533 char *bufp;
535 if (last_asm_file != NULL
536 && filename_cmp (last_asm_file, file) == 0)
537 return;
539 /* Rather than try to do this in some efficient fashion, we just
540 generate a string and then parse it again. That lets us use the
541 existing stabs hook, which expect to see a string, rather than
542 inventing new ones. */
543 sprintf (sym, "%sF%d", FAKE_LABEL_NAME, file_label_count);
544 ++file_label_count;
546 /* Allocate enough space for the file name (possibly extended with
547 doubled up backslashes), the symbol name, and the other characters
548 that make up a stabs file directive. */
549 bufp = buf = XNEWVEC (char, 2 * strlen (file) + strlen (sym) + 12);
551 *bufp++ = '"';
553 while (tmp < file_endp)
555 const char *bslash = strchr (tmp, '\\');
556 size_t len = bslash != NULL ? bslash - tmp + 1 : file_endp - tmp;
558 /* Double all backslashes, since demand_copy_C_string (used by
559 s_stab to extract the part in quotes) will try to replace them as
560 escape sequences. backslash may appear in a filespec. */
561 memcpy (bufp, tmp, len);
563 tmp += len;
564 bufp += len;
566 if (bslash != NULL)
567 *bufp++ = '\\';
570 sprintf (bufp, "\",%d,0,0,%s\n", type, sym);
572 temp_ilp (buf);
573 s_stab ('s');
574 restore_ilp ();
576 colon (sym);
578 free (last_asm_file);
579 last_asm_file = xstrdup (file);
581 free (buf);
584 /* Generate stabs debugging information for the current line. This is
585 used to produce debugging information for an assembler file. */
587 void
588 stabs_generate_asm_lineno (void)
590 const char *file;
591 unsigned int lineno;
592 char *buf;
593 char sym[30];
595 /* Rather than try to do this in some efficient fashion, we just
596 generate a string and then parse it again. That lets us use the
597 existing stabs hook, which expect to see a string, rather than
598 inventing new ones. */
600 file = as_where (&lineno);
602 /* Don't emit sequences of stabs for the same line. */
603 if (prev_line_file != NULL
604 && filename_cmp (file, prev_line_file) == 0)
606 if (lineno == prev_lineno)
607 /* Same file/line as last time. */
608 return;
610 else
612 /* Remember file/line for next time. */
613 free (prev_line_file);
614 prev_line_file = xstrdup (file);
617 prev_lineno = lineno;
619 /* Let the world know that we are in the middle of generating a
620 piece of stabs line debugging information. */
621 outputting_stabs_line_debug = 1;
623 generate_asm_file (N_SOL, file);
625 sprintf (sym, "%sL%d", FAKE_LABEL_NAME, line_label_count);
626 ++line_label_count;
628 if (current_function_label)
630 buf = XNEWVEC (char, 100 + strlen (current_function_label));
631 sprintf (buf, "%d,0,%d,%s-%s\n", N_SLINE, lineno,
632 sym, current_function_label);
634 else
636 buf = XNEWVEC (char, 100);
637 sprintf (buf, "%d,0,%d,%s\n", N_SLINE, lineno, sym);
640 temp_ilp (buf);
641 s_stab ('n');
642 restore_ilp ();
644 colon (sym);
646 outputting_stabs_line_debug = 0;
647 free (buf);
650 /* Emit a function stab.
651 All assembler functions are assumed to have return type `void'. */
653 void
654 stabs_generate_asm_func (const char *funcname, const char *startlabname)
656 char *buf;
657 unsigned int lineno;
659 if (! void_emitted_p)
661 temp_ilp ((char *) "\"void:t1=1\",128,0,0,0");
662 s_stab ('s');
663 restore_ilp ();
664 void_emitted_p = true;
667 as_where (&lineno);
668 if (asprintf (&buf, "\"%s:F1\",%d,0,%d,%s",
669 funcname, N_FUN, lineno + 1, startlabname) == -1)
670 as_fatal ("%s", xstrerror (errno));
672 temp_ilp (buf);
673 s_stab ('s');
674 restore_ilp ();
675 free (buf);
677 free ((char *) current_function_label);
678 current_function_label = xstrdup (startlabname);
681 /* Emit a stab to record the end of a function. */
683 void
684 stabs_generate_asm_endfunc (const char *funcname ATTRIBUTE_UNUSED,
685 const char *startlabname)
687 char *buf;
688 char sym[30];
690 sprintf (sym, "%sendfunc%d", FAKE_LABEL_NAME, endfunc_label_count);
691 ++endfunc_label_count;
692 colon (sym);
694 if (asprintf (&buf, "\"\",%d,0,0,%s-%s", N_FUN, sym, startlabname) == -1)
695 as_fatal ("%s", xstrerror (errno));
697 temp_ilp (buf);
698 s_stab ('s');
699 restore_ilp ();
700 free (buf);
702 free ((char *) current_function_label);
703 current_function_label = NULL;
706 void
707 stabs_begin (void)
709 current_function_label = NULL;
710 cached_sec = NULL;
711 last_asm_file = NULL;
712 file_label_count = 0;
713 line_label_count = 0;
714 prev_lineno = -1u;
715 prev_line_file = NULL;
716 void_emitted_p = false;
717 endfunc_label_count = 0;
720 void
721 stabs_end (void)
723 free ((char *) current_function_label);
724 free (last_asm_file);
725 free (prev_line_file);