Home | History | Annotate | Line # | Download | only in gas
stabs.c revision 1.1.1.9
      1 /* Generic stabs parsing for gas.
      2    Copyright (C) 1989-2022 Free Software Foundation, Inc.
      3 
      4    This file is part of GAS, the GNU Assembler.
      5 
      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.
     10 
     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.
     15 
     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.  */
     20 
     21 #include "as.h"
     22 #include "filenames.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 generate_asm_file (int, const char *);
     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 
     48 /* True if we're in the middle of a .func function, in which case
     49    stabs_generate_asm_lineno emits function relative line number stabs.
     50    Otherwise it emits line number stabs with absolute addresses.  Note that
     51    both cases only apply to assembler code assembled with -gstabs.  */
     52 static bool in_dot_func_p = false;
     53 
     54 /* Label at start of current function if in_dot_func_p != FALSE.  */
     55 static const char *current_function_label;
     56 
     57 /*
     58  * Handle .stabX directives, which used to be open-coded.
     59  * So much creeping featurism overloaded the semantics that we decided
     60  * to put all .stabX thinking in one place. Here.
     61  *
     62  * We try to make any .stabX directive legal. Other people's AS will often
     63  * do assembly-time consistency checks: eg assigning meaning to n_type bits
     64  * and "protecting" you from setting them to certain values. (They also zero
     65  * certain bits before emitting symbols. Tut tut.)
     66  *
     67  * If an expression is not absolute we either gripe or use the relocation
     68  * information. Other people's assemblers silently forget information they
     69  * don't need and invent information they need that you didn't supply.
     70  */
     71 
     72 /*
     73  * Build a string dictionary entry for a .stabX symbol.
     74  * The symbol is added to the .<secname>str section.
     75  */
     76 
     77 #ifndef SEPARATE_STAB_SECTIONS
     78 #define SEPARATE_STAB_SECTIONS 0
     79 #endif
     80 
     81 unsigned int
     82 get_stab_string_offset (const char *string, const char *stabstr_secname,
     83 			bool free_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, if it doesn't already exist.  */
    101   seg = subseg_new (stabstr_secname, 0);
    102   if (free_stabstr_secname && seg->name != stabstr_secname)
    103     free ((char *) stabstr_secname);
    104 
    105   retval = seg_info (seg)->stabu.stab_string_size;
    106   if (retval <= 0)
    107     {
    108       /* Make sure the first string is empty.  */
    109       p = frag_more (1);
    110       *p = 0;
    111       retval = seg_info (seg)->stabu.stab_string_size = 1;
    112       bfd_set_section_flags (seg, SEC_READONLY | SEC_DEBUGGING);
    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 (int what, const char *string, int type, int other, int desc)
    138 {
    139   /* Put the stab information in the symbol table.  */
    140   symbolS *symbol;
    141 
    142   /* Create the symbol now, but only insert it into the symbol chain
    143      after any symbols mentioned in the value expression get into the
    144      symbol chain.  This is to avoid "continuation symbols" (where one
    145      ends in "\" and the debug info is continued in the next .stabs
    146      directive) from being separated by other random symbols.  */
    147   symbol = symbol_create (string, undefined_section, &zero_address_frag, 0);
    148   if (what == 's' || what == 'n')
    149     {
    150       /* Pick up the value from the input line.  */
    151       pseudo_set (symbol);
    152     }
    153   else
    154     {
    155       /* .stabd sets the name to NULL.  Why?  */
    156       S_SET_NAME (symbol, NULL);
    157       symbol_set_frag (symbol, frag_now);
    158       S_SET_VALUE (symbol, (valueT) frag_now_fix ());
    159     }
    160 
    161   symbol_append (symbol, symbol_lastP, &symbol_rootP, &symbol_lastP);
    162 
    163   symbol_get_bfdsym (symbol)->flags |= BSF_DEBUGGING;
    164 
    165   S_SET_TYPE (symbol, type);
    166   S_SET_OTHER (symbol, other);
    167   S_SET_DESC (symbol, desc);
    168 }
    169 #endif
    170 
    171 /* This can handle different kinds of stabs (s,n,d) and different
    172    kinds of stab sections.  If STAB_SECNAME_OBSTACK_END is non-NULL,
    173    then STAB_SECNAME and STABSTR_SECNAME will be freed if possible
    174    before this function returns (the former by obstack_free).  */
    175 
    176 static void
    177 s_stab_generic (int what,
    178 		const char *stab_secname,
    179 		const char *stabstr_secname,
    180 		const char *stab_secname_obstack_end)
    181 {
    182   long longint;
    183   const char *string;
    184   char *saved_string_obstack_end;
    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     {
    199       string = "";
    200       saved_string_obstack_end = 0;
    201     }
    202   else
    203     {
    204       int length;
    205 
    206       string = demand_copy_C_string (&length);
    207       if (string == NULL)
    208 	{
    209 	  as_warn (_(".stab%c: missing string"), what);
    210 	  ignore_rest_of_line ();
    211 	  return;
    212 	}
    213       /* FIXME: We should probably find some other temporary storage
    214 	 for string, rather than leaking memory if someone else
    215 	 happens to use the notes obstack.  */
    216       saved_string_obstack_end = obstack_next_free (&notes);
    217       SKIP_WHITESPACE ();
    218       if (*input_line_pointer == ',')
    219 	input_line_pointer++;
    220       else
    221 	{
    222 	  as_warn (_(".stab%c: missing comma"), what);
    223 	  ignore_rest_of_line ();
    224 	  return;
    225 	}
    226     }
    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   type = longint;
    235 
    236   if (get_absolute_expression_and_terminator (&longint) != ',')
    237     {
    238       as_warn (_(".stab%c: missing comma"), what);
    239       ignore_rest_of_line ();
    240       return;
    241     }
    242   other = longint;
    243 
    244   desc = get_absolute_expression ();
    245 
    246   if ((desc > 0xffff) || (desc < -0x8000))
    247     /* This could happen for example with a source file with a huge
    248        number of lines.  The only cure is to use a different debug
    249        format, probably DWARF.  */
    250     as_warn (_(".stab%c: description field '%x' too big, try a different debug format"),
    251 	     what, desc);
    252 
    253   if (what == 's' || what == 'n')
    254     {
    255       if (*input_line_pointer != ',')
    256 	{
    257 	  as_warn (_(".stab%c: missing comma"), what);
    258 	  ignore_rest_of_line ();
    259 	  return;
    260 	}
    261       input_line_pointer++;
    262       SKIP_WHITESPACE ();
    263     }
    264 
    265 #ifdef TC_PPC
    266 #ifdef OBJ_ELF
    267   /* Solaris on PowerPC has decided that .stabd can take 4 arguments, so if we were
    268      given 4 arguments, make it a .stabn */
    269   else if (what == 'd')
    270     {
    271       char *save_location = input_line_pointer;
    272 
    273       SKIP_WHITESPACE ();
    274       if (*input_line_pointer == ',')
    275 	{
    276 	  input_line_pointer++;
    277 	  what = 'n';
    278 	}
    279       else
    280 	input_line_pointer = save_location;
    281     }
    282 #endif /* OBJ_ELF */
    283 #endif /* TC_PPC */
    284 
    285 #ifndef NO_LISTING
    286   if (listing)
    287     {
    288       switch (type)
    289 	{
    290 	case N_SLINE:
    291 	  listing_source_line ((unsigned int) desc);
    292 	  break;
    293 	case N_SO:
    294 	case N_SOL:
    295 	  listing_source_file (string);
    296 	  break;
    297 	}
    298     }
    299 #endif /* ! NO_LISTING */
    300 
    301   /* We have now gathered the type, other, and desc information.  For
    302      .stabs or .stabn, input_line_pointer is now pointing at the
    303      value.  */
    304 
    305   if (SEPARATE_STAB_SECTIONS)
    306     /* Output the stab information in a separate section.  This is used
    307        at least for COFF and ELF.  */
    308     {
    309       segT saved_seg = now_seg;
    310       subsegT saved_subseg = now_subseg;
    311       fragS *saved_frag = frag_now;
    312       valueT dot;
    313       segT seg;
    314       unsigned int stroff;
    315       char *p;
    316 
    317       static segT cached_sec;
    318 
    319       dot = frag_now_fix ();
    320 
    321 #ifdef md_flush_pending_output
    322       md_flush_pending_output ();
    323 #endif
    324 
    325       if (cached_sec && strcmp (cached_sec->name, stab_secname) == 0)
    326 	{
    327 	  seg = cached_sec;
    328 	  subseg_set (seg, 0);
    329 	}
    330       else
    331 	{
    332 	  seg = subseg_new (stab_secname, 0);
    333 	  cached_sec = seg;
    334 	}
    335 
    336       if (! seg_info (seg)->hadone)
    337 	{
    338 	  bfd_set_section_flags (seg,
    339 				 SEC_READONLY | SEC_RELOC | SEC_DEBUGGING);
    340 #ifdef INIT_STAB_SECTION
    341 	  INIT_STAB_SECTION (seg);
    342 #endif
    343 	  seg_info (seg)->hadone = 1;
    344 	}
    345 
    346       stroff = get_stab_string_offset (string, stabstr_secname,
    347 				       stab_secname_obstack_end != NULL);
    348 
    349       /* Release the string, if nobody else has used the obstack.  */
    350       if (saved_string_obstack_end != NULL
    351 	  && saved_string_obstack_end == obstack_next_free (&notes))
    352 	obstack_free (&notes, string);
    353       /* Similarly for the section name.  This must be done before
    354 	 creating symbols below, which uses the notes obstack.  */
    355       if (seg->name != stab_secname
    356 	  && stab_secname_obstack_end != NULL
    357 	  && stab_secname_obstack_end == obstack_next_free (&notes))
    358 	obstack_free (&notes, stab_secname);
    359 
    360       /* At least for now, stabs in a special stab section are always
    361 	 output as 12 byte blocks of information.  */
    362       p = frag_more (8);
    363       md_number_to_chars (p, (valueT) stroff, 4);
    364       md_number_to_chars (p + 4, (valueT) type, 1);
    365       md_number_to_chars (p + 5, (valueT) other, 1);
    366       md_number_to_chars (p + 6, (valueT) desc, 2);
    367 
    368       if (what == 's' || what == 'n')
    369 	{
    370 	  /* Pick up the value from the input line.  */
    371 	  cons (4);
    372 	  input_line_pointer--;
    373 	}
    374       else
    375 	{
    376 	  symbolS *symbol;
    377 	  expressionS exp;
    378 
    379 	  /* Arrange for a value representing the current location.  */
    380 	  symbol = symbol_temp_new (saved_seg, saved_frag, dot);
    381 
    382 	  exp.X_op = O_symbol;
    383 	  exp.X_add_symbol = symbol;
    384 	  exp.X_add_number = 0;
    385 
    386 	  emit_expr (&exp, 4);
    387 	}
    388 
    389 #ifdef OBJ_PROCESS_STAB
    390       OBJ_PROCESS_STAB (seg, what, string, type, other, desc);
    391 #endif
    392 
    393       subseg_set (saved_seg, saved_subseg);
    394     }
    395   else
    396     {
    397       if (stab_secname_obstack_end != NULL)
    398 	{
    399 	  free ((char *) stabstr_secname);
    400 	  if (stab_secname_obstack_end == obstack_next_free (&notes))
    401 	    obstack_free (&notes, stab_secname);
    402 	}
    403 #ifdef OBJ_PROCESS_STAB
    404       OBJ_PROCESS_STAB (0, what, string, type, other, desc);
    405 #else
    406       abort ();
    407 #endif
    408     }
    409 
    410   demand_empty_rest_of_line ();
    411 }
    412 
    413 /* Regular stab directive.  */
    414 
    415 void
    416 s_stab (int what)
    417 {
    418   s_stab_generic (what, STAB_SECTION_NAME, STAB_STRING_SECTION_NAME, NULL);
    419 }
    420 
    421 /* "Extended stabs", used in Solaris only now.  */
    422 
    423 void
    424 s_xstab (int what)
    425 {
    426   int length;
    427   char *stab_secname, *stabstr_secname, *stab_secname_obstack_end;
    428 
    429   stab_secname = demand_copy_C_string (&length);
    430   stab_secname_obstack_end = obstack_next_free (&notes);
    431   SKIP_WHITESPACE ();
    432   if (*input_line_pointer == ',')
    433     input_line_pointer++;
    434   else
    435     {
    436       as_bad (_("comma missing in .xstabs"));
    437       ignore_rest_of_line ();
    438       return;
    439     }
    440 
    441   /* To get the name of the stab string section, simply add "str" to
    442      the stab section name.  */
    443   stabstr_secname = concat (stab_secname, "str", (char *) NULL);
    444   s_stab_generic (what, stab_secname, stabstr_secname,
    445 		  stab_secname_obstack_end);
    446 }
    447 
    448 #ifdef S_SET_DESC
    449 
    450 /* Frob invented at RMS' request. Set the n_desc of a symbol.  */
    451 
    452 void
    453 s_desc (int ignore ATTRIBUTE_UNUSED)
    454 {
    455   char *name;
    456   char c;
    457   char *p;
    458   symbolS *symbolP;
    459   int temp;
    460 
    461   c = get_symbol_name (&name);
    462   p = input_line_pointer;
    463   *p = c;
    464   SKIP_WHITESPACE_AFTER_NAME ();
    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   const char *file;
    492   unsigned int lineno;
    493 
    494   file = as_where (&lineno);
    495   if (use_gnu_debug_info_extensions)
    496     {
    497       char *dir;
    498       char *dir2;
    499 
    500       dir = remap_debug_filename (getpwd ());
    501       dir2 = concat (dir, "/", NULL);
    502       generate_asm_file (N_SO, dir2);
    503       free (dir2);
    504       free (dir);
    505     }
    506   generate_asm_file (N_SO, file);
    507 }
    508 
    509 /* Generate stabs debugging information to denote the source file.
    510    TYPE is one of N_SO, N_SOL.  */
    511 
    512 static void
    513 generate_asm_file (int type, const char *file)
    514 {
    515   static char *last_file;
    516   static int label_count;
    517   char sym[30];
    518   char *buf;
    519   const char *tmp = file;
    520   const char *file_endp = file + strlen (file);
    521   char *bufp;
    522 
    523   if (last_file != NULL
    524       && filename_cmp (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   sprintf (sym, "%sF%d", FAKE_LABEL_NAME, label_count);
    532   ++label_count;
    533 
    534   /* Allocate enough space for the file name (possibly extended with
    535      doubled up backslashes), the symbol name, and the other characters
    536      that make up a stabs file directive.  */
    537   bufp = buf = XNEWVEC (char, 2 * strlen (file) + strlen (sym) + 12);
    538 
    539   *bufp++ = '"';
    540 
    541   while (tmp < file_endp)
    542     {
    543       const char *bslash = strchr (tmp, '\\');
    544       size_t len = bslash != NULL ? bslash - tmp + 1 : file_endp - tmp;
    545 
    546       /* Double all backslashes, since demand_copy_C_string (used by
    547 	 s_stab to extract the part in quotes) will try to replace them as
    548 	 escape sequences.  backslash may appear in a filespec.  */
    549       memcpy (bufp, tmp, len);
    550 
    551       tmp += len;
    552       bufp += len;
    553 
    554       if (bslash != NULL)
    555 	*bufp++ = '\\';
    556     }
    557 
    558   sprintf (bufp, "\",%d,0,0,%s\n", type, sym);
    559 
    560   temp_ilp (buf);
    561   s_stab ('s');
    562   restore_ilp ();
    563 
    564   colon (sym);
    565 
    566   free (last_file);
    567   last_file = xstrdup (file);
    568 
    569   free (buf);
    570 }
    571 
    572 /* Generate stabs debugging information for the current line.  This is
    573    used to produce debugging information for an assembler file.  */
    574 
    575 void
    576 stabs_generate_asm_lineno (void)
    577 {
    578   static int label_count;
    579   const char *file;
    580   unsigned int lineno;
    581   char *buf;
    582   char sym[30];
    583   /* Remember the last file/line and avoid duplicates.  */
    584   static unsigned int prev_lineno = -1;
    585   static char *prev_file = NULL;
    586 
    587   /* Rather than try to do this in some efficient fashion, we just
    588      generate a string and then parse it again.  That lets us use the
    589      existing stabs hook, which expect to see a string, rather than
    590      inventing new ones.  */
    591 
    592   file = as_where (&lineno);
    593 
    594   /* Don't emit sequences of stabs for the same line.  */
    595   if (prev_file == NULL)
    596     {
    597       /* First time through.  */
    598       prev_file = xstrdup (file);
    599       prev_lineno = lineno;
    600     }
    601   else if (lineno == prev_lineno
    602 	   && filename_cmp (file, prev_file) == 0)
    603     {
    604       /* Same file/line as last time.  */
    605       return;
    606     }
    607   else
    608     {
    609       /* Remember file/line for next time.  */
    610       prev_lineno = lineno;
    611       if (filename_cmp (file, prev_file) != 0)
    612 	{
    613 	  free (prev_file);
    614 	  prev_file = xstrdup (file);
    615 	}
    616     }
    617 
    618   /* Let the world know that we are in the middle of generating a
    619      piece of stabs line debugging information.  */
    620   outputting_stabs_line_debug = 1;
    621 
    622   generate_asm_file (N_SOL, file);
    623 
    624   sprintf (sym, "%sL%d", FAKE_LABEL_NAME, label_count);
    625   ++label_count;
    626 
    627   if (in_dot_func_p)
    628     {
    629       buf = XNEWVEC (char, 100 + strlen (current_function_label));
    630       sprintf (buf, "%d,0,%d,%s-%s\n", N_SLINE, lineno,
    631 	       sym, current_function_label);
    632     }
    633   else
    634     {
    635       buf = XNEWVEC (char, 100);
    636       sprintf (buf, "%d,0,%d,%s\n", N_SLINE, lineno, sym);
    637     }
    638 
    639   temp_ilp (buf);
    640   s_stab ('n');
    641   restore_ilp ();
    642 
    643   colon (sym);
    644 
    645   outputting_stabs_line_debug = 0;
    646   free (buf);
    647 }
    648 
    649 /* Emit a function stab.
    650    All assembler functions are assumed to have return type `void'.  */
    651 
    652 void
    653 stabs_generate_asm_func (const char *funcname, const char *startlabname)
    654 {
    655   static bool void_emitted_p = false;
    656   char *buf;
    657   unsigned int lineno;
    658 
    659   if (! void_emitted_p)
    660     {
    661       temp_ilp ((char *) "\"void:t1=1\",128,0,0,0");
    662       s_stab ('s');
    663       restore_ilp ();
    664       void_emitted_p = true;
    665     }
    666 
    667   as_where (&lineno);
    668   if (asprintf (&buf, "\"%s:F1\",%d,0,%d,%s",
    669 		funcname, N_FUN, lineno + 1, startlabname) == -1)
    670     as_fatal ("%s", xstrerror (errno));
    671 
    672   temp_ilp (buf);
    673   s_stab ('s');
    674   restore_ilp ();
    675   free (buf);
    676 
    677   current_function_label = xstrdup (startlabname);
    678   in_dot_func_p = true;
    679 }
    680 
    681 /* Emit a stab to record the end of a function.  */
    682 
    683 void
    684 stabs_generate_asm_endfunc (const char *funcname ATTRIBUTE_UNUSED,
    685 			    const char *startlabname)
    686 {
    687   static int label_count;
    688   char *buf;
    689   char sym[30];
    690 
    691   sprintf (sym, "%sendfunc%d", FAKE_LABEL_NAME, label_count);
    692   ++label_count;
    693   colon (sym);
    694 
    695   if (asprintf (&buf, "\"\",%d,0,0,%s-%s", N_FUN, sym, startlabname) == -1)
    696     as_fatal ("%s", xstrerror (errno));
    697 
    698   temp_ilp (buf);
    699   s_stab ('s');
    700   restore_ilp ();
    701   free (buf);
    702 
    703   in_dot_func_p = false;
    704   current_function_label = NULL;
    705 }
    706