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