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