]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gas/stabs.c
Automatic date update in version.in
[thirdparty/binutils-gdb.git] / gas / stabs.c
CommitLineData
252b5132 1/* Generic stabs parsing for gas.
fd67aa11 2 Copyright (C) 1989-2024 Free Software Foundation, Inc.
252b5132 3
ec2655a6 4 This file is part of GAS, the GNU Assembler.
252b5132 5
ec2655a6
NC
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.
252b5132 10
ec2655a6
NC
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.
252b5132 15
ec2655a6
NC
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. */
252b5132
RH
20
21#include "as.h"
8b6efd89 22#include "filenames.h"
252b5132
RH
23#include "obstack.h"
24#include "subsegs.h"
25#include "ecoff.h"
26
27/* We need this, despite the apparent object format dependency, since
f0e652b4 28 it defines stab types, which all object formats can use now. */
252b5132
RH
29
30#include "aout/stab_gnu.h"
31
bccba5f0
NC
32/* Holds whether the assembler is generating stabs line debugging
33 information or not. Potentially used by md_cleanup function. */
34
92eb7b32 35int outputting_stabs_line_debug = 0;
bccba5f0 36
3b4dbbbf 37static void generate_asm_file (int, const char *);
252b5132
RH
38
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
43
44#ifndef STAB_STRING_SECTION_NAME
45#define STAB_STRING_SECTION_NAME ".stabstr"
46#endif
47
24b7e8b1
AM
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. */
252b5132
RH
53static const char *current_function_label;
54
24b7e8b1
AM
55/* State used by generate_asm_file. */
56static char *last_asm_file;
57static int file_label_count;
58
59/* State used by stabs_generate_asm_lineno. */
60static int line_label_count;
61static unsigned int prev_lineno;
62static char *prev_line_file;
63
64/* State used by stabs_generate_asm_func. */
65static bool void_emitted_p;
66
67/* State used by stabs_generate_asm_endfunc. */
68static int endfunc_label_count;
69
252b5132
RH
70/*
71 * Handle .stabX directives, which used to be open-coded.
72 * So much creeping featurism overloaded the semantics that we decided
73 * to put all .stabX thinking in one place. Here.
74 *
75 * We try to make any .stabX directive legal. Other people's AS will often
76 * do assembly-time consistency checks: eg assigning meaning to n_type bits
77 * and "protecting" you from setting them to certain values. (They also zero
78 * certain bits before emitting symbols. Tut tut.)
79 *
80 * If an expression is not absolute we either gripe or use the relocation
81 * information. Other people's assemblers silently forget information they
82 * don't need and invent information they need that you didn't supply.
83 */
84
85/*
86 * Build a string dictionary entry for a .stabX symbol.
87 * The symbol is added to the .<secname>str section.
88 */
89
90#ifndef SEPARATE_STAB_SECTIONS
91#define SEPARATE_STAB_SECTIONS 0
92#endif
93
94unsigned int
3bab069c 95get_stab_string_offset (const char *string, segT stabstr)
252b5132
RH
96{
97 unsigned int length;
98 unsigned int retval;
99 segT save_seg;
100 subsegT save_subseg;
252b5132
RH
101 char *p;
102
103 if (! SEPARATE_STAB_SECTIONS)
104 abort ();
105
106 length = strlen (string);
107
108 save_seg = now_seg;
109 save_subseg = now_subseg;
110
3bab069c 111 subseg_set (stabstr, 0);
252b5132 112
3bab069c 113 retval = seg_info (stabstr)->stabu.stab_string_size;
252b5132
RH
114 if (retval <= 0)
115 {
116 /* Make sure the first string is empty. */
117 p = frag_more (1);
118 *p = 0;
3bab069c
AM
119 retval = seg_info (stabstr)->stabu.stab_string_size = 1;
120 bfd_set_section_flags (stabstr, SEC_READONLY | SEC_DEBUGGING);
252b5132
RH
121 }
122
123 if (length > 0)
f0e652b4 124 { /* Ordinary case. */
252b5132
RH
125 p = frag_more (length + 1);
126 strcpy (p, string);
127
3bab069c 128 seg_info (stabstr)->stabu.stab_string_size += length + 1;
252b5132
RH
129 }
130 else
131 retval = 0;
132
133 subseg_set (save_seg, save_subseg);
134
135 return retval;
136}
137
138#ifdef AOUT_STABS
139#ifndef OBJ_PROCESS_STAB
53330039 140#define OBJ_PROCESS_STAB(W,S,T,O,D) aout_process_stab(W,S,T,O,D)
252b5132
RH
141#endif
142
0aa5d426
HPN
143/* Here instead of obj-aout.c because other formats use it too. */
144void
e046cf80 145aout_process_stab (int what, const char *string, int type, int other, int desc)
252b5132
RH
146{
147 /* Put the stab information in the symbol table. */
148 symbolS *symbol;
149
150 /* Create the symbol now, but only insert it into the symbol chain
151 after any symbols mentioned in the value expression get into the
152 symbol chain. This is to avoid "continuation symbols" (where one
153 ends in "\" and the debug info is continued in the next .stabs
154 directive) from being separated by other random symbols. */
e01e1cee 155 symbol = symbol_create (string, undefined_section, &zero_address_frag, 0);
252b5132
RH
156 if (what == 's' || what == 'n')
157 {
158 /* Pick up the value from the input line. */
252b5132
RH
159 pseudo_set (symbol);
160 }
161 else
162 {
163 /* .stabd sets the name to NULL. Why? */
164 S_SET_NAME (symbol, NULL);
49309057 165 symbol_set_frag (symbol, frag_now);
252b5132
RH
166 S_SET_VALUE (symbol, (valueT) frag_now_fix ());
167 }
168
169 symbol_append (symbol, symbol_lastP, &symbol_rootP, &symbol_lastP);
170
df98fa7d
AM
171 symbol_get_bfdsym (symbol)->flags |= BSF_DEBUGGING;
172
252b5132
RH
173 S_SET_TYPE (symbol, type);
174 S_SET_OTHER (symbol, other);
175 S_SET_DESC (symbol, desc);
176}
177#endif
178
3bab069c
AM
179static bool
180eat_comma (int what)
181{
182 if (*input_line_pointer == ',')
183 {
184 input_line_pointer++;
185 return true;
186 }
187 as_warn (_(".stab%c: missing comma"), what);
188 ignore_rest_of_line ();
189 return false;
190}
191
252b5132 192/* This can handle different kinds of stabs (s,n,d) and different
3bab069c
AM
193 kinds of stab sections. If FREENAMES is true, then STAB_SECNAME
194 and STABSTR_SECNAME are allocated in that order on the notes
195 obstack and will be freed if possible. */
252b5132 196
f0e652b4 197static void
0acc7632
AM
198s_stab_generic (int what,
199 const char *stab_secname,
200 const char *stabstr_secname,
3bab069c 201 bool freenames)
252b5132 202{
b37283a6
NC
203 const char *string;
204 char *saved_string_obstack_end;
252b5132
RH
205 int type;
206 int other;
207 int desc;
3bab069c
AM
208 segT stab, stabstr = NULL;
209 segT saved_seg = now_seg;
210 subsegT saved_subseg = now_subseg;
211 fragS *saved_frag = frag_now;
212 valueT dot = 0;
213
214 if (SEPARATE_STAB_SECTIONS)
215 /* Output the stab information in a separate section. This is used
216 at least for COFF and ELF. */
217 {
218 dot = frag_now_fix ();
219
220#ifdef md_flush_pending_output
221 md_flush_pending_output ();
222#endif
223 stab = subseg_new (stab_secname, 0);
224 stabstr = subseg_new (stabstr_secname, 0);
225
226 if (freenames
227 && stab->name != stab_secname
228 && stabstr->name != stabstr_secname)
229 obstack_free (&notes, stab_secname);
230
231 subseg_set (stab, 0);
232 if (!seg_info (stab)->hadone)
233 {
234 bfd_set_section_flags (stab,
235 SEC_READONLY | SEC_RELOC | SEC_DEBUGGING);
236#ifdef INIT_STAB_SECTION
237 INIT_STAB_SECTION (stab, stabstr);
238#endif
239 seg_info (stab)->hadone = 1;
240 }
241 }
242 else if (freenames)
243 obstack_free (&notes, stab_secname);
252b5132
RH
244
245 /* The general format is:
246 .stabs "STRING",TYPE,OTHER,DESC,VALUE
247 .stabn TYPE,OTHER,DESC,VALUE
248 .stabd TYPE,OTHER,DESC
249 At this point input_line_pointer points after the pseudo-op and
250 any trailing whitespace. The argument what is one of 's', 'n' or
251 'd' indicating which type of .stab this is. */
252
3bab069c 253 saved_string_obstack_end = NULL;
252b5132 254 if (what != 's')
3bab069c 255 string = "";
252b5132
RH
256 else
257 {
258 int length;
259
260 string = demand_copy_C_string (&length);
c77852c8
NC
261 if (string == NULL)
262 {
263 as_warn (_(".stab%c: missing string"), what);
264 ignore_rest_of_line ();
9e99d10c 265 goto out2;
c77852c8 266 }
d68d4570
DD
267 /* FIXME: We should probably find some other temporary storage
268 for string, rather than leaking memory if someone else
269 happens to use the notes obstack. */
0acc7632 270 saved_string_obstack_end = obstack_next_free (&notes);
252b5132 271 SKIP_WHITESPACE ();
3bab069c
AM
272 if (!eat_comma (what))
273 goto out;
252b5132
RH
274 }
275
3bab069c
AM
276 type = get_absolute_expression ();
277 if (!eat_comma (what))
278 goto out;
252b5132 279
3bab069c
AM
280 other = get_absolute_expression ();
281 if (!eat_comma (what))
282 goto out;
252b5132
RH
283
284 desc = get_absolute_expression ();
6360824b
NC
285
286 if ((desc > 0xffff) || (desc < -0x8000))
287 /* This could happen for example with a source file with a huge
288 number of lines. The only cure is to use a different debug
289 format, probably DWARF. */
7193a0e7 290 as_warn (_(".stab%c: description field '%x' too big, try a different debug format"),
6360824b 291 what, desc);
411863a4 292
252b5132
RH
293 if (what == 's' || what == 'n')
294 {
3bab069c
AM
295 if (!eat_comma (what))
296 goto out;
252b5132
RH
297 SKIP_WHITESPACE ();
298 }
299
300#ifdef TC_PPC
301#ifdef OBJ_ELF
302 /* Solaris on PowerPC has decided that .stabd can take 4 arguments, so if we were
303 given 4 arguments, make it a .stabn */
304 else if (what == 'd')
305 {
306 char *save_location = input_line_pointer;
307
308 SKIP_WHITESPACE ();
309 if (*input_line_pointer == ',')
310 {
311 input_line_pointer++;
312 what = 'n';
313 }
314 else
315 input_line_pointer = save_location;
316 }
317#endif /* OBJ_ELF */
318#endif /* TC_PPC */
319
320#ifndef NO_LISTING
321 if (listing)
322 {
323 switch (type)
324 {
325 case N_SLINE:
326 listing_source_line ((unsigned int) desc);
327 break;
328 case N_SO:
329 case N_SOL:
330 listing_source_file (string);
331 break;
332 }
333 }
334#endif /* ! NO_LISTING */
335
336 /* We have now gathered the type, other, and desc information. For
337 .stabs or .stabn, input_line_pointer is now pointing at the
338 value. */
339
340 if (SEPARATE_STAB_SECTIONS)
341 /* Output the stab information in a separate section. This is used
342 at least for COFF and ELF. */
343 {
252b5132
RH
344 unsigned int stroff;
345 char *p;
346
3bab069c 347 stroff = get_stab_string_offset (string, stabstr);
252b5132 348
3bab069c
AM
349 /* Release the string, if nobody else has used the obstack.
350 This must be done before creating symbols below, which uses
351 the notes obstack. */
352 if (saved_string_obstack_end == obstack_next_free (&notes))
9e99d10c
AM
353 {
354 obstack_free (&notes, string);
355 saved_string_obstack_end = NULL;
356 }
252b5132
RH
357
358 /* At least for now, stabs in a special stab section are always
359 output as 12 byte blocks of information. */
360 p = frag_more (8);
361 md_number_to_chars (p, (valueT) stroff, 4);
362 md_number_to_chars (p + 4, (valueT) type, 1);
363 md_number_to_chars (p + 5, (valueT) other, 1);
364 md_number_to_chars (p + 6, (valueT) desc, 2);
365
366 if (what == 's' || what == 'n')
367 {
368 /* Pick up the value from the input line. */
369 cons (4);
370 input_line_pointer--;
371 }
372 else
373 {
252b5132
RH
374 symbolS *symbol;
375 expressionS exp;
376
377 /* Arrange for a value representing the current location. */
e01e1cee 378 symbol = symbol_temp_new (saved_seg, saved_frag, dot);
252b5132
RH
379
380 exp.X_op = O_symbol;
381 exp.X_add_symbol = symbol;
382 exp.X_add_number = 0;
383
384 emit_expr (&exp, 4);
385 }
386
387#ifdef OBJ_PROCESS_STAB
53330039 388 OBJ_PROCESS_STAB (what, string, type, other, desc);
252b5132 389#endif
252b5132
RH
390 }
391 else
392 {
393#ifdef OBJ_PROCESS_STAB
53330039 394 OBJ_PROCESS_STAB (what, string, type, other, desc);
252b5132
RH
395#else
396 abort ();
397#endif
398 }
399
400 demand_empty_rest_of_line ();
3bab069c
AM
401 out:
402 if (saved_string_obstack_end == obstack_next_free (&notes))
403 obstack_free (&notes, string);
9e99d10c 404 out2:
3bab069c 405 subseg_set (saved_seg, saved_subseg);
252b5132
RH
406}
407
f0e652b4 408/* Regular stab directive. */
252b5132
RH
409
410void
24361518 411s_stab (int what)
252b5132 412{
3bab069c 413 s_stab_generic (what, STAB_SECTION_NAME, STAB_STRING_SECTION_NAME, false);
252b5132
RH
414}
415
f0e652b4 416/* "Extended stabs", used in Solaris only now. */
252b5132
RH
417
418void
24361518 419s_xstab (int what)
252b5132
RH
420{
421 int length;
3bab069c 422 char *stab_secname, *stabstr_secname;
252b5132 423
252b5132
RH
424 stab_secname = demand_copy_C_string (&length);
425 SKIP_WHITESPACE ();
426 if (*input_line_pointer == ',')
3bab069c
AM
427 {
428 input_line_pointer++;
429 /* To get the name of the stab string section, simply add
430 "str" to the stab section name. */
431 stabstr_secname = notes_concat (stab_secname, "str", (char *) NULL);
432 s_stab_generic (what, stab_secname, stabstr_secname, true);
433 }
252b5132
RH
434 else
435 {
436 as_bad (_("comma missing in .xstabs"));
437 ignore_rest_of_line ();
252b5132 438 }
252b5132
RH
439}
440
441#ifdef S_SET_DESC
442
443/* Frob invented at RMS' request. Set the n_desc of a symbol. */
444
f0e652b4 445void
e046cf80 446s_desc (int ignore ATTRIBUTE_UNUSED)
252b5132
RH
447{
448 char *name;
449 char c;
450 char *p;
451 symbolS *symbolP;
452 int temp;
453
d02603dc 454 c = get_symbol_name (&name);
252b5132
RH
455 p = input_line_pointer;
456 *p = c;
d02603dc 457 SKIP_WHITESPACE_AFTER_NAME ();
252b5132
RH
458 if (*input_line_pointer != ',')
459 {
460 *p = 0;
0e389e77 461 as_bad (_("expected comma after \"%s\""), name);
252b5132
RH
462 *p = c;
463 ignore_rest_of_line ();
464 }
465 else
466 {
467 input_line_pointer++;
468 temp = get_absolute_expression ();
469 *p = 0;
470 symbolP = symbol_find_or_make (name);
471 *p = c;
472 S_SET_DESC (symbolP, temp);
473 }
474 demand_empty_rest_of_line ();
475} /* s_desc() */
476
477#endif /* defined (S_SET_DESC) */
478
479/* Generate stabs debugging information to denote the main source file. */
480
481void
24361518 482stabs_generate_asm_file (void)
252b5132 483{
3b4dbbbf 484 const char *file;
252b5132
RH
485 unsigned int lineno;
486
3b4dbbbf 487 file = as_where (&lineno);
05da4302
NC
488 if (use_gnu_debug_info_extensions)
489 {
82cb2524 490 char *dir;
3d6b762c 491 char *dir2;
05da4302 492
3d6b762c 493 dir = remap_debug_filename (getpwd ());
e1fa0163 494 dir2 = concat (dir, "/", NULL);
05da4302 495 generate_asm_file (N_SO, dir2);
e1fa0163 496 free (dir2);
82cb2524 497 free (dir);
05da4302 498 }
252b5132
RH
499 generate_asm_file (N_SO, file);
500}
501
502/* Generate stabs debugging information to denote the source file.
503 TYPE is one of N_SO, N_SOL. */
504
505static void
3b4dbbbf 506generate_asm_file (int type, const char *file)
252b5132 507{
252b5132 508 char sym[30];
604d524f 509 char *buf;
3b4dbbbf
TS
510 const char *tmp = file;
511 const char *file_endp = file + strlen (file);
2f01ffbf 512 char *bufp;
43ad3147 513
24b7e8b1
AM
514 if (last_asm_file != NULL
515 && filename_cmp (last_asm_file, file) == 0)
604d524f 516 return;
43ad3147 517
252b5132
RH
518 /* Rather than try to do this in some efficient fashion, we just
519 generate a string and then parse it again. That lets us use the
520 existing stabs hook, which expect to see a string, rather than
521 inventing new ones. */
24b7e8b1
AM
522 sprintf (sym, "%sF%d", FAKE_LABEL_NAME, file_label_count);
523 ++file_label_count;
604d524f
NC
524
525 /* Allocate enough space for the file name (possibly extended with
526 doubled up backslashes), the symbol name, and the other characters
527 that make up a stabs file directive. */
add39d23 528 bufp = buf = XNEWVEC (char, 2 * strlen (file) + strlen (sym) + 12);
43ad3147 529
604d524f
NC
530 *bufp++ = '"';
531
91d6fa6a 532 while (tmp < file_endp)
252b5132 533 {
82b8a785 534 const char *bslash = strchr (tmp, '\\');
5a6312e8 535 size_t len = bslash != NULL ? bslash - tmp + 1 : file_endp - tmp;
43ad3147 536
604d524f
NC
537 /* Double all backslashes, since demand_copy_C_string (used by
538 s_stab to extract the part in quotes) will try to replace them as
539 escape sequences. backslash may appear in a filespec. */
5a6312e8 540 memcpy (bufp, tmp, len);
43ad3147 541
604d524f
NC
542 tmp += len;
543 bufp += len;
544
545 if (bslash != NULL)
546 *bufp++ = '\\';
252b5132
RH
547 }
548
604d524f
NC
549 sprintf (bufp, "\",%d,0,0,%s\n", type, sym);
550
1181551e 551 temp_ilp (buf);
604d524f 552 s_stab ('s');
1181551e
NC
553 restore_ilp ();
554
604d524f
NC
555 colon (sym);
556
24b7e8b1
AM
557 free (last_asm_file);
558 last_asm_file = xstrdup (file);
43ad3147 559
210dcc61 560 free (buf);
252b5132
RH
561}
562
563/* Generate stabs debugging information for the current line. This is
564 used to produce debugging information for an assembler file. */
565
566void
24361518 567stabs_generate_asm_lineno (void)
252b5132 568{
3b4dbbbf 569 const char *file;
252b5132
RH
570 unsigned int lineno;
571 char *buf;
572 char sym[30];
bccba5f0 573
252b5132
RH
574 /* Rather than try to do this in some efficient fashion, we just
575 generate a string and then parse it again. That lets us use the
576 existing stabs hook, which expect to see a string, rather than
577 inventing new ones. */
578
3b4dbbbf 579 file = as_where (&lineno);
252b5132 580
d1a6c242 581 /* Don't emit sequences of stabs for the same line. */
24b7e8b1
AM
582 if (prev_line_file != NULL
583 && filename_cmp (file, prev_line_file) == 0)
1ea5c325 584 {
24b7e8b1
AM
585 if (lineno == prev_lineno)
586 /* Same file/line as last time. */
587 return;
1ea5c325
MS
588 }
589 else
590 {
d1a6c242 591 /* Remember file/line for next time. */
24b7e8b1
AM
592 free (prev_line_file);
593 prev_line_file = xstrdup (file);
1ea5c325
MS
594 }
595
24b7e8b1
AM
596 prev_lineno = lineno;
597
1ea5c325
MS
598 /* Let the world know that we are in the middle of generating a
599 piece of stabs line debugging information. */
600 outputting_stabs_line_debug = 1;
601
252b5132
RH
602 generate_asm_file (N_SOL, file);
603
24b7e8b1
AM
604 sprintf (sym, "%sL%d", FAKE_LABEL_NAME, line_label_count);
605 ++line_label_count;
252b5132 606
24b7e8b1 607 if (current_function_label)
252b5132 608 {
add39d23 609 buf = XNEWVEC (char, 100 + strlen (current_function_label));
252b5132
RH
610 sprintf (buf, "%d,0,%d,%s-%s\n", N_SLINE, lineno,
611 sym, current_function_label);
612 }
613 else
614 {
add39d23 615 buf = XNEWVEC (char, 100);
252b5132
RH
616 sprintf (buf, "%d,0,%d,%s\n", N_SLINE, lineno, sym);
617 }
1181551e
NC
618
619 temp_ilp (buf);
252b5132 620 s_stab ('n');
1181551e
NC
621 restore_ilp ();
622
252b5132
RH
623 colon (sym);
624
bccba5f0 625 outputting_stabs_line_debug = 0;
e1fa0163 626 free (buf);
252b5132
RH
627}
628
629/* Emit a function stab.
630 All assembler functions are assumed to have return type `void'. */
631
632void
24361518 633stabs_generate_asm_func (const char *funcname, const char *startlabname)
252b5132 634{
252b5132 635 char *buf;
252b5132
RH
636 unsigned int lineno;
637
638 if (! void_emitted_p)
639 {
1181551e 640 temp_ilp ((char *) "\"void:t1=1\",128,0,0,0");
252b5132 641 s_stab ('s');
1181551e 642 restore_ilp ();
5b7c81bd 643 void_emitted_p = true;
252b5132
RH
644 }
645
3b4dbbbf 646 as_where (&lineno);
05f4ab67
AM
647 if (asprintf (&buf, "\"%s:F1\",%d,0,%d,%s",
648 funcname, N_FUN, lineno + 1, startlabname) == -1)
649 as_fatal ("%s", xstrerror (errno));
1181551e
NC
650
651 temp_ilp (buf);
252b5132 652 s_stab ('s');
1181551e 653 restore_ilp ();
252b5132
RH
654 free (buf);
655
24b7e8b1 656 free ((char *) current_function_label);
252b5132 657 current_function_label = xstrdup (startlabname);
252b5132
RH
658}
659
660/* Emit a stab to record the end of a function. */
661
662void
24361518
KH
663stabs_generate_asm_endfunc (const char *funcname ATTRIBUTE_UNUSED,
664 const char *startlabname)
252b5132 665{
252b5132
RH
666 char *buf;
667 char sym[30];
668
24b7e8b1
AM
669 sprintf (sym, "%sendfunc%d", FAKE_LABEL_NAME, endfunc_label_count);
670 ++endfunc_label_count;
252b5132
RH
671 colon (sym);
672
05f4ab67
AM
673 if (asprintf (&buf, "\"\",%d,0,0,%s-%s", N_FUN, sym, startlabname) == -1)
674 as_fatal ("%s", xstrerror (errno));
1181551e
NC
675
676 temp_ilp (buf);
252b5132 677 s_stab ('s');
1181551e 678 restore_ilp ();
252b5132
RH
679 free (buf);
680
24b7e8b1 681 free ((char *) current_function_label);
252b5132
RH
682 current_function_label = NULL;
683}
24b7e8b1
AM
684
685void
686stabs_begin (void)
687{
688 current_function_label = NULL;
24b7e8b1
AM
689 last_asm_file = NULL;
690 file_label_count = 0;
691 line_label_count = 0;
692 prev_lineno = -1u;
693 prev_line_file = NULL;
694 void_emitted_p = false;
695 endfunc_label_count = 0;
696}
697
698void
699stabs_end (void)
700{
701 free ((char *) current_function_label);
702 free (last_asm_file);
703 free (prev_line_file);
704}