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