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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [gas/] [stabs.c] - Blame information for rev 148

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

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

powered by: WebSVN 2.1.0

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