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