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