xref: /netbsd/external/gpl3/binutils/dist/bfd/som.c (revision 6550d01e)
1 /* bfd back-end for HP PA-RISC SOM objects.
2    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3    2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
4    Free Software Foundation, Inc.
5 
6    Contributed by the Center for Software Science at the
7    University of Utah.
8 
9    This file is part of BFD, the Binary File Descriptor library.
10 
11    This program is free software; you can redistribute it and/or modify
12    it under the terms of the GNU General Public License as published by
13    the Free Software Foundation; either version 3 of the License, or
14    (at your option) any later version.
15 
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19    GNU General Public License for more details.
20 
21    You should have received a copy of the GNU General Public License
22    along with this program; if not, write to the Free Software
23    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
24    02110-1301, USA.  */
25 
26 #include "sysdep.h"
27 #include "bfd.h"
28 
29 #if defined (HOST_HPPAHPUX) || defined (HOST_HPPABSD) || defined (HOST_HPPAOSF) || defined(HOST_HPPAMPEIX)
30 
31 #include "libbfd.h"
32 #include "som.h"
33 #include "safe-ctype.h"
34 
35 #include <sys/param.h>
36 #include <signal.h>
37 #include <machine/reg.h>
38 #include <sys/file.h>
39 
40 /* This is the code recommended in the autoconf documentation, almost
41    verbatim.  */
42 
43 #ifndef __GNUC__
44 # if HAVE_ALLOCA_H
45 #  include <alloca.h>
46 # else
47 #  ifdef _AIX
48 /* Indented so that pre-ansi C compilers will ignore it, rather than
49    choke on it.  Some versions of AIX require this to be the first
50    thing in the file.  */
51  #pragma alloca
52 #  else
53 #   ifndef alloca /* predefined by HP cc +Olibcalls */
54 #    if !defined (__STDC__) && !defined (__hpux)
55 extern char *alloca ();
56 #    else
57 extern void *alloca ();
58 #    endif /* __STDC__, __hpux */
59 #   endif /* alloca */
60 #  endif /* _AIX */
61 # endif /* HAVE_ALLOCA_H */
62 #else
63 extern void *alloca (size_t);
64 #endif /* __GNUC__ */
65 
66 static bfd_reloc_status_type hppa_som_reloc
67   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
68 static bfd_boolean som_mkobject (bfd *);
69 static bfd_boolean som_is_space (asection *);
70 static bfd_boolean som_is_subspace (asection *);
71 static int compare_subspaces (const void *, const void *);
72 static unsigned long som_compute_checksum (bfd *);
73 static bfd_boolean som_build_and_write_symbol_table (bfd *);
74 static unsigned int som_slurp_symbol_table (bfd *);
75 
76 /* Magic not defined in standard HP-UX header files until 8.0.  */
77 
78 #ifndef CPU_PA_RISC1_0
79 #define CPU_PA_RISC1_0 0x20B
80 #endif /* CPU_PA_RISC1_0 */
81 
82 #ifndef CPU_PA_RISC1_1
83 #define CPU_PA_RISC1_1 0x210
84 #endif /* CPU_PA_RISC1_1 */
85 
86 #ifndef CPU_PA_RISC2_0
87 #define CPU_PA_RISC2_0 0x214
88 #endif /* CPU_PA_RISC2_0 */
89 
90 #ifndef _PA_RISC1_0_ID
91 #define _PA_RISC1_0_ID CPU_PA_RISC1_0
92 #endif /* _PA_RISC1_0_ID */
93 
94 #ifndef _PA_RISC1_1_ID
95 #define _PA_RISC1_1_ID CPU_PA_RISC1_1
96 #endif /* _PA_RISC1_1_ID */
97 
98 #ifndef _PA_RISC2_0_ID
99 #define _PA_RISC2_0_ID CPU_PA_RISC2_0
100 #endif /* _PA_RISC2_0_ID */
101 
102 #ifndef _PA_RISC_MAXID
103 #define _PA_RISC_MAXID	0x2FF
104 #endif /* _PA_RISC_MAXID */
105 
106 #ifndef _PA_RISC_ID
107 #define _PA_RISC_ID(__m_num)		\
108     (((__m_num) == _PA_RISC1_0_ID) ||	\
109      ((__m_num) >= _PA_RISC1_1_ID && (__m_num) <= _PA_RISC_MAXID))
110 #endif /* _PA_RISC_ID */
111 
112 /* HIUX in it's infinite stupidity changed the names for several "well
113    known" constants.  Work around such braindamage.  Try the HPUX version
114    first, then the HIUX version, and finally provide a default.  */
115 #ifdef HPUX_AUX_ID
116 #define EXEC_AUX_ID HPUX_AUX_ID
117 #endif
118 
119 #if !defined (EXEC_AUX_ID) && defined (HIUX_AUX_ID)
120 #define EXEC_AUX_ID HIUX_AUX_ID
121 #endif
122 
123 #ifndef EXEC_AUX_ID
124 #define EXEC_AUX_ID 0
125 #endif
126 
127 /* Size (in chars) of the temporary buffers used during fixup and string
128    table writes.   */
129 
130 #define SOM_TMP_BUFSIZE 8192
131 
132 /* Size of the hash table in archives.  */
133 #define SOM_LST_HASH_SIZE 31
134 
135 /* Max number of SOMs to be found in an archive.  */
136 #define SOM_LST_MODULE_LIMIT 1024
137 
138 /* Generic alignment macro.  */
139 #define SOM_ALIGN(val, alignment) \
140   (((val) + (alignment) - 1) &~ ((unsigned long) (alignment) - 1))
141 
142 /* SOM allows any one of the four previous relocations to be reused
143    with a "R_PREV_FIXUP" relocation entry.  Since R_PREV_FIXUP
144    relocations are always a single byte, using a R_PREV_FIXUP instead
145    of some multi-byte relocation makes object files smaller.
146 
147    Note one side effect of using a R_PREV_FIXUP is the relocation that
148    is being repeated moves to the front of the queue.  */
149 struct reloc_queue
150 {
151   unsigned char *reloc;
152   unsigned int size;
153 } reloc_queue[4];
154 
155 /* This fully describes the symbol types which may be attached to
156    an EXPORT or IMPORT directive.  Only SOM uses this formation
157    (ELF has no need for it).  */
158 typedef enum
159 {
160   SYMBOL_TYPE_UNKNOWN,
161   SYMBOL_TYPE_ABSOLUTE,
162   SYMBOL_TYPE_CODE,
163   SYMBOL_TYPE_DATA,
164   SYMBOL_TYPE_ENTRY,
165   SYMBOL_TYPE_MILLICODE,
166   SYMBOL_TYPE_PLABEL,
167   SYMBOL_TYPE_PRI_PROG,
168   SYMBOL_TYPE_SEC_PROG,
169 } pa_symbol_type;
170 
171 struct section_to_type
172 {
173   char *section;
174   char type;
175 };
176 
177 /* Assorted symbol information that needs to be derived from the BFD symbol
178    and/or the BFD backend private symbol data.  */
179 struct som_misc_symbol_info
180 {
181   unsigned int symbol_type;
182   unsigned int symbol_scope;
183   unsigned int arg_reloc;
184   unsigned int symbol_info;
185   unsigned int symbol_value;
186   unsigned int priv_level;
187   unsigned int secondary_def;
188   unsigned int is_comdat;
189   unsigned int is_common;
190   unsigned int dup_common;
191 };
192 
193 /* Map SOM section names to POSIX/BSD single-character symbol types.
194 
195    This table includes all the standard subspaces as defined in the
196    current "PRO ABI for PA-RISC Systems", $UNWIND$ which for
197    some reason was left out, and sections specific to embedded stabs.  */
198 
199 static const struct section_to_type stt[] =
200 {
201   {"$TEXT$", 't'},
202   {"$SHLIB_INFO$", 't'},
203   {"$MILLICODE$", 't'},
204   {"$LIT$", 't'},
205   {"$CODE$", 't'},
206   {"$UNWIND_START$", 't'},
207   {"$UNWIND$", 't'},
208   {"$PRIVATE$", 'd'},
209   {"$PLT$", 'd'},
210   {"$SHLIB_DATA$", 'd'},
211   {"$DATA$", 'd'},
212   {"$SHORTDATA$", 'g'},
213   {"$DLT$", 'd'},
214   {"$GLOBAL$", 'g'},
215   {"$SHORTBSS$", 's'},
216   {"$BSS$", 'b'},
217   {"$GDB_STRINGS$", 'N'},
218   {"$GDB_SYMBOLS$", 'N'},
219   {0, 0}
220 };
221 
222 /* About the relocation formatting table...
223 
224    There are 256 entries in the table, one for each possible
225    relocation opcode available in SOM.  We index the table by
226    the relocation opcode.  The names and operations are those
227    defined by a.out_800 (4).
228 
229    Right now this table is only used to count and perform minimal
230    processing on relocation streams so that they can be internalized
231    into BFD and symbolically printed by utilities.  To make actual use
232    of them would be much more difficult, BFD's concept of relocations
233    is far too simple to handle SOM relocations.  The basic assumption
234    that a relocation can be completely processed independent of other
235    relocations before an object file is written is invalid for SOM.
236 
237    The SOM relocations are meant to be processed as a stream, they
238    specify copying of data from the input section to the output section
239    while possibly modifying the data in some manner.  They also can
240    specify that a variable number of zeros or uninitialized data be
241    inserted on in the output segment at the current offset.  Some
242    relocations specify that some previous relocation be re-applied at
243    the current location in the input/output sections.  And finally a number
244    of relocations have effects on other sections (R_ENTRY, R_EXIT,
245    R_UNWIND_AUX and a variety of others).  There isn't even enough room
246    in the BFD relocation data structure to store enough information to
247    perform all the relocations.
248 
249    Each entry in the table has three fields.
250 
251    The first entry is an index into this "class" of relocations.  This
252    index can then be used as a variable within the relocation itself.
253 
254    The second field is a format string which actually controls processing
255    of the relocation.  It uses a simple postfix machine to do calculations
256    based on variables/constants found in the string and the relocation
257    stream.
258 
259    The third field specifys whether or not this relocation may use
260    a constant (V) from the previous R_DATA_OVERRIDE rather than a constant
261    stored in the instruction.
262 
263    Variables:
264 
265    L = input space byte count
266    D = index into class of relocations
267    M = output space byte count
268    N = statement number (unused?)
269    O = stack operation
270    R = parameter relocation bits
271    S = symbol index
272    T = first 32 bits of stack unwind information
273    U = second 32 bits of stack unwind information
274    V = a literal constant (usually used in the next relocation)
275    P = a previous relocation
276 
277    Lower case letters (starting with 'b') refer to following
278    bytes in the relocation stream.  'b' is the next 1 byte,
279    c is the next 2 bytes, d is the next 3 bytes, etc...
280    This is the variable part of the relocation entries that
281    makes our life a living hell.
282 
283    numerical constants are also used in the format string.  Note
284    the constants are represented in decimal.
285 
286    '+', "*" and "=" represents the obvious postfix operators.
287    '<' represents a left shift.
288 
289    Stack Operations:
290 
291    Parameter Relocation Bits:
292 
293    Unwind Entries:
294 
295    Previous Relocations:  The index field represents which in the queue
296    of 4 previous fixups should be re-applied.
297 
298    Literal Constants:  These are generally used to represent addend
299    parts of relocations when these constants are not stored in the
300    fields of the instructions themselves.  For example the instruction
301    addil foo-$global$-0x1234 would use an override for "0x1234" rather
302    than storing it into the addil itself.  */
303 
304 struct fixup_format
305 {
306   int D;
307   const char *format;
308 };
309 
310 static const struct fixup_format som_fixup_formats[256] =
311 {
312   /* R_NO_RELOCATION.  */
313   {  0, "LD1+4*=" },		/* 0x00 */
314   {  1, "LD1+4*=" },		/* 0x01 */
315   {  2, "LD1+4*=" },		/* 0x02 */
316   {  3, "LD1+4*=" },		/* 0x03 */
317   {  4, "LD1+4*=" },		/* 0x04 */
318   {  5, "LD1+4*=" },		/* 0x05 */
319   {  6, "LD1+4*=" },		/* 0x06 */
320   {  7, "LD1+4*=" },		/* 0x07 */
321   {  8, "LD1+4*=" },		/* 0x08 */
322   {  9, "LD1+4*=" },		/* 0x09 */
323   { 10, "LD1+4*=" },		/* 0x0a */
324   { 11, "LD1+4*=" },		/* 0x0b */
325   { 12, "LD1+4*=" },		/* 0x0c */
326   { 13, "LD1+4*=" },		/* 0x0d */
327   { 14, "LD1+4*=" },		/* 0x0e */
328   { 15, "LD1+4*=" },		/* 0x0f */
329   { 16, "LD1+4*=" },		/* 0x10 */
330   { 17, "LD1+4*=" },		/* 0x11 */
331   { 18, "LD1+4*=" },		/* 0x12 */
332   { 19, "LD1+4*=" },		/* 0x13 */
333   { 20, "LD1+4*=" },		/* 0x14 */
334   { 21, "LD1+4*=" },		/* 0x15 */
335   { 22, "LD1+4*=" },		/* 0x16 */
336   { 23, "LD1+4*=" },		/* 0x17 */
337   {  0, "LD8<b+1+4*=" },	/* 0x18 */
338   {  1, "LD8<b+1+4*=" },	/* 0x19 */
339   {  2, "LD8<b+1+4*=" },	/* 0x1a */
340   {  3, "LD8<b+1+4*=" },	/* 0x1b */
341   {  0, "LD16<c+1+4*=" },	/* 0x1c */
342   {  1, "LD16<c+1+4*=" },	/* 0x1d */
343   {  2, "LD16<c+1+4*=" },	/* 0x1e */
344   {  0, "Ld1+=" },		/* 0x1f */
345   /* R_ZEROES.  */
346   {  0, "Lb1+4*=" },		/* 0x20 */
347   {  1, "Ld1+=" },		/* 0x21 */
348   /* R_UNINIT.  */
349   {  0, "Lb1+4*=" },		/* 0x22 */
350   {  1, "Ld1+=" },		/* 0x23 */
351   /* R_RELOCATION.  */
352   {  0, "L4=" },		/* 0x24 */
353   /* R_DATA_ONE_SYMBOL.  */
354   {  0, "L4=Sb=" },		/* 0x25 */
355   {  1, "L4=Sd=" },		/* 0x26 */
356   /* R_DATA_PLABEL.  */
357   {  0, "L4=Sb=" },		/* 0x27 */
358   {  1, "L4=Sd=" },		/* 0x28 */
359   /* R_SPACE_REF.  */
360   {  0, "L4=" },		/* 0x29 */
361   /* R_REPEATED_INIT.  */
362   {  0, "L4=Mb1+4*=" },		/* 0x2a */
363   {  1, "Lb4*=Mb1+L*=" },	/* 0x2b */
364   {  2, "Lb4*=Md1+4*=" },	/* 0x2c */
365   {  3, "Ld1+=Me1+=" },		/* 0x2d */
366   {  0, "" },			/* 0x2e */
367   {  0, "" },			/* 0x2f */
368   /* R_PCREL_CALL.  */
369   {  0, "L4=RD=Sb=" },		/* 0x30 */
370   {  1, "L4=RD=Sb=" },		/* 0x31 */
371   {  2, "L4=RD=Sb=" },		/* 0x32 */
372   {  3, "L4=RD=Sb=" },		/* 0x33 */
373   {  4, "L4=RD=Sb=" },		/* 0x34 */
374   {  5, "L4=RD=Sb=" },		/* 0x35 */
375   {  6, "L4=RD=Sb=" },		/* 0x36 */
376   {  7, "L4=RD=Sb=" },		/* 0x37 */
377   {  8, "L4=RD=Sb=" },		/* 0x38 */
378   {  9, "L4=RD=Sb=" },		/* 0x39 */
379   {  0, "L4=RD8<b+=Sb=" },	/* 0x3a */
380   {  1, "L4=RD8<b+=Sb=" },	/* 0x3b */
381   {  0, "L4=RD8<b+=Sd=" },	/* 0x3c */
382   {  1, "L4=RD8<b+=Sd=" },	/* 0x3d */
383   /* R_SHORT_PCREL_MODE.  */
384   {  0, "" },			/* 0x3e */
385   /* R_LONG_PCREL_MODE.  */
386   {  0, "" },			/* 0x3f */
387   /* R_ABS_CALL.  */
388   {  0, "L4=RD=Sb=" },		/* 0x40 */
389   {  1, "L4=RD=Sb=" },		/* 0x41 */
390   {  2, "L4=RD=Sb=" },		/* 0x42 */
391   {  3, "L4=RD=Sb=" },		/* 0x43 */
392   {  4, "L4=RD=Sb=" },		/* 0x44 */
393   {  5, "L4=RD=Sb=" },		/* 0x45 */
394   {  6, "L4=RD=Sb=" },		/* 0x46 */
395   {  7, "L4=RD=Sb=" },		/* 0x47 */
396   {  8, "L4=RD=Sb=" },		/* 0x48 */
397   {  9, "L4=RD=Sb=" },		/* 0x49 */
398   {  0, "L4=RD8<b+=Sb=" },	/* 0x4a */
399   {  1, "L4=RD8<b+=Sb=" },	/* 0x4b */
400   {  0, "L4=RD8<b+=Sd=" },	/* 0x4c */
401   {  1, "L4=RD8<b+=Sd=" },	/* 0x4d */
402   /* R_RESERVED.  */
403   {  0, "" },			/* 0x4e */
404   {  0, "" },			/* 0x4f */
405   /* R_DP_RELATIVE.  */
406   {  0, "L4=SD=" },		/* 0x50 */
407   {  1, "L4=SD=" },		/* 0x51 */
408   {  2, "L4=SD=" },		/* 0x52 */
409   {  3, "L4=SD=" },		/* 0x53 */
410   {  4, "L4=SD=" },		/* 0x54 */
411   {  5, "L4=SD=" },		/* 0x55 */
412   {  6, "L4=SD=" },		/* 0x56 */
413   {  7, "L4=SD=" },		/* 0x57 */
414   {  8, "L4=SD=" },		/* 0x58 */
415   {  9, "L4=SD=" },		/* 0x59 */
416   { 10, "L4=SD=" },		/* 0x5a */
417   { 11, "L4=SD=" },		/* 0x5b */
418   { 12, "L4=SD=" },		/* 0x5c */
419   { 13, "L4=SD=" },		/* 0x5d */
420   { 14, "L4=SD=" },		/* 0x5e */
421   { 15, "L4=SD=" },		/* 0x5f */
422   { 16, "L4=SD=" },		/* 0x60 */
423   { 17, "L4=SD=" },		/* 0x61 */
424   { 18, "L4=SD=" },		/* 0x62 */
425   { 19, "L4=SD=" },		/* 0x63 */
426   { 20, "L4=SD=" },		/* 0x64 */
427   { 21, "L4=SD=" },		/* 0x65 */
428   { 22, "L4=SD=" },		/* 0x66 */
429   { 23, "L4=SD=" },		/* 0x67 */
430   { 24, "L4=SD=" },		/* 0x68 */
431   { 25, "L4=SD=" },		/* 0x69 */
432   { 26, "L4=SD=" },		/* 0x6a */
433   { 27, "L4=SD=" },		/* 0x6b */
434   { 28, "L4=SD=" },		/* 0x6c */
435   { 29, "L4=SD=" },		/* 0x6d */
436   { 30, "L4=SD=" },		/* 0x6e */
437   { 31, "L4=SD=" },		/* 0x6f */
438   { 32, "L4=Sb=" },		/* 0x70 */
439   { 33, "L4=Sd=" },		/* 0x71 */
440   /* R_DATA_GPREL.  */
441   {  0, "L4=Sd=" },		/* 0x72 */
442   /* R_RESERVED.  */
443   {  0, "" },			/* 0x73 */
444   {  0, "" },			/* 0x74 */
445   {  0, "" },			/* 0x75 */
446   {  0, "" },			/* 0x76 */
447   {  0, "" },			/* 0x77 */
448   /* R_DLT_REL.  */
449   {  0, "L4=Sb=" },		/* 0x78 */
450   {  1, "L4=Sd=" },		/* 0x79 */
451   /* R_RESERVED.  */
452   {  0, "" },			/* 0x7a */
453   {  0, "" },			/* 0x7b */
454   {  0, "" },			/* 0x7c */
455   {  0, "" },			/* 0x7d */
456   {  0, "" },			/* 0x7e */
457   {  0, "" },			/* 0x7f */
458   /* R_CODE_ONE_SYMBOL.  */
459   {  0, "L4=SD=" },		/* 0x80 */
460   {  1, "L4=SD=" },		/* 0x81 */
461   {  2, "L4=SD=" },		/* 0x82 */
462   {  3, "L4=SD=" },		/* 0x83 */
463   {  4, "L4=SD=" },		/* 0x84 */
464   {  5, "L4=SD=" },		/* 0x85 */
465   {  6, "L4=SD=" },		/* 0x86 */
466   {  7, "L4=SD=" },		/* 0x87 */
467   {  8, "L4=SD=" },		/* 0x88 */
468   {  9, "L4=SD=" },		/* 0x89 */
469   { 10, "L4=SD=" },		/* 0x8q */
470   { 11, "L4=SD=" },		/* 0x8b */
471   { 12, "L4=SD=" },		/* 0x8c */
472   { 13, "L4=SD=" },		/* 0x8d */
473   { 14, "L4=SD=" },		/* 0x8e */
474   { 15, "L4=SD=" },		/* 0x8f */
475   { 16, "L4=SD=" },		/* 0x90 */
476   { 17, "L4=SD=" },		/* 0x91 */
477   { 18, "L4=SD=" },		/* 0x92 */
478   { 19, "L4=SD=" },		/* 0x93 */
479   { 20, "L4=SD=" },		/* 0x94 */
480   { 21, "L4=SD=" },		/* 0x95 */
481   { 22, "L4=SD=" },		/* 0x96 */
482   { 23, "L4=SD=" },		/* 0x97 */
483   { 24, "L4=SD=" },		/* 0x98 */
484   { 25, "L4=SD=" },		/* 0x99 */
485   { 26, "L4=SD=" },		/* 0x9a */
486   { 27, "L4=SD=" },		/* 0x9b */
487   { 28, "L4=SD=" },		/* 0x9c */
488   { 29, "L4=SD=" },		/* 0x9d */
489   { 30, "L4=SD=" },		/* 0x9e */
490   { 31, "L4=SD=" },		/* 0x9f */
491   { 32, "L4=Sb=" },		/* 0xa0 */
492   { 33, "L4=Sd=" },		/* 0xa1 */
493   /* R_RESERVED.  */
494   {  0, "" },			/* 0xa2 */
495   {  0, "" },			/* 0xa3 */
496   {  0, "" },			/* 0xa4 */
497   {  0, "" },			/* 0xa5 */
498   {  0, "" },			/* 0xa6 */
499   {  0, "" },			/* 0xa7 */
500   {  0, "" },			/* 0xa8 */
501   {  0, "" },			/* 0xa9 */
502   {  0, "" },			/* 0xaa */
503   {  0, "" },			/* 0xab */
504   {  0, "" },			/* 0xac */
505   {  0, "" },			/* 0xad */
506   /* R_MILLI_REL.  */
507   {  0, "L4=Sb=" },		/* 0xae */
508   {  1, "L4=Sd=" },		/* 0xaf */
509   /* R_CODE_PLABEL.  */
510   {  0, "L4=Sb=" },		/* 0xb0 */
511   {  1, "L4=Sd=" },		/* 0xb1 */
512   /* R_BREAKPOINT.  */
513   {  0, "L4=" },		/* 0xb2 */
514   /* R_ENTRY.  */
515   {  0, "Te=Ue=" },		/* 0xb3 */
516   {  1, "Uf=" },		/* 0xb4 */
517   /* R_ALT_ENTRY.  */
518   {  0, "" },			/* 0xb5 */
519   /* R_EXIT.  */
520   {  0, "" },			/* 0xb6 */
521   /* R_BEGIN_TRY.  */
522   {  0, "" },			/* 0xb7 */
523   /* R_END_TRY.  */
524   {  0, "R0=" },		/* 0xb8 */
525   {  1, "Rb4*=" },		/* 0xb9 */
526   {  2, "Rd4*=" },		/* 0xba */
527   /* R_BEGIN_BRTAB.  */
528   {  0, "" },			/* 0xbb */
529   /* R_END_BRTAB.  */
530   {  0, "" },			/* 0xbc */
531   /* R_STATEMENT.  */
532   {  0, "Nb=" },		/* 0xbd */
533   {  1, "Nc=" },		/* 0xbe */
534   {  2, "Nd=" },		/* 0xbf */
535   /* R_DATA_EXPR.  */
536   {  0, "L4=" },		/* 0xc0 */
537   /* R_CODE_EXPR.  */
538   {  0, "L4=" },		/* 0xc1 */
539   /* R_FSEL.  */
540   {  0, "" },			/* 0xc2 */
541   /* R_LSEL.  */
542   {  0, "" },			/* 0xc3 */
543   /* R_RSEL.  */
544   {  0, "" },			/* 0xc4 */
545   /* R_N_MODE.  */
546   {  0, "" },			/* 0xc5 */
547   /* R_S_MODE.  */
548   {  0, "" },			/* 0xc6 */
549   /* R_D_MODE.  */
550   {  0, "" },			/* 0xc7 */
551   /* R_R_MODE.  */
552   {  0, "" },			/* 0xc8 */
553   /* R_DATA_OVERRIDE.  */
554   {  0, "V0=" },		/* 0xc9 */
555   {  1, "Vb=" },		/* 0xca */
556   {  2, "Vc=" },		/* 0xcb */
557   {  3, "Vd=" },		/* 0xcc */
558   {  4, "Ve=" },		/* 0xcd */
559   /* R_TRANSLATED.  */
560   {  0, "" },			/* 0xce */
561   /* R_AUX_UNWIND.  */
562   {  0,"Sd=Ve=Ee=" },	       /* 0xcf */
563   /* R_COMP1.  */
564   {  0, "Ob=" },		/* 0xd0 */
565   /* R_COMP2.  */
566   {  0, "Ob=Sd=" },		/* 0xd1 */
567   /* R_COMP3.  */
568   {  0, "Ob=Ve=" },		/* 0xd2 */
569   /* R_PREV_FIXUP.  */
570   {  0, "P" },			/* 0xd3 */
571   {  1, "P" },			/* 0xd4 */
572   {  2, "P" },			/* 0xd5 */
573   {  3, "P" },			/* 0xd6 */
574   /* R_SEC_STMT.  */
575   {  0, "" },			/* 0xd7 */
576   /* R_N0SEL.  */
577   {  0, "" },			/* 0xd8 */
578   /* R_N1SEL.  */
579   {  0, "" },			/* 0xd9 */
580   /* R_LINETAB.  */
581   {  0, "Eb=Sd=Ve=" },		/* 0xda */
582   /* R_LINETAB_ESC.  */
583   {  0, "Eb=Mb=" },		/* 0xdb */
584   /* R_LTP_OVERRIDE.  */
585   {  0, "" },			/* 0xdc */
586   /* R_COMMENT.  */
587   {  0, "Ob=Vf=" },		/* 0xdd */
588   /* R_RESERVED.  */
589   {  0, "" },			/* 0xde */
590   {  0, "" },			/* 0xdf */
591   {  0, "" },			/* 0xe0 */
592   {  0, "" },			/* 0xe1 */
593   {  0, "" },			/* 0xe2 */
594   {  0, "" },			/* 0xe3 */
595   {  0, "" },			/* 0xe4 */
596   {  0, "" },			/* 0xe5 */
597   {  0, "" },			/* 0xe6 */
598   {  0, "" },			/* 0xe7 */
599   {  0, "" },			/* 0xe8 */
600   {  0, "" },			/* 0xe9 */
601   {  0, "" },			/* 0xea */
602   {  0, "" },			/* 0xeb */
603   {  0, "" },			/* 0xec */
604   {  0, "" },			/* 0xed */
605   {  0, "" },			/* 0xee */
606   {  0, "" },			/* 0xef */
607   {  0, "" },			/* 0xf0 */
608   {  0, "" },			/* 0xf1 */
609   {  0, "" },			/* 0xf2 */
610   {  0, "" },			/* 0xf3 */
611   {  0, "" },			/* 0xf4 */
612   {  0, "" },			/* 0xf5 */
613   {  0, "" },			/* 0xf6 */
614   {  0, "" },			/* 0xf7 */
615   {  0, "" },			/* 0xf8 */
616   {  0, "" },			/* 0xf9 */
617   {  0, "" },			/* 0xfa */
618   {  0, "" },			/* 0xfb */
619   {  0, "" },			/* 0xfc */
620   {  0, "" },			/* 0xfd */
621   {  0, "" },			/* 0xfe */
622   {  0, "" },			/* 0xff */
623 };
624 
625 static const int comp1_opcodes[] =
626 {
627   0x00,
628   0x40,
629   0x41,
630   0x42,
631   0x43,
632   0x44,
633   0x45,
634   0x46,
635   0x47,
636   0x48,
637   0x49,
638   0x4a,
639   0x4b,
640   0x60,
641   0x80,
642   0xa0,
643   0xc0,
644   -1
645 };
646 
647 static const int comp2_opcodes[] =
648 {
649   0x00,
650   0x80,
651   0x82,
652   0xc0,
653   -1
654 };
655 
656 static const int comp3_opcodes[] =
657 {
658   0x00,
659   0x02,
660   -1
661 };
662 
663 /* These apparently are not in older versions of hpux reloc.h (hpux7).  */
664 #ifndef R_DLT_REL
665 #define R_DLT_REL 0x78
666 #endif
667 
668 #ifndef R_AUX_UNWIND
669 #define R_AUX_UNWIND 0xcf
670 #endif
671 
672 #ifndef R_SEC_STMT
673 #define R_SEC_STMT 0xd7
674 #endif
675 
676 /* And these first appeared in hpux10.  */
677 #ifndef R_SHORT_PCREL_MODE
678 #define NO_PCREL_MODES
679 #define R_SHORT_PCREL_MODE 0x3e
680 #endif
681 
682 #ifndef R_LONG_PCREL_MODE
683 #define R_LONG_PCREL_MODE 0x3f
684 #endif
685 
686 #ifndef R_N0SEL
687 #define R_N0SEL 0xd8
688 #endif
689 
690 #ifndef R_N1SEL
691 #define R_N1SEL 0xd9
692 #endif
693 
694 #ifndef R_LINETAB
695 #define R_LINETAB 0xda
696 #endif
697 
698 #ifndef R_LINETAB_ESC
699 #define R_LINETAB_ESC 0xdb
700 #endif
701 
702 #ifndef R_LTP_OVERRIDE
703 #define R_LTP_OVERRIDE 0xdc
704 #endif
705 
706 #ifndef R_COMMENT
707 #define R_COMMENT 0xdd
708 #endif
709 
710 #define SOM_HOWTO(TYPE, NAME)	\
711   HOWTO(TYPE, 0, 0, 32, FALSE, 0, 0, hppa_som_reloc, NAME, FALSE, 0, 0, FALSE)
712 
713 static reloc_howto_type som_hppa_howto_table[] =
714 {
715   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
716   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
717   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
718   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
719   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
720   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
721   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
722   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
723   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
724   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
725   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
726   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
727   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
728   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
729   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
730   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
731   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
732   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
733   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
734   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
735   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
736   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
737   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
738   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
739   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
740   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
741   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
742   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
743   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
744   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
745   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
746   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
747   SOM_HOWTO (R_ZEROES, "R_ZEROES"),
748   SOM_HOWTO (R_ZEROES, "R_ZEROES"),
749   SOM_HOWTO (R_UNINIT, "R_UNINIT"),
750   SOM_HOWTO (R_UNINIT, "R_UNINIT"),
751   SOM_HOWTO (R_RELOCATION, "R_RELOCATION"),
752   SOM_HOWTO (R_DATA_ONE_SYMBOL, "R_DATA_ONE_SYMBOL"),
753   SOM_HOWTO (R_DATA_ONE_SYMBOL, "R_DATA_ONE_SYMBOL"),
754   SOM_HOWTO (R_DATA_PLABEL, "R_DATA_PLABEL"),
755   SOM_HOWTO (R_DATA_PLABEL, "R_DATA_PLABEL"),
756   SOM_HOWTO (R_SPACE_REF, "R_SPACE_REF"),
757   SOM_HOWTO (R_REPEATED_INIT, "REPEATED_INIT"),
758   SOM_HOWTO (R_REPEATED_INIT, "REPEATED_INIT"),
759   SOM_HOWTO (R_REPEATED_INIT, "REPEATED_INIT"),
760   SOM_HOWTO (R_REPEATED_INIT, "REPEATED_INIT"),
761   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
762   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
763   SOM_HOWTO (R_PCREL_CALL, "R_PCREL_CALL"),
764   SOM_HOWTO (R_PCREL_CALL, "R_PCREL_CALL"),
765   SOM_HOWTO (R_PCREL_CALL, "R_PCREL_CALL"),
766   SOM_HOWTO (R_PCREL_CALL, "R_PCREL_CALL"),
767   SOM_HOWTO (R_PCREL_CALL, "R_PCREL_CALL"),
768   SOM_HOWTO (R_PCREL_CALL, "R_PCREL_CALL"),
769   SOM_HOWTO (R_PCREL_CALL, "R_PCREL_CALL"),
770   SOM_HOWTO (R_PCREL_CALL, "R_PCREL_CALL"),
771   SOM_HOWTO (R_PCREL_CALL, "R_PCREL_CALL"),
772   SOM_HOWTO (R_PCREL_CALL, "R_PCREL_CALL"),
773   SOM_HOWTO (R_PCREL_CALL, "R_PCREL_CALL"),
774   SOM_HOWTO (R_PCREL_CALL, "R_PCREL_CALL"),
775   SOM_HOWTO (R_PCREL_CALL, "R_PCREL_CALL"),
776   SOM_HOWTO (R_PCREL_CALL, "R_PCREL_CALL"),
777   SOM_HOWTO (R_SHORT_PCREL_MODE, "R_SHORT_PCREL_MODE"),
778   SOM_HOWTO (R_LONG_PCREL_MODE, "R_LONG_PCREL_MODE"),
779   SOM_HOWTO (R_ABS_CALL, "R_ABS_CALL"),
780   SOM_HOWTO (R_ABS_CALL, "R_ABS_CALL"),
781   SOM_HOWTO (R_ABS_CALL, "R_ABS_CALL"),
782   SOM_HOWTO (R_ABS_CALL, "R_ABS_CALL"),
783   SOM_HOWTO (R_ABS_CALL, "R_ABS_CALL"),
784   SOM_HOWTO (R_ABS_CALL, "R_ABS_CALL"),
785   SOM_HOWTO (R_ABS_CALL, "R_ABS_CALL"),
786   SOM_HOWTO (R_ABS_CALL, "R_ABS_CALL"),
787   SOM_HOWTO (R_ABS_CALL, "R_ABS_CALL"),
788   SOM_HOWTO (R_ABS_CALL, "R_ABS_CALL"),
789   SOM_HOWTO (R_ABS_CALL, "R_ABS_CALL"),
790   SOM_HOWTO (R_ABS_CALL, "R_ABS_CALL"),
791   SOM_HOWTO (R_ABS_CALL, "R_ABS_CALL"),
792   SOM_HOWTO (R_ABS_CALL, "R_ABS_CALL"),
793   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
794   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
795   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
796   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
797   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
798   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
799   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
800   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
801   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
802   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
803   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
804   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
805   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
806   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
807   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
808   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
809   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
810   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
811   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
812   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
813   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
814   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
815   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
816   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
817   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
818   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
819   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
820   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
821   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
822   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
823   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
824   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
825   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
826   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
827   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
828   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
829   SOM_HOWTO (R_DATA_GPREL, "R_DATA_GPREL"),
830   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
831   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
832   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
833   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
834   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
835   SOM_HOWTO (R_DLT_REL, "R_DLT_REL"),
836   SOM_HOWTO (R_DLT_REL, "R_DLT_REL"),
837   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
838   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
839   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
840   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
841   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
842   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
843   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
844   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
845   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
846   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
847   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
848   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
849   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
850   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
851   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
852   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
853   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
854   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
855   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
856   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
857   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
858   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
859   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
860   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
861   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
862   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
863   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
864   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
865   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
866   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
867   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
868   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
869   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
870   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
871   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
872   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
873   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
874   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
875   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
876   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
877   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
878   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
879   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
880   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
881   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
882   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
883   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
884   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
885   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
886   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
887   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
888   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
889   SOM_HOWTO (R_MILLI_REL, "R_MILLI_REL"),
890   SOM_HOWTO (R_MILLI_REL, "R_MILLI_REL"),
891   SOM_HOWTO (R_CODE_PLABEL, "R_CODE_PLABEL"),
892   SOM_HOWTO (R_CODE_PLABEL, "R_CODE_PLABEL"),
893   SOM_HOWTO (R_BREAKPOINT, "R_BREAKPOINT"),
894   SOM_HOWTO (R_ENTRY, "R_ENTRY"),
895   SOM_HOWTO (R_ENTRY, "R_ENTRY"),
896   SOM_HOWTO (R_ALT_ENTRY, "R_ALT_ENTRY"),
897   SOM_HOWTO (R_EXIT, "R_EXIT"),
898   SOM_HOWTO (R_BEGIN_TRY, "R_BEGIN_TRY"),
899   SOM_HOWTO (R_END_TRY, "R_END_TRY"),
900   SOM_HOWTO (R_END_TRY, "R_END_TRY"),
901   SOM_HOWTO (R_END_TRY, "R_END_TRY"),
902   SOM_HOWTO (R_BEGIN_BRTAB, "R_BEGIN_BRTAB"),
903   SOM_HOWTO (R_END_BRTAB, "R_END_BRTAB"),
904   SOM_HOWTO (R_STATEMENT, "R_STATEMENT"),
905   SOM_HOWTO (R_STATEMENT, "R_STATEMENT"),
906   SOM_HOWTO (R_STATEMENT, "R_STATEMENT"),
907   SOM_HOWTO (R_DATA_EXPR, "R_DATA_EXPR"),
908   SOM_HOWTO (R_CODE_EXPR, "R_CODE_EXPR"),
909   SOM_HOWTO (R_FSEL, "R_FSEL"),
910   SOM_HOWTO (R_LSEL, "R_LSEL"),
911   SOM_HOWTO (R_RSEL, "R_RSEL"),
912   SOM_HOWTO (R_N_MODE, "R_N_MODE"),
913   SOM_HOWTO (R_S_MODE, "R_S_MODE"),
914   SOM_HOWTO (R_D_MODE, "R_D_MODE"),
915   SOM_HOWTO (R_R_MODE, "R_R_MODE"),
916   SOM_HOWTO (R_DATA_OVERRIDE, "R_DATA_OVERRIDE"),
917   SOM_HOWTO (R_DATA_OVERRIDE, "R_DATA_OVERRIDE"),
918   SOM_HOWTO (R_DATA_OVERRIDE, "R_DATA_OVERRIDE"),
919   SOM_HOWTO (R_DATA_OVERRIDE, "R_DATA_OVERRIDE"),
920   SOM_HOWTO (R_DATA_OVERRIDE, "R_DATA_OVERRIDE"),
921   SOM_HOWTO (R_TRANSLATED, "R_TRANSLATED"),
922   SOM_HOWTO (R_AUX_UNWIND, "R_AUX_UNWIND"),
923   SOM_HOWTO (R_COMP1, "R_COMP1"),
924   SOM_HOWTO (R_COMP2, "R_COMP2"),
925   SOM_HOWTO (R_COMP3, "R_COMP3"),
926   SOM_HOWTO (R_PREV_FIXUP, "R_PREV_FIXUP"),
927   SOM_HOWTO (R_PREV_FIXUP, "R_PREV_FIXUP"),
928   SOM_HOWTO (R_PREV_FIXUP, "R_PREV_FIXUP"),
929   SOM_HOWTO (R_PREV_FIXUP, "R_PREV_FIXUP"),
930   SOM_HOWTO (R_SEC_STMT, "R_SEC_STMT"),
931   SOM_HOWTO (R_N0SEL, "R_N0SEL"),
932   SOM_HOWTO (R_N1SEL, "R_N1SEL"),
933   SOM_HOWTO (R_LINETAB, "R_LINETAB"),
934   SOM_HOWTO (R_LINETAB_ESC, "R_LINETAB_ESC"),
935   SOM_HOWTO (R_LTP_OVERRIDE, "R_LTP_OVERRIDE"),
936   SOM_HOWTO (R_COMMENT, "R_COMMENT"),
937   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
938   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
939   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
940   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
941   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
942   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
943   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
944   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
945   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
946   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
947   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
948   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
949   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
950   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
951   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
952   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
953   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
954   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
955   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
956   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
957   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
958   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
959   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
960   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
961   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
962   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
963   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
964   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
965   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
966   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
967   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
968   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
969   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
970   SOM_HOWTO (R_RESERVED, "R_RESERVED")
971 };
972 
973 /* Initialize the SOM relocation queue.  By definition the queue holds
974    the last four multibyte fixups.  */
975 
976 static void
977 som_initialize_reloc_queue (struct reloc_queue *queue)
978 {
979   queue[0].reloc = NULL;
980   queue[0].size = 0;
981   queue[1].reloc = NULL;
982   queue[1].size = 0;
983   queue[2].reloc = NULL;
984   queue[2].size = 0;
985   queue[3].reloc = NULL;
986   queue[3].size = 0;
987 }
988 
989 /* Insert a new relocation into the relocation queue.  */
990 
991 static void
992 som_reloc_queue_insert (unsigned char *p,
993 			unsigned int size,
994 			struct reloc_queue *queue)
995 {
996   queue[3].reloc = queue[2].reloc;
997   queue[3].size = queue[2].size;
998   queue[2].reloc = queue[1].reloc;
999   queue[2].size = queue[1].size;
1000   queue[1].reloc = queue[0].reloc;
1001   queue[1].size = queue[0].size;
1002   queue[0].reloc = p;
1003   queue[0].size = size;
1004 }
1005 
1006 /* When an entry in the relocation queue is reused, the entry moves
1007    to the front of the queue.  */
1008 
1009 static void
1010 som_reloc_queue_fix (struct reloc_queue *queue, unsigned int index)
1011 {
1012   if (index == 0)
1013     return;
1014 
1015   if (index == 1)
1016     {
1017       unsigned char *tmp1 = queue[0].reloc;
1018       unsigned int tmp2 = queue[0].size;
1019 
1020       queue[0].reloc = queue[1].reloc;
1021       queue[0].size = queue[1].size;
1022       queue[1].reloc = tmp1;
1023       queue[1].size = tmp2;
1024       return;
1025     }
1026 
1027   if (index == 2)
1028     {
1029       unsigned char *tmp1 = queue[0].reloc;
1030       unsigned int tmp2 = queue[0].size;
1031 
1032       queue[0].reloc = queue[2].reloc;
1033       queue[0].size = queue[2].size;
1034       queue[2].reloc = queue[1].reloc;
1035       queue[2].size = queue[1].size;
1036       queue[1].reloc = tmp1;
1037       queue[1].size = tmp2;
1038       return;
1039     }
1040 
1041   if (index == 3)
1042     {
1043       unsigned char *tmp1 = queue[0].reloc;
1044       unsigned int tmp2 = queue[0].size;
1045 
1046       queue[0].reloc = queue[3].reloc;
1047       queue[0].size = queue[3].size;
1048       queue[3].reloc = queue[2].reloc;
1049       queue[3].size = queue[2].size;
1050       queue[2].reloc = queue[1].reloc;
1051       queue[2].size = queue[1].size;
1052       queue[1].reloc = tmp1;
1053       queue[1].size = tmp2;
1054       return;
1055     }
1056   abort ();
1057 }
1058 
1059 /* Search for a particular relocation in the relocation queue.  */
1060 
1061 static int
1062 som_reloc_queue_find (unsigned char *p,
1063 		      unsigned int size,
1064 		      struct reloc_queue *queue)
1065 {
1066   if (queue[0].reloc && !memcmp (p, queue[0].reloc, size)
1067       && size == queue[0].size)
1068     return 0;
1069   if (queue[1].reloc && !memcmp (p, queue[1].reloc, size)
1070       && size == queue[1].size)
1071     return 1;
1072   if (queue[2].reloc && !memcmp (p, queue[2].reloc, size)
1073       && size == queue[2].size)
1074     return 2;
1075   if (queue[3].reloc && !memcmp (p, queue[3].reloc, size)
1076       && size == queue[3].size)
1077     return 3;
1078   return -1;
1079 }
1080 
1081 static unsigned char *
1082 try_prev_fixup (bfd *abfd ATTRIBUTE_UNUSED,
1083 		unsigned int *subspace_reloc_sizep,
1084 		unsigned char *p,
1085 		unsigned int size,
1086 		struct reloc_queue *queue)
1087 {
1088   int queue_index = som_reloc_queue_find (p, size, queue);
1089 
1090   if (queue_index != -1)
1091     {
1092       /* Found this in a previous fixup.  Undo the fixup we
1093 	 just built and use R_PREV_FIXUP instead.  We saved
1094 	 a total of size - 1 bytes in the fixup stream.  */
1095       bfd_put_8 (abfd, R_PREV_FIXUP + queue_index, p);
1096       p += 1;
1097       *subspace_reloc_sizep += 1;
1098       som_reloc_queue_fix (queue, queue_index);
1099     }
1100   else
1101     {
1102       som_reloc_queue_insert (p, size, queue);
1103       *subspace_reloc_sizep += size;
1104       p += size;
1105     }
1106   return p;
1107 }
1108 
1109 /* Emit the proper R_NO_RELOCATION fixups to map the next SKIP
1110    bytes without any relocation.  Update the size of the subspace
1111    relocation stream via SUBSPACE_RELOC_SIZE_P; also return the
1112    current pointer into the relocation stream.  */
1113 
1114 static unsigned char *
1115 som_reloc_skip (bfd *abfd,
1116 		unsigned int skip,
1117 		unsigned char *p,
1118 		unsigned int *subspace_reloc_sizep,
1119 		struct reloc_queue *queue)
1120 {
1121   /* Use a 4 byte R_NO_RELOCATION entry with a maximal value
1122      then R_PREV_FIXUPs to get the difference down to a
1123      reasonable size.  */
1124   if (skip >= 0x1000000)
1125     {
1126       skip -= 0x1000000;
1127       bfd_put_8 (abfd, R_NO_RELOCATION + 31, p);
1128       bfd_put_8 (abfd, 0xff, p + 1);
1129       bfd_put_16 (abfd, (bfd_vma) 0xffff, p + 2);
1130       p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 4, queue);
1131       while (skip >= 0x1000000)
1132 	{
1133 	  skip -= 0x1000000;
1134 	  bfd_put_8 (abfd, R_PREV_FIXUP, p);
1135 	  p++;
1136 	  *subspace_reloc_sizep += 1;
1137 	  /* No need to adjust queue here since we are repeating the
1138 	     most recent fixup.  */
1139 	}
1140     }
1141 
1142   /* The difference must be less than 0x1000000.  Use one
1143      more R_NO_RELOCATION entry to get to the right difference.  */
1144   if ((skip & 3) == 0 && skip <= 0xc0000 && skip > 0)
1145     {
1146       /* Difference can be handled in a simple single-byte
1147 	 R_NO_RELOCATION entry.  */
1148       if (skip <= 0x60)
1149 	{
1150 	  bfd_put_8 (abfd, R_NO_RELOCATION + (skip >> 2) - 1, p);
1151 	  *subspace_reloc_sizep += 1;
1152 	  p++;
1153 	}
1154       /* Handle it with a two byte R_NO_RELOCATION entry.  */
1155       else if (skip <= 0x1000)
1156 	{
1157 	  bfd_put_8 (abfd, R_NO_RELOCATION + 24 + (((skip >> 2) - 1) >> 8), p);
1158 	  bfd_put_8 (abfd, (skip >> 2) - 1, p + 1);
1159 	  p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 2, queue);
1160 	}
1161       /* Handle it with a three byte R_NO_RELOCATION entry.  */
1162       else
1163 	{
1164 	  bfd_put_8 (abfd, R_NO_RELOCATION + 28 + (((skip >> 2) - 1) >> 16), p);
1165 	  bfd_put_16 (abfd, (bfd_vma) (skip >> 2) - 1, p + 1);
1166 	  p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 3, queue);
1167 	}
1168     }
1169   /* Ugh.  Punt and use a 4 byte entry.  */
1170   else if (skip > 0)
1171     {
1172       bfd_put_8 (abfd, R_NO_RELOCATION + 31, p);
1173       bfd_put_8 (abfd, (skip - 1) >> 16, p + 1);
1174       bfd_put_16 (abfd, (bfd_vma) skip - 1, p + 2);
1175       p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 4, queue);
1176     }
1177   return p;
1178 }
1179 
1180 /* Emit the proper R_DATA_OVERRIDE fixups to handle a nonzero addend
1181    from a BFD relocation.  Update the size of the subspace relocation
1182    stream via SUBSPACE_RELOC_SIZE_P; also return the current pointer
1183    into the relocation stream.  */
1184 
1185 static unsigned char *
1186 som_reloc_addend (bfd *abfd,
1187 		  bfd_vma addend,
1188 		  unsigned char *p,
1189 		  unsigned int *subspace_reloc_sizep,
1190 		  struct reloc_queue *queue)
1191 {
1192   if (addend + 0x80 < 0x100)
1193     {
1194       bfd_put_8 (abfd, R_DATA_OVERRIDE + 1, p);
1195       bfd_put_8 (abfd, addend, p + 1);
1196       p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 2, queue);
1197     }
1198   else if (addend + 0x8000 < 0x10000)
1199     {
1200       bfd_put_8 (abfd, R_DATA_OVERRIDE + 2, p);
1201       bfd_put_16 (abfd, addend, p + 1);
1202       p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 3, queue);
1203     }
1204   else if (addend + 0x800000 < 0x1000000)
1205     {
1206       bfd_put_8 (abfd, R_DATA_OVERRIDE + 3, p);
1207       bfd_put_8 (abfd, addend >> 16, p + 1);
1208       bfd_put_16 (abfd, addend, p + 2);
1209       p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 4, queue);
1210     }
1211   else
1212     {
1213       bfd_put_8 (abfd, R_DATA_OVERRIDE + 4, p);
1214       bfd_put_32 (abfd, addend, p + 1);
1215       p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 5, queue);
1216     }
1217   return p;
1218 }
1219 
1220 /* Handle a single function call relocation.  */
1221 
1222 static unsigned char *
1223 som_reloc_call (bfd *abfd,
1224 		unsigned char *p,
1225 		unsigned int *subspace_reloc_sizep,
1226 		arelent *bfd_reloc,
1227 		int sym_num,
1228 		struct reloc_queue *queue)
1229 {
1230   int arg_bits = HPPA_R_ARG_RELOC (bfd_reloc->addend);
1231   int rtn_bits = arg_bits & 0x3;
1232   int type, done = 0;
1233 
1234   /* You'll never believe all this is necessary to handle relocations
1235      for function calls.  Having to compute and pack the argument
1236      relocation bits is the real nightmare.
1237 
1238      If you're interested in how this works, just forget it.  You really
1239      do not want to know about this braindamage.  */
1240 
1241   /* First see if this can be done with a "simple" relocation.  Simple
1242      relocations have a symbol number < 0x100 and have simple encodings
1243      of argument relocations.  */
1244 
1245   if (sym_num < 0x100)
1246     {
1247       switch (arg_bits)
1248 	{
1249 	case 0:
1250 	case 1:
1251 	  type = 0;
1252 	  break;
1253 	case 1 << 8:
1254 	case 1 << 8 | 1:
1255 	  type = 1;
1256 	  break;
1257 	case 1 << 8 | 1 << 6:
1258 	case 1 << 8 | 1 << 6 | 1:
1259 	  type = 2;
1260 	  break;
1261 	case 1 << 8 | 1 << 6 | 1 << 4:
1262 	case 1 << 8 | 1 << 6 | 1 << 4 | 1:
1263 	  type = 3;
1264 	  break;
1265 	case 1 << 8 | 1 << 6 | 1 << 4 | 1 << 2:
1266 	case 1 << 8 | 1 << 6 | 1 << 4 | 1 << 2 | 1:
1267 	  type = 4;
1268 	  break;
1269 	default:
1270 	  /* Not one of the easy encodings.  This will have to be
1271 	     handled by the more complex code below.  */
1272 	  type = -1;
1273 	  break;
1274 	}
1275       if (type != -1)
1276 	{
1277 	  /* Account for the return value too.  */
1278 	  if (rtn_bits)
1279 	    type += 5;
1280 
1281 	  /* Emit a 2 byte relocation.  Then see if it can be handled
1282 	     with a relocation which is already in the relocation queue.  */
1283 	  bfd_put_8 (abfd, bfd_reloc->howto->type + type, p);
1284 	  bfd_put_8 (abfd, sym_num, p + 1);
1285 	  p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 2, queue);
1286 	  done = 1;
1287 	}
1288     }
1289 
1290   /* If this could not be handled with a simple relocation, then do a hard
1291      one.  Hard relocations occur if the symbol number was too high or if
1292      the encoding of argument relocation bits is too complex.  */
1293   if (! done)
1294     {
1295       /* Don't ask about these magic sequences.  I took them straight
1296 	 from gas-1.36 which took them from the a.out man page.  */
1297       type = rtn_bits;
1298       if ((arg_bits >> 6 & 0xf) == 0xe)
1299 	type += 9 * 40;
1300       else
1301 	type += (3 * (arg_bits >> 8 & 3) + (arg_bits >> 6 & 3)) * 40;
1302       if ((arg_bits >> 2 & 0xf) == 0xe)
1303 	type += 9 * 4;
1304       else
1305 	type += (3 * (arg_bits >> 4 & 3) + (arg_bits >> 2 & 3)) * 4;
1306 
1307       /* Output the first two bytes of the relocation.  These describe
1308 	 the length of the relocation and encoding style.  */
1309       bfd_put_8 (abfd, bfd_reloc->howto->type + 10
1310 		 + 2 * (sym_num >= 0x100) + (type >= 0x100),
1311 		 p);
1312       bfd_put_8 (abfd, type, p + 1);
1313 
1314       /* Now output the symbol index and see if this bizarre relocation
1315 	 just happened to be in the relocation queue.  */
1316       if (sym_num < 0x100)
1317 	{
1318 	  bfd_put_8 (abfd, sym_num, p + 2);
1319 	  p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 3, queue);
1320 	}
1321       else
1322 	{
1323 	  bfd_put_8 (abfd, sym_num >> 16, p + 2);
1324 	  bfd_put_16 (abfd, (bfd_vma) sym_num, p + 3);
1325 	  p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 5, queue);
1326 	}
1327     }
1328   return p;
1329 }
1330 
1331 /* Return the logarithm of X, base 2, considering X unsigned,
1332    if X is a power of 2.  Otherwise, returns -1.  */
1333 
1334 static int
1335 exact_log2 (unsigned int x)
1336 {
1337   int log = 0;
1338 
1339   /* Test for 0 or a power of 2.  */
1340   if (x == 0 || x != (x & -x))
1341     return -1;
1342 
1343   while ((x >>= 1) != 0)
1344     log++;
1345   return log;
1346 }
1347 
1348 static bfd_reloc_status_type
1349 hppa_som_reloc (bfd *abfd ATTRIBUTE_UNUSED,
1350 		arelent *reloc_entry,
1351 		asymbol *symbol_in ATTRIBUTE_UNUSED,
1352 		void *data ATTRIBUTE_UNUSED,
1353 		asection *input_section,
1354 		bfd *output_bfd,
1355 		char **error_message ATTRIBUTE_UNUSED)
1356 {
1357   if (output_bfd)
1358     reloc_entry->address += input_section->output_offset;
1359 
1360   return bfd_reloc_ok;
1361 }
1362 
1363 /* Given a generic HPPA relocation type, the instruction format,
1364    and a field selector, return one or more appropriate SOM relocations.  */
1365 
1366 int **
1367 hppa_som_gen_reloc_type (bfd *abfd,
1368 			 int base_type,
1369 			 int format,
1370 			 enum hppa_reloc_field_selector_type_alt field,
1371 			 int sym_diff,
1372 			 asymbol *sym)
1373 {
1374   int *final_type, **final_types;
1375 
1376   final_types = bfd_alloc (abfd, (bfd_size_type) sizeof (int *) * 6);
1377   final_type = bfd_alloc (abfd, (bfd_size_type) sizeof (int));
1378   if (!final_types || !final_type)
1379     return NULL;
1380 
1381   /* The field selector may require additional relocations to be
1382      generated.  It's impossible to know at this moment if additional
1383      relocations will be needed, so we make them.  The code to actually
1384      write the relocation/fixup stream is responsible for removing
1385      any redundant relocations.  */
1386   switch (field)
1387     {
1388     case e_fsel:
1389     case e_psel:
1390     case e_lpsel:
1391     case e_rpsel:
1392       final_types[0] = final_type;
1393       final_types[1] = NULL;
1394       final_types[2] = NULL;
1395       *final_type = base_type;
1396       break;
1397 
1398     case e_tsel:
1399     case e_ltsel:
1400     case e_rtsel:
1401       final_types[0] = bfd_alloc (abfd, (bfd_size_type) sizeof (int));
1402       if (!final_types[0])
1403 	return NULL;
1404       if (field == e_tsel)
1405 	*final_types[0] = R_FSEL;
1406       else if (field == e_ltsel)
1407 	*final_types[0] = R_LSEL;
1408       else
1409 	*final_types[0] = R_RSEL;
1410       final_types[1] = final_type;
1411       final_types[2] = NULL;
1412       *final_type = base_type;
1413       break;
1414 
1415     case e_lssel:
1416     case e_rssel:
1417       final_types[0] = bfd_alloc (abfd, (bfd_size_type) sizeof (int));
1418       if (!final_types[0])
1419 	return NULL;
1420       *final_types[0] = R_S_MODE;
1421       final_types[1] = final_type;
1422       final_types[2] = NULL;
1423       *final_type = base_type;
1424       break;
1425 
1426     case e_lsel:
1427     case e_rsel:
1428       final_types[0] = bfd_alloc (abfd, (bfd_size_type) sizeof (int));
1429       if (!final_types[0])
1430 	return NULL;
1431       *final_types[0] = R_N_MODE;
1432       final_types[1] = final_type;
1433       final_types[2] = NULL;
1434       *final_type = base_type;
1435       break;
1436 
1437     case e_ldsel:
1438     case e_rdsel:
1439       final_types[0] = bfd_alloc (abfd, (bfd_size_type) sizeof (int));
1440       if (!final_types[0])
1441 	return NULL;
1442       *final_types[0] = R_D_MODE;
1443       final_types[1] = final_type;
1444       final_types[2] = NULL;
1445       *final_type = base_type;
1446       break;
1447 
1448     case e_lrsel:
1449     case e_rrsel:
1450       final_types[0] = bfd_alloc (abfd, (bfd_size_type) sizeof (int));
1451       if (!final_types[0])
1452 	return NULL;
1453       *final_types[0] = R_R_MODE;
1454       final_types[1] = final_type;
1455       final_types[2] = NULL;
1456       *final_type = base_type;
1457       break;
1458 
1459     case e_nsel:
1460       final_types[0] = bfd_alloc (abfd, (bfd_size_type) sizeof (int));
1461       if (!final_types[0])
1462 	return NULL;
1463       *final_types[0] = R_N1SEL;
1464       final_types[1] = final_type;
1465       final_types[2] = NULL;
1466       *final_type = base_type;
1467       break;
1468 
1469     case e_nlsel:
1470     case e_nlrsel:
1471       final_types[0] = bfd_alloc (abfd, (bfd_size_type) sizeof (int));
1472       if (!final_types[0])
1473 	return NULL;
1474       *final_types[0] = R_N0SEL;
1475       final_types[1] = bfd_alloc (abfd, (bfd_size_type) sizeof (int));
1476       if (!final_types[1])
1477 	return NULL;
1478       if (field == e_nlsel)
1479 	*final_types[1] = R_N_MODE;
1480       else
1481 	*final_types[1] = R_R_MODE;
1482       final_types[2] = final_type;
1483       final_types[3] = NULL;
1484       *final_type = base_type;
1485       break;
1486 
1487     /* FIXME: These two field selectors are not currently supported.  */
1488     case e_ltpsel:
1489     case e_rtpsel:
1490       abort ();
1491     }
1492 
1493   switch (base_type)
1494     {
1495     case R_HPPA:
1496       /* The difference of two symbols needs *very* special handling.  */
1497       if (sym_diff)
1498 	{
1499 	  bfd_size_type amt = sizeof (int);
1500 
1501 	  final_types[0] = bfd_alloc (abfd, amt);
1502 	  final_types[1] = bfd_alloc (abfd, amt);
1503 	  final_types[2] = bfd_alloc (abfd, amt);
1504 	  final_types[3] = bfd_alloc (abfd, amt);
1505 	  if (!final_types[0] || !final_types[1] || !final_types[2])
1506 	    return NULL;
1507 	  if (field == e_fsel)
1508 	    *final_types[0] = R_FSEL;
1509 	  else if (field == e_rsel)
1510 	    *final_types[0] = R_RSEL;
1511 	  else if (field == e_lsel)
1512 	    *final_types[0] = R_LSEL;
1513 	  *final_types[1] = R_COMP2;
1514 	  *final_types[2] = R_COMP2;
1515 	  *final_types[3] = R_COMP1;
1516 	  final_types[4] = final_type;
1517 	  if (format == 32)
1518 	    *final_types[4] = R_DATA_EXPR;
1519 	  else
1520 	    *final_types[4] = R_CODE_EXPR;
1521 	  final_types[5] = NULL;
1522 	  break;
1523 	}
1524       /* PLABELs get their own relocation type.  */
1525       else if (field == e_psel
1526 	       || field == e_lpsel
1527 	       || field == e_rpsel)
1528 	{
1529 	  /* A PLABEL relocation that has a size of 32 bits must
1530 	     be a R_DATA_PLABEL.  All others are R_CODE_PLABELs.  */
1531 	  if (format == 32)
1532 	    *final_type = R_DATA_PLABEL;
1533 	  else
1534 	    *final_type = R_CODE_PLABEL;
1535 	}
1536       /* PIC stuff.  */
1537       else if (field == e_tsel
1538 	       || field == e_ltsel
1539 	       || field == e_rtsel)
1540 	*final_type = R_DLT_REL;
1541       /* A relocation in the data space is always a full 32bits.  */
1542       else if (format == 32)
1543 	{
1544 	  *final_type = R_DATA_ONE_SYMBOL;
1545 
1546 	  /* If there's no SOM symbol type associated with this BFD
1547 	     symbol, then set the symbol type to ST_DATA.
1548 
1549 	     Only do this if the type is going to default later when
1550 	     we write the object file.
1551 
1552 	     This is done so that the linker never encounters an
1553 	     R_DATA_ONE_SYMBOL reloc involving an ST_CODE symbol.
1554 
1555 	     This allows the compiler to generate exception handling
1556 	     tables.
1557 
1558 	     Note that one day we may need to also emit BEGIN_BRTAB and
1559 	     END_BRTAB to prevent the linker from optimizing away insns
1560 	     in exception handling regions.  */
1561 	  if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_UNKNOWN
1562 	      && (sym->flags & BSF_SECTION_SYM) == 0
1563 	      && (sym->flags & BSF_FUNCTION) == 0
1564 	      && ! bfd_is_com_section (sym->section))
1565 	    som_symbol_data (sym)->som_type = SYMBOL_TYPE_DATA;
1566 	}
1567       break;
1568 
1569     case R_HPPA_GOTOFF:
1570       /* More PLABEL special cases.  */
1571       if (field == e_psel
1572 	  || field == e_lpsel
1573 	  || field == e_rpsel)
1574 	*final_type = R_DATA_PLABEL;
1575       else if (field == e_fsel && format == 32)
1576 	*final_type = R_DATA_GPREL;
1577       break;
1578 
1579     case R_HPPA_COMPLEX:
1580       /* The difference of two symbols needs *very* special handling.  */
1581       if (sym_diff)
1582 	{
1583 	  bfd_size_type amt = sizeof (int);
1584 
1585 	  final_types[0] = bfd_alloc (abfd, amt);
1586 	  final_types[1] = bfd_alloc (abfd, amt);
1587 	  final_types[2] = bfd_alloc (abfd, amt);
1588 	  final_types[3] = bfd_alloc (abfd, amt);
1589 	  if (!final_types[0] || !final_types[1] || !final_types[2])
1590 	    return NULL;
1591 	  if (field == e_fsel)
1592 	    *final_types[0] = R_FSEL;
1593 	  else if (field == e_rsel)
1594 	    *final_types[0] = R_RSEL;
1595 	  else if (field == e_lsel)
1596 	    *final_types[0] = R_LSEL;
1597 	  *final_types[1] = R_COMP2;
1598 	  *final_types[2] = R_COMP2;
1599 	  *final_types[3] = R_COMP1;
1600 	  final_types[4] = final_type;
1601 	  if (format == 32)
1602 	    *final_types[4] = R_DATA_EXPR;
1603 	  else
1604 	    *final_types[4] = R_CODE_EXPR;
1605 	  final_types[5] = NULL;
1606 	  break;
1607 	}
1608       else
1609 	break;
1610 
1611     case R_HPPA_NONE:
1612     case R_HPPA_ABS_CALL:
1613       /* Right now we can default all these.  */
1614       break;
1615 
1616     case R_HPPA_PCREL_CALL:
1617       {
1618 #ifndef NO_PCREL_MODES
1619 	/* If we have short and long pcrel modes, then generate the proper
1620 	   mode selector, then the pcrel relocation.  Redundant selectors
1621 	   will be eliminated as the relocs are sized and emitted.  */
1622 	bfd_size_type amt = sizeof (int);
1623 
1624 	final_types[0] = bfd_alloc (abfd, amt);
1625 	if (!final_types[0])
1626 	  return NULL;
1627 	if (format == 17)
1628 	  *final_types[0] = R_SHORT_PCREL_MODE;
1629 	else
1630 	  *final_types[0] = R_LONG_PCREL_MODE;
1631 	final_types[1] = final_type;
1632 	final_types[2] = NULL;
1633 	*final_type = base_type;
1634 #endif
1635 	break;
1636       }
1637     }
1638   return final_types;
1639 }
1640 
1641 /* Return the address of the correct entry in the PA SOM relocation
1642    howto table.  */
1643 
1644 static reloc_howto_type *
1645 som_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1646 			   bfd_reloc_code_real_type code)
1647 {
1648   if ((int) code < (int) R_NO_RELOCATION + 255)
1649     {
1650       BFD_ASSERT ((int) som_hppa_howto_table[(int) code].type == (int) code);
1651       return &som_hppa_howto_table[(int) code];
1652     }
1653 
1654   return NULL;
1655 }
1656 
1657 static reloc_howto_type *
1658 som_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1659 			   const char *r_name)
1660 {
1661   unsigned int i;
1662 
1663   for (i = 0;
1664        i < sizeof (som_hppa_howto_table) / sizeof (som_hppa_howto_table[0]);
1665        i++)
1666     if (som_hppa_howto_table[i].name != NULL
1667 	&& strcasecmp (som_hppa_howto_table[i].name, r_name) == 0)
1668       return &som_hppa_howto_table[i];
1669 
1670   return NULL;
1671 }
1672 
1673 /* Perform some initialization for an object.  Save results of this
1674    initialization in the BFD.  */
1675 
1676 static const bfd_target *
1677 som_object_setup (bfd *abfd,
1678 		  struct header *file_hdrp,
1679 		  struct som_exec_auxhdr *aux_hdrp,
1680 		  unsigned long current_offset)
1681 {
1682   asection *section;
1683 
1684   /* som_mkobject will set bfd_error if som_mkobject fails.  */
1685   if (! som_mkobject (abfd))
1686     return NULL;
1687 
1688   /* Set BFD flags based on what information is available in the SOM.  */
1689   abfd->flags = BFD_NO_FLAGS;
1690   if (file_hdrp->symbol_total)
1691     abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
1692 
1693   switch (file_hdrp->a_magic)
1694     {
1695     case DEMAND_MAGIC:
1696       abfd->flags |= (D_PAGED | WP_TEXT | EXEC_P);
1697       break;
1698     case SHARE_MAGIC:
1699       abfd->flags |= (WP_TEXT | EXEC_P);
1700       break;
1701     case EXEC_MAGIC:
1702       abfd->flags |= (EXEC_P);
1703       break;
1704     case RELOC_MAGIC:
1705       abfd->flags |= HAS_RELOC;
1706       break;
1707 #ifdef SHL_MAGIC
1708     case SHL_MAGIC:
1709 #endif
1710 #ifdef DL_MAGIC
1711     case DL_MAGIC:
1712 #endif
1713       abfd->flags |= DYNAMIC;
1714       break;
1715 
1716     default:
1717       break;
1718     }
1719 
1720   /* Save the auxiliary header.  */
1721   obj_som_exec_hdr (abfd) = aux_hdrp;
1722 
1723   /* Allocate space to hold the saved exec header information.  */
1724   obj_som_exec_data (abfd) = bfd_zalloc (abfd, (bfd_size_type) sizeof (struct som_exec_data));
1725   if (obj_som_exec_data (abfd) == NULL)
1726     return NULL;
1727 
1728   /* The braindamaged OSF1 linker switched exec_flags and exec_entry!
1729 
1730      We used to identify OSF1 binaries based on NEW_VERSION_ID, but
1731      apparently the latest HPUX linker is using NEW_VERSION_ID now.
1732 
1733      It's about time, OSF has used the new id since at least 1992;
1734      HPUX didn't start till nearly 1995!.
1735 
1736      The new approach examines the entry field for an executable.  If
1737      it is not 4-byte aligned then it's not a proper code address and
1738      we guess it's really the executable flags.  For a main program,
1739      we also consider zero to be indicative of a buggy linker, since
1740      that is not a valid entry point.  The entry point for a shared
1741      library, however, can be zero so we do not consider that to be
1742      indicative of a buggy linker.  */
1743   if (aux_hdrp)
1744     {
1745       int found = 0;
1746 
1747       for (section = abfd->sections; section; section = section->next)
1748 	{
1749 	  bfd_vma entry;
1750 
1751 	  if ((section->flags & SEC_CODE) == 0)
1752 	    continue;
1753 	  entry = aux_hdrp->exec_entry + aux_hdrp->exec_tmem;
1754 	  if (entry >= section->vma
1755 	      && entry < section->vma + section->size)
1756 	    found = 1;
1757 	}
1758       if ((aux_hdrp->exec_entry == 0 && !(abfd->flags & DYNAMIC))
1759 	  || (aux_hdrp->exec_entry & 0x3) != 0
1760 	  || ! found)
1761 	{
1762 	  bfd_get_start_address (abfd) = aux_hdrp->exec_flags;
1763 	  obj_som_exec_data (abfd)->exec_flags = aux_hdrp->exec_entry;
1764 	}
1765       else
1766 	{
1767 	  bfd_get_start_address (abfd) = aux_hdrp->exec_entry + current_offset;
1768 	  obj_som_exec_data (abfd)->exec_flags = aux_hdrp->exec_flags;
1769 	}
1770     }
1771 
1772   obj_som_exec_data (abfd)->version_id = file_hdrp->version_id;
1773 
1774   bfd_default_set_arch_mach (abfd, bfd_arch_hppa, pa10);
1775   bfd_get_symcount (abfd) = file_hdrp->symbol_total;
1776 
1777   /* Initialize the saved symbol table and string table to NULL.
1778      Save important offsets and sizes from the SOM header into
1779      the BFD.  */
1780   obj_som_stringtab (abfd) = NULL;
1781   obj_som_symtab (abfd) = NULL;
1782   obj_som_sorted_syms (abfd) = NULL;
1783   obj_som_stringtab_size (abfd) = file_hdrp->symbol_strings_size;
1784   obj_som_sym_filepos (abfd) = file_hdrp->symbol_location + current_offset;
1785   obj_som_str_filepos (abfd) = (file_hdrp->symbol_strings_location
1786 				+ current_offset);
1787   obj_som_reloc_filepos (abfd) = (file_hdrp->fixup_request_location
1788 				  + current_offset);
1789   obj_som_exec_data (abfd)->system_id = file_hdrp->system_id;
1790 
1791   return abfd->xvec;
1792 }
1793 
1794 /* Convert all of the space and subspace info into BFD sections.  Each space
1795    contains a number of subspaces, which in turn describe the mapping between
1796    regions of the exec file, and the address space that the program runs in.
1797    BFD sections which correspond to spaces will overlap the sections for the
1798    associated subspaces.  */
1799 
1800 static bfd_boolean
1801 setup_sections (bfd *abfd,
1802 		struct header *file_hdr,
1803 		unsigned long current_offset)
1804 {
1805   char *space_strings;
1806   unsigned int space_index, i;
1807   unsigned int total_subspaces = 0;
1808   asection **subspace_sections = NULL;
1809   asection *section;
1810   bfd_size_type amt;
1811 
1812   /* First, read in space names.  */
1813   amt = file_hdr->space_strings_size;
1814   space_strings = bfd_malloc (amt);
1815   if (!space_strings && amt != 0)
1816     goto error_return;
1817 
1818   if (bfd_seek (abfd, current_offset + file_hdr->space_strings_location,
1819 		SEEK_SET) != 0)
1820     goto error_return;
1821   if (bfd_bread (space_strings, amt, abfd) != amt)
1822     goto error_return;
1823 
1824   /* Loop over all of the space dictionaries, building up sections.  */
1825   for (space_index = 0; space_index < file_hdr->space_total; space_index++)
1826     {
1827       struct space_dictionary_record space;
1828       struct som_subspace_dictionary_record subspace, save_subspace;
1829       unsigned int subspace_index;
1830       asection *space_asect;
1831       bfd_size_type space_size = 0;
1832       char *newname;
1833 
1834       /* Read the space dictionary element.  */
1835       if (bfd_seek (abfd,
1836 		    (current_offset + file_hdr->space_location
1837 		     + space_index * sizeof space),
1838 		    SEEK_SET) != 0)
1839 	goto error_return;
1840       amt = sizeof space;
1841       if (bfd_bread (&space, amt, abfd) != amt)
1842 	goto error_return;
1843 
1844       /* Setup the space name string.  */
1845       space.name.n_name = space.name.n_strx + space_strings;
1846 
1847       /* Make a section out of it.  */
1848       amt = strlen (space.name.n_name) + 1;
1849       newname = bfd_alloc (abfd, amt);
1850       if (!newname)
1851 	goto error_return;
1852       strcpy (newname, space.name.n_name);
1853 
1854       space_asect = bfd_make_section_anyway (abfd, newname);
1855       if (!space_asect)
1856 	goto error_return;
1857 
1858       if (space.is_loadable == 0)
1859 	space_asect->flags |= SEC_DEBUGGING;
1860 
1861       /* Set up all the attributes for the space.  */
1862       if (! bfd_som_set_section_attributes (space_asect, space.is_defined,
1863 					    space.is_private, space.sort_key,
1864 					    space.space_number))
1865 	goto error_return;
1866 
1867       /* If the space has no subspaces, then we're done.  */
1868       if (space.subspace_quantity == 0)
1869 	continue;
1870 
1871       /* Now, read in the first subspace for this space.  */
1872       if (bfd_seek (abfd,
1873 		    (current_offset + file_hdr->subspace_location
1874 		     + space.subspace_index * sizeof subspace),
1875 		    SEEK_SET) != 0)
1876 	goto error_return;
1877       amt = sizeof subspace;
1878       if (bfd_bread (&subspace, amt, abfd) != amt)
1879 	goto error_return;
1880       /* Seek back to the start of the subspaces for loop below.  */
1881       if (bfd_seek (abfd,
1882 		    (current_offset + file_hdr->subspace_location
1883 		     + space.subspace_index * sizeof subspace),
1884 		    SEEK_SET) != 0)
1885 	goto error_return;
1886 
1887       /* Setup the start address and file loc from the first subspace
1888 	 record.  */
1889       space_asect->vma = subspace.subspace_start;
1890       space_asect->filepos = subspace.file_loc_init_value + current_offset;
1891       space_asect->alignment_power = exact_log2 (subspace.alignment);
1892       if (space_asect->alignment_power == (unsigned) -1)
1893 	goto error_return;
1894 
1895       /* Initialize save_subspace so we can reliably determine if this
1896 	 loop placed any useful values into it.  */
1897       memset (&save_subspace, 0, sizeof (save_subspace));
1898 
1899       /* Loop over the rest of the subspaces, building up more sections.  */
1900       for (subspace_index = 0; subspace_index < space.subspace_quantity;
1901 	   subspace_index++)
1902 	{
1903 	  asection *subspace_asect;
1904 
1905 	  /* Read in the next subspace.  */
1906 	  amt = sizeof subspace;
1907 	  if (bfd_bread (&subspace, amt, abfd) != amt)
1908 	    goto error_return;
1909 
1910 	  /* Setup the subspace name string.  */
1911 	  subspace.name.n_name = subspace.name.n_strx + space_strings;
1912 
1913 	  amt = strlen (subspace.name.n_name) + 1;
1914 	  newname = bfd_alloc (abfd, amt);
1915 	  if (!newname)
1916 	    goto error_return;
1917 	  strcpy (newname, subspace.name.n_name);
1918 
1919 	  /* Make a section out of this subspace.  */
1920 	  subspace_asect = bfd_make_section_anyway (abfd, newname);
1921 	  if (!subspace_asect)
1922 	    goto error_return;
1923 
1924 	  /* Store private information about the section.  */
1925 	  if (! bfd_som_set_subsection_attributes (subspace_asect, space_asect,
1926 						   subspace.access_control_bits,
1927 						   subspace.sort_key,
1928 						   subspace.quadrant,
1929 						   subspace.is_comdat,
1930 						   subspace.is_common,
1931 						   subspace.dup_common))
1932 	    goto error_return;
1933 
1934 	  /* Keep an easy mapping between subspaces and sections.
1935 	     Note we do not necessarily read the subspaces in the
1936 	     same order in which they appear in the object file.
1937 
1938 	     So to make the target index come out correctly, we
1939 	     store the location of the subspace header in target
1940 	     index, then sort using the location of the subspace
1941 	     header as the key.  Then we can assign correct
1942 	     subspace indices.  */
1943 	  total_subspaces++;
1944 	  subspace_asect->target_index = bfd_tell (abfd) - sizeof (subspace);
1945 
1946 	  /* Set SEC_READONLY and SEC_CODE/SEC_DATA as specified
1947 	     by the access_control_bits in the subspace header.  */
1948 	  switch (subspace.access_control_bits >> 4)
1949 	    {
1950 	    /* Readonly data.  */
1951 	    case 0x0:
1952 	      subspace_asect->flags |= SEC_DATA | SEC_READONLY;
1953 	      break;
1954 
1955 	    /* Normal data.  */
1956 	    case 0x1:
1957 	      subspace_asect->flags |= SEC_DATA;
1958 	      break;
1959 
1960 	    /* Readonly code and the gateways.
1961 	       Gateways have other attributes which do not map
1962 	       into anything BFD knows about.  */
1963 	    case 0x2:
1964 	    case 0x4:
1965 	    case 0x5:
1966 	    case 0x6:
1967 	    case 0x7:
1968 	      subspace_asect->flags |= SEC_CODE | SEC_READONLY;
1969 	      break;
1970 
1971 	    /* dynamic (writable) code.  */
1972 	    case 0x3:
1973 	      subspace_asect->flags |= SEC_CODE;
1974 	      break;
1975 	    }
1976 
1977 	  if (subspace.is_comdat || subspace.is_common || subspace.dup_common)
1978 	    subspace_asect->flags |= SEC_LINK_ONCE;
1979 
1980 	  if (subspace.subspace_length > 0)
1981 	    subspace_asect->flags |= SEC_HAS_CONTENTS;
1982 
1983 	  if (subspace.is_loadable)
1984 	    subspace_asect->flags |= SEC_ALLOC | SEC_LOAD;
1985 	  else
1986 	    subspace_asect->flags |= SEC_DEBUGGING;
1987 
1988 	  if (subspace.code_only)
1989 	    subspace_asect->flags |= SEC_CODE;
1990 
1991 	  /* Both file_loc_init_value and initialization_length will
1992 	     be zero for a BSS like subspace.  */
1993 	  if (subspace.file_loc_init_value == 0
1994 	      && subspace.initialization_length == 0)
1995 	    subspace_asect->flags &= ~(SEC_DATA | SEC_LOAD | SEC_HAS_CONTENTS);
1996 
1997 	  /* This subspace has relocations.
1998 	     The fixup_request_quantity is a byte count for the number of
1999 	     entries in the relocation stream; it is not the actual number
2000 	     of relocations in the subspace.  */
2001 	  if (subspace.fixup_request_quantity != 0)
2002 	    {
2003 	      subspace_asect->flags |= SEC_RELOC;
2004 	      subspace_asect->rel_filepos = subspace.fixup_request_index;
2005 	      som_section_data (subspace_asect)->reloc_size
2006 		= subspace.fixup_request_quantity;
2007 	      /* We can not determine this yet.  When we read in the
2008 		 relocation table the correct value will be filled in.  */
2009 	      subspace_asect->reloc_count = (unsigned) -1;
2010 	    }
2011 
2012 	  /* Update save_subspace if appropriate.  */
2013 	  if (subspace.file_loc_init_value > save_subspace.file_loc_init_value)
2014 	    save_subspace = subspace;
2015 
2016 	  subspace_asect->vma = subspace.subspace_start;
2017 	  subspace_asect->size = subspace.subspace_length;
2018 	  subspace_asect->filepos = (subspace.file_loc_init_value
2019 				     + current_offset);
2020 	  subspace_asect->alignment_power = exact_log2 (subspace.alignment);
2021 	  if (subspace_asect->alignment_power == (unsigned) -1)
2022 	    goto error_return;
2023 
2024 	  /* Keep track of the accumulated sizes of the sections.  */
2025 	  space_size += subspace.subspace_length;
2026 	}
2027 
2028       /* This can happen for a .o which defines symbols in otherwise
2029 	 empty subspaces.  */
2030       if (!save_subspace.file_loc_init_value)
2031 	space_asect->size = 0;
2032       else
2033 	{
2034 	  if (file_hdr->a_magic != RELOC_MAGIC)
2035 	    {
2036 	      /* Setup the size for the space section based upon the info
2037 		 in the last subspace of the space.  */
2038 	      space_asect->size = (save_subspace.subspace_start
2039 				   - space_asect->vma
2040 				   + save_subspace.subspace_length);
2041 	    }
2042 	  else
2043 	    {
2044 	      /* The subspace_start field is not initialised in relocatable
2045 	         only objects, so it cannot be used for length calculations.
2046 		 Instead we use the space_size value which we have been
2047 		 accumulating.  This isn't an accurate estimate since it
2048 		 ignores alignment and ordering issues.  */
2049 	      space_asect->size = space_size;
2050 	    }
2051 	}
2052     }
2053   /* Now that we've read in all the subspace records, we need to assign
2054      a target index to each subspace.  */
2055   amt = total_subspaces;
2056   amt *= sizeof (asection *);
2057   subspace_sections = bfd_malloc (amt);
2058   if (subspace_sections == NULL)
2059     goto error_return;
2060 
2061   for (i = 0, section = abfd->sections; section; section = section->next)
2062     {
2063       if (!som_is_subspace (section))
2064 	continue;
2065 
2066       subspace_sections[i] = section;
2067       i++;
2068     }
2069   qsort (subspace_sections, total_subspaces,
2070 	 sizeof (asection *), compare_subspaces);
2071 
2072   /* subspace_sections is now sorted in the order in which the subspaces
2073      appear in the object file.  Assign an index to each one now.  */
2074   for (i = 0; i < total_subspaces; i++)
2075     subspace_sections[i]->target_index = i;
2076 
2077   if (space_strings != NULL)
2078     free (space_strings);
2079 
2080   if (subspace_sections != NULL)
2081     free (subspace_sections);
2082 
2083   return TRUE;
2084 
2085  error_return:
2086   if (space_strings != NULL)
2087     free (space_strings);
2088 
2089   if (subspace_sections != NULL)
2090     free (subspace_sections);
2091   return FALSE;
2092 }
2093 
2094 /* Read in a SOM object and make it into a BFD.  */
2095 
2096 static const bfd_target *
2097 som_object_p (bfd *abfd)
2098 {
2099   struct header file_hdr;
2100   struct som_exec_auxhdr *aux_hdr_ptr = NULL;
2101   unsigned long current_offset = 0;
2102   struct lst_header lst_header;
2103   struct som_entry som_entry;
2104   bfd_size_type amt;
2105 #define ENTRY_SIZE sizeof (struct som_entry)
2106 
2107   amt = FILE_HDR_SIZE;
2108   if (bfd_bread ((void *) &file_hdr, amt, abfd) != amt)
2109     {
2110       if (bfd_get_error () != bfd_error_system_call)
2111 	bfd_set_error (bfd_error_wrong_format);
2112       return NULL;
2113     }
2114 
2115   if (!_PA_RISC_ID (file_hdr.system_id))
2116     {
2117       bfd_set_error (bfd_error_wrong_format);
2118       return NULL;
2119     }
2120 
2121   switch (file_hdr.a_magic)
2122     {
2123     case RELOC_MAGIC:
2124     case EXEC_MAGIC:
2125     case SHARE_MAGIC:
2126     case DEMAND_MAGIC:
2127 #ifdef DL_MAGIC
2128     case DL_MAGIC:
2129 #endif
2130 #ifdef SHL_MAGIC
2131     case SHL_MAGIC:
2132 #endif
2133 #ifdef SHARED_MAGIC_CNX
2134     case SHARED_MAGIC_CNX:
2135 #endif
2136       break;
2137 
2138 #ifdef EXECLIBMAGIC
2139     case EXECLIBMAGIC:
2140       /* Read the lst header and determine where the SOM directory begins.  */
2141 
2142       if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
2143 	{
2144 	  if (bfd_get_error () != bfd_error_system_call)
2145 	    bfd_set_error (bfd_error_wrong_format);
2146 	  return NULL;
2147 	}
2148 
2149       amt = SLSTHDR;
2150       if (bfd_bread ((void *) &lst_header, amt, abfd) != amt)
2151 	{
2152 	  if (bfd_get_error () != bfd_error_system_call)
2153 	    bfd_set_error (bfd_error_wrong_format);
2154 	  return NULL;
2155 	}
2156 
2157       /* Position to and read the first directory entry.  */
2158 
2159       if (bfd_seek (abfd, lst_header.dir_loc, SEEK_SET) != 0)
2160 	{
2161 	  if (bfd_get_error () != bfd_error_system_call)
2162 	    bfd_set_error (bfd_error_wrong_format);
2163 	  return NULL;
2164 	}
2165 
2166       amt = ENTRY_SIZE;
2167       if (bfd_bread ((void *) &som_entry, amt, abfd) != amt)
2168 	{
2169 	  if (bfd_get_error () != bfd_error_system_call)
2170 	    bfd_set_error (bfd_error_wrong_format);
2171 	  return NULL;
2172 	}
2173 
2174       /* Now position to the first SOM.  */
2175 
2176       if (bfd_seek (abfd, som_entry.location, SEEK_SET) != 0)
2177 	{
2178 	  if (bfd_get_error () != bfd_error_system_call)
2179 	    bfd_set_error (bfd_error_wrong_format);
2180 	  return NULL;
2181 	}
2182 
2183       current_offset = som_entry.location;
2184 
2185       /* And finally, re-read the som header.  */
2186       amt = FILE_HDR_SIZE;
2187       if (bfd_bread ((void *) &file_hdr, amt, abfd) != amt)
2188 	{
2189 	  if (bfd_get_error () != bfd_error_system_call)
2190 	    bfd_set_error (bfd_error_wrong_format);
2191 	  return NULL;
2192 	}
2193 
2194       break;
2195 #endif
2196 
2197     default:
2198       bfd_set_error (bfd_error_wrong_format);
2199       return NULL;
2200     }
2201 
2202   if (file_hdr.version_id != VERSION_ID
2203       && file_hdr.version_id != NEW_VERSION_ID)
2204     {
2205       bfd_set_error (bfd_error_wrong_format);
2206       return NULL;
2207     }
2208 
2209   /* If the aux_header_size field in the file header is zero, then this
2210      object is an incomplete executable (a .o file).  Do not try to read
2211      a non-existant auxiliary header.  */
2212   if (file_hdr.aux_header_size != 0)
2213     {
2214       aux_hdr_ptr = bfd_zalloc (abfd,
2215 				(bfd_size_type) sizeof (*aux_hdr_ptr));
2216       if (aux_hdr_ptr == NULL)
2217 	return NULL;
2218       amt = AUX_HDR_SIZE;
2219       if (bfd_bread ((void *) aux_hdr_ptr, amt, abfd) != amt)
2220 	{
2221 	  if (bfd_get_error () != bfd_error_system_call)
2222 	    bfd_set_error (bfd_error_wrong_format);
2223 	  return NULL;
2224 	}
2225     }
2226 
2227   if (!setup_sections (abfd, &file_hdr, current_offset))
2228     {
2229       /* setup_sections does not bubble up a bfd error code.  */
2230       bfd_set_error (bfd_error_bad_value);
2231       return NULL;
2232     }
2233 
2234   /* This appears to be a valid SOM object.  Do some initialization.  */
2235   return som_object_setup (abfd, &file_hdr, aux_hdr_ptr, current_offset);
2236 }
2237 
2238 /* Create a SOM object.  */
2239 
2240 static bfd_boolean
2241 som_mkobject (bfd *abfd)
2242 {
2243   /* Allocate memory to hold backend information.  */
2244   abfd->tdata.som_data = bfd_zalloc (abfd, (bfd_size_type) sizeof (struct som_data_struct));
2245   if (abfd->tdata.som_data == NULL)
2246     return FALSE;
2247   return TRUE;
2248 }
2249 
2250 /* Initialize some information in the file header.  This routine makes
2251    not attempt at doing the right thing for a full executable; it
2252    is only meant to handle relocatable objects.  */
2253 
2254 static bfd_boolean
2255 som_prep_headers (bfd *abfd)
2256 {
2257   struct header *file_hdr;
2258   asection *section;
2259   bfd_size_type amt = sizeof (struct header);
2260 
2261   /* Make and attach a file header to the BFD.  */
2262   file_hdr = bfd_zalloc (abfd, amt);
2263   if (file_hdr == NULL)
2264     return FALSE;
2265   obj_som_file_hdr (abfd) = file_hdr;
2266 
2267   if (abfd->flags & (EXEC_P | DYNAMIC))
2268     {
2269       /* Make and attach an exec header to the BFD.  */
2270       amt = sizeof (struct som_exec_auxhdr);
2271       obj_som_exec_hdr (abfd) = bfd_zalloc (abfd, amt);
2272       if (obj_som_exec_hdr (abfd) == NULL)
2273 	return FALSE;
2274 
2275       if (abfd->flags & D_PAGED)
2276 	file_hdr->a_magic = DEMAND_MAGIC;
2277       else if (abfd->flags & WP_TEXT)
2278 	file_hdr->a_magic = SHARE_MAGIC;
2279 #ifdef SHL_MAGIC
2280       else if (abfd->flags & DYNAMIC)
2281 	file_hdr->a_magic = SHL_MAGIC;
2282 #endif
2283       else
2284 	file_hdr->a_magic = EXEC_MAGIC;
2285     }
2286   else
2287     file_hdr->a_magic = RELOC_MAGIC;
2288 
2289   /* These fields are optional, and embedding timestamps is not always
2290      a wise thing to do, it makes comparing objects during a multi-stage
2291      bootstrap difficult.  */
2292   file_hdr->file_time.secs = 0;
2293   file_hdr->file_time.nanosecs = 0;
2294 
2295   file_hdr->entry_space = 0;
2296   file_hdr->entry_subspace = 0;
2297   file_hdr->entry_offset = 0;
2298   file_hdr->presumed_dp = 0;
2299 
2300   /* Now iterate over the sections translating information from
2301      BFD sections to SOM spaces/subspaces.  */
2302   for (section = abfd->sections; section != NULL; section = section->next)
2303     {
2304       /* Ignore anything which has not been marked as a space or
2305 	 subspace.  */
2306       if (!som_is_space (section) && !som_is_subspace (section))
2307 	continue;
2308 
2309       if (som_is_space (section))
2310 	{
2311 	  /* Allocate space for the space dictionary.  */
2312 	  amt = sizeof (struct space_dictionary_record);
2313 	  som_section_data (section)->space_dict = bfd_zalloc (abfd, amt);
2314 	  if (som_section_data (section)->space_dict == NULL)
2315 	    return FALSE;
2316 	  /* Set space attributes.  Note most attributes of SOM spaces
2317 	     are set based on the subspaces it contains.  */
2318 	  som_section_data (section)->space_dict->loader_fix_index = -1;
2319 	  som_section_data (section)->space_dict->init_pointer_index = -1;
2320 
2321 	  /* Set more attributes that were stuffed away in private data.  */
2322 	  som_section_data (section)->space_dict->sort_key =
2323 	    som_section_data (section)->copy_data->sort_key;
2324 	  som_section_data (section)->space_dict->is_defined =
2325 	    som_section_data (section)->copy_data->is_defined;
2326 	  som_section_data (section)->space_dict->is_private =
2327 	    som_section_data (section)->copy_data->is_private;
2328 	  som_section_data (section)->space_dict->space_number =
2329 	    som_section_data (section)->copy_data->space_number;
2330 	}
2331       else
2332 	{
2333 	  /* Allocate space for the subspace dictionary.  */
2334 	  amt = sizeof (struct som_subspace_dictionary_record);
2335 	  som_section_data (section)->subspace_dict = bfd_zalloc (abfd, amt);
2336 	  if (som_section_data (section)->subspace_dict == NULL)
2337 	    return FALSE;
2338 
2339 	  /* Set subspace attributes.  Basic stuff is done here, additional
2340 	     attributes are filled in later as more information becomes
2341 	     available.  */
2342 	  if (section->flags & SEC_ALLOC)
2343 	    som_section_data (section)->subspace_dict->is_loadable = 1;
2344 
2345 	  if (section->flags & SEC_CODE)
2346 	    som_section_data (section)->subspace_dict->code_only = 1;
2347 
2348 	  som_section_data (section)->subspace_dict->subspace_start =
2349 	    section->vma;
2350 	  som_section_data (section)->subspace_dict->subspace_length =
2351 	    section->size;
2352 	  som_section_data (section)->subspace_dict->initialization_length =
2353 	    section->size;
2354 	  som_section_data (section)->subspace_dict->alignment =
2355 	    1 << section->alignment_power;
2356 
2357 	  /* Set more attributes that were stuffed away in private data.  */
2358 	  som_section_data (section)->subspace_dict->sort_key =
2359 	    som_section_data (section)->copy_data->sort_key;
2360 	  som_section_data (section)->subspace_dict->access_control_bits =
2361 	    som_section_data (section)->copy_data->access_control_bits;
2362 	  som_section_data (section)->subspace_dict->quadrant =
2363 	    som_section_data (section)->copy_data->quadrant;
2364 	  som_section_data (section)->subspace_dict->is_comdat =
2365 	    som_section_data (section)->copy_data->is_comdat;
2366 	  som_section_data (section)->subspace_dict->is_common =
2367 	    som_section_data (section)->copy_data->is_common;
2368 	  som_section_data (section)->subspace_dict->dup_common =
2369 	    som_section_data (section)->copy_data->dup_common;
2370 	}
2371     }
2372   return TRUE;
2373 }
2374 
2375 /* Return TRUE if the given section is a SOM space, FALSE otherwise.  */
2376 
2377 static bfd_boolean
2378 som_is_space (asection *section)
2379 {
2380   /* If no copy data is available, then it's neither a space nor a
2381      subspace.  */
2382   if (som_section_data (section)->copy_data == NULL)
2383     return FALSE;
2384 
2385   /* If the containing space isn't the same as the given section,
2386      then this isn't a space.  */
2387   if (som_section_data (section)->copy_data->container != section
2388       && (som_section_data (section)->copy_data->container->output_section
2389 	  != section))
2390     return FALSE;
2391 
2392   /* OK.  Must be a space.  */
2393   return TRUE;
2394 }
2395 
2396 /* Return TRUE if the given section is a SOM subspace, FALSE otherwise.  */
2397 
2398 static bfd_boolean
2399 som_is_subspace (asection *section)
2400 {
2401   /* If no copy data is available, then it's neither a space nor a
2402      subspace.  */
2403   if (som_section_data (section)->copy_data == NULL)
2404     return FALSE;
2405 
2406   /* If the containing space is the same as the given section,
2407      then this isn't a subspace.  */
2408   if (som_section_data (section)->copy_data->container == section
2409       || (som_section_data (section)->copy_data->container->output_section
2410 	  == section))
2411     return FALSE;
2412 
2413   /* OK.  Must be a subspace.  */
2414   return TRUE;
2415 }
2416 
2417 /* Return TRUE if the given space contains the given subspace.  It
2418    is safe to assume space really is a space, and subspace really
2419    is a subspace.  */
2420 
2421 static bfd_boolean
2422 som_is_container (asection *space, asection *subspace)
2423 {
2424   return (som_section_data (subspace)->copy_data->container == space)
2425     || (som_section_data (subspace)->copy_data->container->output_section
2426 	== space);
2427 }
2428 
2429 /* Count and return the number of spaces attached to the given BFD.  */
2430 
2431 static unsigned long
2432 som_count_spaces (bfd *abfd)
2433 {
2434   int count = 0;
2435   asection *section;
2436 
2437   for (section = abfd->sections; section != NULL; section = section->next)
2438     count += som_is_space (section);
2439 
2440   return count;
2441 }
2442 
2443 /* Count the number of subspaces attached to the given BFD.  */
2444 
2445 static unsigned long
2446 som_count_subspaces (bfd *abfd)
2447 {
2448   int count = 0;
2449   asection *section;
2450 
2451   for (section = abfd->sections; section != NULL; section = section->next)
2452     count += som_is_subspace (section);
2453 
2454   return count;
2455 }
2456 
2457 /* Return -1, 0, 1 indicating the relative ordering of sym1 and sym2.
2458 
2459    We desire symbols to be ordered starting with the symbol with the
2460    highest relocation count down to the symbol with the lowest relocation
2461    count.  Doing so compacts the relocation stream.  */
2462 
2463 static int
2464 compare_syms (const void *arg1, const void *arg2)
2465 {
2466   asymbol **sym1 = (asymbol **) arg1;
2467   asymbol **sym2 = (asymbol **) arg2;
2468   unsigned int count1, count2;
2469 
2470   /* Get relocation count for each symbol.  Note that the count
2471      is stored in the udata pointer for section symbols!  */
2472   if ((*sym1)->flags & BSF_SECTION_SYM)
2473     count1 = (*sym1)->udata.i;
2474   else
2475     count1 = som_symbol_data (*sym1)->reloc_count;
2476 
2477   if ((*sym2)->flags & BSF_SECTION_SYM)
2478     count2 = (*sym2)->udata.i;
2479   else
2480     count2 = som_symbol_data (*sym2)->reloc_count;
2481 
2482   /* Return the appropriate value.  */
2483   if (count1 < count2)
2484     return 1;
2485   else if (count1 > count2)
2486     return -1;
2487   return 0;
2488 }
2489 
2490 /* Return -1, 0, 1 indicating the relative ordering of subspace1
2491    and subspace.  */
2492 
2493 static int
2494 compare_subspaces (const void *arg1, const void *arg2)
2495 {
2496   asection **subspace1 = (asection **) arg1;
2497   asection **subspace2 = (asection **) arg2;
2498 
2499   if ((*subspace1)->target_index < (*subspace2)->target_index)
2500     return -1;
2501   else if ((*subspace2)->target_index < (*subspace1)->target_index)
2502     return 1;
2503   else
2504     return 0;
2505 }
2506 
2507 /* Perform various work in preparation for emitting the fixup stream.  */
2508 
2509 static void
2510 som_prep_for_fixups (bfd *abfd, asymbol **syms, unsigned long num_syms)
2511 {
2512   unsigned long i;
2513   asection *section;
2514   asymbol **sorted_syms;
2515   bfd_size_type amt;
2516 
2517   /* Most SOM relocations involving a symbol have a length which is
2518      dependent on the index of the symbol.  So symbols which are
2519      used often in relocations should have a small index.  */
2520 
2521   /* First initialize the counters for each symbol.  */
2522   for (i = 0; i < num_syms; i++)
2523     {
2524       /* Handle a section symbol; these have no pointers back to the
2525 	 SOM symbol info.  So we just use the udata field to hold the
2526 	 relocation count.  */
2527       if (som_symbol_data (syms[i]) == NULL
2528 	  || syms[i]->flags & BSF_SECTION_SYM)
2529 	{
2530 	  syms[i]->flags |= BSF_SECTION_SYM;
2531 	  syms[i]->udata.i = 0;
2532 	}
2533       else
2534 	som_symbol_data (syms[i])->reloc_count = 0;
2535     }
2536 
2537   /* Now that the counters are initialized, make a weighted count
2538      of how often a given symbol is used in a relocation.  */
2539   for (section = abfd->sections; section != NULL; section = section->next)
2540     {
2541       int j;
2542 
2543       /* Does this section have any relocations?  */
2544       if ((int) section->reloc_count <= 0)
2545 	continue;
2546 
2547       /* Walk through each relocation for this section.  */
2548       for (j = 1; j < (int) section->reloc_count; j++)
2549 	{
2550 	  arelent *reloc = section->orelocation[j];
2551 	  int scale;
2552 
2553 	  /* A relocation against a symbol in the *ABS* section really
2554 	     does not have a symbol.  Likewise if the symbol isn't associated
2555 	     with any section.  */
2556 	  if (reloc->sym_ptr_ptr == NULL
2557 	      || bfd_is_abs_section ((*reloc->sym_ptr_ptr)->section))
2558 	    continue;
2559 
2560 	  /* Scaling to encourage symbols involved in R_DP_RELATIVE
2561 	     and R_CODE_ONE_SYMBOL relocations to come first.  These
2562 	     two relocations have single byte versions if the symbol
2563 	     index is very small.  */
2564 	  if (reloc->howto->type == R_DP_RELATIVE
2565 	      || reloc->howto->type == R_CODE_ONE_SYMBOL)
2566 	    scale = 2;
2567 	  else
2568 	    scale = 1;
2569 
2570 	  /* Handle section symbols by storing the count in the udata
2571 	     field.  It will not be used and the count is very important
2572 	     for these symbols.  */
2573 	  if ((*reloc->sym_ptr_ptr)->flags & BSF_SECTION_SYM)
2574 	    {
2575 	      (*reloc->sym_ptr_ptr)->udata.i =
2576 		(*reloc->sym_ptr_ptr)->udata.i + scale;
2577 	      continue;
2578 	    }
2579 
2580 	  /* A normal symbol.  Increment the count.  */
2581 	  som_symbol_data (*reloc->sym_ptr_ptr)->reloc_count += scale;
2582 	}
2583     }
2584 
2585   /* Sort a copy of the symbol table, rather than the canonical
2586      output symbol table.  */
2587   amt = num_syms;
2588   amt *= sizeof (asymbol *);
2589   sorted_syms = bfd_zalloc (abfd, amt);
2590   memcpy (sorted_syms, syms, num_syms * sizeof (asymbol *));
2591   qsort (sorted_syms, num_syms, sizeof (asymbol *), compare_syms);
2592   obj_som_sorted_syms (abfd) = sorted_syms;
2593 
2594   /* Compute the symbol indexes, they will be needed by the relocation
2595      code.  */
2596   for (i = 0; i < num_syms; i++)
2597     {
2598       /* A section symbol.  Again, there is no pointer to backend symbol
2599 	 information, so we reuse the udata field again.  */
2600       if (sorted_syms[i]->flags & BSF_SECTION_SYM)
2601 	sorted_syms[i]->udata.i = i;
2602       else
2603 	som_symbol_data (sorted_syms[i])->index = i;
2604     }
2605 }
2606 
2607 static bfd_boolean
2608 som_write_fixups (bfd *abfd,
2609 		  unsigned long current_offset,
2610 		  unsigned int *total_reloc_sizep)
2611 {
2612   unsigned int i, j;
2613   /* Chunk of memory that we can use as buffer space, then throw
2614      away.  */
2615   unsigned char tmp_space[SOM_TMP_BUFSIZE];
2616   unsigned char *p;
2617   unsigned int total_reloc_size = 0;
2618   unsigned int subspace_reloc_size = 0;
2619   unsigned int num_spaces = obj_som_file_hdr (abfd)->space_total;
2620   asection *section = abfd->sections;
2621   bfd_size_type amt;
2622 
2623   memset (tmp_space, 0, SOM_TMP_BUFSIZE);
2624   p = tmp_space;
2625 
2626   /* All the fixups for a particular subspace are emitted in a single
2627      stream.  All the subspaces for a particular space are emitted
2628      as a single stream.
2629 
2630      So, to get all the locations correct one must iterate through all the
2631      spaces, for each space iterate through its subspaces and output a
2632      fixups stream.  */
2633   for (i = 0; i < num_spaces; i++)
2634     {
2635       asection *subsection;
2636 
2637       /* Find a space.  */
2638       while (!som_is_space (section))
2639 	section = section->next;
2640 
2641       /* Now iterate through each of its subspaces.  */
2642       for (subsection = abfd->sections;
2643 	   subsection != NULL;
2644 	   subsection = subsection->next)
2645 	{
2646 	  int reloc_offset;
2647 	  unsigned int current_rounding_mode;
2648 #ifndef NO_PCREL_MODES
2649 	  unsigned int current_call_mode;
2650 #endif
2651 
2652 	  /* Find a subspace of this space.  */
2653 	  if (!som_is_subspace (subsection)
2654 	      || !som_is_container (section, subsection))
2655 	    continue;
2656 
2657 	  /* If this subspace does not have real data, then we are
2658 	     finished with it.  */
2659 	  if ((subsection->flags & SEC_HAS_CONTENTS) == 0)
2660 	    {
2661 	      som_section_data (subsection)->subspace_dict->fixup_request_index
2662 		= -1;
2663 	      continue;
2664 	    }
2665 
2666 	  /* This subspace has some relocations.  Put the relocation stream
2667 	     index into the subspace record.  */
2668 	  som_section_data (subsection)->subspace_dict->fixup_request_index
2669 	    = total_reloc_size;
2670 
2671 	  /* To make life easier start over with a clean slate for
2672 	     each subspace.  Seek to the start of the relocation stream
2673 	     for this subspace in preparation for writing out its fixup
2674 	     stream.  */
2675 	  if (bfd_seek (abfd, current_offset + total_reloc_size, SEEK_SET) != 0)
2676 	    return FALSE;
2677 
2678 	  /* Buffer space has already been allocated.  Just perform some
2679 	     initialization here.  */
2680 	  p = tmp_space;
2681 	  subspace_reloc_size = 0;
2682 	  reloc_offset = 0;
2683 	  som_initialize_reloc_queue (reloc_queue);
2684 	  current_rounding_mode = R_N_MODE;
2685 #ifndef NO_PCREL_MODES
2686 	  current_call_mode = R_SHORT_PCREL_MODE;
2687 #endif
2688 
2689 	  /* Translate each BFD relocation into one or more SOM
2690 	     relocations.  */
2691 	  for (j = 0; j < subsection->reloc_count; j++)
2692 	    {
2693 	      arelent *bfd_reloc = subsection->orelocation[j];
2694 	      unsigned int skip;
2695 	      int sym_num;
2696 
2697 	      /* Get the symbol number.  Remember it's stored in a
2698 		 special place for section symbols.  */
2699 	      if ((*bfd_reloc->sym_ptr_ptr)->flags & BSF_SECTION_SYM)
2700 		sym_num = (*bfd_reloc->sym_ptr_ptr)->udata.i;
2701 	      else
2702 		sym_num = som_symbol_data (*bfd_reloc->sym_ptr_ptr)->index;
2703 
2704 	      /* If there is not enough room for the next couple relocations,
2705 		 then dump the current buffer contents now.  Also reinitialize
2706 		 the relocation queue.
2707 
2708 		 No single BFD relocation could ever translate into more
2709 		 than 100 bytes of SOM relocations (20bytes is probably the
2710 		 upper limit, but leave lots of space for growth).  */
2711 	      if (p - tmp_space + 100 > SOM_TMP_BUFSIZE)
2712 		{
2713 		  amt = p - tmp_space;
2714 		  if (bfd_bwrite ((void *) tmp_space, amt, abfd) != amt)
2715 		    return FALSE;
2716 
2717 		  p = tmp_space;
2718 		  som_initialize_reloc_queue (reloc_queue);
2719 		}
2720 
2721 	      /* Emit R_NO_RELOCATION fixups to map any bytes which were
2722 		 skipped.  */
2723 	      skip = bfd_reloc->address - reloc_offset;
2724 	      p = som_reloc_skip (abfd, skip, p,
2725 				  &subspace_reloc_size, reloc_queue);
2726 
2727 	      /* Update reloc_offset for the next iteration.
2728 
2729 		 Many relocations do not consume input bytes.  They
2730 		 are markers, or set state necessary to perform some
2731 		 later relocation.  */
2732 	      switch (bfd_reloc->howto->type)
2733 		{
2734 		case R_ENTRY:
2735 		case R_ALT_ENTRY:
2736 		case R_EXIT:
2737 		case R_N_MODE:
2738 		case R_S_MODE:
2739 		case R_D_MODE:
2740 		case R_R_MODE:
2741 		case R_FSEL:
2742 		case R_LSEL:
2743 		case R_RSEL:
2744 		case R_COMP1:
2745 		case R_COMP2:
2746 		case R_BEGIN_BRTAB:
2747 		case R_END_BRTAB:
2748 		case R_BEGIN_TRY:
2749 		case R_END_TRY:
2750 		case R_N0SEL:
2751 		case R_N1SEL:
2752 #ifndef NO_PCREL_MODES
2753 		case R_SHORT_PCREL_MODE:
2754 		case R_LONG_PCREL_MODE:
2755 #endif
2756 		  reloc_offset = bfd_reloc->address;
2757 		  break;
2758 
2759 		default:
2760 		  reloc_offset = bfd_reloc->address + 4;
2761 		  break;
2762 		}
2763 
2764 	      /* Now the actual relocation we care about.  */
2765 	      switch (bfd_reloc->howto->type)
2766 		{
2767 		case R_PCREL_CALL:
2768 		case R_ABS_CALL:
2769 		  p = som_reloc_call (abfd, p, &subspace_reloc_size,
2770 				      bfd_reloc, sym_num, reloc_queue);
2771 		  break;
2772 
2773 		case R_CODE_ONE_SYMBOL:
2774 		case R_DP_RELATIVE:
2775 		  /* Account for any addend.  */
2776 		  if (bfd_reloc->addend)
2777 		    p = som_reloc_addend (abfd, bfd_reloc->addend, p,
2778 					  &subspace_reloc_size, reloc_queue);
2779 
2780 		  if (sym_num < 0x20)
2781 		    {
2782 		      bfd_put_8 (abfd, bfd_reloc->howto->type + sym_num, p);
2783 		      subspace_reloc_size += 1;
2784 		      p += 1;
2785 		    }
2786 		  else if (sym_num < 0x100)
2787 		    {
2788 		      bfd_put_8 (abfd, bfd_reloc->howto->type + 32, p);
2789 		      bfd_put_8 (abfd, sym_num, p + 1);
2790 		      p = try_prev_fixup (abfd, &subspace_reloc_size, p,
2791 					  2, reloc_queue);
2792 		    }
2793 		  else if (sym_num < 0x10000000)
2794 		    {
2795 		      bfd_put_8 (abfd, bfd_reloc->howto->type + 33, p);
2796 		      bfd_put_8 (abfd, sym_num >> 16, p + 1);
2797 		      bfd_put_16 (abfd, (bfd_vma) sym_num, p + 2);
2798 		      p = try_prev_fixup (abfd, &subspace_reloc_size,
2799 					  p, 4, reloc_queue);
2800 		    }
2801 		  else
2802 		    abort ();
2803 		  break;
2804 
2805 		case R_DATA_GPREL:
2806 		  /* Account for any addend.  */
2807 		  if (bfd_reloc->addend)
2808 		    p = som_reloc_addend (abfd, bfd_reloc->addend, p,
2809 					  &subspace_reloc_size, reloc_queue);
2810 
2811 		  if (sym_num < 0x10000000)
2812 		    {
2813 		      bfd_put_8 (abfd, bfd_reloc->howto->type, p);
2814 		      bfd_put_8 (abfd, sym_num >> 16, p + 1);
2815 		      bfd_put_16 (abfd, (bfd_vma) sym_num, p + 2);
2816 		      p = try_prev_fixup (abfd, &subspace_reloc_size,
2817 					  p, 4, reloc_queue);
2818 		    }
2819 		  else
2820 		    abort ();
2821 		  break;
2822 
2823 		case R_DATA_ONE_SYMBOL:
2824 		case R_DATA_PLABEL:
2825 		case R_CODE_PLABEL:
2826 		case R_DLT_REL:
2827 		  /* Account for any addend using R_DATA_OVERRIDE.  */
2828 		  if (bfd_reloc->howto->type != R_DATA_ONE_SYMBOL
2829 		      && bfd_reloc->addend)
2830 		    p = som_reloc_addend (abfd, bfd_reloc->addend, p,
2831 					  &subspace_reloc_size, reloc_queue);
2832 
2833 		  if (sym_num < 0x100)
2834 		    {
2835 		      bfd_put_8 (abfd, bfd_reloc->howto->type, p);
2836 		      bfd_put_8 (abfd, sym_num, p + 1);
2837 		      p = try_prev_fixup (abfd, &subspace_reloc_size, p,
2838 					  2, reloc_queue);
2839 		    }
2840 		  else if (sym_num < 0x10000000)
2841 		    {
2842 		      bfd_put_8 (abfd, bfd_reloc->howto->type + 1, p);
2843 		      bfd_put_8 (abfd, sym_num >> 16, p + 1);
2844 		      bfd_put_16 (abfd, (bfd_vma) sym_num, p + 2);
2845 		      p = try_prev_fixup (abfd, &subspace_reloc_size,
2846 					  p, 4, reloc_queue);
2847 		    }
2848 		  else
2849 		    abort ();
2850 		  break;
2851 
2852 		case R_ENTRY:
2853 		  {
2854 		    unsigned int tmp;
2855 		    arelent *tmp_reloc = NULL;
2856 		    bfd_put_8 (abfd, R_ENTRY, p);
2857 
2858 		    /* R_ENTRY relocations have 64 bits of associated
2859 		       data.  Unfortunately the addend field of a bfd
2860 		       relocation is only 32 bits.  So, we split up
2861 		       the 64bit unwind information and store part in
2862 		       the R_ENTRY relocation, and the rest in the R_EXIT
2863 		       relocation.  */
2864 		    bfd_put_32 (abfd, bfd_reloc->addend, p + 1);
2865 
2866 		    /* Find the next R_EXIT relocation.  */
2867 		    for (tmp = j; tmp < subsection->reloc_count; tmp++)
2868 		      {
2869 			tmp_reloc = subsection->orelocation[tmp];
2870 			if (tmp_reloc->howto->type == R_EXIT)
2871 			  break;
2872 		      }
2873 
2874 		    if (tmp == subsection->reloc_count)
2875 		      abort ();
2876 
2877 		    bfd_put_32 (abfd, tmp_reloc->addend, p + 5);
2878 		    p = try_prev_fixup (abfd, &subspace_reloc_size,
2879 					p, 9, reloc_queue);
2880 		    break;
2881 		  }
2882 
2883 		case R_N_MODE:
2884 		case R_S_MODE:
2885 		case R_D_MODE:
2886 		case R_R_MODE:
2887 		  /* If this relocation requests the current rounding
2888 		     mode, then it is redundant.  */
2889 		  if (bfd_reloc->howto->type != current_rounding_mode)
2890 		    {
2891 		      bfd_put_8 (abfd, bfd_reloc->howto->type, p);
2892 		      subspace_reloc_size += 1;
2893 		      p += 1;
2894 		      current_rounding_mode = bfd_reloc->howto->type;
2895 		    }
2896 		  break;
2897 
2898 #ifndef NO_PCREL_MODES
2899 		case R_LONG_PCREL_MODE:
2900 		case R_SHORT_PCREL_MODE:
2901 		  if (bfd_reloc->howto->type != current_call_mode)
2902 		    {
2903 		      bfd_put_8 (abfd, bfd_reloc->howto->type, p);
2904 		      subspace_reloc_size += 1;
2905 		      p += 1;
2906 		      current_call_mode = bfd_reloc->howto->type;
2907 		    }
2908 		  break;
2909 #endif
2910 
2911 		case R_EXIT:
2912 		case R_ALT_ENTRY:
2913 		case R_FSEL:
2914 		case R_LSEL:
2915 		case R_RSEL:
2916 		case R_BEGIN_BRTAB:
2917 		case R_END_BRTAB:
2918 		case R_BEGIN_TRY:
2919 		case R_N0SEL:
2920 		case R_N1SEL:
2921 		  bfd_put_8 (abfd, bfd_reloc->howto->type, p);
2922 		  subspace_reloc_size += 1;
2923 		  p += 1;
2924 		  break;
2925 
2926 		case R_END_TRY:
2927 		  /* The end of an exception handling region.  The reloc's
2928 		     addend contains the offset of the exception handling
2929 		     code.  */
2930 		  if (bfd_reloc->addend == 0)
2931 		    bfd_put_8 (abfd, bfd_reloc->howto->type, p);
2932 		  else if (bfd_reloc->addend < 1024)
2933 		    {
2934 		      bfd_put_8 (abfd, bfd_reloc->howto->type + 1, p);
2935 		      bfd_put_8 (abfd, bfd_reloc->addend / 4, p + 1);
2936 		      p = try_prev_fixup (abfd, &subspace_reloc_size,
2937 					  p, 2, reloc_queue);
2938 		    }
2939 		  else
2940 		    {
2941 		      bfd_put_8 (abfd, bfd_reloc->howto->type + 2, p);
2942 		      bfd_put_8 (abfd, (bfd_reloc->addend / 4) >> 16, p + 1);
2943 		      bfd_put_16 (abfd, bfd_reloc->addend / 4, p + 2);
2944 		      p = try_prev_fixup (abfd, &subspace_reloc_size,
2945 					  p, 4, reloc_queue);
2946 		    }
2947 		  break;
2948 
2949 		case R_COMP1:
2950 		  /* The only time we generate R_COMP1, R_COMP2 and
2951 		     R_CODE_EXPR relocs is for the difference of two
2952 		     symbols.  Hence we can cheat here.  */
2953 		  bfd_put_8 (abfd, bfd_reloc->howto->type, p);
2954 		  bfd_put_8 (abfd, 0x44, p + 1);
2955 		  p = try_prev_fixup (abfd, &subspace_reloc_size,
2956 				      p, 2, reloc_queue);
2957 		  break;
2958 
2959 		case R_COMP2:
2960 		  /* The only time we generate R_COMP1, R_COMP2 and
2961 		     R_CODE_EXPR relocs is for the difference of two
2962 		     symbols.  Hence we can cheat here.  */
2963 		  bfd_put_8 (abfd, bfd_reloc->howto->type, p);
2964 		  bfd_put_8 (abfd, 0x80, p + 1);
2965 		  bfd_put_8 (abfd, sym_num >> 16, p + 2);
2966 		  bfd_put_16 (abfd, (bfd_vma) sym_num, p + 3);
2967 		  p = try_prev_fixup (abfd, &subspace_reloc_size,
2968 				      p, 5, reloc_queue);
2969 		  break;
2970 
2971 		case R_CODE_EXPR:
2972 		case R_DATA_EXPR:
2973 		  /* The only time we generate R_COMP1, R_COMP2 and
2974 		     R_CODE_EXPR relocs is for the difference of two
2975 		     symbols.  Hence we can cheat here.  */
2976 		  bfd_put_8 (abfd, bfd_reloc->howto->type, p);
2977 		  subspace_reloc_size += 1;
2978 		  p += 1;
2979 		  break;
2980 
2981 		/* Put a "R_RESERVED" relocation in the stream if
2982 		   we hit something we do not understand.  The linker
2983 		   will complain loudly if this ever happens.  */
2984 		default:
2985 		  bfd_put_8 (abfd, 0xff, p);
2986 		  subspace_reloc_size += 1;
2987 		  p += 1;
2988 		  break;
2989 		}
2990 	    }
2991 
2992 	  /* Last BFD relocation for a subspace has been processed.
2993 	     Map the rest of the subspace with R_NO_RELOCATION fixups.  */
2994 	  p = som_reloc_skip (abfd, subsection->size - reloc_offset,
2995 			      p, &subspace_reloc_size, reloc_queue);
2996 
2997 	  /* Scribble out the relocations.  */
2998 	  amt = p - tmp_space;
2999 	  if (bfd_bwrite ((void *) tmp_space, amt, abfd) != amt)
3000 	    return FALSE;
3001 	  p = tmp_space;
3002 
3003 	  total_reloc_size += subspace_reloc_size;
3004 	  som_section_data (subsection)->subspace_dict->fixup_request_quantity
3005 	    = subspace_reloc_size;
3006 	}
3007       section = section->next;
3008     }
3009   *total_reloc_sizep = total_reloc_size;
3010   return TRUE;
3011 }
3012 
3013 /* Write out the space/subspace string table.  */
3014 
3015 static bfd_boolean
3016 som_write_space_strings (bfd *abfd,
3017 			 unsigned long current_offset,
3018 			 unsigned int *string_sizep)
3019 {
3020   /* Chunk of memory that we can use as buffer space, then throw
3021      away.  */
3022   size_t tmp_space_size = SOM_TMP_BUFSIZE;
3023   char *tmp_space = alloca (tmp_space_size);
3024   char *p = tmp_space;
3025   unsigned int strings_size = 0;
3026   asection *section;
3027   bfd_size_type amt;
3028 
3029   /* Seek to the start of the space strings in preparation for writing
3030      them out.  */
3031   if (bfd_seek (abfd, (file_ptr) current_offset, SEEK_SET) != 0)
3032     return FALSE;
3033 
3034   /* Walk through all the spaces and subspaces (order is not important)
3035      building up and writing string table entries for their names.  */
3036   for (section = abfd->sections; section != NULL; section = section->next)
3037     {
3038       size_t length;
3039 
3040       /* Only work with space/subspaces; avoid any other sections
3041 	 which might have been made (.text for example).  */
3042       if (!som_is_space (section) && !som_is_subspace (section))
3043 	continue;
3044 
3045       /* Get the length of the space/subspace name.  */
3046       length = strlen (section->name);
3047 
3048       /* If there is not enough room for the next entry, then dump the
3049 	 current buffer contents now and maybe allocate a larger
3050 	 buffer.  Each entry will take 4 bytes to hold the string
3051 	 length + the string itself + null terminator.  */
3052       if (p - tmp_space + 5 + length > tmp_space_size)
3053 	{
3054 	  /* Flush buffer before refilling or reallocating.  */
3055 	  amt = p - tmp_space;
3056 	  if (bfd_bwrite ((void *) &tmp_space[0], amt, abfd) != amt)
3057 	    return FALSE;
3058 
3059 	  /* Reallocate if now empty buffer still too small.  */
3060 	  if (5 + length > tmp_space_size)
3061 	    {
3062 	      /* Ensure a minimum growth factor to avoid O(n**2) space
3063 		 consumption for n strings.  The optimal minimum
3064 		 factor seems to be 2, as no other value can guarantee
3065 		 wasting less than 50% space.  (Note that we cannot
3066 		 deallocate space allocated by `alloca' without
3067 		 returning from this function.)  The same technique is
3068 		 used a few more times below when a buffer is
3069 		 reallocated.  */
3070 	      tmp_space_size = MAX (2 * tmp_space_size, 5 + length);
3071 	      tmp_space = alloca (tmp_space_size);
3072 	    }
3073 
3074 	  /* Reset to beginning of the (possibly new) buffer space.  */
3075 	  p = tmp_space;
3076 	}
3077 
3078       /* First element in a string table entry is the length of the
3079 	 string.  Alignment issues are already handled.  */
3080       bfd_put_32 (abfd, (bfd_vma) length, p);
3081       p += 4;
3082       strings_size += 4;
3083 
3084       /* Record the index in the space/subspace records.  */
3085       if (som_is_space (section))
3086 	som_section_data (section)->space_dict->name.n_strx = strings_size;
3087       else
3088 	som_section_data (section)->subspace_dict->name.n_strx = strings_size;
3089 
3090       /* Next comes the string itself + a null terminator.  */
3091       strcpy (p, section->name);
3092       p += length + 1;
3093       strings_size += length + 1;
3094 
3095       /* Always align up to the next word boundary.  */
3096       while (strings_size % 4)
3097 	{
3098 	  bfd_put_8 (abfd, 0, p);
3099 	  p++;
3100 	  strings_size++;
3101 	}
3102     }
3103 
3104   /* Done with the space/subspace strings.  Write out any information
3105      contained in a partial block.  */
3106   amt = p - tmp_space;
3107   if (bfd_bwrite ((void *) &tmp_space[0], amt, abfd) != amt)
3108     return FALSE;
3109   *string_sizep = strings_size;
3110   return TRUE;
3111 }
3112 
3113 /* Write out the symbol string table.  */
3114 
3115 static bfd_boolean
3116 som_write_symbol_strings (bfd *abfd,
3117 			  unsigned long current_offset,
3118 			  asymbol **syms,
3119 			  unsigned int num_syms,
3120 			  unsigned int *string_sizep,
3121 			  COMPUNIT *compilation_unit)
3122 {
3123   unsigned int i;
3124 
3125   /* Chunk of memory that we can use as buffer space, then throw
3126      away.  */
3127   size_t tmp_space_size = SOM_TMP_BUFSIZE;
3128   char *tmp_space = alloca (tmp_space_size);
3129   char *p = tmp_space;
3130 
3131   unsigned int strings_size = 0;
3132   char *comp[4];
3133   bfd_size_type amt;
3134 
3135   /* This gets a bit gruesome because of the compilation unit.  The
3136      strings within the compilation unit are part of the symbol
3137      strings, but don't have symbol_dictionary entries.  So, manually
3138      write them and update the compilation unit header.  On input, the
3139      compilation unit header contains local copies of the strings.
3140      Move them aside.  */
3141   if (compilation_unit)
3142     {
3143       comp[0] = compilation_unit->name.n_name;
3144       comp[1] = compilation_unit->language_name.n_name;
3145       comp[2] = compilation_unit->product_id.n_name;
3146       comp[3] = compilation_unit->version_id.n_name;
3147     }
3148 
3149   /* Seek to the start of the space strings in preparation for writing
3150      them out.  */
3151   if (bfd_seek (abfd, (file_ptr) current_offset, SEEK_SET) != 0)
3152     return FALSE;
3153 
3154   if (compilation_unit)
3155     {
3156       for (i = 0; i < 4; i++)
3157 	{
3158 	  size_t length = strlen (comp[i]);
3159 
3160 	  /* If there is not enough room for the next entry, then dump
3161 	     the current buffer contents now and maybe allocate a
3162 	     larger buffer.  */
3163 	  if (p - tmp_space + 5 + length > tmp_space_size)
3164 	    {
3165 	      /* Flush buffer before refilling or reallocating.  */
3166 	      amt = p - tmp_space;
3167 	      if (bfd_bwrite ((void *) &tmp_space[0], amt, abfd) != amt)
3168 		return FALSE;
3169 
3170 	      /* Reallocate if now empty buffer still too small.  */
3171 	      if (5 + length > tmp_space_size)
3172 		{
3173 		  /* See alloca above for discussion of new size.  */
3174 		  tmp_space_size = MAX (2 * tmp_space_size, 5 + length);
3175 		  tmp_space = alloca (tmp_space_size);
3176 		}
3177 
3178 	      /* Reset to beginning of the (possibly new) buffer
3179 		 space.  */
3180 	      p = tmp_space;
3181 	    }
3182 
3183 	  /* First element in a string table entry is the length of
3184 	     the string.  This must always be 4 byte aligned.  This is
3185 	     also an appropriate time to fill in the string index
3186 	     field in the symbol table entry.  */
3187 	  bfd_put_32 (abfd, (bfd_vma) length, p);
3188 	  strings_size += 4;
3189 	  p += 4;
3190 
3191 	  /* Next comes the string itself + a null terminator.  */
3192 	  strcpy (p, comp[i]);
3193 
3194 	  switch (i)
3195 	    {
3196 	    case 0:
3197 	      obj_som_compilation_unit (abfd)->name.n_strx = strings_size;
3198 	      break;
3199 	    case 1:
3200 	      obj_som_compilation_unit (abfd)->language_name.n_strx =
3201 		strings_size;
3202 	      break;
3203 	    case 2:
3204 	      obj_som_compilation_unit (abfd)->product_id.n_strx =
3205 		strings_size;
3206 	      break;
3207 	    case 3:
3208 	      obj_som_compilation_unit (abfd)->version_id.n_strx =
3209 		strings_size;
3210 	      break;
3211 	    }
3212 
3213 	  p += length + 1;
3214 	  strings_size += length + 1;
3215 
3216 	  /* Always align up to the next word boundary.  */
3217 	  while (strings_size % 4)
3218 	    {
3219 	      bfd_put_8 (abfd, 0, p);
3220 	      strings_size++;
3221 	      p++;
3222 	    }
3223 	}
3224     }
3225 
3226   for (i = 0; i < num_syms; i++)
3227     {
3228       size_t length = strlen (syms[i]->name);
3229 
3230       /* If there is not enough room for the next entry, then dump the
3231 	 current buffer contents now and maybe allocate a larger buffer.  */
3232      if (p - tmp_space + 5 + length > tmp_space_size)
3233 	{
3234 	  /* Flush buffer before refilling or reallocating.  */
3235 	  amt = p - tmp_space;
3236 	  if (bfd_bwrite ((void *) &tmp_space[0], amt, abfd) != amt)
3237 	    return FALSE;
3238 
3239 	  /* Reallocate if now empty buffer still too small.  */
3240 	  if (5 + length > tmp_space_size)
3241 	    {
3242 	      /* See alloca above for discussion of new size.  */
3243 	      tmp_space_size = MAX (2 * tmp_space_size, 5 + length);
3244 	      tmp_space = alloca (tmp_space_size);
3245 	    }
3246 
3247 	  /* Reset to beginning of the (possibly new) buffer space.  */
3248 	  p = tmp_space;
3249 	}
3250 
3251       /* First element in a string table entry is the length of the
3252 	 string.  This must always be 4 byte aligned.  This is also
3253 	 an appropriate time to fill in the string index field in the
3254 	 symbol table entry.  */
3255       bfd_put_32 (abfd, (bfd_vma) length, p);
3256       strings_size += 4;
3257       p += 4;
3258 
3259       /* Next comes the string itself + a null terminator.  */
3260       strcpy (p, syms[i]->name);
3261 
3262       som_symbol_data (syms[i])->stringtab_offset = strings_size;
3263       p += length + 1;
3264       strings_size += length + 1;
3265 
3266       /* Always align up to the next word boundary.  */
3267       while (strings_size % 4)
3268 	{
3269 	  bfd_put_8 (abfd, 0, p);
3270 	  strings_size++;
3271 	  p++;
3272 	}
3273     }
3274 
3275   /* Scribble out any partial block.  */
3276   amt = p - tmp_space;
3277   if (bfd_bwrite ((void *) &tmp_space[0], amt, abfd) != amt)
3278     return FALSE;
3279 
3280   *string_sizep = strings_size;
3281   return TRUE;
3282 }
3283 
3284 /* Compute variable information to be placed in the SOM headers,
3285    space/subspace dictionaries, relocation streams, etc.  Begin
3286    writing parts of the object file.  */
3287 
3288 static bfd_boolean
3289 som_begin_writing (bfd *abfd)
3290 {
3291   unsigned long current_offset = 0;
3292   unsigned int strings_size = 0;
3293   unsigned long num_spaces, num_subspaces, i;
3294   asection *section;
3295   unsigned int total_subspaces = 0;
3296   struct som_exec_auxhdr *exec_header = NULL;
3297 
3298   /* The file header will always be first in an object file,
3299      everything else can be in random locations.  To keep things
3300      "simple" BFD will lay out the object file in the manner suggested
3301      by the PRO ABI for PA-RISC Systems.  */
3302 
3303   /* Before any output can really begin offsets for all the major
3304      portions of the object file must be computed.  So, starting
3305      with the initial file header compute (and sometimes write)
3306      each portion of the object file.  */
3307 
3308   /* Make room for the file header, it's contents are not complete
3309      yet, so it can not be written at this time.  */
3310   current_offset += sizeof (struct header);
3311 
3312   /* Any auxiliary headers will follow the file header.  Right now
3313      we support only the copyright and version headers.  */
3314   obj_som_file_hdr (abfd)->aux_header_location = current_offset;
3315   obj_som_file_hdr (abfd)->aux_header_size = 0;
3316   if (abfd->flags & (EXEC_P | DYNAMIC))
3317     {
3318       /* Parts of the exec header will be filled in later, so
3319 	 delay writing the header itself.  Fill in the defaults,
3320 	 and write it later.  */
3321       current_offset += sizeof (struct som_exec_auxhdr);
3322       obj_som_file_hdr (abfd)->aux_header_size
3323 	+= sizeof (struct som_exec_auxhdr);
3324       exec_header = obj_som_exec_hdr (abfd);
3325       exec_header->som_auxhdr.type = EXEC_AUX_ID;
3326       exec_header->som_auxhdr.length = 40;
3327     }
3328   if (obj_som_version_hdr (abfd) != NULL)
3329     {
3330       bfd_size_type len;
3331 
3332       if (bfd_seek (abfd, (file_ptr) current_offset, SEEK_SET) != 0)
3333 	return FALSE;
3334 
3335       /* Write the aux_id structure and the string length.  */
3336       len = sizeof (struct aux_id) + sizeof (unsigned int);
3337       obj_som_file_hdr (abfd)->aux_header_size += len;
3338       current_offset += len;
3339       if (bfd_bwrite ((void *) obj_som_version_hdr (abfd), len, abfd) != len)
3340 	return FALSE;
3341 
3342       /* Write the version string.  */
3343       len = obj_som_version_hdr (abfd)->header_id.length - sizeof (int);
3344       obj_som_file_hdr (abfd)->aux_header_size += len;
3345       current_offset += len;
3346       if (bfd_bwrite ((void *) obj_som_version_hdr (abfd)->user_string, len, abfd)
3347 	  != len)
3348 	return FALSE;
3349     }
3350 
3351   if (obj_som_copyright_hdr (abfd) != NULL)
3352     {
3353       bfd_size_type len;
3354 
3355       if (bfd_seek (abfd, (file_ptr) current_offset, SEEK_SET) != 0)
3356 	return FALSE;
3357 
3358       /* Write the aux_id structure and the string length.  */
3359       len = sizeof (struct aux_id) + sizeof (unsigned int);
3360       obj_som_file_hdr (abfd)->aux_header_size += len;
3361       current_offset += len;
3362       if (bfd_bwrite ((void *) obj_som_copyright_hdr (abfd), len, abfd) != len)
3363 	return FALSE;
3364 
3365       /* Write the copyright string.  */
3366       len = obj_som_copyright_hdr (abfd)->header_id.length - sizeof (int);
3367       obj_som_file_hdr (abfd)->aux_header_size += len;
3368       current_offset += len;
3369       if (bfd_bwrite ((void *) obj_som_copyright_hdr (abfd)->copyright, len, abfd)
3370 	  != len)
3371 	return FALSE;
3372     }
3373 
3374   /* Next comes the initialization pointers; we have no initialization
3375      pointers, so current offset does not change.  */
3376   obj_som_file_hdr (abfd)->init_array_location = current_offset;
3377   obj_som_file_hdr (abfd)->init_array_total = 0;
3378 
3379   /* Next are the space records.  These are fixed length records.
3380 
3381      Count the number of spaces to determine how much room is needed
3382      in the object file for the space records.
3383 
3384      The names of the spaces are stored in a separate string table,
3385      and the index for each space into the string table is computed
3386      below.  Therefore, it is not possible to write the space headers
3387      at this time.  */
3388   num_spaces = som_count_spaces (abfd);
3389   obj_som_file_hdr (abfd)->space_location = current_offset;
3390   obj_som_file_hdr (abfd)->space_total = num_spaces;
3391   current_offset += num_spaces * sizeof (struct space_dictionary_record);
3392 
3393   /* Next are the subspace records.  These are fixed length records.
3394 
3395      Count the number of subspaes to determine how much room is needed
3396      in the object file for the subspace records.
3397 
3398      A variety if fields in the subspace record are still unknown at
3399      this time (index into string table, fixup stream location/size, etc).  */
3400   num_subspaces = som_count_subspaces (abfd);
3401   obj_som_file_hdr (abfd)->subspace_location = current_offset;
3402   obj_som_file_hdr (abfd)->subspace_total = num_subspaces;
3403   current_offset
3404     += num_subspaces * sizeof (struct som_subspace_dictionary_record);
3405 
3406   /* Next is the string table for the space/subspace names.  We will
3407      build and write the string table on the fly.  At the same time
3408      we will fill in the space/subspace name index fields.  */
3409 
3410   /* The string table needs to be aligned on a word boundary.  */
3411   if (current_offset % 4)
3412     current_offset += (4 - (current_offset % 4));
3413 
3414   /* Mark the offset of the space/subspace string table in the
3415      file header.  */
3416   obj_som_file_hdr (abfd)->space_strings_location = current_offset;
3417 
3418   /* Scribble out the space strings.  */
3419   if (! som_write_space_strings (abfd, current_offset, &strings_size))
3420     return FALSE;
3421 
3422   /* Record total string table size in the header and update the
3423      current offset.  */
3424   obj_som_file_hdr (abfd)->space_strings_size = strings_size;
3425   current_offset += strings_size;
3426 
3427   /* Next is the compilation unit.  */
3428   obj_som_file_hdr (abfd)->compiler_location = current_offset;
3429   obj_som_file_hdr (abfd)->compiler_total = 0;
3430   if (obj_som_compilation_unit (abfd))
3431     {
3432       obj_som_file_hdr (abfd)->compiler_total = 1;
3433       current_offset += COMPUNITSZ;
3434     }
3435 
3436   /* Now compute the file positions for the loadable subspaces, taking
3437      care to make sure everything stays properly aligned.  */
3438 
3439   section = abfd->sections;
3440   for (i = 0; i < num_spaces; i++)
3441     {
3442       asection *subsection;
3443       int first_subspace;
3444       unsigned int subspace_offset = 0;
3445 
3446       /* Find a space.  */
3447       while (!som_is_space (section))
3448 	section = section->next;
3449 
3450       first_subspace = 1;
3451       /* Now look for all its subspaces.  */
3452       for (subsection = abfd->sections;
3453 	   subsection != NULL;
3454 	   subsection = subsection->next)
3455 	{
3456 
3457 	  if (!som_is_subspace (subsection)
3458 	      || !som_is_container (section, subsection)
3459 	      || (subsection->flags & SEC_ALLOC) == 0)
3460 	    continue;
3461 
3462 	  /* If this is the first subspace in the space, and we are
3463 	     building an executable, then take care to make sure all
3464 	     the alignments are correct and update the exec header.  */
3465 	  if (first_subspace
3466 	      && (abfd->flags & (EXEC_P | DYNAMIC)))
3467 	    {
3468 	      /* Demand paged executables have each space aligned to a
3469 		 page boundary.  Sharable executables (write-protected
3470 		 text) have just the private (aka data & bss) space aligned
3471 		 to a page boundary.  Ugh.  Not true for HPUX.
3472 
3473 		 The HPUX kernel requires the text to always be page aligned
3474 		 within the file regardless of the executable's type.  */
3475 	      if (abfd->flags & (D_PAGED | DYNAMIC)
3476 		  || (subsection->flags & SEC_CODE)
3477 		  || ((abfd->flags & WP_TEXT)
3478 		      && (subsection->flags & SEC_DATA)))
3479 		current_offset = SOM_ALIGN (current_offset, PA_PAGESIZE);
3480 
3481 	      /* Update the exec header.  */
3482 	      if (subsection->flags & SEC_CODE && exec_header->exec_tfile == 0)
3483 		{
3484 		  exec_header->exec_tmem = section->vma;
3485 		  exec_header->exec_tfile = current_offset;
3486 		}
3487 	      if (subsection->flags & SEC_DATA && exec_header->exec_dfile == 0)
3488 		{
3489 		  exec_header->exec_dmem = section->vma;
3490 		  exec_header->exec_dfile = current_offset;
3491 		}
3492 
3493 	      /* Keep track of exactly where we are within a particular
3494 		 space.  This is necessary as the braindamaged HPUX
3495 		 loader will create holes between subspaces *and*
3496 		 subspace alignments are *NOT* preserved.  What a crock.  */
3497 	      subspace_offset = subsection->vma;
3498 
3499 	      /* Only do this for the first subspace within each space.  */
3500 	      first_subspace = 0;
3501 	    }
3502 	  else if (abfd->flags & (EXEC_P | DYNAMIC))
3503 	    {
3504 	      /* The braindamaged HPUX loader may have created a hole
3505 		 between two subspaces.  It is *not* sufficient to use
3506 		 the alignment specifications within the subspaces to
3507 		 account for these holes -- I've run into at least one
3508 		 case where the loader left one code subspace unaligned
3509 		 in a final executable.
3510 
3511 		 To combat this we keep a current offset within each space,
3512 		 and use the subspace vma fields to detect and preserve
3513 		 holes.  What a crock!
3514 
3515 		 ps.  This is not necessary for unloadable space/subspaces.  */
3516 	      current_offset += subsection->vma - subspace_offset;
3517 	      if (subsection->flags & SEC_CODE)
3518 		exec_header->exec_tsize += subsection->vma - subspace_offset;
3519 	      else
3520 		exec_header->exec_dsize += subsection->vma - subspace_offset;
3521 	      subspace_offset += subsection->vma - subspace_offset;
3522 	    }
3523 
3524 	  subsection->target_index = total_subspaces++;
3525 	  /* This is real data to be loaded from the file.  */
3526 	  if (subsection->flags & SEC_LOAD)
3527 	    {
3528 	      /* Update the size of the code & data.  */
3529 	      if (abfd->flags & (EXEC_P | DYNAMIC)
3530 		  && subsection->flags & SEC_CODE)
3531 		exec_header->exec_tsize += subsection->size;
3532 	      else if (abfd->flags & (EXEC_P | DYNAMIC)
3533 		       && subsection->flags & SEC_DATA)
3534 		exec_header->exec_dsize += subsection->size;
3535 	      som_section_data (subsection)->subspace_dict->file_loc_init_value
3536 		= current_offset;
3537 	      subsection->filepos = current_offset;
3538 	      current_offset += subsection->size;
3539 	      subspace_offset += subsection->size;
3540 	    }
3541 	  /* Looks like uninitialized data.  */
3542 	  else
3543 	    {
3544 	      /* Update the size of the bss section.  */
3545 	      if (abfd->flags & (EXEC_P | DYNAMIC))
3546 		exec_header->exec_bsize += subsection->size;
3547 
3548 	      som_section_data (subsection)->subspace_dict->file_loc_init_value
3549 		= 0;
3550 	      som_section_data (subsection)->subspace_dict->
3551 		initialization_length = 0;
3552 	    }
3553 	}
3554       /* Goto the next section.  */
3555       section = section->next;
3556     }
3557 
3558   /* Finally compute the file positions for unloadable subspaces.
3559      If building an executable, start the unloadable stuff on its
3560      own page.  */
3561 
3562   if (abfd->flags & (EXEC_P | DYNAMIC))
3563     current_offset = SOM_ALIGN (current_offset, PA_PAGESIZE);
3564 
3565   obj_som_file_hdr (abfd)->unloadable_sp_location = current_offset;
3566   section = abfd->sections;
3567   for (i = 0; i < num_spaces; i++)
3568     {
3569       asection *subsection;
3570 
3571       /* Find a space.  */
3572       while (!som_is_space (section))
3573 	section = section->next;
3574 
3575       if (abfd->flags & (EXEC_P | DYNAMIC))
3576 	current_offset = SOM_ALIGN (current_offset, PA_PAGESIZE);
3577 
3578       /* Now look for all its subspaces.  */
3579       for (subsection = abfd->sections;
3580 	   subsection != NULL;
3581 	   subsection = subsection->next)
3582 	{
3583 
3584 	  if (!som_is_subspace (subsection)
3585 	      || !som_is_container (section, subsection)
3586 	      || (subsection->flags & SEC_ALLOC) != 0)
3587 	    continue;
3588 
3589 	  subsection->target_index = total_subspaces++;
3590 	  /* This is real data to be loaded from the file.  */
3591 	  if ((subsection->flags & SEC_LOAD) == 0)
3592 	    {
3593 	      som_section_data (subsection)->subspace_dict->file_loc_init_value
3594 		= current_offset;
3595 	      subsection->filepos = current_offset;
3596 	      current_offset += subsection->size;
3597 	    }
3598 	  /* Looks like uninitialized data.  */
3599 	  else
3600 	    {
3601 	      som_section_data (subsection)->subspace_dict->file_loc_init_value
3602 		= 0;
3603 	      som_section_data (subsection)->subspace_dict->
3604 		initialization_length = subsection->size;
3605 	    }
3606 	}
3607       /* Goto the next section.  */
3608       section = section->next;
3609     }
3610 
3611   /* If building an executable, then make sure to seek to and write
3612      one byte at the end of the file to make sure any necessary
3613      zeros are filled in.  Ugh.  */
3614   if (abfd->flags & (EXEC_P | DYNAMIC))
3615     current_offset = SOM_ALIGN (current_offset, PA_PAGESIZE);
3616   if (bfd_seek (abfd, (file_ptr) current_offset - 1, SEEK_SET) != 0)
3617     return FALSE;
3618   if (bfd_bwrite ((void *) "", (bfd_size_type) 1, abfd) != 1)
3619     return FALSE;
3620 
3621   obj_som_file_hdr (abfd)->unloadable_sp_size
3622     = current_offset - obj_som_file_hdr (abfd)->unloadable_sp_location;
3623 
3624   /* Loader fixups are not supported in any way shape or form.  */
3625   obj_som_file_hdr (abfd)->loader_fixup_location = 0;
3626   obj_som_file_hdr (abfd)->loader_fixup_total = 0;
3627 
3628   /* Done.  Store the total size of the SOM so far.  */
3629   obj_som_file_hdr (abfd)->som_length = current_offset;
3630 
3631   return TRUE;
3632 }
3633 
3634 /* Finally, scribble out the various headers to the disk.  */
3635 
3636 static bfd_boolean
3637 som_finish_writing (bfd *abfd)
3638 {
3639   int num_spaces = som_count_spaces (abfd);
3640   asymbol **syms = bfd_get_outsymbols (abfd);
3641   int i, num_syms;
3642   int subspace_index = 0;
3643   file_ptr location;
3644   asection *section;
3645   unsigned long current_offset;
3646   unsigned int strings_size, total_reloc_size;
3647   bfd_size_type amt;
3648 
3649   /* We must set up the version identifier here as objcopy/strip copy
3650      private BFD data too late for us to handle this in som_begin_writing.  */
3651   if (obj_som_exec_data (abfd)
3652       && obj_som_exec_data (abfd)->version_id)
3653     obj_som_file_hdr (abfd)->version_id = obj_som_exec_data (abfd)->version_id;
3654   else
3655     obj_som_file_hdr (abfd)->version_id = NEW_VERSION_ID;
3656 
3657   /* Next is the symbol table.  These are fixed length records.
3658 
3659      Count the number of symbols to determine how much room is needed
3660      in the object file for the symbol table.
3661 
3662      The names of the symbols are stored in a separate string table,
3663      and the index for each symbol name into the string table is computed
3664      below.  Therefore, it is not possible to write the symbol table
3665      at this time.
3666 
3667      These used to be output before the subspace contents, but they
3668      were moved here to work around a stupid bug in the hpux linker
3669      (fixed in hpux10).  */
3670   current_offset = obj_som_file_hdr (abfd)->som_length;
3671 
3672   /* Make sure we're on a word boundary.  */
3673   if (current_offset % 4)
3674     current_offset += (4 - (current_offset % 4));
3675 
3676   num_syms = bfd_get_symcount (abfd);
3677   obj_som_file_hdr (abfd)->symbol_location = current_offset;
3678   obj_som_file_hdr (abfd)->symbol_total = num_syms;
3679   current_offset += num_syms * sizeof (struct symbol_dictionary_record);
3680 
3681   /* Next are the symbol strings.
3682      Align them to a word boundary.  */
3683   if (current_offset % 4)
3684     current_offset += (4 - (current_offset % 4));
3685   obj_som_file_hdr (abfd)->symbol_strings_location = current_offset;
3686 
3687   /* Scribble out the symbol strings.  */
3688   if (! som_write_symbol_strings (abfd, current_offset, syms,
3689 				  num_syms, &strings_size,
3690 				  obj_som_compilation_unit (abfd)))
3691     return FALSE;
3692 
3693   /* Record total string table size in header and update the
3694      current offset.  */
3695   obj_som_file_hdr (abfd)->symbol_strings_size = strings_size;
3696   current_offset += strings_size;
3697 
3698   /* Do prep work before handling fixups.  */
3699   som_prep_for_fixups (abfd,
3700 		       bfd_get_outsymbols (abfd),
3701 		       bfd_get_symcount (abfd));
3702 
3703   /* At the end of the file is the fixup stream which starts on a
3704      word boundary.  */
3705   if (current_offset % 4)
3706     current_offset += (4 - (current_offset % 4));
3707   obj_som_file_hdr (abfd)->fixup_request_location = current_offset;
3708 
3709   /* Write the fixups and update fields in subspace headers which
3710      relate to the fixup stream.  */
3711   if (! som_write_fixups (abfd, current_offset, &total_reloc_size))
3712     return FALSE;
3713 
3714   /* Record the total size of the fixup stream in the file header.  */
3715   obj_som_file_hdr (abfd)->fixup_request_total = total_reloc_size;
3716 
3717   /* Done.  Store the total size of the SOM.  */
3718   obj_som_file_hdr (abfd)->som_length = current_offset + total_reloc_size;
3719 
3720   /* Now that the symbol table information is complete, build and
3721      write the symbol table.  */
3722   if (! som_build_and_write_symbol_table (abfd))
3723     return FALSE;
3724 
3725   /* Subspaces are written first so that we can set up information
3726      about them in their containing spaces as the subspace is written.  */
3727 
3728   /* Seek to the start of the subspace dictionary records.  */
3729   location = obj_som_file_hdr (abfd)->subspace_location;
3730   if (bfd_seek (abfd, location, SEEK_SET) != 0)
3731     return FALSE;
3732 
3733   section = abfd->sections;
3734   /* Now for each loadable space write out records for its subspaces.  */
3735   for (i = 0; i < num_spaces; i++)
3736     {
3737       asection *subsection;
3738 
3739       /* Find a space.  */
3740       while (!som_is_space (section))
3741 	section = section->next;
3742 
3743       /* Now look for all its subspaces.  */
3744       for (subsection = abfd->sections;
3745 	   subsection != NULL;
3746 	   subsection = subsection->next)
3747 	{
3748 
3749 	  /* Skip any section which does not correspond to a space
3750 	     or subspace.  Or does not have SEC_ALLOC set (and therefore
3751 	     has no real bits on the disk).  */
3752 	  if (!som_is_subspace (subsection)
3753 	      || !som_is_container (section, subsection)
3754 	      || (subsection->flags & SEC_ALLOC) == 0)
3755 	    continue;
3756 
3757 	  /* If this is the first subspace for this space, then save
3758 	     the index of the subspace in its containing space.  Also
3759 	     set "is_loadable" in the containing space.  */
3760 
3761 	  if (som_section_data (section)->space_dict->subspace_quantity == 0)
3762 	    {
3763 	      som_section_data (section)->space_dict->is_loadable = 1;
3764 	      som_section_data (section)->space_dict->subspace_index
3765 		= subspace_index;
3766 	    }
3767 
3768 	  /* Increment the number of subspaces seen and the number of
3769 	     subspaces contained within the current space.  */
3770 	  subspace_index++;
3771 	  som_section_data (section)->space_dict->subspace_quantity++;
3772 
3773 	  /* Mark the index of the current space within the subspace's
3774 	     dictionary record.  */
3775 	  som_section_data (subsection)->subspace_dict->space_index = i;
3776 
3777 	  /* Dump the current subspace header.  */
3778 	  amt = sizeof (struct som_subspace_dictionary_record);
3779 	  if (bfd_bwrite ((void *) som_section_data (subsection)->subspace_dict,
3780 			 amt, abfd) != amt)
3781 	    return FALSE;
3782 	}
3783       /* Goto the next section.  */
3784       section = section->next;
3785     }
3786 
3787   /* Now repeat the process for unloadable subspaces.  */
3788   section = abfd->sections;
3789   /* Now for each space write out records for its subspaces.  */
3790   for (i = 0; i < num_spaces; i++)
3791     {
3792       asection *subsection;
3793 
3794       /* Find a space.  */
3795       while (!som_is_space (section))
3796 	section = section->next;
3797 
3798       /* Now look for all its subspaces.  */
3799       for (subsection = abfd->sections;
3800 	   subsection != NULL;
3801 	   subsection = subsection->next)
3802 	{
3803 
3804 	  /* Skip any section which does not correspond to a space or
3805 	     subspace, or which SEC_ALLOC set (and therefore handled
3806 	     in the loadable spaces/subspaces code above).  */
3807 
3808 	  if (!som_is_subspace (subsection)
3809 	      || !som_is_container (section, subsection)
3810 	      || (subsection->flags & SEC_ALLOC) != 0)
3811 	    continue;
3812 
3813 	  /* If this is the first subspace for this space, then save
3814 	     the index of the subspace in its containing space.  Clear
3815 	     "is_loadable".  */
3816 
3817 	  if (som_section_data (section)->space_dict->subspace_quantity == 0)
3818 	    {
3819 	      som_section_data (section)->space_dict->is_loadable = 0;
3820 	      som_section_data (section)->space_dict->subspace_index
3821 		= subspace_index;
3822 	    }
3823 
3824 	  /* Increment the number of subspaces seen and the number of
3825 	     subspaces contained within the current space.  */
3826 	  som_section_data (section)->space_dict->subspace_quantity++;
3827 	  subspace_index++;
3828 
3829 	  /* Mark the index of the current space within the subspace's
3830 	     dictionary record.  */
3831 	  som_section_data (subsection)->subspace_dict->space_index = i;
3832 
3833 	  /* Dump this subspace header.  */
3834 	  amt = sizeof (struct som_subspace_dictionary_record);
3835 	  if (bfd_bwrite ((void *) som_section_data (subsection)->subspace_dict,
3836 			 amt, abfd) != amt)
3837 	    return FALSE;
3838 	}
3839       /* Goto the next section.  */
3840       section = section->next;
3841     }
3842 
3843   /* All the subspace dictionary records are written, and all the
3844      fields are set up in the space dictionary records.
3845 
3846      Seek to the right location and start writing the space
3847      dictionary records.  */
3848   location = obj_som_file_hdr (abfd)->space_location;
3849   if (bfd_seek (abfd, location, SEEK_SET) != 0)
3850     return FALSE;
3851 
3852   section = abfd->sections;
3853   for (i = 0; i < num_spaces; i++)
3854     {
3855       /* Find a space.  */
3856       while (!som_is_space (section))
3857 	section = section->next;
3858 
3859       /* Dump its header.  */
3860       amt = sizeof (struct space_dictionary_record);
3861       if (bfd_bwrite ((void *) som_section_data (section)->space_dict,
3862 		     amt, abfd) != amt)
3863 	return FALSE;
3864 
3865       /* Goto the next section.  */
3866       section = section->next;
3867     }
3868 
3869   /* Write the compilation unit record if there is one.  */
3870   if (obj_som_compilation_unit (abfd))
3871     {
3872       location = obj_som_file_hdr (abfd)->compiler_location;
3873       if (bfd_seek (abfd, location, SEEK_SET) != 0)
3874 	return FALSE;
3875 
3876       amt = COMPUNITSZ;
3877       if (bfd_bwrite ((void *) obj_som_compilation_unit (abfd), amt, abfd) != amt)
3878 	return FALSE;
3879     }
3880 
3881   /* Setting of the system_id has to happen very late now that copying of
3882      BFD private data happens *after* section contents are set.  */
3883   if (abfd->flags & (EXEC_P | DYNAMIC))
3884     obj_som_file_hdr (abfd)->system_id = obj_som_exec_data (abfd)->system_id;
3885   else if (bfd_get_mach (abfd) == pa20)
3886     obj_som_file_hdr (abfd)->system_id = CPU_PA_RISC2_0;
3887   else if (bfd_get_mach (abfd) == pa11)
3888     obj_som_file_hdr (abfd)->system_id = CPU_PA_RISC1_1;
3889   else
3890     obj_som_file_hdr (abfd)->system_id = CPU_PA_RISC1_0;
3891 
3892   /* Compute the checksum for the file header just before writing
3893      the header to disk.  */
3894   obj_som_file_hdr (abfd)->checksum = som_compute_checksum (abfd);
3895 
3896   /* Only thing left to do is write out the file header.  It is always
3897      at location zero.  Seek there and write it.  */
3898   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
3899     return FALSE;
3900   amt = sizeof (struct header);
3901   if (bfd_bwrite ((void *) obj_som_file_hdr (abfd), amt, abfd) != amt)
3902     return FALSE;
3903 
3904   /* Now write the exec header.  */
3905   if (abfd->flags & (EXEC_P | DYNAMIC))
3906     {
3907       long tmp, som_length;
3908       struct som_exec_auxhdr *exec_header;
3909 
3910       exec_header = obj_som_exec_hdr (abfd);
3911       exec_header->exec_entry = bfd_get_start_address (abfd);
3912       exec_header->exec_flags = obj_som_exec_data (abfd)->exec_flags;
3913 
3914       /* Oh joys.  Ram some of the BSS data into the DATA section
3915 	 to be compatible with how the hp linker makes objects
3916 	 (saves memory space).  */
3917       tmp = exec_header->exec_dsize;
3918       tmp = SOM_ALIGN (tmp, PA_PAGESIZE);
3919       exec_header->exec_bsize -= (tmp - exec_header->exec_dsize);
3920       if (exec_header->exec_bsize < 0)
3921 	exec_header->exec_bsize = 0;
3922       exec_header->exec_dsize = tmp;
3923 
3924       /* Now perform some sanity checks.  The idea is to catch bogons now and
3925 	 inform the user, instead of silently generating a bogus file.  */
3926       som_length = obj_som_file_hdr (abfd)->som_length;
3927       if (exec_header->exec_tfile + exec_header->exec_tsize > som_length
3928 	  || exec_header->exec_dfile + exec_header->exec_dsize > som_length)
3929 	{
3930 	  bfd_set_error (bfd_error_bad_value);
3931 	  return FALSE;
3932 	}
3933 
3934       if (bfd_seek (abfd, obj_som_file_hdr (abfd)->aux_header_location,
3935 		    SEEK_SET) != 0)
3936 	return FALSE;
3937 
3938       amt = AUX_HDR_SIZE;
3939       if (bfd_bwrite ((void *) exec_header, amt, abfd) != amt)
3940 	return FALSE;
3941     }
3942   return TRUE;
3943 }
3944 
3945 /* Compute and return the checksum for a SOM file header.  */
3946 
3947 static unsigned long
3948 som_compute_checksum (bfd *abfd)
3949 {
3950   unsigned long checksum, count, i;
3951   unsigned long *buffer = (unsigned long *) obj_som_file_hdr (abfd);
3952 
3953   checksum = 0;
3954   count = sizeof (struct header) / sizeof (unsigned long);
3955   for (i = 0; i < count; i++)
3956     checksum ^= *(buffer + i);
3957 
3958   return checksum;
3959 }
3960 
3961 static void
3962 som_bfd_derive_misc_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
3963 				 asymbol *sym,
3964 				 struct som_misc_symbol_info *info)
3965 {
3966   /* Initialize.  */
3967   memset (info, 0, sizeof (struct som_misc_symbol_info));
3968 
3969   /* The HP SOM linker requires detailed type information about
3970      all symbols (including undefined symbols!).  Unfortunately,
3971      the type specified in an import/export statement does not
3972      always match what the linker wants.  Severe braindamage.  */
3973 
3974   /* Section symbols will not have a SOM symbol type assigned to
3975      them yet.  Assign all section symbols type ST_DATA.  */
3976   if (sym->flags & BSF_SECTION_SYM)
3977     info->symbol_type = ST_DATA;
3978   else
3979     {
3980       /* For BFD style common, the linker will choke unless we set the
3981 	 type and scope to ST_STORAGE and SS_UNSAT, respectively.  */
3982       if (bfd_is_com_section (sym->section))
3983 	{
3984 	  info->symbol_type = ST_STORAGE;
3985 	  info->symbol_scope = SS_UNSAT;
3986 	}
3987 
3988       /* It is possible to have a symbol without an associated
3989 	 type.  This happens if the user imported the symbol
3990 	 without a type and the symbol was never defined
3991 	 locally.  If BSF_FUNCTION is set for this symbol, then
3992 	 assign it type ST_CODE (the HP linker requires undefined
3993 	 external functions to have type ST_CODE rather than ST_ENTRY).  */
3994       else if ((som_symbol_data (sym)->som_type == SYMBOL_TYPE_UNKNOWN
3995 		|| som_symbol_data (sym)->som_type == SYMBOL_TYPE_CODE)
3996 	       && bfd_is_und_section (sym->section)
3997 	       && sym->flags & BSF_FUNCTION)
3998 	info->symbol_type = ST_CODE;
3999 
4000       /* Handle function symbols which were defined in this file.
4001 	 They should have type ST_ENTRY.  Also retrieve the argument
4002 	 relocation bits from the SOM backend information.  */
4003       else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_ENTRY
4004 	       || (som_symbol_data (sym)->som_type == SYMBOL_TYPE_CODE
4005 		   && (sym->flags & BSF_FUNCTION))
4006 	       || (som_symbol_data (sym)->som_type == SYMBOL_TYPE_UNKNOWN
4007 		   && (sym->flags & BSF_FUNCTION)))
4008 	{
4009 	  info->symbol_type = ST_ENTRY;
4010 	  info->arg_reloc = som_symbol_data (sym)->tc_data.ap.hppa_arg_reloc;
4011 	  info->priv_level= som_symbol_data (sym)->tc_data.ap.hppa_priv_level;
4012 	}
4013 
4014       /* For unknown symbols set the symbol's type based on the symbol's
4015 	 section (ST_DATA for DATA sections, ST_CODE for CODE sections).  */
4016       else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_UNKNOWN)
4017 	{
4018 	  if (sym->section->flags & SEC_CODE)
4019 	    info->symbol_type = ST_CODE;
4020 	  else
4021 	    info->symbol_type = ST_DATA;
4022 	}
4023 
4024       /* From now on it's a very simple mapping.  */
4025       else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_ABSOLUTE)
4026 	info->symbol_type = ST_ABSOLUTE;
4027       else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_CODE)
4028 	info->symbol_type = ST_CODE;
4029       else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_DATA)
4030 	info->symbol_type = ST_DATA;
4031       else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_MILLICODE)
4032 	info->symbol_type = ST_MILLICODE;
4033       else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_PLABEL)
4034 	info->symbol_type = ST_PLABEL;
4035       else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_PRI_PROG)
4036 	info->symbol_type = ST_PRI_PROG;
4037       else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_SEC_PROG)
4038 	info->symbol_type = ST_SEC_PROG;
4039     }
4040 
4041   /* Now handle the symbol's scope.  Exported data which is not
4042      in the common section has scope SS_UNIVERSAL.  Note scope
4043      of common symbols was handled earlier!  */
4044   if (bfd_is_com_section (sym->section))
4045     ;
4046   else if (bfd_is_und_section (sym->section))
4047     info->symbol_scope = SS_UNSAT;
4048   else if (sym->flags & (BSF_EXPORT | BSF_WEAK))
4049     info->symbol_scope = SS_UNIVERSAL;
4050   /* Anything else which is not in the common section has scope
4051      SS_LOCAL.  */
4052   else
4053     info->symbol_scope = SS_LOCAL;
4054 
4055   /* Now set the symbol_info field.  It has no real meaning
4056      for undefined or common symbols, but the HP linker will
4057      choke if it's not set to some "reasonable" value.  We
4058      use zero as a reasonable value.  */
4059   if (bfd_is_com_section (sym->section)
4060       || bfd_is_und_section (sym->section)
4061       || bfd_is_abs_section (sym->section))
4062     info->symbol_info = 0;
4063   /* For all other symbols, the symbol_info field contains the
4064      subspace index of the space this symbol is contained in.  */
4065   else
4066     info->symbol_info = sym->section->target_index;
4067 
4068   /* Set the symbol's value.  */
4069   info->symbol_value = sym->value + sym->section->vma;
4070 
4071   /* The secondary_def field is for "weak" symbols.  */
4072   if (sym->flags & BSF_WEAK)
4073     info->secondary_def = TRUE;
4074   else
4075     info->secondary_def = FALSE;
4076 
4077   /* The is_comdat, is_common and dup_common fields provide various
4078      flavors of common.
4079 
4080      For data symbols, setting IS_COMMON provides Fortran style common
4081      (duplicate definitions and overlapped initialization).  Setting both
4082      IS_COMMON and DUP_COMMON provides Cobol style common (duplicate
4083      definitions as long as they are all the same length).  In a shared
4084      link data symbols retain their IS_COMMON and DUP_COMMON flags.
4085      An IS_COMDAT data symbol is similar to a IS_COMMON | DUP_COMMON
4086      symbol except in that it loses its IS_COMDAT flag in a shared link.
4087 
4088      For code symbols, IS_COMDAT and DUP_COMMON have effect.  Universal
4089      DUP_COMMON code symbols are not exported from shared libraries.
4090      IS_COMDAT symbols are exported but they lose their IS_COMDAT flag.
4091 
4092      We take a simplified approach to setting the is_comdat, is_common
4093      and dup_common flags in symbols based on the flag settings of their
4094      subspace.  This avoids having to add directives like `.comdat' but
4095      the linker behavior is probably undefined if there is more than one
4096      universal symbol (comdat key sysmbol) in a subspace.
4097 
4098      The behavior of these flags is not well documentmented, so there
4099      may be bugs and some surprising interactions with other flags.  */
4100   if (som_section_data (sym->section)
4101       && som_section_data (sym->section)->subspace_dict
4102       && info->symbol_scope == SS_UNIVERSAL
4103       && (info->symbol_type == ST_ENTRY
4104 	  || info->symbol_type == ST_CODE
4105 	  || info->symbol_type == ST_DATA))
4106     {
4107       info->is_comdat
4108 	= som_section_data (sym->section)->subspace_dict->is_comdat;
4109       info->is_common
4110 	= som_section_data (sym->section)->subspace_dict->is_common;
4111       info->dup_common
4112 	= som_section_data (sym->section)->subspace_dict->dup_common;
4113     }
4114 }
4115 
4116 /* Build and write, in one big chunk, the entire symbol table for
4117    this BFD.  */
4118 
4119 static bfd_boolean
4120 som_build_and_write_symbol_table (bfd *abfd)
4121 {
4122   unsigned int num_syms = bfd_get_symcount (abfd);
4123   file_ptr symtab_location = obj_som_file_hdr (abfd)->symbol_location;
4124   asymbol **bfd_syms = obj_som_sorted_syms (abfd);
4125   struct symbol_dictionary_record *som_symtab = NULL;
4126   unsigned int i;
4127   bfd_size_type symtab_size;
4128 
4129   /* Compute total symbol table size and allocate a chunk of memory
4130      to hold the symbol table as we build it.  */
4131   symtab_size = num_syms;
4132   symtab_size *= sizeof (struct symbol_dictionary_record);
4133   som_symtab = bfd_zmalloc (symtab_size);
4134   if (som_symtab == NULL && symtab_size != 0)
4135     goto error_return;
4136 
4137   /* Walk over each symbol.  */
4138   for (i = 0; i < num_syms; i++)
4139     {
4140       struct som_misc_symbol_info info;
4141 
4142       /* This is really an index into the symbol strings table.
4143 	 By the time we get here, the index has already been
4144 	 computed and stored into the name field in the BFD symbol.  */
4145       som_symtab[i].name.n_strx = som_symbol_data(bfd_syms[i])->stringtab_offset;
4146 
4147       /* Derive SOM information from the BFD symbol.  */
4148       som_bfd_derive_misc_symbol_info (abfd, bfd_syms[i], &info);
4149 
4150       /* Now use it.  */
4151       som_symtab[i].symbol_type = info.symbol_type;
4152       som_symtab[i].symbol_scope = info.symbol_scope;
4153       som_symtab[i].arg_reloc = info.arg_reloc;
4154       som_symtab[i].symbol_info = info.symbol_info;
4155       som_symtab[i].xleast = 3;
4156       som_symtab[i].symbol_value = info.symbol_value | info.priv_level;
4157       som_symtab[i].secondary_def = info.secondary_def;
4158       som_symtab[i].is_comdat = info.is_comdat;
4159       som_symtab[i].is_common = info.is_common;
4160       som_symtab[i].dup_common = info.dup_common;
4161     }
4162 
4163   /* Everything is ready, seek to the right location and
4164      scribble out the symbol table.  */
4165   if (bfd_seek (abfd, symtab_location, SEEK_SET) != 0)
4166     return FALSE;
4167 
4168   if (bfd_bwrite ((void *) som_symtab, symtab_size, abfd) != symtab_size)
4169     goto error_return;
4170 
4171   if (som_symtab != NULL)
4172     free (som_symtab);
4173   return TRUE;
4174  error_return:
4175   if (som_symtab != NULL)
4176     free (som_symtab);
4177   return FALSE;
4178 }
4179 
4180 /* Write an object in SOM format.  */
4181 
4182 static bfd_boolean
4183 som_write_object_contents (bfd *abfd)
4184 {
4185   if (! abfd->output_has_begun)
4186     {
4187       /* Set up fixed parts of the file, space, and subspace headers.
4188 	 Notify the world that output has begun.  */
4189       som_prep_headers (abfd);
4190       abfd->output_has_begun = TRUE;
4191       /* Start writing the object file.  This include all the string
4192 	 tables, fixup streams, and other portions of the object file.  */
4193       som_begin_writing (abfd);
4194     }
4195 
4196   return som_finish_writing (abfd);
4197 }
4198 
4199 /* Read and save the string table associated with the given BFD.  */
4200 
4201 static bfd_boolean
4202 som_slurp_string_table (bfd *abfd)
4203 {
4204   char *stringtab;
4205   bfd_size_type amt;
4206 
4207   /* Use the saved version if its available.  */
4208   if (obj_som_stringtab (abfd) != NULL)
4209     return TRUE;
4210 
4211   /* I don't think this can currently happen, and I'm not sure it should
4212      really be an error, but it's better than getting unpredictable results
4213      from the host's malloc when passed a size of zero.  */
4214   if (obj_som_stringtab_size (abfd) == 0)
4215     {
4216       bfd_set_error (bfd_error_no_symbols);
4217       return FALSE;
4218     }
4219 
4220   /* Allocate and read in the string table.  */
4221   amt = obj_som_stringtab_size (abfd);
4222   stringtab = bfd_zmalloc (amt);
4223   if (stringtab == NULL)
4224     return FALSE;
4225 
4226   if (bfd_seek (abfd, obj_som_str_filepos (abfd), SEEK_SET) != 0)
4227     return FALSE;
4228 
4229   if (bfd_bread (stringtab, amt, abfd) != amt)
4230     return FALSE;
4231 
4232   /* Save our results and return success.  */
4233   obj_som_stringtab (abfd) = stringtab;
4234   return TRUE;
4235 }
4236 
4237 /* Return the amount of data (in bytes) required to hold the symbol
4238    table for this object.  */
4239 
4240 static long
4241 som_get_symtab_upper_bound (bfd *abfd)
4242 {
4243   if (!som_slurp_symbol_table (abfd))
4244     return -1;
4245 
4246   return (bfd_get_symcount (abfd) + 1) * sizeof (asymbol *);
4247 }
4248 
4249 /* Convert from a SOM subspace index to a BFD section.  */
4250 
4251 static asection *
4252 bfd_section_from_som_symbol (bfd *abfd, struct symbol_dictionary_record *symbol)
4253 {
4254   asection *section;
4255 
4256   /* The meaning of the symbol_info field changes for functions
4257      within executables.  So only use the quick symbol_info mapping for
4258      incomplete objects and non-function symbols in executables.  */
4259   if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0
4260       || (symbol->symbol_type != ST_ENTRY
4261 	  && symbol->symbol_type != ST_PRI_PROG
4262 	  && symbol->symbol_type != ST_SEC_PROG
4263 	  && symbol->symbol_type != ST_MILLICODE))
4264     {
4265       int index = symbol->symbol_info;
4266 
4267       for (section = abfd->sections; section != NULL; section = section->next)
4268 	if (section->target_index == index && som_is_subspace (section))
4269 	  return section;
4270     }
4271   else
4272     {
4273       unsigned int value = symbol->symbol_value;
4274 
4275       /* For executables we will have to use the symbol's address and
4276 	 find out what section would contain that address.   Yuk.  */
4277       for (section = abfd->sections; section; section = section->next)
4278 	if (value >= section->vma
4279 	    && value <= section->vma + section->size
4280 	    && som_is_subspace (section))
4281 	  return section;
4282     }
4283 
4284   /* Could be a symbol from an external library (such as an OMOS
4285      shared library).  Don't abort.  */
4286   return bfd_abs_section_ptr;
4287 }
4288 
4289 /* Read and save the symbol table associated with the given BFD.  */
4290 
4291 static unsigned int
4292 som_slurp_symbol_table (bfd *abfd)
4293 {
4294   int symbol_count = bfd_get_symcount (abfd);
4295   int symsize = sizeof (struct symbol_dictionary_record);
4296   char *stringtab;
4297   struct symbol_dictionary_record *buf = NULL, *bufp, *endbufp;
4298   som_symbol_type *sym, *symbase;
4299   bfd_size_type amt;
4300 
4301   /* Return saved value if it exists.  */
4302   if (obj_som_symtab (abfd) != NULL)
4303     goto successful_return;
4304 
4305   /* Special case.  This is *not* an error.  */
4306   if (symbol_count == 0)
4307     goto successful_return;
4308 
4309   if (!som_slurp_string_table (abfd))
4310     goto error_return;
4311 
4312   stringtab = obj_som_stringtab (abfd);
4313 
4314   amt = symbol_count;
4315   amt *= sizeof (som_symbol_type);
4316   symbase = bfd_zmalloc (amt);
4317   if (symbase == NULL)
4318     goto error_return;
4319 
4320   /* Read in the external SOM representation.  */
4321   amt = symbol_count;
4322   amt *= symsize;
4323   buf = bfd_malloc (amt);
4324   if (buf == NULL && amt != 0)
4325     goto error_return;
4326   if (bfd_seek (abfd, obj_som_sym_filepos (abfd), SEEK_SET) != 0)
4327     goto error_return;
4328   if (bfd_bread (buf, amt, abfd) != amt)
4329     goto error_return;
4330 
4331   /* Iterate over all the symbols and internalize them.  */
4332   endbufp = buf + symbol_count;
4333   for (bufp = buf, sym = symbase; bufp < endbufp; ++bufp)
4334     {
4335       /* I don't think we care about these.  */
4336       if (bufp->symbol_type == ST_SYM_EXT
4337 	  || bufp->symbol_type == ST_ARG_EXT)
4338 	continue;
4339 
4340       /* Set some private data we care about.  */
4341       if (bufp->symbol_type == ST_NULL)
4342 	som_symbol_data (sym)->som_type = SYMBOL_TYPE_UNKNOWN;
4343       else if (bufp->symbol_type == ST_ABSOLUTE)
4344 	som_symbol_data (sym)->som_type = SYMBOL_TYPE_ABSOLUTE;
4345       else if (bufp->symbol_type == ST_DATA)
4346 	som_symbol_data (sym)->som_type = SYMBOL_TYPE_DATA;
4347       else if (bufp->symbol_type == ST_CODE)
4348 	som_symbol_data (sym)->som_type = SYMBOL_TYPE_CODE;
4349       else if (bufp->symbol_type == ST_PRI_PROG)
4350 	som_symbol_data (sym)->som_type = SYMBOL_TYPE_PRI_PROG;
4351       else if (bufp->symbol_type == ST_SEC_PROG)
4352 	som_symbol_data (sym)->som_type = SYMBOL_TYPE_SEC_PROG;
4353       else if (bufp->symbol_type == ST_ENTRY)
4354 	som_symbol_data (sym)->som_type = SYMBOL_TYPE_ENTRY;
4355       else if (bufp->symbol_type == ST_MILLICODE)
4356 	som_symbol_data (sym)->som_type = SYMBOL_TYPE_MILLICODE;
4357       else if (bufp->symbol_type == ST_PLABEL)
4358 	som_symbol_data (sym)->som_type = SYMBOL_TYPE_PLABEL;
4359       else
4360 	som_symbol_data (sym)->som_type = SYMBOL_TYPE_UNKNOWN;
4361       som_symbol_data (sym)->tc_data.ap.hppa_arg_reloc = bufp->arg_reloc;
4362 
4363       /* Some reasonable defaults.  */
4364       sym->symbol.the_bfd = abfd;
4365       sym->symbol.name = bufp->name.n_strx + stringtab;
4366       sym->symbol.value = bufp->symbol_value;
4367       sym->symbol.section = 0;
4368       sym->symbol.flags = 0;
4369 
4370       switch (bufp->symbol_type)
4371 	{
4372 	case ST_ENTRY:
4373 	case ST_MILLICODE:
4374 	  sym->symbol.flags |= BSF_FUNCTION;
4375 	  som_symbol_data (sym)->tc_data.ap.hppa_priv_level =
4376 	    sym->symbol.value & 0x3;
4377 	  sym->symbol.value &= ~0x3;
4378 	  break;
4379 
4380 	case ST_STUB:
4381 	case ST_CODE:
4382 	case ST_PRI_PROG:
4383 	case ST_SEC_PROG:
4384 	  som_symbol_data (sym)->tc_data.ap.hppa_priv_level =
4385 	    sym->symbol.value & 0x3;
4386 	  sym->symbol.value &= ~0x3;
4387 	  /* If the symbol's scope is SS_UNSAT, then these are
4388 	     undefined function symbols.  */
4389 	  if (bufp->symbol_scope == SS_UNSAT)
4390 	    sym->symbol.flags |= BSF_FUNCTION;
4391 
4392 	default:
4393 	  break;
4394 	}
4395 
4396       /* Handle scoping and section information.  */
4397       switch (bufp->symbol_scope)
4398 	{
4399 	/* symbol_info field is undefined for SS_EXTERNAL and SS_UNSAT symbols,
4400 	   so the section associated with this symbol can't be known.  */
4401 	case SS_EXTERNAL:
4402 	  if (bufp->symbol_type != ST_STORAGE)
4403 	    sym->symbol.section = bfd_und_section_ptr;
4404 	  else
4405 	    sym->symbol.section = bfd_com_section_ptr;
4406 	  sym->symbol.flags |= (BSF_EXPORT | BSF_GLOBAL);
4407 	  break;
4408 
4409 	case SS_UNSAT:
4410 	  if (bufp->symbol_type != ST_STORAGE)
4411 	    sym->symbol.section = bfd_und_section_ptr;
4412 	  else
4413 	    sym->symbol.section = bfd_com_section_ptr;
4414 	  break;
4415 
4416 	case SS_UNIVERSAL:
4417 	  sym->symbol.flags |= (BSF_EXPORT | BSF_GLOBAL);
4418 	  sym->symbol.section = bfd_section_from_som_symbol (abfd, bufp);
4419 	  sym->symbol.value -= sym->symbol.section->vma;
4420 	  break;
4421 
4422 	case SS_LOCAL:
4423 	  sym->symbol.flags |= BSF_LOCAL;
4424 	  sym->symbol.section = bfd_section_from_som_symbol (abfd, bufp);
4425 	  sym->symbol.value -= sym->symbol.section->vma;
4426 	  break;
4427 	}
4428 
4429       /* Check for a weak symbol.  */
4430       if (bufp->secondary_def)
4431 	sym->symbol.flags |= BSF_WEAK;
4432 
4433       /* Mark section symbols and symbols used by the debugger.
4434 	 Note $START$ is a magic code symbol, NOT a section symbol.  */
4435       if (sym->symbol.name[0] == '$'
4436 	  && sym->symbol.name[strlen (sym->symbol.name) - 1] == '$'
4437 	  && !strcmp (sym->symbol.name, sym->symbol.section->name))
4438 	sym->symbol.flags |= BSF_SECTION_SYM;
4439       else if (CONST_STRNEQ (sym->symbol.name, "L$0\002"))
4440 	{
4441 	  sym->symbol.flags |= BSF_SECTION_SYM;
4442 	  sym->symbol.name = sym->symbol.section->name;
4443 	}
4444       else if (CONST_STRNEQ (sym->symbol.name, "L$0\001"))
4445 	sym->symbol.flags |= BSF_DEBUGGING;
4446 
4447       /* Note increment at bottom of loop, since we skip some symbols
4448 	 we can not include it as part of the for statement.  */
4449       sym++;
4450     }
4451 
4452   /* We modify the symbol count to record the number of BFD symbols we
4453      created.  */
4454   bfd_get_symcount (abfd) = sym - symbase;
4455 
4456   /* Save our results and return success.  */
4457   obj_som_symtab (abfd) = symbase;
4458  successful_return:
4459   if (buf != NULL)
4460     free (buf);
4461   return (TRUE);
4462 
4463  error_return:
4464   if (buf != NULL)
4465     free (buf);
4466   return FALSE;
4467 }
4468 
4469 /* Canonicalize a SOM symbol table.  Return the number of entries
4470    in the symbol table.  */
4471 
4472 static long
4473 som_canonicalize_symtab (bfd *abfd, asymbol **location)
4474 {
4475   int i;
4476   som_symbol_type *symbase;
4477 
4478   if (!som_slurp_symbol_table (abfd))
4479     return -1;
4480 
4481   i = bfd_get_symcount (abfd);
4482   symbase = obj_som_symtab (abfd);
4483 
4484   for (; i > 0; i--, location++, symbase++)
4485     *location = &symbase->symbol;
4486 
4487   /* Final null pointer.  */
4488   *location = 0;
4489   return (bfd_get_symcount (abfd));
4490 }
4491 
4492 /* Make a SOM symbol.  There is nothing special to do here.  */
4493 
4494 static asymbol *
4495 som_make_empty_symbol (bfd *abfd)
4496 {
4497   bfd_size_type amt = sizeof (som_symbol_type);
4498   som_symbol_type *new = bfd_zalloc (abfd, amt);
4499 
4500   if (new == NULL)
4501     return NULL;
4502   new->symbol.the_bfd = abfd;
4503 
4504   return &new->symbol;
4505 }
4506 
4507 /* Print symbol information.  */
4508 
4509 static void
4510 som_print_symbol (bfd *abfd,
4511 		  void *afile,
4512 		  asymbol *symbol,
4513 		  bfd_print_symbol_type how)
4514 {
4515   FILE *file = (FILE *) afile;
4516 
4517   switch (how)
4518     {
4519     case bfd_print_symbol_name:
4520       fprintf (file, "%s", symbol->name);
4521       break;
4522     case bfd_print_symbol_more:
4523       fprintf (file, "som ");
4524       fprintf_vma (file, symbol->value);
4525       fprintf (file, " %lx", (long) symbol->flags);
4526       break;
4527     case bfd_print_symbol_all:
4528       {
4529 	const char *section_name;
4530 
4531 	section_name = symbol->section ? symbol->section->name : "(*none*)";
4532 	bfd_print_symbol_vandf (abfd, (void *) file, symbol);
4533 	fprintf (file, " %s\t%s", section_name, symbol->name);
4534 	break;
4535       }
4536     }
4537 }
4538 
4539 static bfd_boolean
4540 som_bfd_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED,
4541 			     const char *name)
4542 {
4543   return name[0] == 'L' && name[1] == '$';
4544 }
4545 
4546 /* Count or process variable-length SOM fixup records.
4547 
4548    To avoid code duplication we use this code both to compute the number
4549    of relocations requested by a stream, and to internalize the stream.
4550 
4551    When computing the number of relocations requested by a stream the
4552    variables rptr, section, and symbols have no meaning.
4553 
4554    Return the number of relocations requested by the fixup stream.  When
4555    not just counting
4556 
4557    This needs at least two or three more passes to get it cleaned up.  */
4558 
4559 static unsigned int
4560 som_set_reloc_info (unsigned char *fixup,
4561 		    unsigned int end,
4562 		    arelent *internal_relocs,
4563 		    asection *section,
4564 		    asymbol **symbols,
4565 		    bfd_boolean just_count)
4566 {
4567   unsigned int op, varname, deallocate_contents = 0;
4568   unsigned char *end_fixups = &fixup[end];
4569   const struct fixup_format *fp;
4570   const char *cp;
4571   unsigned char *save_fixup;
4572   int variables[26], stack[20], c, v, count, prev_fixup, *sp, saved_unwind_bits;
4573   const int *subop;
4574   arelent *rptr = internal_relocs;
4575   unsigned int offset = 0;
4576 
4577 #define	var(c)		variables[(c) - 'A']
4578 #define	push(v)		(*sp++ = (v))
4579 #define	pop()		(*--sp)
4580 #define	emptystack()	(sp == stack)
4581 
4582   som_initialize_reloc_queue (reloc_queue);
4583   memset (variables, 0, sizeof (variables));
4584   memset (stack, 0, sizeof (stack));
4585   count = 0;
4586   prev_fixup = 0;
4587   saved_unwind_bits = 0;
4588   sp = stack;
4589 
4590   while (fixup < end_fixups)
4591     {
4592       /* Save pointer to the start of this fixup.  We'll use
4593 	 it later to determine if it is necessary to put this fixup
4594 	 on the queue.  */
4595       save_fixup = fixup;
4596 
4597       /* Get the fixup code and its associated format.  */
4598       op = *fixup++;
4599       fp = &som_fixup_formats[op];
4600 
4601       /* Handle a request for a previous fixup.  */
4602       if (*fp->format == 'P')
4603 	{
4604 	  /* Get pointer to the beginning of the prev fixup, move
4605 	     the repeated fixup to the head of the queue.  */
4606 	  fixup = reloc_queue[fp->D].reloc;
4607 	  som_reloc_queue_fix (reloc_queue, fp->D);
4608 	  prev_fixup = 1;
4609 
4610 	  /* Get the fixup code and its associated format.  */
4611 	  op = *fixup++;
4612 	  fp = &som_fixup_formats[op];
4613 	}
4614 
4615       /* If this fixup will be passed to BFD, set some reasonable defaults.  */
4616       if (! just_count
4617 	  && som_hppa_howto_table[op].type != R_NO_RELOCATION
4618 	  && som_hppa_howto_table[op].type != R_DATA_OVERRIDE)
4619 	{
4620 	  rptr->address = offset;
4621 	  rptr->howto = &som_hppa_howto_table[op];
4622 	  rptr->addend = 0;
4623 	  rptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
4624 	}
4625 
4626       /* Set default input length to 0.  Get the opcode class index
4627 	 into D.  */
4628       var ('L') = 0;
4629       var ('D') = fp->D;
4630       var ('U') = saved_unwind_bits;
4631 
4632       /* Get the opcode format.  */
4633       cp = fp->format;
4634 
4635       /* Process the format string.  Parsing happens in two phases,
4636 	 parse RHS, then assign to LHS.  Repeat until no more
4637 	 characters in the format string.  */
4638       while (*cp)
4639 	{
4640 	  /* The variable this pass is going to compute a value for.  */
4641 	  varname = *cp++;
4642 
4643 	  /* Start processing RHS.  Continue until a NULL or '=' is found.  */
4644 	  do
4645 	    {
4646 	      c = *cp++;
4647 
4648 	      /* If this is a variable, push it on the stack.  */
4649 	      if (ISUPPER (c))
4650 		push (var (c));
4651 
4652 	      /* If this is a lower case letter, then it represents
4653 		 additional data from the fixup stream to be pushed onto
4654 		 the stack.  */
4655 	      else if (ISLOWER (c))
4656 		{
4657 		  int bits = (c - 'a') * 8;
4658 		  for (v = 0; c > 'a'; --c)
4659 		    v = (v << 8) | *fixup++;
4660 		  if (varname == 'V')
4661 		    v = sign_extend (v, bits);
4662 		  push (v);
4663 		}
4664 
4665 	      /* A decimal constant.  Push it on the stack.  */
4666 	      else if (ISDIGIT (c))
4667 		{
4668 		  v = c - '0';
4669 		  while (ISDIGIT (*cp))
4670 		    v = (v * 10) + (*cp++ - '0');
4671 		  push (v);
4672 		}
4673 	      else
4674 		/* An operator.  Pop two two values from the stack and
4675 		   use them as operands to the given operation.  Push
4676 		   the result of the operation back on the stack.  */
4677 		switch (c)
4678 		  {
4679 		  case '+':
4680 		    v = pop ();
4681 		    v += pop ();
4682 		    push (v);
4683 		    break;
4684 		  case '*':
4685 		    v = pop ();
4686 		    v *= pop ();
4687 		    push (v);
4688 		    break;
4689 		  case '<':
4690 		    v = pop ();
4691 		    v = pop () << v;
4692 		    push (v);
4693 		    break;
4694 		  default:
4695 		    abort ();
4696 		  }
4697 	    }
4698 	  while (*cp && *cp != '=');
4699 
4700 	  /* Move over the equal operator.  */
4701 	  cp++;
4702 
4703 	  /* Pop the RHS off the stack.  */
4704 	  c = pop ();
4705 
4706 	  /* Perform the assignment.  */
4707 	  var (varname) = c;
4708 
4709 	  /* Handle side effects. and special 'O' stack cases.  */
4710 	  switch (varname)
4711 	    {
4712 	    /* Consume some bytes from the input space.  */
4713 	    case 'L':
4714 	      offset += c;
4715 	      break;
4716 	    /* A symbol to use in the relocation.  Make a note
4717 	       of this if we are not just counting.  */
4718 	    case 'S':
4719 	      if (! just_count)
4720 		rptr->sym_ptr_ptr = &symbols[c];
4721 	      break;
4722 	    /* Argument relocation bits for a function call.  */
4723 	    case 'R':
4724 	      if (! just_count)
4725 		{
4726 		  unsigned int tmp = var ('R');
4727 		  rptr->addend = 0;
4728 
4729 		  if ((som_hppa_howto_table[op].type == R_PCREL_CALL
4730 		       && R_PCREL_CALL + 10 > op)
4731 		      || (som_hppa_howto_table[op].type == R_ABS_CALL
4732 			  && R_ABS_CALL + 10 > op))
4733 		    {
4734 		      /* Simple encoding.  */
4735 		      if (tmp > 4)
4736 			{
4737 			  tmp -= 5;
4738 			  rptr->addend |= 1;
4739 			}
4740 		      if (tmp == 4)
4741 			rptr->addend |= 1 << 8 | 1 << 6 | 1 << 4 | 1 << 2;
4742 		      else if (tmp == 3)
4743 			rptr->addend |= 1 << 8 | 1 << 6 | 1 << 4;
4744 		      else if (tmp == 2)
4745 			rptr->addend |= 1 << 8 | 1 << 6;
4746 		      else if (tmp == 1)
4747 			rptr->addend |= 1 << 8;
4748 		    }
4749 		  else
4750 		    {
4751 		      unsigned int tmp1, tmp2;
4752 
4753 		      /* First part is easy -- low order two bits are
4754 			 directly copied, then shifted away.  */
4755 		      rptr->addend = tmp & 0x3;
4756 		      tmp >>= 2;
4757 
4758 		      /* Diving the result by 10 gives us the second
4759 			 part.  If it is 9, then the first two words
4760 			 are a double precision paramater, else it is
4761 			 3 * the first arg bits + the 2nd arg bits.  */
4762 		      tmp1 = tmp / 10;
4763 		      tmp -= tmp1 * 10;
4764 		      if (tmp1 == 9)
4765 			rptr->addend += (0xe << 6);
4766 		      else
4767 			{
4768 			  /* Get the two pieces.  */
4769 			  tmp2 = tmp1 / 3;
4770 			  tmp1 -= tmp2 * 3;
4771 			  /* Put them in the addend.  */
4772 			  rptr->addend += (tmp2 << 8) + (tmp1 << 6);
4773 			}
4774 
4775 		      /* What's left is the third part.  It's unpacked
4776 			 just like the second.  */
4777 		      if (tmp == 9)
4778 			rptr->addend += (0xe << 2);
4779 		      else
4780 			{
4781 			  tmp2 = tmp / 3;
4782 			  tmp -= tmp2 * 3;
4783 			  rptr->addend += (tmp2 << 4) + (tmp << 2);
4784 			}
4785 		    }
4786 		  rptr->addend = HPPA_R_ADDEND (rptr->addend, 0);
4787 		}
4788 	      break;
4789 	    /* Handle the linker expression stack.  */
4790 	    case 'O':
4791 	      switch (op)
4792 		{
4793 		case R_COMP1:
4794 		  subop = comp1_opcodes;
4795 		  break;
4796 		case R_COMP2:
4797 		  subop = comp2_opcodes;
4798 		  break;
4799 		case R_COMP3:
4800 		  subop = comp3_opcodes;
4801 		  break;
4802 		default:
4803 		  abort ();
4804 		}
4805 	      while (*subop <= (unsigned char) c)
4806 		++subop;
4807 	      --subop;
4808 	      break;
4809 	    /* The lower 32unwind bits must be persistent.  */
4810 	    case 'U':
4811 	      saved_unwind_bits = var ('U');
4812 	      break;
4813 
4814 	    default:
4815 	      break;
4816 	    }
4817 	}
4818 
4819       /* If we used a previous fixup, clean up after it.  */
4820       if (prev_fixup)
4821 	{
4822 	  fixup = save_fixup + 1;
4823 	  prev_fixup = 0;
4824 	}
4825       /* Queue it.  */
4826       else if (fixup > save_fixup + 1)
4827 	som_reloc_queue_insert (save_fixup, fixup - save_fixup, reloc_queue);
4828 
4829       /* We do not pass R_DATA_OVERRIDE or R_NO_RELOCATION
4830 	 fixups to BFD.  */
4831       if (som_hppa_howto_table[op].type != R_DATA_OVERRIDE
4832 	  && som_hppa_howto_table[op].type != R_NO_RELOCATION)
4833 	{
4834 	  /* Done with a single reloction. Loop back to the top.  */
4835 	  if (! just_count)
4836 	    {
4837 	      if (som_hppa_howto_table[op].type == R_ENTRY)
4838 		rptr->addend = var ('T');
4839 	      else if (som_hppa_howto_table[op].type == R_EXIT)
4840 		rptr->addend = var ('U');
4841 	      else if (som_hppa_howto_table[op].type == R_PCREL_CALL
4842 		       || som_hppa_howto_table[op].type == R_ABS_CALL)
4843 		;
4844 	      else if (som_hppa_howto_table[op].type == R_DATA_ONE_SYMBOL)
4845 		{
4846 		  /* Try what was specified in R_DATA_OVERRIDE first
4847 		     (if anything).  Then the hard way using the
4848 		     section contents.  */
4849 		  rptr->addend = var ('V');
4850 
4851 		  if (rptr->addend == 0 && !section->contents)
4852 		    {
4853 		      /* Got to read the damn contents first.  We don't
4854 			 bother saving the contents (yet).  Add it one
4855 			 day if the need arises.  */
4856 		      bfd_byte *contents;
4857 		      if (!bfd_malloc_and_get_section (section->owner, section,
4858 						       &contents))
4859 			{
4860 			  if (contents != NULL)
4861 			    free (contents);
4862 			  return (unsigned) -1;
4863 			}
4864 		      section->contents = contents;
4865 		      deallocate_contents = 1;
4866 		    }
4867 		  else if (rptr->addend == 0)
4868 		    rptr->addend = bfd_get_32 (section->owner,
4869 					       (section->contents
4870 						+ offset - var ('L')));
4871 
4872 		}
4873 	      else
4874 		rptr->addend = var ('V');
4875 	      rptr++;
4876 	    }
4877 	  count++;
4878 	  /* Now that we've handled a "full" relocation, reset
4879 	     some state.  */
4880 	  memset (variables, 0, sizeof (variables));
4881 	  memset (stack, 0, sizeof (stack));
4882 	}
4883     }
4884   if (deallocate_contents)
4885     free (section->contents);
4886 
4887   return count;
4888 
4889 #undef var
4890 #undef push
4891 #undef pop
4892 #undef emptystack
4893 }
4894 
4895 /* Read in the relocs (aka fixups in SOM terms) for a section.
4896 
4897    som_get_reloc_upper_bound calls this routine with JUST_COUNT
4898    set to TRUE to indicate it only needs a count of the number
4899    of actual relocations.  */
4900 
4901 static bfd_boolean
4902 som_slurp_reloc_table (bfd *abfd,
4903 		       asection *section,
4904 		       asymbol **symbols,
4905 		       bfd_boolean just_count)
4906 {
4907   unsigned char *external_relocs;
4908   unsigned int fixup_stream_size;
4909   arelent *internal_relocs;
4910   unsigned int num_relocs;
4911   bfd_size_type amt;
4912 
4913   fixup_stream_size = som_section_data (section)->reloc_size;
4914   /* If there were no relocations, then there is nothing to do.  */
4915   if (section->reloc_count == 0)
4916     return TRUE;
4917 
4918   /* If reloc_count is -1, then the relocation stream has not been
4919      parsed.  We must do so now to know how many relocations exist.  */
4920   if (section->reloc_count == (unsigned) -1)
4921     {
4922       amt = fixup_stream_size;
4923       external_relocs = bfd_malloc (amt);
4924       if (external_relocs == NULL)
4925 	return FALSE;
4926       /* Read in the external forms.  */
4927       if (bfd_seek (abfd,
4928 		    obj_som_reloc_filepos (abfd) + section->rel_filepos,
4929 		    SEEK_SET)
4930 	  != 0)
4931 	return FALSE;
4932       if (bfd_bread (external_relocs, amt, abfd) != amt)
4933 	return FALSE;
4934 
4935       /* Let callers know how many relocations found.
4936 	 also save the relocation stream as we will
4937 	 need it again.  */
4938       section->reloc_count = som_set_reloc_info (external_relocs,
4939 						 fixup_stream_size,
4940 						 NULL, NULL, NULL, TRUE);
4941 
4942       som_section_data (section)->reloc_stream = external_relocs;
4943     }
4944 
4945   /* If the caller only wanted a count, then return now.  */
4946   if (just_count)
4947     return TRUE;
4948 
4949   num_relocs = section->reloc_count;
4950   external_relocs = som_section_data (section)->reloc_stream;
4951   /* Return saved information about the relocations if it is available.  */
4952   if (section->relocation != NULL)
4953     return TRUE;
4954 
4955   amt = num_relocs;
4956   amt *= sizeof (arelent);
4957   internal_relocs = bfd_zalloc (abfd, (amt));
4958   if (internal_relocs == NULL)
4959     return FALSE;
4960 
4961   /* Process and internalize the relocations.  */
4962   som_set_reloc_info (external_relocs, fixup_stream_size,
4963 		      internal_relocs, section, symbols, FALSE);
4964 
4965   /* We're done with the external relocations.  Free them.  */
4966   free (external_relocs);
4967   som_section_data (section)->reloc_stream = NULL;
4968 
4969   /* Save our results and return success.  */
4970   section->relocation = internal_relocs;
4971   return TRUE;
4972 }
4973 
4974 /* Return the number of bytes required to store the relocation
4975    information associated with the given section.  */
4976 
4977 static long
4978 som_get_reloc_upper_bound (bfd *abfd, sec_ptr asect)
4979 {
4980   /* If section has relocations, then read in the relocation stream
4981      and parse it to determine how many relocations exist.  */
4982   if (asect->flags & SEC_RELOC)
4983     {
4984       if (! som_slurp_reloc_table (abfd, asect, NULL, TRUE))
4985 	return -1;
4986       return (asect->reloc_count + 1) * sizeof (arelent *);
4987     }
4988 
4989   /* There are no relocations.  Return enough space to hold the
4990      NULL pointer which will be installed if som_canonicalize_reloc
4991      is called.  */
4992   return sizeof (arelent *);
4993 }
4994 
4995 /* Convert relocations from SOM (external) form into BFD internal
4996    form.  Return the number of relocations.  */
4997 
4998 static long
4999 som_canonicalize_reloc (bfd *abfd,
5000 			sec_ptr section,
5001 			arelent **relptr,
5002 			asymbol **symbols)
5003 {
5004   arelent *tblptr;
5005   int count;
5006 
5007   if (! som_slurp_reloc_table (abfd, section, symbols, FALSE))
5008     return -1;
5009 
5010   count = section->reloc_count;
5011   tblptr = section->relocation;
5012 
5013   while (count--)
5014     *relptr++ = tblptr++;
5015 
5016   *relptr = NULL;
5017   return section->reloc_count;
5018 }
5019 
5020 extern const bfd_target som_vec;
5021 
5022 /* A hook to set up object file dependent section information.  */
5023 
5024 static bfd_boolean
5025 som_new_section_hook (bfd *abfd, asection *newsect)
5026 {
5027   if (!newsect->used_by_bfd)
5028     {
5029       bfd_size_type amt = sizeof (struct som_section_data_struct);
5030 
5031       newsect->used_by_bfd = bfd_zalloc (abfd, amt);
5032       if (!newsect->used_by_bfd)
5033 	return FALSE;
5034     }
5035   newsect->alignment_power = 3;
5036 
5037   /* We allow more than three sections internally.  */
5038   return _bfd_generic_new_section_hook (abfd, newsect);
5039 }
5040 
5041 /* Copy any private info we understand from the input symbol
5042    to the output symbol.  */
5043 
5044 static bfd_boolean
5045 som_bfd_copy_private_symbol_data (bfd *ibfd,
5046 				  asymbol *isymbol,
5047 				  bfd *obfd,
5048 				  asymbol *osymbol)
5049 {
5050   struct som_symbol *input_symbol = (struct som_symbol *) isymbol;
5051   struct som_symbol *output_symbol = (struct som_symbol *) osymbol;
5052 
5053   /* One day we may try to grok other private data.  */
5054   if (ibfd->xvec->flavour != bfd_target_som_flavour
5055       || obfd->xvec->flavour != bfd_target_som_flavour)
5056     return FALSE;
5057 
5058   /* The only private information we need to copy is the argument relocation
5059      bits.  */
5060   output_symbol->tc_data.ap.hppa_arg_reloc =
5061     input_symbol->tc_data.ap.hppa_arg_reloc;
5062 
5063   return TRUE;
5064 }
5065 
5066 /* Copy any private info we understand from the input section
5067    to the output section.  */
5068 
5069 static bfd_boolean
5070 som_bfd_copy_private_section_data (bfd *ibfd,
5071 				   asection *isection,
5072 				   bfd *obfd,
5073 				   asection *osection)
5074 {
5075   bfd_size_type amt;
5076 
5077   /* One day we may try to grok other private data.  */
5078   if (ibfd->xvec->flavour != bfd_target_som_flavour
5079       || obfd->xvec->flavour != bfd_target_som_flavour
5080       || (!som_is_space (isection) && !som_is_subspace (isection)))
5081     return TRUE;
5082 
5083   amt = sizeof (struct som_copyable_section_data_struct);
5084   som_section_data (osection)->copy_data = bfd_zalloc (obfd, amt);
5085   if (som_section_data (osection)->copy_data == NULL)
5086     return FALSE;
5087 
5088   memcpy (som_section_data (osection)->copy_data,
5089 	  som_section_data (isection)->copy_data,
5090 	  sizeof (struct som_copyable_section_data_struct));
5091 
5092   /* Reparent if necessary.  */
5093   if (som_section_data (osection)->copy_data->container)
5094     som_section_data (osection)->copy_data->container =
5095       som_section_data (osection)->copy_data->container->output_section;
5096 
5097   return TRUE;
5098 }
5099 
5100 /* Copy any private info we understand from the input bfd
5101    to the output bfd.  */
5102 
5103 static bfd_boolean
5104 som_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
5105 {
5106   /* One day we may try to grok other private data.  */
5107   if (ibfd->xvec->flavour != bfd_target_som_flavour
5108       || obfd->xvec->flavour != bfd_target_som_flavour)
5109     return TRUE;
5110 
5111   /* Allocate some memory to hold the data we need.  */
5112   obj_som_exec_data (obfd) = bfd_zalloc (obfd, (bfd_size_type) sizeof (struct som_exec_data));
5113   if (obj_som_exec_data (obfd) == NULL)
5114     return FALSE;
5115 
5116   /* Now copy the data.  */
5117   memcpy (obj_som_exec_data (obfd), obj_som_exec_data (ibfd),
5118 	  sizeof (struct som_exec_data));
5119 
5120   return TRUE;
5121 }
5122 
5123 /* Display the SOM header.  */
5124 
5125 static bfd_boolean
5126 som_bfd_print_private_bfd_data (bfd *abfd, void *farg)
5127 {
5128   struct som_exec_auxhdr *exec_header;
5129   struct aux_id* auxhdr;
5130   FILE *f;
5131 
5132   f = (FILE *) farg;
5133 
5134   exec_header = obj_som_exec_hdr (abfd);
5135   if (exec_header)
5136     {
5137       fprintf (f, _("\nExec Auxiliary Header\n"));
5138       fprintf (f, "  flags              ");
5139       auxhdr = &exec_header->som_auxhdr;
5140       if (auxhdr->mandatory)
5141 	fprintf (f, "mandatory ");
5142       if (auxhdr->copy)
5143 	fprintf (f, "copy ");
5144       if (auxhdr->append)
5145 	fprintf (f, "append ");
5146       if (auxhdr->ignore)
5147 	fprintf (f, "ignore ");
5148       fprintf (f, "\n");
5149       fprintf (f, "  type               %#x\n", auxhdr->type);
5150       fprintf (f, "  length             %#x\n", auxhdr->length);
5151 
5152       /* Note that, depending on the HP-UX version, the following fields can be
5153          either ints, or longs.  */
5154 
5155       fprintf (f, "  text size          %#lx\n", (long) exec_header->exec_tsize);
5156       fprintf (f, "  text memory offset %#lx\n", (long) exec_header->exec_tmem);
5157       fprintf (f, "  text file offset   %#lx\n", (long) exec_header->exec_tfile);
5158       fprintf (f, "  data size          %#lx\n", (long) exec_header->exec_dsize);
5159       fprintf (f, "  data memory offset %#lx\n", (long) exec_header->exec_dmem);
5160       fprintf (f, "  data file offset   %#lx\n", (long) exec_header->exec_dfile);
5161       fprintf (f, "  bss size           %#lx\n", (long) exec_header->exec_bsize);
5162       fprintf (f, "  entry point        %#lx\n", (long) exec_header->exec_entry);
5163       fprintf (f, "  loader flags       %#lx\n", (long) exec_header->exec_flags);
5164       fprintf (f, "  bss initializer    %#lx\n", (long) exec_header->exec_bfill);
5165     }
5166 
5167   return TRUE;
5168 }
5169 
5170 /* Set backend info for sections which can not be described
5171    in the BFD data structures.  */
5172 
5173 bfd_boolean
5174 bfd_som_set_section_attributes (asection *section,
5175 				int defined,
5176 				int private,
5177 				unsigned int sort_key,
5178 				int spnum)
5179 {
5180   /* Allocate memory to hold the magic information.  */
5181   if (som_section_data (section)->copy_data == NULL)
5182     {
5183       bfd_size_type amt = sizeof (struct som_copyable_section_data_struct);
5184 
5185       som_section_data (section)->copy_data = bfd_zalloc (section->owner, amt);
5186       if (som_section_data (section)->copy_data == NULL)
5187 	return FALSE;
5188     }
5189   som_section_data (section)->copy_data->sort_key = sort_key;
5190   som_section_data (section)->copy_data->is_defined = defined;
5191   som_section_data (section)->copy_data->is_private = private;
5192   som_section_data (section)->copy_data->container = section;
5193   som_section_data (section)->copy_data->space_number = spnum;
5194   return TRUE;
5195 }
5196 
5197 /* Set backend info for subsections which can not be described
5198    in the BFD data structures.  */
5199 
5200 bfd_boolean
5201 bfd_som_set_subsection_attributes (asection *section,
5202 				   asection *container,
5203 				   int access,
5204 				   unsigned int sort_key,
5205 				   int quadrant,
5206 				   int comdat,
5207 				   int common,
5208 				   int dup_common)
5209 {
5210   /* Allocate memory to hold the magic information.  */
5211   if (som_section_data (section)->copy_data == NULL)
5212     {
5213       bfd_size_type amt = sizeof (struct som_copyable_section_data_struct);
5214 
5215       som_section_data (section)->copy_data = bfd_zalloc (section->owner, amt);
5216       if (som_section_data (section)->copy_data == NULL)
5217 	return FALSE;
5218     }
5219   som_section_data (section)->copy_data->sort_key = sort_key;
5220   som_section_data (section)->copy_data->access_control_bits = access;
5221   som_section_data (section)->copy_data->quadrant = quadrant;
5222   som_section_data (section)->copy_data->container = container;
5223   som_section_data (section)->copy_data->is_comdat = comdat;
5224   som_section_data (section)->copy_data->is_common = common;
5225   som_section_data (section)->copy_data->dup_common = dup_common;
5226   return TRUE;
5227 }
5228 
5229 /* Set the full SOM symbol type.  SOM needs far more symbol information
5230    than any other object file format I'm aware of.  It is mandatory
5231    to be able to know if a symbol is an entry point, millicode, data,
5232    code, absolute, storage request, or procedure label.  If you get
5233    the symbol type wrong your program will not link.  */
5234 
5235 void
5236 bfd_som_set_symbol_type (asymbol *symbol, unsigned int type)
5237 {
5238   som_symbol_data (symbol)->som_type = type;
5239 }
5240 
5241 /* Attach an auxiliary header to the BFD backend so that it may be
5242    written into the object file.  */
5243 
5244 bfd_boolean
5245 bfd_som_attach_aux_hdr (bfd *abfd, int type, char *string)
5246 {
5247   bfd_size_type amt;
5248 
5249   if (type == VERSION_AUX_ID)
5250     {
5251       size_t len = strlen (string);
5252       int pad = 0;
5253 
5254       if (len % 4)
5255 	pad = (4 - (len % 4));
5256       amt = sizeof (struct aux_id) + sizeof (unsigned int) + len + pad;
5257       obj_som_version_hdr (abfd) = bfd_zalloc (abfd, amt);
5258       if (!obj_som_version_hdr (abfd))
5259 	return FALSE;
5260       obj_som_version_hdr (abfd)->header_id.type = VERSION_AUX_ID;
5261       obj_som_version_hdr (abfd)->header_id.length = len + pad;
5262       obj_som_version_hdr (abfd)->header_id.length += sizeof (int);
5263       obj_som_version_hdr (abfd)->string_length = len;
5264       strncpy (obj_som_version_hdr (abfd)->user_string, string, len);
5265     }
5266   else if (type == COPYRIGHT_AUX_ID)
5267     {
5268       int len = strlen (string);
5269       int pad = 0;
5270 
5271       if (len % 4)
5272 	pad = (4 - (len % 4));
5273       amt = sizeof (struct aux_id) + sizeof (unsigned int) + len + pad;
5274       obj_som_copyright_hdr (abfd) = bfd_zalloc (abfd, amt);
5275       if (!obj_som_copyright_hdr (abfd))
5276 	return FALSE;
5277       obj_som_copyright_hdr (abfd)->header_id.type = COPYRIGHT_AUX_ID;
5278       obj_som_copyright_hdr (abfd)->header_id.length = len + pad;
5279       obj_som_copyright_hdr (abfd)->header_id.length += sizeof (int);
5280       obj_som_copyright_hdr (abfd)->string_length = len;
5281       strcpy (obj_som_copyright_hdr (abfd)->copyright, string);
5282     }
5283   return TRUE;
5284 }
5285 
5286 /* Attach a compilation unit header to the BFD backend so that it may be
5287    written into the object file.  */
5288 
5289 bfd_boolean
5290 bfd_som_attach_compilation_unit (bfd *abfd,
5291 				 const char *name,
5292 				 const char *language_name,
5293 				 const char *product_id,
5294 				 const char *version_id)
5295 {
5296   COMPUNIT *n = (COMPUNIT *) bfd_zalloc (abfd, (bfd_size_type) COMPUNITSZ);
5297 
5298   if (n == NULL)
5299     return FALSE;
5300 
5301 #define STRDUP(f) \
5302   if (f != NULL) \
5303     { \
5304       n->f.n_name = bfd_alloc (abfd, (bfd_size_type) strlen (f) + 1); \
5305       if (n->f.n_name == NULL) \
5306 	return FALSE; \
5307       strcpy (n->f.n_name, f); \
5308     }
5309 
5310   STRDUP (name);
5311   STRDUP (language_name);
5312   STRDUP (product_id);
5313   STRDUP (version_id);
5314 
5315 #undef STRDUP
5316 
5317   obj_som_compilation_unit (abfd) = n;
5318 
5319   return TRUE;
5320 }
5321 
5322 static bfd_boolean
5323 som_get_section_contents (bfd *abfd,
5324 			  sec_ptr section,
5325 			  void *location,
5326 			  file_ptr offset,
5327 			  bfd_size_type count)
5328 {
5329   if (count == 0 || ((section->flags & SEC_HAS_CONTENTS) == 0))
5330     return TRUE;
5331   if ((bfd_size_type) (offset+count) > section->size
5332       || bfd_seek (abfd, (file_ptr) (section->filepos + offset), SEEK_SET) != 0
5333       || bfd_bread (location, count, abfd) != count)
5334     return FALSE; /* On error.  */
5335   return TRUE;
5336 }
5337 
5338 static bfd_boolean
5339 som_set_section_contents (bfd *abfd,
5340 			  sec_ptr section,
5341 			  const void *location,
5342 			  file_ptr offset,
5343 			  bfd_size_type count)
5344 {
5345   if (! abfd->output_has_begun)
5346     {
5347       /* Set up fixed parts of the file, space, and subspace headers.
5348 	 Notify the world that output has begun.  */
5349       som_prep_headers (abfd);
5350       abfd->output_has_begun = TRUE;
5351       /* Start writing the object file.  This include all the string
5352 	 tables, fixup streams, and other portions of the object file.  */
5353       som_begin_writing (abfd);
5354     }
5355 
5356   /* Only write subspaces which have "real" contents (eg. the contents
5357      are not generated at run time by the OS).  */
5358   if (!som_is_subspace (section)
5359       || ((section->flags & SEC_HAS_CONTENTS) == 0))
5360     return TRUE;
5361 
5362   /* Seek to the proper offset within the object file and write the
5363      data.  */
5364   offset += som_section_data (section)->subspace_dict->file_loc_init_value;
5365   if (bfd_seek (abfd, offset, SEEK_SET) != 0)
5366     return FALSE;
5367 
5368   if (bfd_bwrite (location, count, abfd) != count)
5369     return FALSE;
5370   return TRUE;
5371 }
5372 
5373 static bfd_boolean
5374 som_set_arch_mach (bfd *abfd,
5375 		   enum bfd_architecture arch,
5376 		   unsigned long machine)
5377 {
5378   /* Allow any architecture to be supported by the SOM backend.  */
5379   return bfd_default_set_arch_mach (abfd, arch, machine);
5380 }
5381 
5382 static bfd_boolean
5383 som_find_nearest_line (bfd *abfd,
5384 		       asection *section,
5385 		       asymbol **symbols,
5386 		       bfd_vma offset,
5387 		       const char **filename_ptr,
5388 		       const char **functionname_ptr,
5389 		       unsigned int *line_ptr)
5390 {
5391   bfd_boolean found;
5392   asymbol *func;
5393   bfd_vma low_func;
5394   asymbol **p;
5395 
5396   if (! _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset,
5397                                              & found, filename_ptr,
5398                                              functionname_ptr, line_ptr,
5399                                              & somdata (abfd).line_info))
5400     return FALSE;
5401 
5402   if (found)
5403     return TRUE;
5404 
5405   if (symbols == NULL)
5406     return FALSE;
5407 
5408   /* Fallback: find function name from symbols table.  */
5409   func = NULL;
5410   low_func = 0;
5411 
5412   for (p = symbols; *p != NULL; p++)
5413     {
5414       som_symbol_type *q = (som_symbol_type *) *p;
5415 
5416       if (q->som_type == SYMBOL_TYPE_ENTRY
5417 	  && q->symbol.section == section
5418 	  && q->symbol.value >= low_func
5419 	  && q->symbol.value <= offset)
5420 	{
5421 	  func = (asymbol *) q;
5422 	  low_func = q->symbol.value;
5423 	}
5424     }
5425 
5426   if (func == NULL)
5427     return FALSE;
5428 
5429   *filename_ptr = NULL;
5430   *functionname_ptr = bfd_asymbol_name (func);
5431   *line_ptr = 0;
5432 
5433   return TRUE;
5434 }
5435 
5436 static int
5437 som_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED,
5438 		    struct bfd_link_info *info ATTRIBUTE_UNUSED)
5439 {
5440   (*_bfd_error_handler) (_("som_sizeof_headers unimplemented"));
5441   fflush (stderr);
5442   abort ();
5443   return 0;
5444 }
5445 
5446 /* Return the single-character symbol type corresponding to
5447    SOM section S, or '?' for an unknown SOM section.  */
5448 
5449 static char
5450 som_section_type (const char *s)
5451 {
5452   const struct section_to_type *t;
5453 
5454   for (t = &stt[0]; t->section; t++)
5455     if (!strcmp (s, t->section))
5456       return t->type;
5457   return '?';
5458 }
5459 
5460 static int
5461 som_decode_symclass (asymbol *symbol)
5462 {
5463   char c;
5464 
5465   if (bfd_is_com_section (symbol->section))
5466     return 'C';
5467   if (bfd_is_und_section (symbol->section))
5468     {
5469       if (symbol->flags & BSF_WEAK)
5470 	{
5471 	  /* If weak, determine if it's specifically an object
5472 	     or non-object weak.  */
5473 	  if (symbol->flags & BSF_OBJECT)
5474 	    return 'v';
5475 	  else
5476 	    return 'w';
5477 	}
5478       else
5479 	 return 'U';
5480     }
5481   if (bfd_is_ind_section (symbol->section))
5482     return 'I';
5483   if (symbol->flags & BSF_WEAK)
5484     {
5485       /* If weak, determine if it's specifically an object
5486 	 or non-object weak.  */
5487       if (symbol->flags & BSF_OBJECT)
5488 	return 'V';
5489       else
5490 	return 'W';
5491     }
5492   if (!(symbol->flags & (BSF_GLOBAL | BSF_LOCAL)))
5493     return '?';
5494 
5495   if (bfd_is_abs_section (symbol->section)
5496       || (som_symbol_data (symbol) != NULL
5497 	  && som_symbol_data (symbol)->som_type == SYMBOL_TYPE_ABSOLUTE))
5498     c = 'a';
5499   else if (symbol->section)
5500     c = som_section_type (symbol->section->name);
5501   else
5502     return '?';
5503   if (symbol->flags & BSF_GLOBAL)
5504     c = TOUPPER (c);
5505   return c;
5506 }
5507 
5508 /* Return information about SOM symbol SYMBOL in RET.  */
5509 
5510 static void
5511 som_get_symbol_info (bfd *ignore_abfd ATTRIBUTE_UNUSED,
5512 		     asymbol *symbol,
5513 		     symbol_info *ret)
5514 {
5515   ret->type = som_decode_symclass (symbol);
5516   if (ret->type != 'U')
5517     ret->value = symbol->value + symbol->section->vma;
5518   else
5519     ret->value = 0;
5520   ret->name = symbol->name;
5521 }
5522 
5523 /* Count the number of symbols in the archive symbol table.  Necessary
5524    so that we can allocate space for all the carsyms at once.  */
5525 
5526 static bfd_boolean
5527 som_bfd_count_ar_symbols (bfd *abfd,
5528 			  struct lst_header *lst_header,
5529 			  symindex *count)
5530 {
5531   unsigned int i;
5532   unsigned int *hash_table = NULL;
5533   bfd_size_type amt;
5534   file_ptr lst_filepos = bfd_tell (abfd) - sizeof (struct lst_header);
5535 
5536   amt = lst_header->hash_size;
5537   amt *= sizeof (unsigned int);
5538   hash_table = bfd_malloc (amt);
5539   if (hash_table == NULL && lst_header->hash_size != 0)
5540     goto error_return;
5541 
5542   /* Don't forget to initialize the counter!  */
5543   *count = 0;
5544 
5545   /* Read in the hash table.  The has table is an array of 32bit file offsets
5546      which point to the hash chains.  */
5547   if (bfd_bread ((void *) hash_table, amt, abfd) != amt)
5548     goto error_return;
5549 
5550   /* Walk each chain counting the number of symbols found on that particular
5551      chain.  */
5552   for (i = 0; i < lst_header->hash_size; i++)
5553     {
5554       struct lst_symbol_record lst_symbol;
5555 
5556       /* An empty chain has zero as it's file offset.  */
5557       if (hash_table[i] == 0)
5558 	continue;
5559 
5560       /* Seek to the first symbol in this hash chain.  */
5561       if (bfd_seek (abfd, lst_filepos + hash_table[i], SEEK_SET) != 0)
5562 	goto error_return;
5563 
5564       /* Read in this symbol and update the counter.  */
5565       amt = sizeof (lst_symbol);
5566       if (bfd_bread ((void *) &lst_symbol, amt, abfd) != amt)
5567 	goto error_return;
5568 
5569       (*count)++;
5570 
5571       /* Now iterate through the rest of the symbols on this chain.  */
5572       while (lst_symbol.next_entry)
5573 	{
5574 
5575 	  /* Seek to the next symbol.  */
5576 	  if (bfd_seek (abfd, lst_filepos + lst_symbol.next_entry, SEEK_SET)
5577 	      != 0)
5578 	    goto error_return;
5579 
5580 	  /* Read the symbol in and update the counter.  */
5581 	  amt = sizeof (lst_symbol);
5582 	  if (bfd_bread ((void *) &lst_symbol, amt, abfd) != amt)
5583 	    goto error_return;
5584 
5585 	  (*count)++;
5586 	}
5587     }
5588   if (hash_table != NULL)
5589     free (hash_table);
5590   return TRUE;
5591 
5592  error_return:
5593   if (hash_table != NULL)
5594     free (hash_table);
5595   return FALSE;
5596 }
5597 
5598 /* Fill in the canonical archive symbols (SYMS) from the archive described
5599    by ABFD and LST_HEADER.  */
5600 
5601 static bfd_boolean
5602 som_bfd_fill_in_ar_symbols (bfd *abfd,
5603 			    struct lst_header *lst_header,
5604 			    carsym **syms)
5605 {
5606   unsigned int i, len;
5607   carsym *set = syms[0];
5608   unsigned int *hash_table = NULL;
5609   struct som_entry *som_dict = NULL;
5610   bfd_size_type amt;
5611   file_ptr lst_filepos = bfd_tell (abfd) - sizeof (struct lst_header);
5612 
5613   amt = lst_header->hash_size;
5614   amt *= sizeof (unsigned int);
5615   hash_table = bfd_malloc (amt);
5616   if (hash_table == NULL && lst_header->hash_size != 0)
5617     goto error_return;
5618 
5619   /* Read in the hash table.  The has table is an array of 32bit file offsets
5620      which point to the hash chains.  */
5621   if (bfd_bread ((void *) hash_table, amt, abfd) != amt)
5622     goto error_return;
5623 
5624   /* Seek to and read in the SOM dictionary.  We will need this to fill
5625      in the carsym's filepos field.  */
5626   if (bfd_seek (abfd, lst_filepos + lst_header->dir_loc, SEEK_SET) != 0)
5627     goto error_return;
5628 
5629   amt = lst_header->module_count;
5630   amt *= sizeof (struct som_entry);
5631   som_dict = bfd_malloc (amt);
5632   if (som_dict == NULL && lst_header->module_count != 0)
5633     goto error_return;
5634 
5635   if (bfd_bread ((void *) som_dict, amt, abfd) != amt)
5636     goto error_return;
5637 
5638   /* Walk each chain filling in the carsyms as we go along.  */
5639   for (i = 0; i < lst_header->hash_size; i++)
5640     {
5641       struct lst_symbol_record lst_symbol;
5642 
5643       /* An empty chain has zero as it's file offset.  */
5644       if (hash_table[i] == 0)
5645 	continue;
5646 
5647       /* Seek to and read the first symbol on the chain.  */
5648       if (bfd_seek (abfd, lst_filepos + hash_table[i], SEEK_SET) != 0)
5649 	goto error_return;
5650 
5651       amt = sizeof (lst_symbol);
5652       if (bfd_bread ((void *) &lst_symbol, amt, abfd) != amt)
5653 	goto error_return;
5654 
5655       /* Get the name of the symbol, first get the length which is stored
5656 	 as a 32bit integer just before the symbol.
5657 
5658 	 One might ask why we don't just read in the entire string table
5659 	 and index into it.  Well, according to the SOM ABI the string
5660 	 index can point *anywhere* in the archive to save space, so just
5661 	 using the string table would not be safe.  */
5662       if (bfd_seek (abfd, lst_filepos + lst_header->string_loc
5663 			    + lst_symbol.name.n_strx - 4, SEEK_SET) != 0)
5664 	goto error_return;
5665 
5666       if (bfd_bread (&len, (bfd_size_type) 4, abfd) != 4)
5667 	goto error_return;
5668 
5669       /* Allocate space for the name and null terminate it too.  */
5670       set->name = bfd_zalloc (abfd, (bfd_size_type) len + 1);
5671       if (!set->name)
5672 	goto error_return;
5673       if (bfd_bread (set->name, (bfd_size_type) len, abfd) != len)
5674 	goto error_return;
5675 
5676       set->name[len] = 0;
5677 
5678       /* Fill in the file offset.  Note that the "location" field points
5679 	 to the SOM itself, not the ar_hdr in front of it.  */
5680       set->file_offset = som_dict[lst_symbol.som_index].location
5681 			  - sizeof (struct ar_hdr);
5682 
5683       /* Go to the next symbol.  */
5684       set++;
5685 
5686       /* Iterate through the rest of the chain.  */
5687       while (lst_symbol.next_entry)
5688 	{
5689 	  /* Seek to the next symbol and read it in.  */
5690 	  if (bfd_seek (abfd, lst_filepos + lst_symbol.next_entry, SEEK_SET)
5691 	      != 0)
5692 	    goto error_return;
5693 
5694 	  amt = sizeof (lst_symbol);
5695 	  if (bfd_bread ((void *) &lst_symbol, amt, abfd) != amt)
5696 	    goto error_return;
5697 
5698 	  /* Seek to the name length & string and read them in.  */
5699 	  if (bfd_seek (abfd, lst_filepos + lst_header->string_loc
5700 				+ lst_symbol.name.n_strx - 4, SEEK_SET) != 0)
5701 	    goto error_return;
5702 
5703 	  if (bfd_bread (&len, (bfd_size_type) 4, abfd) != 4)
5704 	    goto error_return;
5705 
5706 	  /* Allocate space for the name and null terminate it too.  */
5707 	  set->name = bfd_zalloc (abfd, (bfd_size_type) len + 1);
5708 	  if (!set->name)
5709 	    goto error_return;
5710 
5711 	  if (bfd_bread (set->name, (bfd_size_type) len, abfd) != len)
5712 	    goto error_return;
5713 	  set->name[len] = 0;
5714 
5715 	  /* Fill in the file offset.  Note that the "location" field points
5716 	     to the SOM itself, not the ar_hdr in front of it.  */
5717 	  set->file_offset = som_dict[lst_symbol.som_index].location
5718 			       - sizeof (struct ar_hdr);
5719 
5720 	  /* Go on to the next symbol.  */
5721 	  set++;
5722 	}
5723     }
5724   /* If we haven't died by now, then we successfully read the entire
5725      archive symbol table.  */
5726   if (hash_table != NULL)
5727     free (hash_table);
5728   if (som_dict != NULL)
5729     free (som_dict);
5730   return TRUE;
5731 
5732  error_return:
5733   if (hash_table != NULL)
5734     free (hash_table);
5735   if (som_dict != NULL)
5736     free (som_dict);
5737   return FALSE;
5738 }
5739 
5740 /* Read in the LST from the archive.  */
5741 
5742 static bfd_boolean
5743 som_slurp_armap (bfd *abfd)
5744 {
5745   struct lst_header lst_header;
5746   struct ar_hdr ar_header;
5747   unsigned int parsed_size;
5748   struct artdata *ardata = bfd_ardata (abfd);
5749   char nextname[17];
5750   bfd_size_type amt = 16;
5751   int i = bfd_bread ((void *) nextname, amt, abfd);
5752 
5753   /* Special cases.  */
5754   if (i == 0)
5755     return TRUE;
5756   if (i != 16)
5757     return FALSE;
5758 
5759   if (bfd_seek (abfd, (file_ptr) -16, SEEK_CUR) != 0)
5760     return FALSE;
5761 
5762   /* For archives without .o files there is no symbol table.  */
5763   if (! CONST_STRNEQ (nextname, "/               "))
5764     {
5765       bfd_has_map (abfd) = FALSE;
5766       return TRUE;
5767     }
5768 
5769   /* Read in and sanity check the archive header.  */
5770   amt = sizeof (struct ar_hdr);
5771   if (bfd_bread ((void *) &ar_header, amt, abfd) != amt)
5772     return FALSE;
5773 
5774   if (strncmp (ar_header.ar_fmag, ARFMAG, 2))
5775     {
5776       bfd_set_error (bfd_error_malformed_archive);
5777       return FALSE;
5778     }
5779 
5780   /* How big is the archive symbol table entry?  */
5781   errno = 0;
5782   parsed_size = strtol (ar_header.ar_size, NULL, 10);
5783   if (errno != 0)
5784     {
5785       bfd_set_error (bfd_error_malformed_archive);
5786       return FALSE;
5787     }
5788 
5789   /* Save off the file offset of the first real user data.  */
5790   ardata->first_file_filepos = bfd_tell (abfd) + parsed_size;
5791 
5792   /* Read in the library symbol table.  We'll make heavy use of this
5793      in just a minute.  */
5794   amt = sizeof (struct lst_header);
5795   if (bfd_bread ((void *) &lst_header, amt, abfd) != amt)
5796     return FALSE;
5797 
5798   /* Sanity check.  */
5799   if (lst_header.a_magic != LIBMAGIC)
5800     {
5801       bfd_set_error (bfd_error_malformed_archive);
5802       return FALSE;
5803     }
5804 
5805   /* Count the number of symbols in the library symbol table.  */
5806   if (! som_bfd_count_ar_symbols (abfd, &lst_header, &ardata->symdef_count))
5807     return FALSE;
5808 
5809   /* Get back to the start of the library symbol table.  */
5810   if (bfd_seek (abfd, (ardata->first_file_filepos - parsed_size
5811 		       + sizeof (struct lst_header)), SEEK_SET) != 0)
5812     return FALSE;
5813 
5814   /* Initialize the cache and allocate space for the library symbols.  */
5815   ardata->cache = 0;
5816   amt = ardata->symdef_count;
5817   amt *= sizeof (carsym);
5818   ardata->symdefs = bfd_alloc (abfd, amt);
5819   if (!ardata->symdefs)
5820     return FALSE;
5821 
5822   /* Now fill in the canonical archive symbols.  */
5823   if (! som_bfd_fill_in_ar_symbols (abfd, &lst_header, &ardata->symdefs))
5824     return FALSE;
5825 
5826   /* Seek back to the "first" file in the archive.  Note the "first"
5827      file may be the extended name table.  */
5828   if (bfd_seek (abfd, ardata->first_file_filepos, SEEK_SET) != 0)
5829     return FALSE;
5830 
5831   /* Notify the generic archive code that we have a symbol map.  */
5832   bfd_has_map (abfd) = TRUE;
5833   return TRUE;
5834 }
5835 
5836 /* Begin preparing to write a SOM library symbol table.
5837 
5838    As part of the prep work we need to determine the number of symbols
5839    and the size of the associated string section.  */
5840 
5841 static bfd_boolean
5842 som_bfd_prep_for_ar_write (bfd *abfd,
5843 			   unsigned int *num_syms,
5844 			   unsigned int *stringsize)
5845 {
5846   bfd *curr_bfd = abfd->archive_head;
5847 
5848   /* Some initialization.  */
5849   *num_syms = 0;
5850   *stringsize = 0;
5851 
5852   /* Iterate over each BFD within this archive.  */
5853   while (curr_bfd != NULL)
5854     {
5855       unsigned int curr_count, i;
5856       som_symbol_type *sym;
5857 
5858       /* Don't bother for non-SOM objects.  */
5859       if (curr_bfd->format != bfd_object
5860 	  || curr_bfd->xvec->flavour != bfd_target_som_flavour)
5861 	{
5862 	  curr_bfd = curr_bfd->archive_next;
5863 	  continue;
5864 	}
5865 
5866       /* Make sure the symbol table has been read, then snag a pointer
5867 	 to it.  It's a little slimey to grab the symbols via obj_som_symtab,
5868 	 but doing so avoids allocating lots of extra memory.  */
5869       if (! som_slurp_symbol_table (curr_bfd))
5870 	return FALSE;
5871 
5872       sym = obj_som_symtab (curr_bfd);
5873       curr_count = bfd_get_symcount (curr_bfd);
5874 
5875       /* Examine each symbol to determine if it belongs in the
5876 	 library symbol table.  */
5877       for (i = 0; i < curr_count; i++, sym++)
5878 	{
5879 	  struct som_misc_symbol_info info;
5880 
5881 	  /* Derive SOM information from the BFD symbol.  */
5882 	  som_bfd_derive_misc_symbol_info (curr_bfd, &sym->symbol, &info);
5883 
5884 	  /* Should we include this symbol?  */
5885 	  if (info.symbol_type == ST_NULL
5886 	      || info.symbol_type == ST_SYM_EXT
5887 	      || info.symbol_type == ST_ARG_EXT)
5888 	    continue;
5889 
5890 	  /* Only global symbols and unsatisfied commons.  */
5891 	  if (info.symbol_scope != SS_UNIVERSAL
5892 	      && info.symbol_type != ST_STORAGE)
5893 	    continue;
5894 
5895 	  /* Do no include undefined symbols.  */
5896 	  if (bfd_is_und_section (sym->symbol.section))
5897 	    continue;
5898 
5899 	  /* Bump the various counters, being careful to honor
5900 	     alignment considerations in the string table.  */
5901 	  (*num_syms)++;
5902 	  *stringsize = *stringsize + strlen (sym->symbol.name) + 5;
5903 	  while (*stringsize % 4)
5904 	    (*stringsize)++;
5905 	}
5906 
5907       curr_bfd = curr_bfd->archive_next;
5908     }
5909   return TRUE;
5910 }
5911 
5912 /* Hash a symbol name based on the hashing algorithm presented in the
5913    SOM ABI.  */
5914 
5915 static unsigned int
5916 som_bfd_ar_symbol_hash (asymbol *symbol)
5917 {
5918   unsigned int len = strlen (symbol->name);
5919 
5920   /* Names with length 1 are special.  */
5921   if (len == 1)
5922     return 0x1000100 | (symbol->name[0] << 16) | symbol->name[0];
5923 
5924   return ((len & 0x7f) << 24) | (symbol->name[1] << 16)
5925 	  | (symbol->name[len - 2] << 8) | symbol->name[len - 1];
5926 }
5927 
5928 /* Do the bulk of the work required to write the SOM library
5929    symbol table.  */
5930 
5931 static bfd_boolean
5932 som_bfd_ar_write_symbol_stuff (bfd *abfd,
5933 			       unsigned int nsyms,
5934 			       unsigned int string_size,
5935 			       struct lst_header lst,
5936 			       unsigned elength)
5937 {
5938   file_ptr lst_filepos;
5939   char *strings = NULL, *p;
5940   struct lst_symbol_record *lst_syms = NULL, *curr_lst_sym;
5941   bfd *curr_bfd;
5942   unsigned int *hash_table = NULL;
5943   struct som_entry *som_dict = NULL;
5944   struct lst_symbol_record **last_hash_entry = NULL;
5945   unsigned int curr_som_offset, som_index = 0;
5946   bfd_size_type amt;
5947 
5948   amt = lst.hash_size;
5949   amt *= sizeof (unsigned int);
5950   hash_table = bfd_zmalloc (amt);
5951   if (hash_table == NULL && lst.hash_size != 0)
5952     goto error_return;
5953 
5954   amt = lst.module_count;
5955   amt *= sizeof (struct som_entry);
5956   som_dict = bfd_zmalloc (amt);
5957   if (som_dict == NULL && lst.module_count != 0)
5958     goto error_return;
5959 
5960   amt = lst.hash_size;
5961   amt *= sizeof (struct lst_symbol_record *);
5962   last_hash_entry = bfd_zmalloc (amt);
5963   if (last_hash_entry == NULL && lst.hash_size != 0)
5964     goto error_return;
5965 
5966   /* Lots of fields are file positions relative to the start
5967      of the lst record.  So save its location.  */
5968   lst_filepos = bfd_tell (abfd) - sizeof (struct lst_header);
5969 
5970   /* Symbols have som_index fields, so we have to keep track of the
5971      index of each SOM in the archive.
5972 
5973      The SOM dictionary has (among other things) the absolute file
5974      position for the SOM which a particular dictionary entry
5975      describes.  We have to compute that information as we iterate
5976      through the SOMs/symbols.  */
5977   som_index = 0;
5978 
5979   /* We add in the size of the archive header twice as the location
5980      in the SOM dictionary is the actual offset of the SOM, not the
5981      archive header before the SOM.  */
5982   curr_som_offset = 8 + 2 * sizeof (struct ar_hdr) + lst.file_end;
5983 
5984   /* Make room for the archive header and the contents of the
5985      extended string table.  Note that elength includes the size
5986      of the archive header for the extended name table!  */
5987   if (elength)
5988     curr_som_offset += elength;
5989 
5990   /* Make sure we're properly aligned.  */
5991   curr_som_offset = (curr_som_offset + 0x1) & ~0x1;
5992 
5993   /* FIXME should be done with buffers just like everything else...  */
5994   amt = nsyms;
5995   amt *= sizeof (struct lst_symbol_record);
5996   lst_syms = bfd_malloc (amt);
5997   if (lst_syms == NULL && nsyms != 0)
5998     goto error_return;
5999   strings = bfd_malloc ((bfd_size_type) string_size);
6000   if (strings == NULL && string_size != 0)
6001     goto error_return;
6002 
6003   p = strings;
6004   curr_lst_sym = lst_syms;
6005 
6006   curr_bfd = abfd->archive_head;
6007   while (curr_bfd != NULL)
6008     {
6009       unsigned int curr_count, i;
6010       som_symbol_type *sym;
6011 
6012       /* Don't bother for non-SOM objects.  */
6013       if (curr_bfd->format != bfd_object
6014 	  || curr_bfd->xvec->flavour != bfd_target_som_flavour)
6015 	{
6016 	  curr_bfd = curr_bfd->archive_next;
6017 	  continue;
6018 	}
6019 
6020       /* Make sure the symbol table has been read, then snag a pointer
6021 	 to it.  It's a little slimey to grab the symbols via obj_som_symtab,
6022 	 but doing so avoids allocating lots of extra memory.  */
6023       if (! som_slurp_symbol_table (curr_bfd))
6024 	goto error_return;
6025 
6026       sym = obj_som_symtab (curr_bfd);
6027       curr_count = bfd_get_symcount (curr_bfd);
6028 
6029       for (i = 0; i < curr_count; i++, sym++)
6030 	{
6031 	  struct som_misc_symbol_info info;
6032 
6033 	  /* Derive SOM information from the BFD symbol.  */
6034 	  som_bfd_derive_misc_symbol_info (curr_bfd, &sym->symbol, &info);
6035 
6036 	  /* Should we include this symbol?  */
6037 	  if (info.symbol_type == ST_NULL
6038 	      || info.symbol_type == ST_SYM_EXT
6039 	      || info.symbol_type == ST_ARG_EXT)
6040 	    continue;
6041 
6042 	  /* Only global symbols and unsatisfied commons.  */
6043 	  if (info.symbol_scope != SS_UNIVERSAL
6044 	      && info.symbol_type != ST_STORAGE)
6045 	    continue;
6046 
6047 	  /* Do no include undefined symbols.  */
6048 	  if (bfd_is_und_section (sym->symbol.section))
6049 	    continue;
6050 
6051 	  /* If this is the first symbol from this SOM, then update
6052 	     the SOM dictionary too.  */
6053 	  if (som_dict[som_index].location == 0)
6054 	    {
6055 	      som_dict[som_index].location = curr_som_offset;
6056 	      som_dict[som_index].length = arelt_size (curr_bfd);
6057 	    }
6058 
6059 	  /* Fill in the lst symbol record.  */
6060 	  curr_lst_sym->hidden = 0;
6061 	  curr_lst_sym->secondary_def = info.secondary_def;
6062 	  curr_lst_sym->symbol_type = info.symbol_type;
6063 	  curr_lst_sym->symbol_scope = info.symbol_scope;
6064 	  curr_lst_sym->check_level = 0;
6065 	  curr_lst_sym->must_qualify = 0;
6066 	  curr_lst_sym->initially_frozen = 0;
6067 	  curr_lst_sym->memory_resident = 0;
6068 	  curr_lst_sym->is_common = bfd_is_com_section (sym->symbol.section);
6069 	  curr_lst_sym->dup_common = info.dup_common;
6070 	  curr_lst_sym->xleast = 3;
6071 	  curr_lst_sym->arg_reloc = info.arg_reloc;
6072 	  curr_lst_sym->name.n_strx = p - strings + 4;
6073 	  curr_lst_sym->qualifier_name.n_strx = 0;
6074 	  curr_lst_sym->symbol_info = info.symbol_info;
6075 	  curr_lst_sym->symbol_value = info.symbol_value | info.priv_level;
6076 	  curr_lst_sym->symbol_descriptor = 0;
6077 	  curr_lst_sym->reserved = 0;
6078 	  curr_lst_sym->som_index = som_index;
6079 	  curr_lst_sym->symbol_key = som_bfd_ar_symbol_hash (&sym->symbol);
6080 	  curr_lst_sym->next_entry = 0;
6081 
6082 	  /* Insert into the hash table.  */
6083 	  if (hash_table[curr_lst_sym->symbol_key % lst.hash_size])
6084 	    {
6085 	      struct lst_symbol_record *tmp;
6086 
6087 	      /* There is already something at the head of this hash chain,
6088 		 so tack this symbol onto the end of the chain.  */
6089 	      tmp = last_hash_entry[curr_lst_sym->symbol_key % lst.hash_size];
6090 	      tmp->next_entry
6091 		= (curr_lst_sym - lst_syms) * sizeof (struct lst_symbol_record)
6092 		  + lst.hash_size * 4
6093 		  + lst.module_count * sizeof (struct som_entry)
6094 		  + sizeof (struct lst_header);
6095 	    }
6096 	  else
6097 	    /* First entry in this hash chain.  */
6098 	    hash_table[curr_lst_sym->symbol_key % lst.hash_size]
6099 	      = (curr_lst_sym - lst_syms) * sizeof (struct lst_symbol_record)
6100 	      + lst.hash_size * 4
6101 	      + lst.module_count * sizeof (struct som_entry)
6102 	      + sizeof (struct lst_header);
6103 
6104 	  /* Keep track of the last symbol we added to this chain so we can
6105 	     easily update its next_entry pointer.  */
6106 	  last_hash_entry[curr_lst_sym->symbol_key % lst.hash_size]
6107 	    = curr_lst_sym;
6108 
6109 	  /* Update the string table.  */
6110 	  bfd_put_32 (abfd, strlen (sym->symbol.name), p);
6111 	  p += 4;
6112 	  strcpy (p, sym->symbol.name);
6113 	  p += strlen (sym->symbol.name) + 1;
6114 	  while ((int) p % 4)
6115 	    {
6116 	      bfd_put_8 (abfd, 0, p);
6117 	      p++;
6118 	    }
6119 
6120 	  /* Head to the next symbol.  */
6121 	  curr_lst_sym++;
6122 	}
6123 
6124       /* Keep track of where each SOM will finally reside; then look
6125 	 at the next BFD.  */
6126       curr_som_offset += arelt_size (curr_bfd) + sizeof (struct ar_hdr);
6127 
6128       /* A particular object in the archive may have an odd length; the
6129 	 linker requires objects begin on an even boundary.  So round
6130 	 up the current offset as necessary.  */
6131       curr_som_offset = (curr_som_offset + 0x1) &~ (unsigned) 1;
6132       curr_bfd = curr_bfd->archive_next;
6133       som_index++;
6134     }
6135 
6136   /* Now scribble out the hash table.  */
6137   amt = lst.hash_size * 4;
6138   if (bfd_bwrite ((void *) hash_table, amt, abfd) != amt)
6139     goto error_return;
6140 
6141   /* Then the SOM dictionary.  */
6142   amt = lst.module_count * sizeof (struct som_entry);
6143   if (bfd_bwrite ((void *) som_dict, amt, abfd) != amt)
6144     goto error_return;
6145 
6146   /* The library symbols.  */
6147   amt = nsyms * sizeof (struct lst_symbol_record);
6148   if (bfd_bwrite ((void *) lst_syms, amt, abfd) != amt)
6149     goto error_return;
6150 
6151   /* And finally the strings.  */
6152   amt = string_size;
6153   if (bfd_bwrite ((void *) strings, amt, abfd) != amt)
6154     goto error_return;
6155 
6156   if (hash_table != NULL)
6157     free (hash_table);
6158   if (som_dict != NULL)
6159     free (som_dict);
6160   if (last_hash_entry != NULL)
6161     free (last_hash_entry);
6162   if (lst_syms != NULL)
6163     free (lst_syms);
6164   if (strings != NULL)
6165     free (strings);
6166   return TRUE;
6167 
6168  error_return:
6169   if (hash_table != NULL)
6170     free (hash_table);
6171   if (som_dict != NULL)
6172     free (som_dict);
6173   if (last_hash_entry != NULL)
6174     free (last_hash_entry);
6175   if (lst_syms != NULL)
6176     free (lst_syms);
6177   if (strings != NULL)
6178     free (strings);
6179 
6180   return FALSE;
6181 }
6182 
6183 /* Write out the LST for the archive.
6184 
6185    You'll never believe this is really how armaps are handled in SOM...  */
6186 
6187 static bfd_boolean
6188 som_write_armap (bfd *abfd,
6189 		 unsigned int elength,
6190 		 struct orl *map ATTRIBUTE_UNUSED,
6191 		 unsigned int orl_count ATTRIBUTE_UNUSED,
6192 		 int stridx ATTRIBUTE_UNUSED)
6193 {
6194   bfd *curr_bfd;
6195   struct stat statbuf;
6196   unsigned int i, lst_size, nsyms, stringsize;
6197   struct ar_hdr hdr;
6198   struct lst_header lst;
6199   int *p;
6200   bfd_size_type amt;
6201 
6202   /* We'll use this for the archive's date and mode later.  */
6203   if (stat (abfd->filename, &statbuf) != 0)
6204     {
6205       bfd_set_error (bfd_error_system_call);
6206       return FALSE;
6207     }
6208   /* Fudge factor.  */
6209   bfd_ardata (abfd)->armap_timestamp = statbuf.st_mtime + 60;
6210 
6211   /* Account for the lst header first.  */
6212   lst_size = sizeof (struct lst_header);
6213 
6214   /* Start building the LST header.  */
6215   /* FIXME:  Do we need to examine each element to determine the
6216      largest id number?  */
6217   lst.system_id = CPU_PA_RISC1_0;
6218   lst.a_magic = LIBMAGIC;
6219   lst.version_id = VERSION_ID;
6220   lst.file_time.secs = 0;
6221   lst.file_time.nanosecs = 0;
6222 
6223   lst.hash_loc = lst_size;
6224   lst.hash_size = SOM_LST_HASH_SIZE;
6225 
6226   /* Hash table is a SOM_LST_HASH_SIZE 32bit offsets.  */
6227   lst_size += 4 * SOM_LST_HASH_SIZE;
6228 
6229   /* We need to count the number of SOMs in this archive.  */
6230   curr_bfd = abfd->archive_head;
6231   lst.module_count = 0;
6232   while (curr_bfd != NULL)
6233     {
6234       /* Only true SOM objects count.  */
6235       if (curr_bfd->format == bfd_object
6236 	  && curr_bfd->xvec->flavour == bfd_target_som_flavour)
6237 	lst.module_count++;
6238       curr_bfd = curr_bfd->archive_next;
6239     }
6240   lst.module_limit = lst.module_count;
6241   lst.dir_loc = lst_size;
6242   lst_size += sizeof (struct som_entry) * lst.module_count;
6243 
6244   /* We don't support import/export tables, auxiliary headers,
6245      or free lists yet.  Make the linker work a little harder
6246      to make our life easier.  */
6247 
6248   lst.export_loc = 0;
6249   lst.export_count = 0;
6250   lst.import_loc = 0;
6251   lst.aux_loc = 0;
6252   lst.aux_size = 0;
6253 
6254   /* Count how many symbols we will have on the hash chains and the
6255      size of the associated string table.  */
6256   if (! som_bfd_prep_for_ar_write (abfd, &nsyms, &stringsize))
6257     return FALSE;
6258 
6259   lst_size += sizeof (struct lst_symbol_record) * nsyms;
6260 
6261   /* For the string table.  One day we might actually use this info
6262      to avoid small seeks/reads when reading archives.  */
6263   lst.string_loc = lst_size;
6264   lst.string_size = stringsize;
6265   lst_size += stringsize;
6266 
6267   /* SOM ABI says this must be zero.  */
6268   lst.free_list = 0;
6269   lst.file_end = lst_size;
6270 
6271   /* Compute the checksum.  Must happen after the entire lst header
6272      has filled in.  */
6273   p = (int *) &lst;
6274   lst.checksum = 0;
6275   for (i = 0; i < sizeof (struct lst_header) / sizeof (int) - 1; i++)
6276     lst.checksum ^= *p++;
6277 
6278   sprintf (hdr.ar_name, "/               ");
6279   sprintf (hdr.ar_date, "%ld", bfd_ardata (abfd)->armap_timestamp);
6280   sprintf (hdr.ar_uid, "%ld", (long) getuid ());
6281   sprintf (hdr.ar_gid, "%ld", (long) getgid ());
6282   sprintf (hdr.ar_mode, "%-8o", (unsigned int) statbuf.st_mode);
6283   sprintf (hdr.ar_size, "%-10d", (int) lst_size);
6284   hdr.ar_fmag[0] = '`';
6285   hdr.ar_fmag[1] = '\012';
6286 
6287   /* Turn any nulls into spaces.  */
6288   for (i = 0; i < sizeof (struct ar_hdr); i++)
6289     if (((char *) (&hdr))[i] == '\0')
6290       (((char *) (&hdr))[i]) = ' ';
6291 
6292   /* Scribble out the ar header.  */
6293   amt = sizeof (struct ar_hdr);
6294   if (bfd_bwrite ((void *) &hdr, amt, abfd) != amt)
6295     return FALSE;
6296 
6297   /* Now scribble out the lst header.  */
6298   amt = sizeof (struct lst_header);
6299   if (bfd_bwrite ((void *) &lst, amt, abfd) != amt)
6300     return FALSE;
6301 
6302   /* Build and write the armap.  */
6303   if (!som_bfd_ar_write_symbol_stuff (abfd, nsyms, stringsize, lst, elength))
6304     return FALSE;
6305 
6306   /* Done.  */
6307   return TRUE;
6308 }
6309 
6310 /* Free all information we have cached for this BFD.  We can always
6311    read it again later if we need it.  */
6312 
6313 static bfd_boolean
6314 som_bfd_free_cached_info (bfd *abfd)
6315 {
6316   asection *o;
6317 
6318   if (bfd_get_format (abfd) != bfd_object)
6319     return TRUE;
6320 
6321 #define FREE(x) if (x != NULL) { free (x); x = NULL; }
6322   /* Free the native string and symbol tables.  */
6323   FREE (obj_som_symtab (abfd));
6324   FREE (obj_som_stringtab (abfd));
6325   for (o = abfd->sections; o != NULL; o = o->next)
6326     {
6327       /* Free the native relocations.  */
6328       o->reloc_count = (unsigned) -1;
6329       FREE (som_section_data (o)->reloc_stream);
6330       /* Free the generic relocations.  */
6331       FREE (o->relocation);
6332     }
6333 #undef FREE
6334 
6335   return TRUE;
6336 }
6337 
6338 /* End of miscellaneous support functions.  */
6339 
6340 /* Linker support functions.  */
6341 
6342 static bfd_boolean
6343 som_bfd_link_split_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
6344 {
6345   return som_is_subspace (sec) && sec->size > 240000;
6346 }
6347 
6348 #define	som_close_and_cleanup		        som_bfd_free_cached_info
6349 #define som_read_ar_hdr			        _bfd_generic_read_ar_hdr
6350 #define som_openr_next_archived_file	        bfd_generic_openr_next_archived_file
6351 #define som_get_elt_at_index		        _bfd_generic_get_elt_at_index
6352 #define som_generic_stat_arch_elt	        bfd_generic_stat_arch_elt
6353 #define som_truncate_arname		        bfd_bsd_truncate_arname
6354 #define som_slurp_extended_name_table	        _bfd_slurp_extended_name_table
6355 #define som_construct_extended_name_table       _bfd_archive_coff_construct_extended_name_table
6356 #define som_update_armap_timestamp	        bfd_true
6357 #define som_bfd_is_target_special_symbol   ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
6358 #define som_get_lineno			        _bfd_nosymbols_get_lineno
6359 #define som_bfd_make_debug_symbol	        _bfd_nosymbols_bfd_make_debug_symbol
6360 #define som_read_minisymbols		        _bfd_generic_read_minisymbols
6361 #define som_minisymbol_to_symbol	        _bfd_generic_minisymbol_to_symbol
6362 #define som_get_section_contents_in_window      _bfd_generic_get_section_contents_in_window
6363 #define som_bfd_get_relocated_section_contents  bfd_generic_get_relocated_section_contents
6364 #define som_bfd_relax_section                   bfd_generic_relax_section
6365 #define som_bfd_link_hash_table_create          _bfd_generic_link_hash_table_create
6366 #define som_bfd_link_hash_table_free            _bfd_generic_link_hash_table_free
6367 #define som_bfd_link_add_symbols                _bfd_generic_link_add_symbols
6368 #define som_bfd_link_just_syms                  _bfd_generic_link_just_syms
6369 #define som_bfd_final_link                      _bfd_generic_final_link
6370 #define som_bfd_gc_sections		        bfd_generic_gc_sections
6371 #define som_bfd_merge_sections		        bfd_generic_merge_sections
6372 #define som_bfd_is_group_section	        bfd_generic_is_group_section
6373 #define som_bfd_discard_group		        bfd_generic_discard_group
6374 #define som_section_already_linked              _bfd_generic_section_already_linked
6375 #define som_bfd_merge_private_bfd_data		_bfd_generic_bfd_merge_private_bfd_data
6376 #define som_bfd_copy_private_header_data	_bfd_generic_bfd_copy_private_header_data
6377 #define som_bfd_set_private_flags		_bfd_generic_bfd_set_private_flags
6378 #define som_find_inliner_info			_bfd_nosymbols_find_inliner_info
6379 
6380 const bfd_target som_vec =
6381 {
6382   "som",			/* Name.  */
6383   bfd_target_som_flavour,
6384   BFD_ENDIAN_BIG,		/* Target byte order.  */
6385   BFD_ENDIAN_BIG,		/* Target headers byte order.  */
6386   (HAS_RELOC | EXEC_P |		/* Object flags.  */
6387    HAS_LINENO | HAS_DEBUG |
6388    HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED | DYNAMIC),
6389   (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS | SEC_LINK_ONCE
6390    | SEC_ALLOC | SEC_LOAD | SEC_RELOC),		/* Section flags.  */
6391 
6392   /* Leading_symbol_char: is the first char of a user symbol
6393      predictable, and if so what is it.  */
6394   0,
6395   '/',				/* AR_pad_char.  */
6396   14,				/* AR_max_namelen.  */
6397   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
6398   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
6399   bfd_getb16, bfd_getb_signed_16, bfd_putb16,	/* Data.  */
6400   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
6401   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
6402   bfd_getb16, bfd_getb_signed_16, bfd_putb16,	/* Headers.  */
6403   {_bfd_dummy_target,
6404    som_object_p,		/* bfd_check_format.  */
6405    bfd_generic_archive_p,
6406    _bfd_dummy_target
6407   },
6408   {
6409     bfd_false,
6410     som_mkobject,
6411     _bfd_generic_mkarchive,
6412     bfd_false
6413   },
6414   {
6415     bfd_false,
6416     som_write_object_contents,
6417     _bfd_write_archive_contents,
6418     bfd_false,
6419   },
6420 #undef som
6421 
6422   BFD_JUMP_TABLE_GENERIC (som),
6423   BFD_JUMP_TABLE_COPY (som),
6424   BFD_JUMP_TABLE_CORE (_bfd_nocore),
6425   BFD_JUMP_TABLE_ARCHIVE (som),
6426   BFD_JUMP_TABLE_SYMBOLS (som),
6427   BFD_JUMP_TABLE_RELOCS (som),
6428   BFD_JUMP_TABLE_WRITE (som),
6429   BFD_JUMP_TABLE_LINK (som),
6430   BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
6431 
6432   NULL,
6433 
6434   NULL
6435 };
6436 
6437 #endif /* HOST_HPPAHPUX || HOST_HPPABSD || HOST_HPPAOSF */
6438