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