* as.h (strdup): Don't declare.
[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 "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) */