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