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