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