* gas/elf/elf.exp: Exclude *-*-linux*coff* as non-elf.
[deliverable/binutils-gdb.git] / gas / stabs.c
CommitLineData
252b5132 1/* Generic stabs parsing for gas.
49309057 2 Copyright (C) 1989, 90, 91, 93, 94, 95, 96, 97, 98, 1999
252b5132
RH
3 Free Software Foundation, Inc.
4
5This file is part of GAS, the GNU Assembler.
6
7GAS is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as
9published by the Free Software Foundation; either version 2,
10or (at your option) any later version.
11
12GAS is distributed in the hope that it will be useful, but
13WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
15the GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GAS; see the file COPYING. If not, write to the Free
19Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2002111-1307, USA. */
21
22#include "as.h"
23#include "obstack.h"
24#include "subsegs.h"
25#include "ecoff.h"
26
27/* We need this, despite the apparent object format dependency, since
28 it defines stab types, which all object formats can use now. */
29
30#include "aout/stab_gnu.h"
31
32static void s_stab_generic PARAMS ((int, char *, char *));
33static void generate_asm_file PARAMS ((int, char *));
34
35/* Allow backends to override the names used for the stab sections. */
36#ifndef STAB_SECTION_NAME
37#define STAB_SECTION_NAME ".stab"
38#endif
39
40#ifndef STAB_STRING_SECTION_NAME
41#define STAB_STRING_SECTION_NAME ".stabstr"
42#endif
43
44/* Non-zero if we're in the middle of a .func function, in which case
45 stabs_generate_asm_lineno emits function relative line number stabs.
46 Otherwise it emits line number stabs with absolute addresses. Note that
47 both cases only apply to assembler code assembled with -gstabs. */
48static int in_dot_func_p;
49
50/* Label at start of current function if in_dot_func_p != 0. */
51static const char *current_function_label;
52
53/*
54 * Handle .stabX directives, which used to be open-coded.
55 * So much creeping featurism overloaded the semantics that we decided
56 * to put all .stabX thinking in one place. Here.
57 *
58 * We try to make any .stabX directive legal. Other people's AS will often
59 * do assembly-time consistency checks: eg assigning meaning to n_type bits
60 * and "protecting" you from setting them to certain values. (They also zero
61 * certain bits before emitting symbols. Tut tut.)
62 *
63 * If an expression is not absolute we either gripe or use the relocation
64 * information. Other people's assemblers silently forget information they
65 * don't need and invent information they need that you didn't supply.
66 */
67
68/*
69 * Build a string dictionary entry for a .stabX symbol.
70 * The symbol is added to the .<secname>str section.
71 */
72
73#ifndef SEPARATE_STAB_SECTIONS
74#define SEPARATE_STAB_SECTIONS 0
75#endif
76
77unsigned int
78get_stab_string_offset (string, stabstr_secname)
79 const char *string;
80 const char *stabstr_secname;
81{
82 unsigned int length;
83 unsigned int retval;
84 segT save_seg;
85 subsegT save_subseg;
86 segT seg;
87 char *p;
88
89 if (! SEPARATE_STAB_SECTIONS)
90 abort ();
91
92 length = strlen (string);
93
94 save_seg = now_seg;
95 save_subseg = now_subseg;
96
97 /* Create the stab string section. */
98 seg = subseg_new (stabstr_secname, 0);
99
100 retval = seg_info (seg)->stabu.stab_string_size;
101 if (retval <= 0)
102 {
103 /* Make sure the first string is empty. */
104 p = frag_more (1);
105 *p = 0;
106 retval = seg_info (seg)->stabu.stab_string_size = 1;
107#ifdef BFD_ASSEMBLER
108 bfd_set_section_flags (stdoutput, seg, SEC_READONLY | SEC_DEBUGGING);
109 if (seg->name == stabstr_secname)
110 seg->name = xstrdup (stabstr_secname);
111#endif
112 }
113
114 if (length > 0)
115 { /* Ordinary case. */
116 p = frag_more (length + 1);
117 strcpy (p, string);
118
119 seg_info (seg)->stabu.stab_string_size += length + 1;
120 }
121 else
122 retval = 0;
123
124 subseg_set (save_seg, save_subseg);
125
126 return retval;
127}
128
129#ifdef AOUT_STABS
130#ifndef OBJ_PROCESS_STAB
131#define OBJ_PROCESS_STAB(SEG,W,S,T,O,D) aout_process_stab(W,S,T,O,D)
132#endif
133
134static void aout_process_stab PARAMS ((int, const char *, int, int, int));
135
136static void
137aout_process_stab (what, string, type, other, desc)
138 int what;
139 const char *string;
140 int type, other, desc;
141{
142 /* Put the stab information in the symbol table. */
143 symbolS *symbol;
144
145 /* Create the symbol now, but only insert it into the symbol chain
146 after any symbols mentioned in the value expression get into the
147 symbol chain. This is to avoid "continuation symbols" (where one
148 ends in "\" and the debug info is continued in the next .stabs
149 directive) from being separated by other random symbols. */
150 symbol = symbol_create (string, undefined_section, 0,
151 (struct frag *) NULL);
152 if (what == 's' || what == 'n')
153 {
154 /* Pick up the value from the input line. */
49309057 155 symbol_set_frag (symbol, &zero_address_frag);
252b5132
RH
156 pseudo_set (symbol);
157 }
158 else
159 {
160 /* .stabd sets the name to NULL. Why? */
161 S_SET_NAME (symbol, NULL);
49309057 162 symbol_set_frag (symbol, frag_now);
252b5132
RH
163 S_SET_VALUE (symbol, (valueT) frag_now_fix ());
164 }
165
166 symbol_append (symbol, symbol_lastP, &symbol_rootP, &symbol_lastP);
167
168 S_SET_TYPE (symbol, type);
169 S_SET_OTHER (symbol, other);
170 S_SET_DESC (symbol, desc);
171}
172#endif
173
174/* This can handle different kinds of stabs (s,n,d) and different
175 kinds of stab sections. */
176
177static void
178s_stab_generic (what, stab_secname, stabstr_secname)
179 int what;
180 char *stab_secname;
181 char *stabstr_secname;
182{
183 long longint;
184 char *string;
185 int type;
186 int other;
187 int desc;
188
189 /* The general format is:
190 .stabs "STRING",TYPE,OTHER,DESC,VALUE
191 .stabn TYPE,OTHER,DESC,VALUE
192 .stabd TYPE,OTHER,DESC
193 At this point input_line_pointer points after the pseudo-op and
194 any trailing whitespace. The argument what is one of 's', 'n' or
195 'd' indicating which type of .stab this is. */
196
197 if (what != 's')
198 string = "";
199 else
200 {
201 int length;
202
203 string = demand_copy_C_string (&length);
204 SKIP_WHITESPACE ();
205 if (*input_line_pointer == ',')
206 input_line_pointer++;
207 else
208 {
209 as_warn (_(".stabs: Missing comma"));
210 ignore_rest_of_line ();
211 return;
212 }
213 }
214
215 if (get_absolute_expression_and_terminator (&longint) != ',')
216 {
217 as_warn (_(".stab%c: Missing comma"), what);
218 ignore_rest_of_line ();
219 return;
220 }
221 type = longint;
222
223 if (get_absolute_expression_and_terminator (&longint) != ',')
224 {
225 as_warn (_(".stab%c: Missing comma"), what);
226 ignore_rest_of_line ();
227 return;
228 }
229 other = longint;
230
231 desc = get_absolute_expression ();
232 if (what == 's' || what == 'n')
233 {
234 if (*input_line_pointer != ',')
235 {
236 as_warn (_(".stab%c: Missing comma"), what);
237 ignore_rest_of_line ();
238 return;
239 }
240 input_line_pointer++;
241 SKIP_WHITESPACE ();
242 }
243
244#ifdef TC_PPC
245#ifdef OBJ_ELF
246 /* Solaris on PowerPC has decided that .stabd can take 4 arguments, so if we were
247 given 4 arguments, make it a .stabn */
248 else if (what == 'd')
249 {
250 char *save_location = input_line_pointer;
251
252 SKIP_WHITESPACE ();
253 if (*input_line_pointer == ',')
254 {
255 input_line_pointer++;
256 what = 'n';
257 }
258 else
259 input_line_pointer = save_location;
260 }
261#endif /* OBJ_ELF */
262#endif /* TC_PPC */
263
264#ifndef NO_LISTING
265 if (listing)
266 {
267 switch (type)
268 {
269 case N_SLINE:
270 listing_source_line ((unsigned int) desc);
271 break;
272 case N_SO:
273 case N_SOL:
274 listing_source_file (string);
275 break;
276 }
277 }
278#endif /* ! NO_LISTING */
279
280 /* We have now gathered the type, other, and desc information. For
281 .stabs or .stabn, input_line_pointer is now pointing at the
282 value. */
283
284 if (SEPARATE_STAB_SECTIONS)
285 /* Output the stab information in a separate section. This is used
286 at least for COFF and ELF. */
287 {
288 segT saved_seg = now_seg;
289 subsegT saved_subseg = now_subseg;
290 fragS *saved_frag = frag_now;
291 valueT dot;
292 segT seg;
293 unsigned int stroff;
294 char *p;
295
296 static segT cached_sec;
297 static char *cached_secname;
298
299 dot = frag_now_fix ();
300
301#ifdef md_flush_pending_output
302 md_flush_pending_output ();
303#endif
304
305 if (cached_secname && !strcmp (cached_secname, stab_secname))
306 {
307 seg = cached_sec;
308 subseg_set (seg, 0);
309 }
310 else
311 {
312 seg = subseg_new (stab_secname, 0);
313 if (cached_secname)
314 free (cached_secname);
315 cached_secname = xstrdup (stab_secname);
316 cached_sec = seg;
317 }
318
319 if (! seg_info (seg)->hadone)
320 {
321#ifdef BFD_ASSEMBLER
322 bfd_set_section_flags (stdoutput, seg,
323 SEC_READONLY | SEC_RELOC | SEC_DEBUGGING);
324#endif
325#ifdef INIT_STAB_SECTION
326 INIT_STAB_SECTION (seg);
327#endif
328 seg_info (seg)->hadone = 1;
329 }
330
331 stroff = get_stab_string_offset (string, stabstr_secname);
332 if (what == 's')
333 {
334 /* release the string */
335 obstack_free (&notes, string);
336 }
337
338 /* At least for now, stabs in a special stab section are always
339 output as 12 byte blocks of information. */
340 p = frag_more (8);
341 md_number_to_chars (p, (valueT) stroff, 4);
342 md_number_to_chars (p + 4, (valueT) type, 1);
343 md_number_to_chars (p + 5, (valueT) other, 1);
344 md_number_to_chars (p + 6, (valueT) desc, 2);
345
346 if (what == 's' || what == 'n')
347 {
348 /* Pick up the value from the input line. */
349 cons (4);
350 input_line_pointer--;
351 }
352 else
353 {
354 const char *fake;
355 symbolS *symbol;
356 expressionS exp;
357
358 /* Arrange for a value representing the current location. */
359 fake = FAKE_LABEL_NAME;
360 symbol = symbol_new (fake, saved_seg, dot, saved_frag);
361
362 exp.X_op = O_symbol;
363 exp.X_add_symbol = symbol;
364 exp.X_add_number = 0;
365
366 emit_expr (&exp, 4);
367 }
368
369#ifdef OBJ_PROCESS_STAB
370 OBJ_PROCESS_STAB (seg, what, string, type, other, desc);
371#endif
372
373 subseg_set (saved_seg, saved_subseg);
374 }
375 else
376 {
377#ifdef OBJ_PROCESS_STAB
378 OBJ_PROCESS_STAB (0, what, string, type, other, desc);
379#else
380 abort ();
381#endif
382 }
383
384 demand_empty_rest_of_line ();
385}
386
387/* Regular stab directive. */
388
389void
390s_stab (what)
391 int what;
392{
393 s_stab_generic (what, STAB_SECTION_NAME, STAB_STRING_SECTION_NAME);
394}
395
396/* "Extended stabs", used in Solaris only now. */
397
398void
399s_xstab (what)
400 int what;
401{
402 int length;
403 char *stab_secname, *stabstr_secname;
404 static char *saved_secname, *saved_strsecname;
405
406 /* @@ MEMORY LEAK: This allocates a copy of the string, but in most
407 cases it will be the same string, so we could release the storage
408 back to the obstack it came from. */
409 stab_secname = demand_copy_C_string (&length);
410 SKIP_WHITESPACE ();
411 if (*input_line_pointer == ',')
412 input_line_pointer++;
413 else
414 {
415 as_bad (_("comma missing in .xstabs"));
416 ignore_rest_of_line ();
417 return;
418 }
419
420 /* To get the name of the stab string section, simply add "str" to
421 the stab section name. */
422 if (saved_secname == 0 || strcmp (saved_secname, stab_secname))
423 {
424 stabstr_secname = (char *) xmalloc (strlen (stab_secname) + 4);
425 strcpy (stabstr_secname, stab_secname);
426 strcat (stabstr_secname, "str");
427 if (saved_secname)
428 {
429 free (saved_secname);
430 free (saved_strsecname);
431 }
432 saved_secname = stab_secname;
433 saved_strsecname = stabstr_secname;
434 }
435 s_stab_generic (what, saved_secname, saved_strsecname);
436}
437
438#ifdef S_SET_DESC
439
440/* Frob invented at RMS' request. Set the n_desc of a symbol. */
441
442void
443s_desc (ignore)
444 int ignore;
445{
446 char *name;
447 char c;
448 char *p;
449 symbolS *symbolP;
450 int temp;
451
452 name = input_line_pointer;
453 c = get_symbol_end ();
454 p = input_line_pointer;
455 *p = c;
456 SKIP_WHITESPACE ();
457 if (*input_line_pointer != ',')
458 {
459 *p = 0;
460 as_bad (_("Expected comma after name \"%s\""), name);
461 *p = c;
462 ignore_rest_of_line ();
463 }
464 else
465 {
466 input_line_pointer++;
467 temp = get_absolute_expression ();
468 *p = 0;
469 symbolP = symbol_find_or_make (name);
470 *p = c;
471 S_SET_DESC (symbolP, temp);
472 }
473 demand_empty_rest_of_line ();
474} /* s_desc() */
475
476#endif /* defined (S_SET_DESC) */
477
478/* Generate stabs debugging information to denote the main source file. */
479
480void
481stabs_generate_asm_file ()
482{
483 char *file;
484 unsigned int lineno;
485
486 as_where (&file, &lineno);
487 generate_asm_file (N_SO, file);
488}
489
490/* Generate stabs debugging information to denote the source file.
491 TYPE is one of N_SO, N_SOL. */
492
493static void
494generate_asm_file (type, file)
495 int type;
496 char *file;
497{
498 static char *last_file;
499 static int label_count;
500 char *hold;
210dcc61 501 char *buf = xmalloc (2 * strlen (file) + 10);
252b5132
RH
502 char sym[30];
503
504 /* Rather than try to do this in some efficient fashion, we just
505 generate a string and then parse it again. That lets us use the
506 existing stabs hook, which expect to see a string, rather than
507 inventing new ones. */
508
509 hold = input_line_pointer;
510
511 if (last_file == NULL
512 || strcmp (last_file, file) != 0)
513 {
210dcc61
TW
514 char *tmp = file;
515 char *endp = file + strlen(file);
516 char *bufp = buf;
517
252b5132
RH
518 sprintf (sym, "%sF%d", FAKE_LABEL_NAME, label_count);
519 ++label_count;
520
210dcc61
TW
521 *bufp++ = '"';
522 while (tmp < endp)
523 {
524 char *bslash = strchr (tmp, '\\');
525 int len = (bslash ? (bslash - tmp + 1) : strlen (tmp));
526 /* double all backslashes, since demand_copy_C_string (used by
527 s_stab to extract the part in quotes) will try to replace them as
528 escape sequences. backslash may appear in a filespec. */
529 strncpy (bufp, tmp, len);
530 tmp += len;
531 bufp += len;
532 if (bslash != NULL)
533 *bufp++ = '\\';
534 }
535 sprintf (bufp, "\",%d,0,0,%s\n", type, sym);
252b5132
RH
536 input_line_pointer = buf;
537 s_stab ('s');
538 colon (sym);
539
540 if (last_file != NULL)
541 free (last_file);
542 last_file = xstrdup (file);
543 }
544
545 input_line_pointer = hold;
210dcc61 546 free (buf);
252b5132
RH
547}
548
549/* Generate stabs debugging information for the current line. This is
550 used to produce debugging information for an assembler file. */
551
552void
553stabs_generate_asm_lineno ()
554{
555 static int label_count;
556 char *hold;
557 char *file;
558 unsigned int lineno;
559 char *buf;
560 char sym[30];
561
562 /* Rather than try to do this in some efficient fashion, we just
563 generate a string and then parse it again. That lets us use the
564 existing stabs hook, which expect to see a string, rather than
565 inventing new ones. */
566
567 hold = input_line_pointer;
568
569 as_where (&file, &lineno);
570
571 generate_asm_file (N_SOL, file);
572
573 sprintf (sym, "%sL%d", FAKE_LABEL_NAME, label_count);
574 ++label_count;
575
576 if (in_dot_func_p)
577 {
578 buf = (char *) alloca (100 + strlen (current_function_label));
579 sprintf (buf, "%d,0,%d,%s-%s\n", N_SLINE, lineno,
580 sym, current_function_label);
581 }
582 else
583 {
584 buf = (char *) alloca (100);
585 sprintf (buf, "%d,0,%d,%s\n", N_SLINE, lineno, sym);
586 }
587 input_line_pointer = buf;
588 s_stab ('n');
589 colon (sym);
590
591 input_line_pointer = hold;
592}
593
594/* Emit a function stab.
595 All assembler functions are assumed to have return type `void'. */
596
597void
598stabs_generate_asm_func (funcname, startlabname)
599 const char *funcname;
600 const char *startlabname;
601{
602 static int void_emitted_p;
603 char *hold = input_line_pointer;
604 char *buf;
605 char *file;
606 unsigned int lineno;
607
608 if (! void_emitted_p)
609 {
610 input_line_pointer = "\"void:t1=1\",128,0,0,0";
611 s_stab ('s');
612 void_emitted_p = 1;
613 }
614
615 as_where (&file, &lineno);
616 asprintf (&buf, "\"%s:F1\",%d,0,%d,%s",
617 funcname, N_FUN, lineno + 1, startlabname);
618 input_line_pointer = buf;
619 s_stab ('s');
620 free (buf);
621
622 input_line_pointer = hold;
623 current_function_label = xstrdup (startlabname);
624 in_dot_func_p = 1;
625}
626
627/* Emit a stab to record the end of a function. */
628
629void
630stabs_generate_asm_endfunc (funcname, startlabname)
ab9da554 631 const char *funcname ATTRIBUTE_UNUSED;
252b5132
RH
632 const char *startlabname;
633{
634 static int label_count;
635 char *hold = input_line_pointer;
636 char *buf;
637 char sym[30];
638
639 sprintf (sym, "%sendfunc%d", FAKE_LABEL_NAME, label_count);
640 ++label_count;
641 colon (sym);
642
643 asprintf (&buf, "\"\",%d,0,0,%s-%s", N_FUN, sym, startlabname);
644 input_line_pointer = buf;
645 s_stab ('s');
646 free (buf);
647
648 input_line_pointer = hold;
649 in_dot_func_p = 0;
650 current_function_label = NULL;
651}
This page took 0.070146 seconds and 4 git commands to generate.