This commit was generated by cvs2svn to track changes on a CVS vendor
[platform/upstream/binutils.git] / gas / config / obj-som.c
1 /* SOM object file format.
2    Copyright (C) 1993, 1998 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 License
17    along with GAS; see the file COPYING.  If not, write to the Free
18    Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19    02111-1307, USA.
20
21    Written by the Center for Software Science at the University of Utah
22    and by Cygnus Support.  */
23
24 #include "as.h"
25 #include "subsegs.h"
26 #include "aout/stab_gnu.h"
27 #include "obstack.h"
28
29 /* SOM does not need any pseudo-ops.  */
30
31 const pseudo_typeS obj_pseudo_table[] =
32 {
33   {NULL}
34 };
35
36 static int version_seen = 0;
37 static int copyright_seen = 0;
38 static int compiler_seen = 0;
39
40 /* Unused by SOM.  */
41 void obj_read_begin_hook () {}
42
43 /* Handle a .compiler directive.   This is intended to create the
44    compilation unit auxiliary header for MPE such that the linkeditor
45    can handle SOM extraction from archives. The format of the quoted
46    string is "sourcefile language version" and is delimited by blanks.*/
47
48 void
49 obj_som_compiler (unused)
50      int unused;
51 {
52   char *buf;
53   char c;
54   char *filename;
55   char *language_name;
56   char *p;
57   char *version_id;
58
59   if (compiler_seen)
60     {
61       as_bad ("Only one .compiler pseudo-op per file!");
62       ignore_rest_of_line ();
63       return;
64     }
65
66   SKIP_WHITESPACE ();
67   if (*input_line_pointer == '\"')
68     {
69       buf = input_line_pointer;
70       ++input_line_pointer;
71       while (is_a_char (next_char_of_string ()))
72         ;
73       c = *input_line_pointer;
74       *input_line_pointer = '\000';
75     }
76   else
77     {
78       as_bad ("Expected quoted string");
79       ignore_rest_of_line ();
80       return;
81     }
82
83   /* Parse the quoted string into its component parts.  Skip the
84      quote.  */
85   filename = buf + 1;
86   p = filename;
87   while (*p != ' ' && *p != '\000')
88     p++;
89   if (*p == '\000')
90     {
91       as_bad (".compiler directive missing language and version");
92       return;
93     }
94   *p = '\000';
95
96   language_name = ++p;
97   while (*p != ' ' && *p != '\000') p++;
98   if (*p == '\000')
99     {
100       as_bad (".compiler directive missing version");
101       return;
102     }
103   *p = '\000';
104
105   version_id    = ++p;
106   while (*p != '\000') p++;
107   /* Remove the trailing quote.  */
108   *(--p) = '\000';
109
110   compiler_seen = 1;
111   if (! bfd_som_attach_compilation_unit (stdoutput, filename, language_name,
112                                          "GNU Tools", version_id))
113     {
114       bfd_perror (stdoutput->filename);
115       as_fatal ("FATAL: Attaching compiler header %s", stdoutput->filename);
116     }
117   *input_line_pointer = c;
118   demand_empty_rest_of_line ();
119 }
120
121 /* Handle a .version directive.  */
122
123 void
124 obj_som_version (unused)
125      int unused;
126 {
127   char *version, c;
128
129   if (version_seen)
130     {
131       as_bad (_("Only one .version pseudo-op per file!"));
132       ignore_rest_of_line ();
133       return;
134     }
135
136   SKIP_WHITESPACE ();
137   if (*input_line_pointer == '\"')
138     {
139       version = input_line_pointer;
140       ++input_line_pointer;
141       while (is_a_char (next_char_of_string ()))
142         ;
143       c = *input_line_pointer;
144       *input_line_pointer = '\000';
145     }
146   else
147     {
148       as_bad (_("Expected quoted string"));
149       ignore_rest_of_line ();
150       return;
151     }
152
153   version_seen = 1;
154   if (bfd_som_attach_aux_hdr (stdoutput, VERSION_AUX_ID, version) == false)
155     {
156       bfd_perror (stdoutput->filename);
157       as_perror (_("FATAL: Attaching version header %s"), stdoutput->filename);
158       exit (EXIT_FAILURE);
159     }
160   *input_line_pointer = c;
161   demand_empty_rest_of_line ();
162 }
163
164 /* Handle a .copyright directive.   This probably isn't complete, but
165    it's of dubious value anyway and (IMHO) not worth the time to finish.
166    If you care about copyright strings that much, you fix it.  */
167
168 void
169 obj_som_copyright (unused)
170      int unused;
171 {
172   char *copyright, c;
173
174   if (copyright_seen)
175     {
176       as_bad (_("Only one .copyright pseudo-op per file!"));
177       ignore_rest_of_line ();
178       return;
179     }
180
181   SKIP_WHITESPACE ();
182   if (*input_line_pointer == '\"')
183     {
184       copyright = input_line_pointer;
185       ++input_line_pointer;
186       while (is_a_char (next_char_of_string ()))
187         ;
188       c = *input_line_pointer;
189       *input_line_pointer = '\000';
190     }
191   else
192     {
193       as_bad (_("Expected quoted string"));
194       ignore_rest_of_line ();
195       return;
196     }
197
198   copyright_seen = 1;
199   if (bfd_som_attach_aux_hdr (stdoutput, COPYRIGHT_AUX_ID, copyright) == false)
200     {
201       bfd_perror (stdoutput->filename);
202       as_perror (_("FATAL: Attaching copyright header %s"), stdoutput->filename);
203       exit (EXIT_FAILURE);
204     }
205   *input_line_pointer = c;
206   demand_empty_rest_of_line ();
207 }
208
209 /* Perform any initialization necessary for stabs support.
210
211    For SOM we need to create the space which will contain the
212    two stabs subspaces.  Additionally we need to set up the
213    space/subspace relationships and set space/subspace attributes
214    which BFD does not understand.  */
215
216 void
217 obj_som_init_stab_section (seg)
218      segT seg;
219 {
220   segT saved_seg = now_seg;
221   segT space;
222   subsegT saved_subseg = now_subseg;
223   char *p, *file;
224   unsigned int stroff;
225
226   /* Make the space which will contain the debug subspaces.  */
227   space = bfd_make_section_old_way (stdoutput, "$GDB_DEBUG$");
228
229   /* Set SOM specific attributes for the space.  In particular we set
230      the space "defined", "private", "sort_key", and "spnum" values. 
231
232      Due to a bug in pxdb (called by hpux linker), the sort keys
233      of the various stabs spaces/subspaces need to be "small".  We
234      reserve range 72/73 which appear to work well.  */
235   obj_set_section_attributes (space, 1, 1, 72, 2);
236   bfd_set_section_alignment (stdoutput, space, 2);
237
238   /* Set the containing space for both stab sections to be $GDB_DEBUG$
239      (just created above).  Also set some attributes which BFD does
240      not understand.  In particular, access bits, sort keys, and load
241      quadrant.  */
242   obj_set_subsection_attributes (seg, space, 0x1f, 73, 0);
243   bfd_set_section_alignment (stdoutput, seg, 2);
244
245   /* Make some space for the first special stab entry and zero the memory.
246      It contains information about the length of this file's
247      stab string and the like.  Using it avoids the need to 
248      relocate the stab strings.
249
250      The $GDB_STRINGS$ space will be created as a side effect of
251      the call to get_stab_string_offset.  */
252   p = frag_more (12);
253   memset (p, 0, 12);
254   as_where (&file, (unsigned int *) NULL);
255   stroff = get_stab_string_offset (file, "$GDB_STRINGS$");
256   know (stroff == 1);
257   md_number_to_chars (p, stroff, 4);
258   seg_info (seg)->stabu.p = p;
259
260   /* Set the containing space for both stab sections to be $GDB_DEBUG$
261      (just created above).  Also set some attributes which BFD does
262      not understand.  In particular, access bits, sort keys, and load
263      quadrant.  */
264   seg = bfd_get_section_by_name (stdoutput, "$GDB_STRINGS$");
265   obj_set_subsection_attributes (seg, space, 0x1f, 72, 0);
266   bfd_set_section_alignment (stdoutput, seg, 2);
267
268   subseg_set (saved_seg, saved_subseg);
269 }
270
271 /* Fill in the counts in the first entry in a .stabs section.  */
272
273 static void
274 adjust_stab_sections (abfd, sec, xxx)
275      bfd *abfd;
276      asection *sec;
277      PTR xxx;
278 {
279   asection *strsec;
280   char *p;
281   int strsz, nsyms;
282
283   if (strcmp ("$GDB_SYMBOLS$", sec->name))
284     return;
285
286   strsec = bfd_get_section_by_name (abfd, "$GDB_STRINGS$");
287   if (strsec)
288     strsz = bfd_section_size (abfd, strsec);
289   else
290     strsz = 0;
291   nsyms = bfd_section_size (abfd, sec) / 12 - 1;
292
293   p = seg_info (sec)->stabu.p;
294   assert (p != 0);
295
296   bfd_h_put_16 (abfd, (bfd_vma) nsyms, (bfd_byte *) p + 6);
297   bfd_h_put_32 (abfd, (bfd_vma) strsz, (bfd_byte *) p + 8);
298 }
299
300 /* Called late in the asssembly phase to adjust the special
301    stab entry and to set the starting address for each code subspace.  */
302
303 void
304 som_frob_file ()
305 {
306   bfd_map_over_sections (stdoutput, adjust_stab_sections, (PTR) 0);
307 }