OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [binutils-2.20.1/] [gas/] [stabs.c] - Blame information for rev 853

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.