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 (¬es);
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 (¬es))
353*fae548d3Szrj obstack_free (¬es, 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 (¬es))
359*fae548d3Szrj obstack_free (¬es, 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 (¬es))
402*fae548d3Szrj obstack_free (¬es, 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 (¬es);
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