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