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