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