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