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