* stabs.c (aout_process_stab): Insert debug symbol into symbol chain after
[external/binutils.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) */