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