* as.h (strdup): Don't declare.
[deliverable/binutils-gdb.git] / gas / stabs.c
1 /* Generic stabs parsing for gas.
2 Copyright (C) 1989, 1990, 1991, 1993 Free Software Foundation, Inc.
3
4 This file is part of GAS, the GNU Assembler.
5
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as
8 published by the Free Software Foundation; either version 2,
9 or (at your option) any later version.
10
11 GAS is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
14 the GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public
17 License along with GAS; see the file COPYING. If not, write
18 to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19
20 #include "as.h"
21 #include "libiberty.h"
22 #include "obstack.h"
23 #include "subsegs.h"
24
25 /* We need this, despite the apparent object format dependency, since
26 it defines stab types, which all object formats can use now. */
27
28 #include "aout/stab_gnu.h"
29
30 /* Allow backends to override the names used for the stab sections. */
31 #ifndef STAB_SECTION_NAME
32 #define STAB_SECTION_NAME ".stab"
33 #endif
34
35 #ifndef STAB_STRING_SECTION_NAME
36 #define STAB_STRING_SECTION_NAME ".stabstr"
37 #endif
38
39 /*
40 * Handle .stabX directives, which used to be open-coded.
41 * So much creeping featurism overloaded the semantics that we decided
42 * to put all .stabX thinking in one place. Here.
43 *
44 * We try to make any .stabX directive legal. Other people's AS will often
45 * do assembly-time consistency checks: eg assigning meaning to n_type bits
46 * and "protecting" you from setting them to certain values. (They also zero
47 * certain bits before emitting symbols. Tut tut.)
48 *
49 * If an expression is not absolute we either gripe or use the relocation
50 * information. Other people's assemblers silently forget information they
51 * don't need and invent information they need that you didn't supply.
52 */
53
54 /*
55 * Build a string dictionary entry for a .stabX symbol.
56 * The symbol is added to the .<secname>str section.
57 */
58
59 #ifndef SEPARATE_STAB_SECTIONS
60 #define SEPARATE_STAB_SECTIONS 0
61 #endif
62
63 unsigned int
64 get_stab_string_offset (string, stabstr_secname)
65 const char *string;
66 const char *stabstr_secname;
67 {
68 unsigned int length;
69 unsigned int retval;
70
71 if (! SEPARATE_STAB_SECTIONS)
72 abort ();
73
74 retval = 0;
75 length = strlen (string);
76 if (length > 0)
77 { /* Ordinary case. */
78 segT save_seg;
79 subsegT save_subseg;
80 segT seg;
81 char *p;
82
83 save_seg = now_seg;
84 save_subseg = now_subseg;
85
86 /* Create the stab string section. */
87 seg = subseg_new (stabstr_secname, 0);
88
89 retval = seg_info (seg)->stabu.stab_string_size;
90 if (retval <= 0)
91 {
92 /* Make sure the first string is empty. */
93 p = frag_more (1);
94 *p = 0;
95 retval = seg_info (seg)->stabu.stab_string_size = 1;
96 #ifdef BFD_ASSEMBLER
97 bfd_set_section_flags (stdoutput, seg, SEC_READONLY | SEC_DEBUGGING);
98 if (seg->name == stabstr_secname)
99 seg->name = xstrdup (stabstr_secname);
100 #endif
101 }
102
103 p = frag_more (length + 1);
104 strcpy (p, string);
105
106 seg_info (seg)->stabu.stab_string_size += length + 1;
107
108 subseg_set (save_seg, save_subseg);
109 }
110
111 return retval;
112 }
113
114 #ifdef AOUT_STABS
115 #ifndef OBJ_PROCESS_STAB
116 #define OBJ_PROCESS_STAB(SEG,W,S,T,O,D) aout_process_stab(W,S,T,O,D)
117 #endif
118
119 static void
120 aout_process_stab (what, string, type, other, desc)
121 int what;
122 const char *string;
123 int type, other, desc;
124 {
125 /* Put the stab information in the symbol table. */
126 symbolS *symbol;
127
128 /* Create the symbol now, but only insert it into the symbol chain
129 after any symbols mentioned in the value expression get into the
130 symbol chain. This is to avoid "continuation symbols" (where one
131 ends in "\" and the debug info is continued in the next .stabs
132 directive) from being separated by other random symbols. */
133 symbol = symbol_create (string, undefined_section, 0,
134 (struct frag *) NULL);
135 if (what == 's' || what == 'n')
136 {
137 /* Pick up the value from the input line. */
138 symbol->sy_frag = &zero_address_frag;
139 pseudo_set (symbol);
140 }
141 else
142 {
143 /* .stabd sets the name to NULL. Why? */
144 S_SET_NAME (symbol, NULL);
145 symbol->sy_frag = frag_now;
146 S_SET_VALUE (symbol, (valueT) frag_now_fix ());
147 }
148
149 symbol_append (symbol, symbol_lastP, &symbol_rootP, &symbol_lastP);
150
151 S_SET_TYPE (symbol, type);
152 S_SET_OTHER (symbol, other);
153 S_SET_DESC (symbol, desc);
154 }
155 #endif
156
157 /* This can handle different kinds of stabs (s,n,d) and different
158 kinds of stab sections. */
159
160 static void
161 s_stab_generic (what, stab_secname, stabstr_secname)
162 int what;
163 char *stab_secname;
164 char *stabstr_secname;
165 {
166 long longint;
167 char *string;
168 int type;
169 int other;
170 int desc;
171
172 /* The general format is:
173 .stabs "STRING",TYPE,OTHER,DESC,VALUE
174 .stabn TYPE,OTHER,DESC,VALUE
175 .stabd TYPE,OTHER,DESC
176 At this point input_line_pointer points after the pseudo-op and
177 any trailing whitespace. The argument what is one of 's', 'n' or
178 'd' indicating which type of .stab this is. */
179
180 if (what != 's')
181 string = "";
182 else
183 {
184 int length;
185
186 string = demand_copy_C_string (&length);
187 SKIP_WHITESPACE ();
188 if (*input_line_pointer == ',')
189 input_line_pointer++;
190 else
191 {
192 as_warn (".stabs: Missing comma");
193 ignore_rest_of_line ();
194 return;
195 }
196 }
197
198 if (get_absolute_expression_and_terminator (&longint) != ',')
199 {
200 as_warn (".stab%c: Missing comma", what);
201 ignore_rest_of_line ();
202 return;
203 }
204 type = longint;
205
206 if (get_absolute_expression_and_terminator (&longint) != ',')
207 {
208 as_warn (".stab%c: Missing comma", what);
209 ignore_rest_of_line ();
210 return;
211 }
212 other = longint;
213
214 desc = get_absolute_expression ();
215 if (what == 's' || what == 'n')
216 {
217 if (*input_line_pointer != ',')
218 {
219 as_warn (".stab%c: Missing comma", what);
220 ignore_rest_of_line ();
221 return;
222 }
223 input_line_pointer++;
224 SKIP_WHITESPACE ();
225 }
226
227 /* We have now gathered the type, other, and desc information. For
228 .stabs or .stabn, input_line_pointer is now pointing at the
229 value. */
230
231 if (SEPARATE_STAB_SECTIONS)
232 /* Output the stab information in a separate section. This is used
233 at least for COFF and ELF. */
234 {
235 segT saved_seg = now_seg;
236 subsegT saved_subseg = now_subseg;
237 fragS *saved_frag = frag_now;
238 valueT dot;
239 segT seg;
240 unsigned int stroff;
241 char *p;
242
243 static segT cached_sec;
244 static char *cached_secname;
245
246 dot = frag_now_fix ();
247
248 if (cached_secname && !strcmp (cached_secname, stab_secname))
249 {
250 seg = cached_sec;
251 subseg_set (seg, 0);
252 }
253 else
254 {
255 seg = subseg_new (stab_secname, 0);
256 if (cached_secname)
257 free (cached_secname);
258 cached_secname = xstrdup (stab_secname);
259 cached_sec = seg;
260 }
261
262 if (! seg_info (seg)->hadone)
263 {
264 #ifdef BFD_ASSEMBLER
265 bfd_set_section_flags (stdoutput, seg,
266 SEC_READONLY | SEC_RELOC | SEC_DEBUGGING);
267 #endif
268 #ifdef INIT_STAB_SECTION
269 INIT_STAB_SECTION (seg);
270 #endif
271 seg_info (seg)->hadone = 1;
272 }
273
274 stroff = get_stab_string_offset (string, stabstr_secname);
275 if (what == 's')
276 {
277 /* release the string */
278 obstack_free (&notes, string);
279 }
280
281 /* At least for now, stabs in a special stab section are always
282 output as 12 byte blocks of information. */
283 p = frag_more (8);
284 md_number_to_chars (p, (valueT) stroff, 4);
285 md_number_to_chars (p + 4, (valueT) type, 1);
286 md_number_to_chars (p + 5, (valueT) other, 1);
287 md_number_to_chars (p + 6, (valueT) desc, 2);
288
289 if (what == 's' || what == 'n')
290 {
291 /* Pick up the value from the input line. */
292 cons (4);
293 input_line_pointer--;
294 }
295 else
296 {
297 const char *fake;
298 symbolS *symbol;
299 expressionS exp;
300
301 /* Arrange for a value representing the current location. */
302 fake = FAKE_LABEL_NAME;
303 symbol = symbol_new (fake, saved_seg, dot, saved_frag);
304
305 exp.X_op = O_symbol;
306 exp.X_add_symbol = symbol;
307 exp.X_add_number = 0;
308
309 emit_expr (&exp, 4);
310 }
311
312 #ifdef OBJ_PROCESS_STAB
313 OBJ_PROCESS_STAB (seg, what, string + stroff, type, other, desc);
314 #endif
315
316 subseg_set (saved_seg, saved_subseg);
317 }
318 else
319 {
320 #ifdef OBJ_PROCESS_STAB
321 OBJ_PROCESS_STAB (0, what, string, type, other, desc);
322 #else
323 abort ();
324 #endif
325 }
326
327 #ifndef NO_LISTING
328 if (listing)
329 {
330 switch (type)
331 {
332 case N_SLINE:
333 listing_source_line ((unsigned int) desc);
334 break;
335 case N_SO:
336 case N_SOL:
337 listing_source_file (string);
338 break;
339 }
340 }
341 #endif /* ! NO_LISTING */
342
343 demand_empty_rest_of_line ();
344 }
345
346 /* Regular stab directive. */
347
348 void
349 s_stab (what)
350 int what;
351 {
352 s_stab_generic (what, STAB_SECTION_NAME, STAB_STRING_SECTION_NAME);
353 }
354
355 /* "Extended stabs", used in Solaris only now. */
356
357 void
358 s_xstab (what)
359 int what;
360 {
361 int length;
362 char *stab_secname, *stabstr_secname;
363 static char *saved_secname, *saved_strsecname;
364
365 /* @@ MEMORY LEAK: This allocates a copy of the string, but in most
366 cases it will be the same string, so we could release the storage
367 back to the obstack it came from. */
368 stab_secname = demand_copy_C_string (&length);
369 SKIP_WHITESPACE ();
370 if (*input_line_pointer == ',')
371 input_line_pointer++;
372 else
373 {
374 as_bad ("comma missing in .xstabs");
375 ignore_rest_of_line ();
376 return;
377 }
378
379 /* To get the name of the stab string section, simply add "str" to
380 the stab section name. */
381 if (saved_secname == 0 || strcmp (saved_secname, stab_secname))
382 {
383 stabstr_secname = (char *) xmalloc (strlen (stab_secname) + 4);
384 strcpy (stabstr_secname, stab_secname);
385 strcat (stabstr_secname, "str");
386 if (saved_secname)
387 {
388 free (saved_secname);
389 free (saved_strsecname);
390 }
391 saved_secname = stab_secname;
392 saved_strsecname = stabstr_secname;
393 }
394 s_stab_generic (what, saved_secname, saved_strsecname);
395 }
396
397 #ifdef S_SET_DESC
398
399 /* Frob invented at RMS' request. Set the n_desc of a symbol. */
400
401 void
402 s_desc (ignore)
403 int ignore;
404 {
405 char *name;
406 char c;
407 char *p;
408 symbolS *symbolP;
409 int temp;
410
411 name = input_line_pointer;
412 c = get_symbol_end ();
413 p = input_line_pointer;
414 *p = c;
415 SKIP_WHITESPACE ();
416 if (*input_line_pointer != ',')
417 {
418 *p = 0;
419 as_bad ("Expected comma after name \"%s\"", name);
420 *p = c;
421 ignore_rest_of_line ();
422 }
423 else
424 {
425 input_line_pointer++;
426 temp = get_absolute_expression ();
427 *p = 0;
428 symbolP = symbol_find_or_make (name);
429 *p = c;
430 S_SET_DESC (symbolP, temp);
431 }
432 demand_empty_rest_of_line ();
433 } /* s_desc() */
434
435 #endif /* defined (S_SET_DESC) */
This page took 0.050155 seconds and 4 git commands to generate.