This commit was generated by cvs2svn to track changes on a CVS vendor
[deliverable/binutils-gdb.git] / gas / stabs.c
1 /* Generic stabs parsing for gas.
2 Copyright (C) 1989, 90, 91, 93, 94, 95, 96, 97, 98, 1999
3 Free Software Foundation, Inc.
4
5 This file is part of GAS, the GNU Assembler.
6
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2,
10 or (at your option) any later version.
11
12 GAS is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
15 the GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-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
32 static void s_stab_generic PARAMS ((int, char *, char *));
33 static 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. */
48 static int in_dot_func_p;
49
50 /* Label at start of current function if in_dot_func_p != 0. */
51 static 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
77 unsigned int
78 get_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
134 static void aout_process_stab PARAMS ((int, const char *, int, int, int));
135
136 static void
137 aout_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. */
155 symbol_set_frag (symbol, &zero_address_frag);
156 pseudo_set (symbol);
157 }
158 else
159 {
160 /* .stabd sets the name to NULL. Why? */
161 S_SET_NAME (symbol, NULL);
162 symbol_set_frag (symbol, frag_now);
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
177 static void
178 s_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
389 void
390 s_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
398 void
399 s_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
442 void
443 s_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
480 void
481 stabs_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
493 static void
494 generate_asm_file (type, file)
495 int type;
496 char *file;
497 {
498 static char *last_file;
499 static int label_count;
500 char *hold;
501 char buf[100];
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 {
514 sprintf (sym, "%sF%d", FAKE_LABEL_NAME, label_count);
515 ++label_count;
516
517 sprintf (buf, "\"%s\",%d,0,0,%s\n", file, type, sym);
518 input_line_pointer = buf;
519 s_stab ('s');
520 colon (sym);
521
522 if (last_file != NULL)
523 free (last_file);
524 last_file = xstrdup (file);
525 }
526
527 input_line_pointer = hold;
528 }
529
530 /* Generate stabs debugging information for the current line. This is
531 used to produce debugging information for an assembler file. */
532
533 void
534 stabs_generate_asm_lineno ()
535 {
536 static int label_count;
537 char *hold;
538 char *file;
539 unsigned int lineno;
540 char *buf;
541 char sym[30];
542
543 /* Rather than try to do this in some efficient fashion, we just
544 generate a string and then parse it again. That lets us use the
545 existing stabs hook, which expect to see a string, rather than
546 inventing new ones. */
547
548 hold = input_line_pointer;
549
550 as_where (&file, &lineno);
551
552 generate_asm_file (N_SOL, file);
553
554 sprintf (sym, "%sL%d", FAKE_LABEL_NAME, label_count);
555 ++label_count;
556
557 if (in_dot_func_p)
558 {
559 buf = (char *) alloca (100 + strlen (current_function_label));
560 sprintf (buf, "%d,0,%d,%s-%s\n", N_SLINE, lineno,
561 sym, current_function_label);
562 }
563 else
564 {
565 buf = (char *) alloca (100);
566 sprintf (buf, "%d,0,%d,%s\n", N_SLINE, lineno, sym);
567 }
568 input_line_pointer = buf;
569 s_stab ('n');
570 colon (sym);
571
572 input_line_pointer = hold;
573 }
574
575 /* Emit a function stab.
576 All assembler functions are assumed to have return type `void'. */
577
578 void
579 stabs_generate_asm_func (funcname, startlabname)
580 const char *funcname;
581 const char *startlabname;
582 {
583 static int void_emitted_p;
584 char *hold = input_line_pointer;
585 char *buf;
586 char *file;
587 unsigned int lineno;
588
589 if (! void_emitted_p)
590 {
591 input_line_pointer = "\"void:t1=1\",128,0,0,0";
592 s_stab ('s');
593 void_emitted_p = 1;
594 }
595
596 as_where (&file, &lineno);
597 asprintf (&buf, "\"%s:F1\",%d,0,%d,%s",
598 funcname, N_FUN, lineno + 1, startlabname);
599 input_line_pointer = buf;
600 s_stab ('s');
601 free (buf);
602
603 input_line_pointer = hold;
604 current_function_label = xstrdup (startlabname);
605 in_dot_func_p = 1;
606 }
607
608 /* Emit a stab to record the end of a function. */
609
610 void
611 stabs_generate_asm_endfunc (funcname, startlabname)
612 const char *funcname ATTRIBUTE_UNUSED;
613 const char *startlabname;
614 {
615 static int label_count;
616 char *hold = input_line_pointer;
617 char *buf;
618 char sym[30];
619
620 sprintf (sym, "%sendfunc%d", FAKE_LABEL_NAME, label_count);
621 ++label_count;
622 colon (sym);
623
624 asprintf (&buf, "\"\",%d,0,0,%s-%s", N_FUN, sym, startlabname);
625 input_line_pointer = buf;
626 s_stab ('s');
627 free (buf);
628
629 input_line_pointer = hold;
630 in_dot_func_p = 0;
631 current_function_label = NULL;
632 }
This page took 0.045822 seconds and 5 git commands to generate.