daily update
[binutils.git] / gas / config / obj-som.c
blob454042a4f4199a845e893feccd32e3ac544e09c0
1 /* SOM object file format.
2 Copyright 1993, 1994, 1998, 2000, 2002 Free Software Foundation, Inc.
4 This file is part of GAS, the GNU Assembler.
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.
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.
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.
21 Written by the Center for Software Science at the University of Utah
22 and by Cygnus Support. */
24 #include "as.h"
25 #include "subsegs.h"
26 #include "aout/stab_gnu.h"
27 #include "obstack.h"
29 static void obj_som_weak PARAMS ((int));
31 const pseudo_typeS obj_pseudo_table[] =
33 {"weak", obj_som_weak, 0},
34 {NULL, NULL, 0}
37 static int version_seen = 0;
38 static int copyright_seen = 0;
39 static int compiler_seen = 0;
41 /* Unused by SOM. */
43 void
44 obj_read_begin_hook ()
48 /* Handle a .compiler directive. This is intended to create the
49 compilation unit auxiliary header for MPE such that the linkeditor
50 can handle SOM extraction from archives. The format of the quoted
51 string is "sourcefile language version" and is delimited by blanks. */
53 void
54 obj_som_compiler (unused)
55 int unused;
57 char *buf;
58 char c;
59 char *filename;
60 char *language_name;
61 char *p;
62 char *version_id;
64 if (compiler_seen)
66 as_bad ("Only one .compiler pseudo-op per file!");
67 ignore_rest_of_line ();
68 return;
71 SKIP_WHITESPACE ();
72 if (*input_line_pointer == '\"')
74 buf = input_line_pointer;
75 ++input_line_pointer;
76 while (is_a_char (next_char_of_string ()))
78 c = *input_line_pointer;
79 *input_line_pointer = '\000';
81 else
83 as_bad ("Expected quoted string");
84 ignore_rest_of_line ();
85 return;
88 /* Parse the quoted string into its component parts. Skip the
89 quote. */
90 filename = buf + 1;
91 p = filename;
92 while (*p != ' ' && *p != '\000')
93 p++;
94 if (*p == '\000')
96 as_bad (".compiler directive missing language and version");
97 return;
99 *p = '\000';
101 language_name = ++p;
102 while (*p != ' ' && *p != '\000')
103 p++;
104 if (*p == '\000')
106 as_bad (".compiler directive missing version");
107 return;
109 *p = '\000';
111 version_id = ++p;
112 while (*p != '\000')
113 p++;
114 /* Remove the trailing quote. */
115 *(--p) = '\000';
117 compiler_seen = 1;
118 if (! bfd_som_attach_compilation_unit (stdoutput, filename, language_name,
119 "GNU Tools", version_id))
121 bfd_perror (stdoutput->filename);
122 as_fatal ("FATAL: Attaching compiler header %s", stdoutput->filename);
124 *input_line_pointer = c;
125 demand_empty_rest_of_line ();
128 /* Handle a .version directive. */
130 void
131 obj_som_version (unused)
132 int unused;
134 char *version, c;
136 if (version_seen)
138 as_bad (_("Only one .version pseudo-op per file!"));
139 ignore_rest_of_line ();
140 return;
143 SKIP_WHITESPACE ();
144 if (*input_line_pointer == '\"')
146 version = input_line_pointer;
147 ++input_line_pointer;
148 while (is_a_char (next_char_of_string ()))
150 c = *input_line_pointer;
151 *input_line_pointer = '\000';
153 else
155 as_bad (_("Expected quoted string"));
156 ignore_rest_of_line ();
157 return;
160 version_seen = 1;
161 if (!bfd_som_attach_aux_hdr (stdoutput, VERSION_AUX_ID, version))
163 bfd_perror (stdoutput->filename);
164 as_perror (_("FATAL: Attaching version header %s"),
165 stdoutput->filename);
166 exit (EXIT_FAILURE);
168 *input_line_pointer = c;
169 demand_empty_rest_of_line ();
172 /* Handle a .copyright directive. This probably isn't complete, but
173 it's of dubious value anyway and (IMHO) not worth the time to finish.
174 If you care about copyright strings that much, you fix it. */
176 void
177 obj_som_copyright (unused)
178 int unused;
180 char *copyright, c;
182 if (copyright_seen)
184 as_bad (_("Only one .copyright pseudo-op per file!"));
185 ignore_rest_of_line ();
186 return;
189 SKIP_WHITESPACE ();
190 if (*input_line_pointer == '\"')
192 copyright = input_line_pointer;
193 ++input_line_pointer;
194 while (is_a_char (next_char_of_string ()))
196 c = *input_line_pointer;
197 *input_line_pointer = '\000';
199 else
201 as_bad (_("Expected quoted string"));
202 ignore_rest_of_line ();
203 return;
206 copyright_seen = 1;
207 if (!bfd_som_attach_aux_hdr (stdoutput, COPYRIGHT_AUX_ID, copyright))
209 bfd_perror (stdoutput->filename);
210 as_perror (_("FATAL: Attaching copyright header %s"),
211 stdoutput->filename);
212 exit (EXIT_FAILURE);
214 *input_line_pointer = c;
215 demand_empty_rest_of_line ();
218 /* Perform any initialization necessary for stabs support.
220 For SOM we need to create the space which will contain the
221 two stabs subspaces. Additionally we need to set up the
222 space/subspace relationships and set space/subspace attributes
223 which BFD does not understand. */
225 void
226 obj_som_init_stab_section (seg)
227 segT seg;
229 segT saved_seg = now_seg;
230 segT space;
231 subsegT saved_subseg = now_subseg;
232 char *p, *file;
233 unsigned int stroff;
235 /* Make the space which will contain the debug subspaces. */
236 space = bfd_make_section_old_way (stdoutput, "$GDB_DEBUG$");
238 /* Set SOM specific attributes for the space. In particular we set
239 the space "defined", "private", "sort_key", and "spnum" values.
241 Due to a bug in pxdb (called by hpux linker), the sort keys
242 of the various stabs spaces/subspaces need to be "small". We
243 reserve range 72/73 which appear to work well. */
244 obj_set_section_attributes (space, 1, 1, 72, 2);
245 bfd_set_section_alignment (stdoutput, space, 2);
247 /* Set the containing space for both stab sections to be $GDB_DEBUG$
248 (just created above). Also set some attributes which BFD does
249 not understand. In particular, access bits, sort keys, and load
250 quadrant. */
251 obj_set_subsection_attributes (seg, space, 0x1f, 73, 0);
252 bfd_set_section_alignment (stdoutput, seg, 2);
254 /* Make some space for the first special stab entry and zero the memory.
255 It contains information about the length of this file's
256 stab string and the like. Using it avoids the need to
257 relocate the stab strings.
259 The $GDB_STRINGS$ space will be created as a side effect of
260 the call to get_stab_string_offset. */
261 p = frag_more (12);
262 memset (p, 0, 12);
263 as_where (&file, (unsigned int *) NULL);
264 stroff = get_stab_string_offset (file, "$GDB_STRINGS$");
265 know (stroff == 1);
266 md_number_to_chars (p, stroff, 4);
267 seg_info (seg)->stabu.p = p;
269 /* Set the containing space for both stab sections to be $GDB_DEBUG$
270 (just created above). Also set some attributes which BFD does
271 not understand. In particular, access bits, sort keys, and load
272 quadrant. */
273 seg = bfd_get_section_by_name (stdoutput, "$GDB_STRINGS$");
274 obj_set_subsection_attributes (seg, space, 0x1f, 72, 0);
275 bfd_set_section_alignment (stdoutput, seg, 2);
277 subseg_set (saved_seg, saved_subseg);
280 /* Fill in the counts in the first entry in a .stabs section. */
282 static void
283 adjust_stab_sections (abfd, sec, xxx)
284 bfd *abfd;
285 asection *sec;
286 PTR xxx;
288 asection *strsec;
289 char *p;
290 int strsz, nsyms;
292 if (strcmp ("$GDB_SYMBOLS$", sec->name))
293 return;
295 strsec = bfd_get_section_by_name (abfd, "$GDB_STRINGS$");
296 if (strsec)
297 strsz = bfd_section_size (abfd, strsec);
298 else
299 strsz = 0;
300 nsyms = bfd_section_size (abfd, sec) / 12 - 1;
302 p = seg_info (sec)->stabu.p;
303 assert (p != 0);
305 bfd_h_put_16 (abfd, (bfd_vma) nsyms, (bfd_byte *) p + 6);
306 bfd_h_put_32 (abfd, (bfd_vma) strsz, (bfd_byte *) p + 8);
309 /* Called late in the assembly phase to adjust the special
310 stab entry and to set the starting address for each code subspace. */
312 void
313 som_frob_file ()
315 bfd_map_over_sections (stdoutput, adjust_stab_sections, (PTR) 0);
318 static void
319 obj_som_weak (ignore)
320 int ignore ATTRIBUTE_UNUSED;
322 char *name;
323 int c;
324 symbolS *symbolP;
328 name = input_line_pointer;
329 c = get_symbol_end ();
330 symbolP = symbol_find_or_make (name);
331 *input_line_pointer = c;
332 SKIP_WHITESPACE ();
333 S_SET_WEAK (symbolP);
334 #if 0
335 symbol_get_obj (symbolP)->local = 1;
336 #endif
337 if (c == ',')
339 input_line_pointer++;
340 SKIP_WHITESPACE ();
341 if (*input_line_pointer == '\n')
342 c = '\n';
345 while (c == ',');
346 demand_empty_rest_of_line ();