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