This commit was generated by cvs2svn to track changes on a CVS vendor
[external/binutils.git] / gas / config / obj-som.c
1 /* SOM object file format.
2    Copyright (C) 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, 675 Mass Ave, Cambridge, MA 02139, USA.
19
20    Written by the Center for Software Science at the University of Utah
21    and by Cygnus Support.  */
22
23 #include "as.h"
24 #include "subsegs.h"
25 #include "aout/stab_gnu.h"
26 #include "obstack.h"
27
28 /* SOM does not need any pseudo-ops.  */
29
30 const pseudo_typeS obj_pseudo_table[] =
31 {
32   {NULL}
33 };
34
35 static int version_seen = 0;
36 static int copyright_seen = 0;
37
38 /* Unused by SOM.  */
39 void obj_read_begin_hook () {}
40
41 /* Handle a .version directive.  */
42
43 void
44 obj_som_version (unused)
45      int unused;
46 {
47   char *version, c;
48
49   if (version_seen)
50     {
51       as_bad ("Only one .version pseudo-op per file!");
52       ignore_rest_of_line ();
53       return;
54     }
55
56   SKIP_WHITESPACE ();
57   if (*input_line_pointer == '\"')
58     {
59       version = input_line_pointer;
60       ++input_line_pointer;
61       while (is_a_char (next_char_of_string ()))
62         ;
63       c = *input_line_pointer;
64       *input_line_pointer = '\000';
65     }
66   else
67     {
68       as_bad ("Expected quoted string");
69       ignore_rest_of_line ();
70       return;
71     }
72
73   version_seen = 1;
74   bfd_som_attach_aux_hdr (stdoutput, VERSION_AUX_ID, version);
75   *input_line_pointer = c;
76   demand_empty_rest_of_line ();
77 }
78
79 /* Handle a .copyright directive.   This probably isn't complete, but
80    it's of dubious value anyway and (IMHO) not worth the time to finish.
81    If you care about copyright strings that much, you fix it.  */
82
83 void
84 obj_som_copyright (unused)
85      int unused;
86 {
87   char *copyright, c;
88
89   if (copyright_seen)
90     {
91       as_bad ("Only one .copyright pseudo-op per file!");
92       ignore_rest_of_line ();
93       return;
94     }
95
96   SKIP_WHITESPACE ();
97   if (*input_line_pointer == '\"')
98     {
99       copyright = input_line_pointer;
100       ++input_line_pointer;
101       while (is_a_char (next_char_of_string ()))
102         ;
103       c = *input_line_pointer;
104       *input_line_pointer = '\000';
105     }
106   else
107     {
108       as_bad ("Expected quoted string");
109       ignore_rest_of_line ();
110       return;
111     }
112
113   copyright_seen = 1;
114   bfd_som_attach_aux_hdr (stdoutput, COPYRIGHT_AUX_ID, copyright);
115   *input_line_pointer = c;
116   demand_empty_rest_of_line ();
117 }
118
119 /* Perform any initialization necessary for stabs support.
120
121    For SOM we need to create the space which will contain the
122    two stabs subspaces.  Additionally we need to set up the
123    space/subspace relationships and set space/subspace attributes
124    which BFD does not understand.  */
125
126 void
127 obj_som_init_stab_section (seg)
128      segT seg;
129 {
130   segT saved_seg = now_seg;
131   segT space;
132   subsegT saved_subseg = now_subseg;
133   char *p, *file;
134   unsigned int stroff;
135
136   /* Make the space which will contain the debug subspaces.  */
137   space = bfd_make_section_old_way (stdoutput, "$GDB_DEBUG$");
138
139   /* Set SOM specific attributes for the space.  In particular we set
140      the space "defined", "private", "sort_key", and "spnum" values. 
141
142      Due to a bug in pxdb (called by hpux linker), the sort keys
143      of the various stabs spaces/subspaces need to be "small".  We
144      reserve range 72/73 which appear to work well.  */
145   obj_set_section_attributes (space, 1, 1, 72, 2);
146   bfd_set_section_alignment (stdoutput, space, 2);
147
148   /* Set the containing space for both stab sections to be $GDB_DEBUG$
149      (just created above).  Also set some attributes which BFD does
150      not understand.  In particular, access bits, sort keys, and load
151      quadrant.  */
152   obj_set_subsection_attributes (seg, space, 0x1f, 73, 0);
153   bfd_set_section_alignment (stdoutput, seg, 2);
154
155   /* Make some space for the first stab entry which is special.
156      It contains information about the length of this file's
157      stab string and the like.  Using it avoids the need to 
158      relocate the stab strings.
159
160      The $GDB_STRINGS$ space will be created as a side effect of
161      the call to get_stab_string_offset.  */
162   p = frag_more (12);
163   as_where (&file, (unsigned int *) NULL);
164   stroff = get_stab_string_offset (file, "$GDB_STRINGS$");
165   know (stroff == 1);
166   md_number_to_chars (p, stroff, 4);
167   seg_info (seg)->stabu.p = p;
168
169   /* Set the containing space for both stab sections to be $GDB_DEBUG$
170      (just created above).  Also set some attributes which BFD does
171      not understand.  In particular, access bits, sort keys, and load
172      quadrant.  */
173   seg = bfd_get_section_by_name (stdoutput, "$GDB_STRINGS$");
174   obj_set_subsection_attributes (seg, space, 0x1f, 72, 0);
175   bfd_set_section_alignment (stdoutput, seg, 2);
176
177   subseg_set (saved_seg, saved_subseg);
178 }
179
180 /* Fill in the counts in the first entry in a .stabs section.  */
181
182 static void
183 adjust_stab_sections (abfd, sec, xxx)
184      bfd *abfd;
185      asection *sec;
186      PTR xxx;
187 {
188   asection *strsec;
189   char *p;
190   int strsz, nsyms;
191
192   if (strcmp ("$GDB_SYMBOLS$", sec->name))
193     return;
194
195   strsec = bfd_get_section_by_name (abfd, "$GDB_STRINGS$");
196   if (strsec)
197     strsz = bfd_section_size (abfd, strsec);
198   else
199     strsz = 0;
200   nsyms = bfd_section_size (abfd, sec) / 12 - 1;
201
202   p = seg_info (sec)->stabu.p;
203   assert (p != 0);
204
205   bfd_h_put_16 (abfd, (bfd_vma) nsyms, (bfd_byte *) p + 6);
206   bfd_h_put_32 (abfd, (bfd_vma) strsz, (bfd_byte *) p + 8);
207 }
208
209 #if 0
210 /* Adjust the VMA address for each $CODE$ subspace.  */
211 static void
212 adjust_code_sections (abfd, sec, xxx)
213      bfd *abfd;
214      asection *sec;
215      PTR xxx;
216 {
217   static unsigned size_so_far = 0;
218
219   if (strcmp (sec->name, "$CODE$"))
220     return;
221
222   bfd_set_section_vma (stdoutput, sec, size_so_far);
223   size_so_far += bfd_get_section_size_before_reloc (sec);
224 }
225 #endif
226
227 /* Called late in the asssembly phase to adjust the special
228    stab entry and to set the starting address for each code subspace.  */
229
230 void
231 som_frob_file ()
232 {
233   bfd_map_over_sections (stdoutput, adjust_stab_sections, (PTR) 0);
234 #if 0
235   See comment in tc-hppa.c:pa_proc about GDB lossage
236   bfd_map_over_sections (stdoutput, adjust_code_sections, (PTR) 0);
237 #endif
238 }