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