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