* som.c (som_slurp_string_table): Allocate the strings with malloc
[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 = malloc (obj_som_stringtab_size (abfd));
3844   bzero (stringtab, obj_som_stringtab_size (abfd));
3845   if (stringtab == NULL)
3846     {
3847       bfd_set_error (bfd_error_no_memory);
3848       return false;
3849     }
3850
3851   if (bfd_seek (abfd, obj_som_str_filepos (abfd), SEEK_SET) < 0)
3852     return false;
3853   
3854   if (bfd_read (stringtab, obj_som_stringtab_size (abfd), 1, abfd)
3855       != obj_som_stringtab_size (abfd))
3856     return false;
3857
3858   /* Save our results and return success. */
3859   obj_som_stringtab (abfd) = stringtab;
3860   return true;
3861 }
3862
3863 /* Return the amount of data (in bytes) required to hold the symbol
3864    table for this object.  */
3865
3866 static long
3867 som_get_symtab_upper_bound (abfd)
3868      bfd *abfd;
3869 {
3870   if (!som_slurp_symbol_table (abfd))
3871     return -1;
3872
3873   return (bfd_get_symcount (abfd) + 1) * (sizeof (asymbol *));
3874 }
3875
3876 /* Convert from a SOM subspace index to a BFD section.  */
3877
3878 static asection *
3879 bfd_section_from_som_symbol (abfd, symbol)
3880      bfd *abfd;
3881      struct symbol_dictionary_record *symbol;
3882 {
3883   asection *section;
3884
3885   /* The meaning of the symbol_info field changes for functions
3886      within executables.  So only use the quick symbol_info mapping for
3887      incomplete objects and non-function symbols in executables.  */
3888   if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0
3889       || (symbol->symbol_type != ST_ENTRY
3890           && symbol->symbol_type != ST_PRI_PROG
3891           && symbol->symbol_type != ST_SEC_PROG
3892           && symbol->symbol_type != ST_MILLICODE))
3893     {
3894       unsigned int index = symbol->symbol_info;
3895       for (section = abfd->sections; section != NULL; section = section->next)
3896         if (section->target_index == index && som_is_subspace (section))
3897           return section;
3898
3899       /* Could be a symbol from an external library (such as an OMOS
3900          shared library).  Don't abort.  */
3901       return bfd_abs_section_ptr;
3902
3903     }
3904   else
3905     {
3906       unsigned int value = symbol->symbol_value;
3907
3908       /* For executables we will have to use the symbol's address and
3909          find out what section would contain that address.   Yuk.  */
3910       for (section = abfd->sections; section; section = section->next)
3911         {
3912           if (value >= section->vma
3913               && value <= section->vma + section->_cooked_size
3914               && som_is_subspace (section))
3915             return section;
3916         }
3917
3918       /* Could be a symbol from an external library (such as an OMOS
3919          shared library).  Don't abort.  */
3920       return bfd_abs_section_ptr;
3921
3922     }
3923 }
3924
3925 /* Read and save the symbol table associated with the given BFD.  */
3926
3927 static unsigned int
3928 som_slurp_symbol_table (abfd)
3929      bfd *abfd;
3930 {
3931   int symbol_count = bfd_get_symcount (abfd);
3932   int symsize = sizeof (struct symbol_dictionary_record);
3933   char *stringtab;
3934   struct symbol_dictionary_record *buf = NULL, *bufp, *endbufp;
3935   som_symbol_type *sym, *symbase;
3936
3937   /* Return saved value if it exists.  */
3938   if (obj_som_symtab (abfd) != NULL)
3939     goto successful_return;
3940
3941   /* Special case.  This is *not* an error.  */
3942   if (symbol_count == 0)
3943     goto successful_return;
3944
3945   if (!som_slurp_string_table (abfd))
3946     goto error_return;
3947
3948   stringtab = obj_som_stringtab (abfd);
3949
3950   symbase = (som_symbol_type *)
3951     malloc (symbol_count * sizeof (som_symbol_type));
3952   bzero (symbase, symbol_count * sizeof (som_symbol_type));
3953   if (symbase == NULL)
3954     {
3955       bfd_set_error (bfd_error_no_memory);
3956       goto error_return;
3957     }
3958
3959   /* Read in the external SOM representation.  */
3960   buf = malloc (symbol_count * symsize);
3961   if (buf == NULL && symbol_count * symsize != 0)
3962     {
3963       bfd_set_error (bfd_error_no_memory);
3964       goto error_return;
3965     }
3966   if (bfd_seek (abfd, obj_som_sym_filepos (abfd), SEEK_SET) < 0)
3967     goto error_return;
3968   if (bfd_read (buf, symbol_count * symsize, 1, abfd) 
3969       != symbol_count * symsize)
3970     goto error_return;
3971
3972   /* Iterate over all the symbols and internalize them.  */
3973   endbufp = buf + symbol_count;
3974   for (bufp = buf, sym = symbase; bufp < endbufp; ++bufp)
3975     {
3976
3977       /* I don't think we care about these.  */
3978       if (bufp->symbol_type == ST_SYM_EXT
3979           || bufp->symbol_type == ST_ARG_EXT)
3980         continue;
3981
3982       /* Set some private data we care about.  */
3983       if (bufp->symbol_type == ST_NULL)
3984         som_symbol_data (sym)->som_type = SYMBOL_TYPE_UNKNOWN;
3985       else if (bufp->symbol_type == ST_ABSOLUTE)
3986         som_symbol_data (sym)->som_type = SYMBOL_TYPE_ABSOLUTE;
3987       else if (bufp->symbol_type == ST_DATA)
3988         som_symbol_data (sym)->som_type = SYMBOL_TYPE_DATA;
3989       else if (bufp->symbol_type == ST_CODE)
3990         som_symbol_data (sym)->som_type = SYMBOL_TYPE_CODE;
3991       else if (bufp->symbol_type == ST_PRI_PROG)
3992         som_symbol_data (sym)->som_type = SYMBOL_TYPE_PRI_PROG;
3993       else if (bufp->symbol_type == ST_SEC_PROG)
3994         som_symbol_data (sym)->som_type = SYMBOL_TYPE_SEC_PROG;
3995       else if (bufp->symbol_type == ST_ENTRY)
3996         som_symbol_data (sym)->som_type = SYMBOL_TYPE_ENTRY;
3997       else if (bufp->symbol_type == ST_MILLICODE)
3998         som_symbol_data (sym)->som_type = SYMBOL_TYPE_MILLICODE;
3999       else if (bufp->symbol_type == ST_PLABEL)
4000         som_symbol_data (sym)->som_type = SYMBOL_TYPE_PLABEL;
4001       else
4002         som_symbol_data (sym)->som_type = SYMBOL_TYPE_UNKNOWN;
4003       som_symbol_data (sym)->tc_data.hppa_arg_reloc = bufp->arg_reloc;
4004
4005       /* Some reasonable defaults.  */
4006       sym->symbol.the_bfd = abfd;
4007       sym->symbol.name = bufp->name.n_strx + stringtab;
4008       sym->symbol.value = bufp->symbol_value;
4009       sym->symbol.section = 0;
4010       sym->symbol.flags = 0;
4011
4012       switch (bufp->symbol_type)
4013         {
4014         case ST_ENTRY:
4015         case ST_MILLICODE:
4016           sym->symbol.flags |= BSF_FUNCTION;
4017           sym->symbol.value &= ~0x3;
4018           break;
4019
4020         case ST_STUB:
4021         case ST_CODE:
4022         case ST_PRI_PROG:
4023         case ST_SEC_PROG:
4024           sym->symbol.value &= ~0x3;
4025           /* If the symbol's scope is ST_UNSAT, then these are
4026              undefined function symbols.  */
4027           if (bufp->symbol_scope == SS_UNSAT)
4028             sym->symbol.flags |= BSF_FUNCTION;
4029              
4030
4031         default:
4032           break;
4033         }
4034
4035       /* Handle scoping and section information.  */
4036       switch (bufp->symbol_scope)
4037         {
4038         /* symbol_info field is undefined for SS_EXTERNAL and SS_UNSAT symbols,
4039            so the section associated with this symbol can't be known.  */
4040         case SS_EXTERNAL:
4041           if (bufp->symbol_type != ST_STORAGE)
4042             sym->symbol.section = bfd_und_section_ptr;
4043           else
4044             sym->symbol.section = bfd_com_section_ptr;
4045           sym->symbol.flags |= (BSF_EXPORT | BSF_GLOBAL);
4046           break;
4047
4048         case SS_UNSAT:
4049           if (bufp->symbol_type != ST_STORAGE)
4050             sym->symbol.section = bfd_und_section_ptr;
4051           else
4052             sym->symbol.section = bfd_com_section_ptr;
4053           break;
4054
4055         case SS_UNIVERSAL:
4056           sym->symbol.flags |= (BSF_EXPORT | BSF_GLOBAL);
4057           sym->symbol.section = bfd_section_from_som_symbol (abfd, bufp);
4058           sym->symbol.value -= sym->symbol.section->vma;
4059           break;
4060
4061 #if 0
4062         /* SS_GLOBAL and SS_LOCAL are two names for the same thing.
4063            Sound dumb?  It is.  */
4064         case SS_GLOBAL:
4065 #endif
4066         case SS_LOCAL:
4067           sym->symbol.flags |= BSF_LOCAL;
4068           sym->symbol.section = bfd_section_from_som_symbol (abfd, bufp);
4069           sym->symbol.value -= sym->symbol.section->vma;
4070           break;
4071         }
4072
4073       /* Mark section symbols and symbols used by the debugger.
4074          Note $START$ is a magic code symbol, NOT a section symbol.  */
4075       if (sym->symbol.name[0] == '$'
4076           && sym->symbol.name[strlen (sym->symbol.name) - 1] == '$'
4077           && !strcmp (sym->symbol.name, sym->symbol.section->name))
4078         sym->symbol.flags |= BSF_SECTION_SYM;
4079       else if (!strncmp (sym->symbol.name, "L$0\002", 4))
4080         {
4081           sym->symbol.flags |= BSF_SECTION_SYM;
4082           sym->symbol.name = sym->symbol.section->name;
4083         }
4084       else if (!strncmp (sym->symbol.name, "L$0\001", 4))
4085         sym->symbol.flags |= BSF_DEBUGGING;
4086
4087       /* Note increment at bottom of loop, since we skip some symbols
4088          we can not include it as part of the for statement.  */
4089       sym++;
4090     }
4091
4092  /* Save our results and return success.  */
4093  obj_som_symtab (abfd) = symbase;
4094  successful_return:
4095   if (buf != NULL)
4096     free (buf);
4097   return (true);
4098
4099  error_return:
4100   if (buf != NULL)
4101     free (buf);
4102   return false;
4103 }
4104
4105 /* Canonicalize a SOM symbol table.  Return the number of entries
4106    in the symbol table.  */
4107
4108 static long
4109 som_get_symtab (abfd, location)
4110      bfd *abfd;
4111      asymbol **location;
4112 {
4113   int i;
4114   som_symbol_type *symbase;
4115
4116   if (!som_slurp_symbol_table (abfd))
4117     return -1;
4118
4119   i = bfd_get_symcount (abfd);
4120   symbase = obj_som_symtab (abfd);
4121
4122   for (; i > 0; i--, location++, symbase++)
4123     *location = &symbase->symbol;
4124
4125   /* Final null pointer.  */
4126   *location = 0;
4127   return (bfd_get_symcount (abfd));
4128 }
4129
4130 /* Make a SOM symbol.  There is nothing special to do here.  */
4131
4132 static asymbol *
4133 som_make_empty_symbol (abfd)
4134      bfd *abfd;
4135 {
4136   som_symbol_type *new =
4137   (som_symbol_type *) bfd_zalloc (abfd, sizeof (som_symbol_type));
4138   if (new == NULL)
4139     {
4140       bfd_set_error (bfd_error_no_memory);
4141       return 0;
4142     }
4143   new->symbol.the_bfd = abfd;
4144
4145   return &new->symbol;
4146 }
4147
4148 /* Print symbol information.  */
4149
4150 static void
4151 som_print_symbol (ignore_abfd, afile, symbol, how)
4152      bfd *ignore_abfd;
4153      PTR afile;
4154      asymbol *symbol;
4155      bfd_print_symbol_type how;
4156 {
4157   FILE *file = (FILE *) afile;
4158   switch (how)
4159     {
4160     case bfd_print_symbol_name:
4161       fprintf (file, "%s", symbol->name);
4162       break;
4163     case bfd_print_symbol_more:
4164       fprintf (file, "som ");
4165       fprintf_vma (file, symbol->value);
4166       fprintf (file, " %lx", (long) symbol->flags);
4167       break;
4168     case bfd_print_symbol_all:
4169       {
4170         CONST char *section_name;
4171         section_name = symbol->section ? symbol->section->name : "(*none*)";
4172         bfd_print_symbol_vandf ((PTR) file, symbol);
4173         fprintf (file, " %s\t%s", section_name, symbol->name);
4174         break;
4175       }
4176     }
4177 }
4178
4179 static boolean
4180 som_bfd_is_local_label (abfd, sym)
4181      bfd *abfd;
4182      asymbol *sym;
4183 {
4184   return (sym->name[0] == 'L' && sym->name[1] == '$');
4185 }
4186
4187 /* Count or process variable-length SOM fixup records.
4188
4189    To avoid code duplication we use this code both to compute the number
4190    of relocations requested by a stream, and to internalize the stream.
4191
4192    When computing the number of relocations requested by a stream the
4193    variables rptr, section, and symbols have no meaning.
4194
4195    Return the number of relocations requested by the fixup stream.  When
4196    not just counting 
4197
4198    This needs at least two or three more passes to get it cleaned up.  */
4199
4200 static unsigned int
4201 som_set_reloc_info (fixup, end, internal_relocs, section, symbols, just_count)
4202      unsigned char *fixup;
4203      unsigned int end;
4204      arelent *internal_relocs;
4205      asection *section;
4206      asymbol **symbols;
4207      boolean just_count;
4208 {
4209   unsigned int op, varname, deallocate_contents = 0;
4210   unsigned char *end_fixups = &fixup[end];
4211   const struct fixup_format *fp;
4212   char *cp;
4213   unsigned char *save_fixup;
4214   int variables[26], stack[20], c, v, count, prev_fixup, *sp, saved_unwind_bits;
4215   const int *subop;
4216   arelent *rptr= internal_relocs;
4217   unsigned int offset = 0;
4218
4219 #define var(c)          variables[(c) - 'A']
4220 #define push(v)         (*sp++ = (v))
4221 #define pop()           (*--sp)
4222 #define emptystack()    (sp == stack)
4223
4224   som_initialize_reloc_queue (reloc_queue);
4225   memset (variables, 0, sizeof (variables));
4226   memset (stack, 0, sizeof (stack));
4227   count = 0;
4228   prev_fixup = 0;
4229   saved_unwind_bits = 0;
4230   sp = stack;
4231
4232   while (fixup < end_fixups)
4233     {
4234
4235       /* Save pointer to the start of this fixup.  We'll use
4236          it later to determine if it is necessary to put this fixup
4237          on the queue.  */
4238       save_fixup = fixup;
4239
4240       /* Get the fixup code and its associated format.  */
4241       op = *fixup++;
4242       fp = &som_fixup_formats[op];
4243
4244       /* Handle a request for a previous fixup.  */
4245       if (*fp->format == 'P')
4246         {
4247           /* Get pointer to the beginning of the prev fixup, move
4248              the repeated fixup to the head of the queue.  */
4249           fixup = reloc_queue[fp->D].reloc;
4250           som_reloc_queue_fix (reloc_queue, fp->D);
4251           prev_fixup = 1;
4252
4253           /* Get the fixup code and its associated format.  */
4254           op = *fixup++;
4255           fp = &som_fixup_formats[op];
4256         }
4257
4258       /* If this fixup will be passed to BFD, set some reasonable defaults.  */
4259       if (! just_count
4260           && som_hppa_howto_table[op].type != R_NO_RELOCATION
4261           && som_hppa_howto_table[op].type != R_DATA_OVERRIDE)
4262         {
4263           rptr->address = offset;
4264           rptr->howto = &som_hppa_howto_table[op];
4265           rptr->addend = 0;
4266           rptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
4267         }
4268
4269       /* Set default input length to 0.  Get the opcode class index
4270          into D.  */
4271       var ('L') = 0;
4272       var ('D') = fp->D;
4273       var ('U') = saved_unwind_bits;
4274
4275       /* Get the opcode format.  */
4276       cp = fp->format;
4277
4278       /* Process the format string.  Parsing happens in two phases,
4279          parse RHS, then assign to LHS.  Repeat until no more 
4280          characters in the format string.  */
4281       while (*cp)
4282         {
4283           /* The variable this pass is going to compute a value for.  */
4284           varname = *cp++;
4285
4286           /* Start processing RHS.  Continue until a NULL or '=' is found.  */
4287           do
4288             {
4289               c = *cp++;
4290
4291               /* If this is a variable, push it on the stack.  */
4292               if (isupper (c))
4293                 push (var (c));
4294
4295               /* If this is a lower case letter, then it represents
4296                  additional data from the fixup stream to be pushed onto
4297                  the stack.  */
4298               else if (islower (c))
4299                 {
4300                   int bits = (c - 'a') * 8;
4301                   for (v = 0; c > 'a'; --c)
4302                     v = (v << 8) | *fixup++;
4303                   if (varname == 'V')
4304                     v = sign_extend (v, bits);
4305                   push (v);
4306                 }
4307
4308               /* A decimal constant.  Push it on the stack.  */
4309               else if (isdigit (c))
4310                 {
4311                   v = c - '0';
4312                   while (isdigit (*cp))
4313                     v = (v * 10) + (*cp++ - '0');
4314                   push (v);
4315                 }
4316               else
4317
4318                 /* An operator.  Pop two two values from the stack and
4319                    use them as operands to the given operation.  Push
4320                    the result of the operation back on the stack.  */
4321                 switch (c)
4322                   {
4323                   case '+':
4324                     v = pop ();
4325                     v += pop ();
4326                     push (v);
4327                     break;
4328                   case '*':
4329                     v = pop ();
4330                     v *= pop ();
4331                     push (v);
4332                     break;
4333                   case '<':
4334                     v = pop ();
4335                     v = pop () << v;
4336                     push (v);
4337                     break;
4338                   default:
4339                     abort ();
4340                   }
4341             }
4342           while (*cp && *cp != '=');
4343
4344           /* Move over the equal operator.  */
4345           cp++;
4346
4347           /* Pop the RHS off the stack.  */
4348           c = pop ();
4349
4350           /* Perform the assignment.  */
4351           var (varname) = c;
4352
4353           /* Handle side effects. and special 'O' stack cases.  */
4354           switch (varname)
4355             {
4356             /* Consume some bytes from the input space.  */
4357             case 'L':
4358               offset += c;
4359               break;
4360             /* A symbol to use in the relocation.  Make a note
4361                of this if we are not just counting.  */
4362             case 'S':
4363               if (! just_count)
4364                 rptr->sym_ptr_ptr = &symbols[c];
4365               break;
4366             /* Argument relocation bits for a function call.  */
4367             case 'R':
4368               if (! just_count)
4369                 {
4370                   unsigned int tmp = var ('R');
4371                   rptr->addend = 0;
4372
4373                   if ((som_hppa_howto_table[op].type == R_PCREL_CALL
4374                        && R_PCREL_CALL + 10 > op)
4375                       || (som_hppa_howto_table[op].type == R_ABS_CALL
4376                           && R_ABS_CALL + 10 > op))
4377                     {
4378                       /* Simple encoding.  */
4379                       if (tmp > 4)
4380                         {
4381                           tmp -= 5;
4382                           rptr->addend |= 1;
4383                         }
4384                       if (tmp == 4)
4385                         rptr->addend |= 1 << 8 | 1 << 6 | 1 << 4 | 1 << 2;
4386                       else if (tmp == 3)
4387                         rptr->addend |= 1 << 8 | 1 << 6 | 1 << 4;
4388                       else if (tmp == 2)
4389                         rptr->addend |= 1 << 8 | 1 << 6;
4390                       else if (tmp == 1)
4391                         rptr->addend |= 1 << 8;
4392                     }
4393                   else
4394                     {
4395                       unsigned int tmp1, tmp2;
4396
4397                       /* First part is easy -- low order two bits are
4398                          directly copied, then shifted away.  */
4399                       rptr->addend = tmp & 0x3;
4400                       tmp >>= 2;
4401
4402                       /* Diving the result by 10 gives us the second
4403                          part.  If it is 9, then the first two words
4404                          are a double precision paramater, else it is
4405                          3 * the first arg bits + the 2nd arg bits.  */
4406                       tmp1 = tmp / 10;
4407                       tmp -= tmp1 * 10;
4408                       if (tmp1 == 9)
4409                         rptr->addend += (0xe << 6);
4410                       else
4411                         {
4412                           /* Get the two pieces.  */
4413                           tmp2 = tmp1 / 3;
4414                           tmp1 -= tmp2 * 3;
4415                           /* Put them in the addend.  */
4416                           rptr->addend += (tmp2 << 8) + (tmp1 << 6);
4417                         }
4418
4419                       /* What's left is the third part.  It's unpacked
4420                          just like the second.  */
4421                       if (tmp == 9)
4422                         rptr->addend += (0xe << 2);
4423                       else
4424                         {
4425                           tmp2 = tmp / 3;
4426                           tmp -= tmp2 * 3;
4427                           rptr->addend += (tmp2 << 4) + (tmp << 2);
4428                         }
4429                     }
4430                   rptr->addend = HPPA_R_ADDEND (rptr->addend, 0);
4431                 }
4432               break;
4433             /* Handle the linker expression stack.  */
4434             case 'O':
4435               switch (op)
4436                 {
4437                 case R_COMP1:
4438                   subop = comp1_opcodes;
4439                   break;
4440                 case R_COMP2:
4441                   subop = comp2_opcodes;
4442                   break;
4443                 case R_COMP3:
4444                   subop = comp3_opcodes;
4445                   break;
4446                 default:
4447                   abort ();
4448                 }
4449               while (*subop <= (unsigned char) c)
4450                 ++subop;
4451               --subop;
4452               break;
4453             /* The lower 32unwind bits must be persistent.  */
4454             case 'U':
4455               saved_unwind_bits = var ('U');
4456               break;
4457
4458             default:
4459               break;
4460             }
4461         }
4462
4463       /* If we used a previous fixup, clean up after it.  */
4464       if (prev_fixup)
4465         {
4466           fixup = save_fixup + 1;
4467           prev_fixup = 0;
4468         }
4469       /* Queue it.  */
4470       else if (fixup > save_fixup + 1)
4471         som_reloc_queue_insert (save_fixup, fixup - save_fixup, reloc_queue);
4472
4473       /* We do not pass R_DATA_OVERRIDE or R_NO_RELOCATION 
4474          fixups to BFD.  */
4475       if (som_hppa_howto_table[op].type != R_DATA_OVERRIDE
4476           && som_hppa_howto_table[op].type != R_NO_RELOCATION)
4477         {
4478           /* Done with a single reloction. Loop back to the top.  */
4479           if (! just_count)
4480             {
4481               if (som_hppa_howto_table[op].type == R_ENTRY)
4482                 rptr->addend = var ('T');
4483               else if (som_hppa_howto_table[op].type == R_EXIT)
4484                 rptr->addend = var ('U');
4485               else if (som_hppa_howto_table[op].type == R_PCREL_CALL
4486                        || som_hppa_howto_table[op].type == R_ABS_CALL)
4487                 ;
4488               else if (som_hppa_howto_table[op].type == R_DATA_ONE_SYMBOL)
4489                 {
4490                   unsigned addend = var ('V');
4491
4492                   /* Try what was specified in R_DATA_OVERRIDE first
4493                      (if anything).  Then the hard way using the
4494                      section contents.  */
4495                   rptr->addend = var ('V');
4496
4497                   if (rptr->addend == 0 && !section->contents)
4498                     {
4499                       /* Got to read the damn contents first.  We don't
4500                          bother saving the contents (yet).  Add it one
4501                          day if the need arises.  */
4502                       section->contents = malloc (section->_raw_size);
4503                       if (section->contents == NULL)
4504                         return -1;
4505
4506                       deallocate_contents = 1;
4507                       bfd_get_section_contents (section->owner,
4508                                                 section,
4509                                                 section->contents,
4510                                                 0,
4511                                                 section->_raw_size);
4512                     }
4513                   else if (rptr->addend == 0)
4514                     rptr->addend = bfd_get_32 (section->owner,
4515                                                (section->contents
4516                                                 + offset - var ('L')));
4517                         
4518                 }
4519               else
4520                 rptr->addend = var ('V');
4521               rptr++;
4522             }
4523           count++;
4524           /* Now that we've handled a "full" relocation, reset
4525              some state.  */
4526           memset (variables, 0, sizeof (variables));
4527           memset (stack, 0, sizeof (stack));
4528         }
4529     }
4530   if (deallocate_contents)
4531     free (section->contents);
4532
4533   return count;
4534
4535 #undef var
4536 #undef push
4537 #undef pop
4538 #undef emptystack
4539 }
4540
4541 /* Read in the relocs (aka fixups in SOM terms) for a section. 
4542
4543    som_get_reloc_upper_bound calls this routine with JUST_COUNT 
4544    set to true to indicate it only needs a count of the number
4545    of actual relocations.  */
4546
4547 static boolean
4548 som_slurp_reloc_table (abfd, section, symbols, just_count)
4549      bfd *abfd;
4550      asection *section;
4551      asymbol **symbols;
4552      boolean just_count;
4553 {
4554   char *external_relocs;
4555   unsigned int fixup_stream_size;
4556   arelent *internal_relocs;
4557   unsigned int num_relocs;
4558
4559   fixup_stream_size = som_section_data (section)->reloc_size;
4560   /* If there were no relocations, then there is nothing to do.  */
4561   if (section->reloc_count == 0)
4562     return true;
4563
4564   /* If reloc_count is -1, then the relocation stream has not been 
4565      parsed.  We must do so now to know how many relocations exist.  */
4566   if (section->reloc_count == -1)
4567     {
4568       external_relocs = (char *) malloc (fixup_stream_size);
4569       if (external_relocs == (char *) NULL)
4570         {
4571           bfd_set_error (bfd_error_no_memory);
4572           return false;
4573         }
4574       /* Read in the external forms. */
4575       if (bfd_seek (abfd,
4576                     obj_som_reloc_filepos (abfd) + section->rel_filepos,
4577                     SEEK_SET)
4578           != 0)
4579         return false;
4580       if (bfd_read (external_relocs, 1, fixup_stream_size, abfd)
4581           != fixup_stream_size)
4582         return false;
4583
4584       /* Let callers know how many relocations found.
4585          also save the relocation stream as we will
4586          need it again.  */
4587       section->reloc_count = som_set_reloc_info (external_relocs,
4588                                                  fixup_stream_size,
4589                                                  NULL, NULL, NULL, true);
4590
4591       som_section_data (section)->reloc_stream = external_relocs;
4592     }
4593
4594   /* If the caller only wanted a count, then return now.  */
4595   if (just_count)
4596     return true;
4597
4598   num_relocs = section->reloc_count;
4599   external_relocs = som_section_data (section)->reloc_stream;
4600   /* Return saved information about the relocations if it is available.  */
4601   if (section->relocation != (arelent *) NULL)
4602     return true;
4603
4604   internal_relocs = (arelent *) 
4605     bfd_zalloc (abfd, (num_relocs * sizeof (arelent)));
4606   if (internal_relocs == (arelent *) NULL)
4607     {
4608       bfd_set_error (bfd_error_no_memory);
4609       return false;
4610     }
4611
4612   /* Process and internalize the relocations.  */
4613   som_set_reloc_info (external_relocs, fixup_stream_size,
4614                       internal_relocs, section, symbols, false);
4615
4616   /* We're done with the external relocations.  Free them.  */
4617   free (external_relocs);
4618
4619   /* Save our results and return success.  */
4620   section->relocation = internal_relocs;
4621   return (true);
4622 }
4623
4624 /* Return the number of bytes required to store the relocation
4625    information associated with the given section.  */ 
4626
4627 static long
4628 som_get_reloc_upper_bound (abfd, asect)
4629      bfd *abfd;
4630      sec_ptr asect;
4631 {
4632   /* If section has relocations, then read in the relocation stream
4633      and parse it to determine how many relocations exist.  */
4634   if (asect->flags & SEC_RELOC)
4635     {
4636       if (! som_slurp_reloc_table (abfd, asect, NULL, true))
4637         return -1;
4638       return (asect->reloc_count + 1) * sizeof (arelent *);
4639     }
4640   /* There are no relocations.  */
4641   return 0;
4642 }
4643
4644 /* Convert relocations from SOM (external) form into BFD internal
4645    form.  Return the number of relocations.  */
4646
4647 static long
4648 som_canonicalize_reloc (abfd, section, relptr, symbols)
4649      bfd *abfd;
4650      sec_ptr section;
4651      arelent **relptr;
4652      asymbol **symbols;
4653 {
4654   arelent *tblptr;
4655   int count;
4656
4657   if (som_slurp_reloc_table (abfd, section, symbols, false) == false)
4658     return -1;
4659
4660   count = section->reloc_count;
4661   tblptr = section->relocation;
4662
4663   while (count--)
4664     *relptr++ = tblptr++;
4665
4666   *relptr = (arelent *) NULL;
4667   return section->reloc_count;
4668 }
4669
4670 extern const bfd_target som_vec;
4671
4672 /* A hook to set up object file dependent section information.  */
4673
4674 static boolean
4675 som_new_section_hook (abfd, newsect)
4676      bfd *abfd;
4677      asection *newsect;
4678 {
4679   newsect->used_by_bfd =
4680     (PTR) bfd_zalloc (abfd, sizeof (struct som_section_data_struct));
4681   if (!newsect->used_by_bfd)
4682     {
4683       bfd_set_error (bfd_error_no_memory);
4684       return false;
4685     }
4686   newsect->alignment_power = 3;
4687
4688   /* We allow more than three sections internally */
4689   return true;
4690 }
4691
4692 /* Copy any private info we understand from the input symbol
4693    to the output symbol.  */
4694
4695 static boolean
4696 som_bfd_copy_private_symbol_data (ibfd, isymbol, obfd, osymbol)
4697      bfd *ibfd;
4698      asymbol *isymbol;
4699      bfd *obfd;
4700      asymbol *osymbol;
4701 {
4702   struct som_symbol *input_symbol = (struct som_symbol *) isymbol;
4703   struct som_symbol *output_symbol = (struct som_symbol *) osymbol;
4704
4705   /* One day we may try to grok other private data.  */
4706   if (ibfd->xvec->flavour != bfd_target_som_flavour
4707       || obfd->xvec->flavour != bfd_target_som_flavour)
4708     return false;
4709
4710   /* The only private information we need to copy is the argument relocation
4711      bits.  */
4712   output_symbol->tc_data.hppa_arg_reloc = input_symbol->tc_data.hppa_arg_reloc;
4713
4714   return true;
4715 }
4716
4717 /* Copy any private info we understand from the input section
4718    to the output section.  */
4719 static boolean
4720 som_bfd_copy_private_section_data (ibfd, isection, obfd, osection)
4721      bfd *ibfd;
4722      asection *isection;
4723      bfd *obfd;
4724      asection *osection;
4725 {
4726   /* One day we may try to grok other private data.  */
4727   if (ibfd->xvec->flavour != bfd_target_som_flavour
4728       || obfd->xvec->flavour != bfd_target_som_flavour
4729       || (!som_is_space (isection) && !som_is_subspace (isection)))
4730     return true;
4731
4732   som_section_data (osection)->copy_data
4733     = (struct som_copyable_section_data_struct *)
4734       bfd_zalloc (obfd, sizeof (struct som_copyable_section_data_struct));
4735   if (som_section_data (osection)->copy_data == NULL)
4736     {
4737       bfd_set_error (bfd_error_no_memory);
4738       return false;
4739     }
4740
4741   memcpy (som_section_data (osection)->copy_data,
4742           som_section_data (isection)->copy_data,
4743           sizeof (struct som_copyable_section_data_struct));
4744
4745   /* Reparent if necessary.  */
4746   if (som_section_data (osection)->copy_data->container)
4747     som_section_data (osection)->copy_data->container =
4748       som_section_data (osection)->copy_data->container->output_section;
4749
4750   return true;
4751 }
4752
4753 /* Copy any private info we understand from the input bfd
4754    to the output bfd.  */
4755
4756 static boolean
4757 som_bfd_copy_private_bfd_data (ibfd, obfd)
4758      bfd *ibfd, *obfd;
4759 {
4760   /* One day we may try to grok other private data.  */
4761   if (ibfd->xvec->flavour != bfd_target_som_flavour
4762       || obfd->xvec->flavour != bfd_target_som_flavour)
4763     return true;
4764
4765   /* Allocate some memory to hold the data we need.  */
4766   obj_som_exec_data (obfd) = (struct som_exec_data *)
4767     bfd_zalloc (obfd, sizeof (struct som_exec_data));
4768   if (obj_som_exec_data (obfd) == NULL)
4769     {
4770       bfd_set_error (bfd_error_no_memory);
4771       return false;
4772     }
4773
4774   /* Now copy the data.  */
4775   memcpy (obj_som_exec_data (obfd), obj_som_exec_data (ibfd),
4776           sizeof (struct som_exec_data));
4777
4778   return true;
4779 }
4780
4781 /* Set backend info for sections which can not be described
4782    in the BFD data structures.  */
4783
4784 boolean
4785 bfd_som_set_section_attributes (section, defined, private, sort_key, spnum)
4786      asection *section;
4787      int defined;
4788      int private;
4789      unsigned int sort_key;
4790      int spnum;
4791 {
4792   /* Allocate memory to hold the magic information.  */
4793   if (som_section_data (section)->copy_data == NULL)
4794     {
4795       som_section_data (section)->copy_data
4796         = (struct som_copyable_section_data_struct *)
4797           bfd_zalloc (section->owner,
4798                       sizeof (struct som_copyable_section_data_struct));
4799       if (som_section_data (section)->copy_data == NULL)
4800         {
4801           bfd_set_error (bfd_error_no_memory);
4802           return false;
4803         }
4804     }
4805   som_section_data (section)->copy_data->sort_key = sort_key;
4806   som_section_data (section)->copy_data->is_defined = defined;
4807   som_section_data (section)->copy_data->is_private = private;
4808   som_section_data (section)->copy_data->container = section;
4809   som_section_data (section)->copy_data->space_number = spnum;
4810   return true;
4811 }
4812
4813 /* Set backend info for subsections which can not be described 
4814    in the BFD data structures.  */
4815
4816 boolean
4817 bfd_som_set_subsection_attributes (section, container, access,
4818                                    sort_key, quadrant)
4819      asection *section;
4820      asection *container;
4821      int access;
4822      unsigned int sort_key;
4823      int quadrant;
4824 {
4825   /* Allocate memory to hold the magic information.  */
4826   if (som_section_data (section)->copy_data == NULL)
4827     {
4828       som_section_data (section)->copy_data
4829         = (struct som_copyable_section_data_struct *)
4830           bfd_zalloc (section->owner,
4831                       sizeof (struct som_copyable_section_data_struct));
4832       if (som_section_data (section)->copy_data == NULL)
4833         {
4834           bfd_set_error (bfd_error_no_memory);
4835           return false;
4836         }
4837     }
4838   som_section_data (section)->copy_data->sort_key = sort_key;
4839   som_section_data (section)->copy_data->access_control_bits = access;
4840   som_section_data (section)->copy_data->quadrant = quadrant;
4841   som_section_data (section)->copy_data->container = container;
4842   return true;
4843 }
4844
4845 /* Set the full SOM symbol type.  SOM needs far more symbol information
4846    than any other object file format I'm aware of.  It is mandatory
4847    to be able to know if a symbol is an entry point, millicode, data,
4848    code, absolute, storage request, or procedure label.  If you get
4849    the symbol type wrong your program will not link.  */
4850
4851 void
4852 bfd_som_set_symbol_type (symbol, type)
4853      asymbol *symbol;
4854      unsigned int type;
4855 {
4856   som_symbol_data (symbol)->som_type = type;
4857 }
4858
4859 /* Attach an auxiliary header to the BFD backend so that it may be
4860    written into the object file.  */
4861 boolean
4862 bfd_som_attach_aux_hdr (abfd, type, string)
4863      bfd *abfd;
4864      int type;
4865      char *string;
4866 {
4867   if (type == VERSION_AUX_ID)
4868     {
4869       int len = strlen (string);
4870       int pad = 0;
4871
4872       if (len % 4)
4873         pad = (4 - (len % 4));
4874       obj_som_version_hdr (abfd) = (struct user_string_aux_hdr *)
4875         bfd_zalloc (abfd, sizeof (struct aux_id)
4876                               + sizeof (unsigned int) + len + pad);
4877       if (!obj_som_version_hdr (abfd))
4878         {
4879           bfd_set_error (bfd_error_no_memory);
4880           return false;
4881         }
4882       obj_som_version_hdr (abfd)->header_id.type = VERSION_AUX_ID;
4883       obj_som_version_hdr (abfd)->header_id.length = len + pad;
4884       obj_som_version_hdr (abfd)->header_id.length += sizeof (int);
4885       obj_som_version_hdr (abfd)->string_length = len;
4886       strncpy (obj_som_version_hdr (abfd)->user_string, string, len);
4887     }
4888   else if (type == COPYRIGHT_AUX_ID)
4889     {
4890       int len = strlen (string);
4891       int pad = 0;
4892
4893       if (len % 4)
4894         pad = (4 - (len % 4));
4895       obj_som_copyright_hdr (abfd) = (struct copyright_aux_hdr *)
4896         bfd_zalloc (abfd, sizeof (struct aux_id)
4897                             + sizeof (unsigned int) + len + pad);
4898       if (!obj_som_copyright_hdr (abfd))
4899         {
4900           bfd_set_error (bfd_error_no_memory);
4901           return false;
4902         }
4903       obj_som_copyright_hdr (abfd)->header_id.type = COPYRIGHT_AUX_ID;
4904       obj_som_copyright_hdr (abfd)->header_id.length = len + pad;
4905       obj_som_copyright_hdr (abfd)->header_id.length += sizeof (int);
4906       obj_som_copyright_hdr (abfd)->string_length = len;
4907       strcpy (obj_som_copyright_hdr (abfd)->copyright, string);
4908     }
4909   return true;
4910 }
4911
4912 static boolean
4913 som_get_section_contents (abfd, section, location, offset, count)
4914      bfd *abfd;
4915      sec_ptr section;
4916      PTR location;
4917      file_ptr offset;
4918      bfd_size_type count;
4919 {
4920   if (count == 0 || ((section->flags & SEC_HAS_CONTENTS) == 0))
4921     return true;
4922   if ((bfd_size_type)(offset+count) > section->_raw_size
4923       || bfd_seek (abfd, (file_ptr)(section->filepos + offset), SEEK_SET) == -1
4924       || bfd_read (location, (bfd_size_type)1, count, abfd) != count)
4925     return (false); /* on error */
4926   return (true);
4927 }
4928
4929 static boolean
4930 som_set_section_contents (abfd, section, location, offset, count)
4931      bfd *abfd;
4932      sec_ptr section;
4933      PTR location;
4934      file_ptr offset;
4935      bfd_size_type count;
4936 {
4937   if (abfd->output_has_begun == false)
4938     {
4939       /* Set up fixed parts of the file, space, and subspace headers.
4940          Notify the world that output has begun.  */
4941       som_prep_headers (abfd);
4942       abfd->output_has_begun = true;
4943       /* Start writing the object file.  This include all the string
4944          tables, fixup streams, and other portions of the object file.  */
4945       som_begin_writing (abfd);
4946     }
4947
4948   /* Only write subspaces which have "real" contents (eg. the contents
4949      are not generated at run time by the OS).  */
4950   if (!som_is_subspace (section)
4951       || ((section->flags & SEC_HAS_CONTENTS) == 0))
4952     return true;
4953
4954   /* Seek to the proper offset within the object file and write the
4955      data.  */
4956   offset += som_section_data (section)->subspace_dict->file_loc_init_value; 
4957   if (bfd_seek (abfd, offset, SEEK_SET) == -1)
4958     return false;
4959
4960   if (bfd_write ((PTR) location, 1, count, abfd) != count)
4961     return false;
4962   return true;
4963 }
4964
4965 static boolean
4966 som_set_arch_mach (abfd, arch, machine)
4967      bfd *abfd;
4968      enum bfd_architecture arch;
4969      unsigned long machine;
4970 {
4971   /* Allow any architecture to be supported by the SOM backend */
4972   return bfd_default_set_arch_mach (abfd, arch, machine);
4973 }
4974
4975 static boolean
4976 som_find_nearest_line (abfd, section, symbols, offset, filename_ptr,
4977                         functionname_ptr, line_ptr)
4978      bfd *abfd;
4979      asection *section;
4980      asymbol **symbols;
4981      bfd_vma offset;
4982      CONST char **filename_ptr;
4983      CONST char **functionname_ptr;
4984      unsigned int *line_ptr;
4985 {
4986   return (false);
4987 }
4988
4989 static int
4990 som_sizeof_headers (abfd, reloc)
4991      bfd *abfd;
4992      boolean reloc;
4993 {
4994   (*_bfd_error_handler) ("som_sizeof_headers unimplemented");
4995   fflush (stderr);
4996   abort ();
4997   return (0);
4998 }
4999
5000 /* Return the single-character symbol type corresponding to
5001    SOM section S, or '?' for an unknown SOM section.  */
5002
5003 static char
5004 som_section_type (s)
5005      const char *s;
5006 {
5007   const struct section_to_type *t;
5008
5009   for (t = &stt[0]; t->section; t++)
5010     if (!strcmp (s, t->section))
5011       return t->type;
5012   return '?';
5013 }
5014
5015 static int
5016 som_decode_symclass (symbol)
5017      asymbol *symbol;
5018 {
5019   char c;
5020
5021   if (bfd_is_com_section (symbol->section))
5022     return 'C';
5023   if (bfd_is_und_section (symbol->section))
5024     return 'U';
5025   if (bfd_is_ind_section (symbol->section))
5026     return 'I';
5027   if (!(symbol->flags & (BSF_GLOBAL|BSF_LOCAL)))
5028     return '?';
5029
5030   if (bfd_is_abs_section (symbol->section)
5031       || (som_symbol_data (symbol) != NULL
5032           && som_symbol_data (symbol)->som_type == SYMBOL_TYPE_ABSOLUTE))
5033     c = 'a';
5034   else if (symbol->section)
5035     c = som_section_type (symbol->section->name);
5036   else
5037     return '?';
5038   if (symbol->flags & BSF_GLOBAL)
5039     c = toupper (c);
5040   return c;
5041 }
5042
5043 /* Return information about SOM symbol SYMBOL in RET.  */
5044
5045 static void
5046 som_get_symbol_info (ignore_abfd, symbol, ret)
5047      bfd *ignore_abfd;
5048      asymbol *symbol;
5049      symbol_info *ret;
5050 {
5051   ret->type = som_decode_symclass (symbol);
5052   if (ret->type != 'U')
5053     ret->value = symbol->value+symbol->section->vma;
5054   else
5055     ret->value = 0;
5056   ret->name = symbol->name;
5057 }
5058
5059 /* Count the number of symbols in the archive symbol table.  Necessary
5060    so that we can allocate space for all the carsyms at once.  */
5061
5062 static boolean
5063 som_bfd_count_ar_symbols (abfd, lst_header, count)
5064      bfd *abfd;
5065      struct lst_header *lst_header;
5066      symindex *count;
5067 {
5068   unsigned int i;
5069   unsigned int *hash_table = NULL;
5070   file_ptr lst_filepos = bfd_tell (abfd) - sizeof (struct lst_header);
5071
5072   hash_table = 
5073     (unsigned int *) malloc (lst_header->hash_size * sizeof (unsigned int));
5074   if (hash_table == NULL && lst_header->hash_size != 0)
5075     {
5076       bfd_set_error (bfd_error_no_memory);
5077       goto error_return;
5078     }
5079
5080   /* Don't forget to initialize the counter!  */
5081   *count = 0;
5082
5083   /* Read in the hash table.  The has table is an array of 32bit file offsets
5084      which point to the hash chains.  */
5085   if (bfd_read ((PTR) hash_table, lst_header->hash_size, 4, abfd)
5086       != lst_header->hash_size * 4)
5087     goto error_return;
5088
5089   /* Walk each chain counting the number of symbols found on that particular
5090      chain.  */
5091   for (i = 0; i < lst_header->hash_size; i++)
5092     {
5093       struct lst_symbol_record lst_symbol;
5094
5095       /* An empty chain has zero as it's file offset.  */
5096       if (hash_table[i] == 0)
5097         continue;
5098
5099       /* Seek to the first symbol in this hash chain.  */
5100       if (bfd_seek (abfd, lst_filepos + hash_table[i], SEEK_SET) < 0)
5101         goto error_return;
5102
5103       /* Read in this symbol and update the counter.  */
5104       if (bfd_read ((PTR) & lst_symbol, 1, sizeof (lst_symbol), abfd)
5105           != sizeof (lst_symbol))
5106         goto error_return;
5107
5108       (*count)++;
5109
5110       /* Now iterate through the rest of the symbols on this chain.  */
5111       while (lst_symbol.next_entry)
5112         {
5113
5114           /* Seek to the next symbol.  */
5115           if (bfd_seek (abfd, lst_filepos + lst_symbol.next_entry, SEEK_SET)
5116               < 0)
5117             goto error_return;
5118
5119           /* Read the symbol in and update the counter.  */
5120           if (bfd_read ((PTR) & lst_symbol, 1, sizeof (lst_symbol), abfd)
5121               != sizeof (lst_symbol))
5122             goto error_return;
5123
5124           (*count)++;
5125         }
5126     }
5127   if (hash_table != NULL)
5128     free (hash_table);
5129   return true;
5130
5131  error_return:
5132   if (hash_table != NULL)
5133     free (hash_table);
5134   return false;
5135 }
5136
5137 /* Fill in the canonical archive symbols (SYMS) from the archive described
5138    by ABFD and LST_HEADER.  */
5139
5140 static boolean
5141 som_bfd_fill_in_ar_symbols (abfd, lst_header, syms)
5142      bfd *abfd;
5143      struct lst_header *lst_header;
5144      carsym **syms;
5145 {
5146   unsigned int i, len;
5147   carsym *set = syms[0];
5148   unsigned int *hash_table = NULL;
5149   struct som_entry *som_dict = NULL;
5150   file_ptr lst_filepos = bfd_tell (abfd) - sizeof (struct lst_header);
5151
5152   hash_table = 
5153     (unsigned int *) malloc (lst_header->hash_size * sizeof (unsigned int));
5154   if (hash_table == NULL && lst_header->hash_size != 0)
5155     {
5156       bfd_set_error (bfd_error_no_memory);
5157       goto error_return;
5158     }
5159
5160   som_dict =
5161     (struct som_entry *) malloc (lst_header->module_count
5162                                  * sizeof (struct som_entry));
5163   if (som_dict == NULL && lst_header->module_count != 0)
5164     {
5165       bfd_set_error (bfd_error_no_memory);
5166       goto error_return;
5167     }
5168
5169   /* Read in the hash table.  The has table is an array of 32bit file offsets
5170      which point to the hash chains.  */
5171   if (bfd_read ((PTR) hash_table, lst_header->hash_size, 4, abfd)
5172       != lst_header->hash_size * 4)
5173     goto error_return;
5174
5175   /* Seek to and read in the SOM dictionary.  We will need this to fill
5176      in the carsym's filepos field.  */
5177   if (bfd_seek (abfd, lst_filepos + lst_header->dir_loc, SEEK_SET) < 0)
5178     goto error_return;
5179
5180   if (bfd_read ((PTR) som_dict, lst_header->module_count, 
5181                 sizeof (struct som_entry), abfd)
5182       != lst_header->module_count * sizeof (struct som_entry))
5183     goto error_return;
5184
5185   /* Walk each chain filling in the carsyms as we go along.  */
5186   for (i = 0; i < lst_header->hash_size; i++)
5187     {
5188       struct lst_symbol_record lst_symbol;
5189
5190       /* An empty chain has zero as it's file offset.  */
5191       if (hash_table[i] == 0)
5192         continue;
5193
5194       /* Seek to and read the first symbol on the chain.  */
5195       if (bfd_seek (abfd, lst_filepos + hash_table[i], SEEK_SET) < 0)
5196         goto error_return;
5197
5198       if (bfd_read ((PTR) & lst_symbol, 1, sizeof (lst_symbol), abfd)
5199           != sizeof (lst_symbol))
5200         goto error_return;
5201
5202       /* Get the name of the symbol, first get the length which is stored
5203          as a 32bit integer just before the symbol.
5204
5205          One might ask why we don't just read in the entire string table
5206          and index into it.  Well, according to the SOM ABI the string
5207          index can point *anywhere* in the archive to save space, so just
5208          using the string table would not be safe.  */
5209       if (bfd_seek (abfd, lst_filepos + lst_header->string_loc
5210                             + lst_symbol.name.n_strx - 4, SEEK_SET) < 0)
5211         goto error_return;
5212
5213       if (bfd_read (&len, 1, 4, abfd) != 4)
5214         goto error_return;
5215
5216       /* Allocate space for the name and null terminate it too.  */
5217       set->name = bfd_zalloc (abfd, len + 1);
5218       if (!set->name)
5219         {
5220           bfd_set_error (bfd_error_no_memory);
5221           goto error_return;
5222         }
5223       if (bfd_read (set->name, 1, len, abfd) != len)
5224         goto error_return;
5225
5226       set->name[len] = 0;
5227
5228       /* Fill in the file offset.  Note that the "location" field points
5229          to the SOM itself, not the ar_hdr in front of it.  */
5230       set->file_offset = som_dict[lst_symbol.som_index].location
5231                           - sizeof (struct ar_hdr);
5232
5233       /* Go to the next symbol.  */
5234       set++;
5235
5236       /* Iterate through the rest of the chain.  */
5237       while (lst_symbol.next_entry)
5238         {
5239           /* Seek to the next symbol and read it in.  */
5240           if (bfd_seek (abfd, lst_filepos + lst_symbol.next_entry, SEEK_SET) <0)
5241             goto error_return;
5242
5243           if (bfd_read ((PTR) & lst_symbol, 1, sizeof (lst_symbol), abfd)
5244               != sizeof (lst_symbol))
5245             goto error_return;
5246
5247           /* Seek to the name length & string and read them in.  */
5248           if (bfd_seek (abfd, lst_filepos + lst_header->string_loc 
5249                                 + lst_symbol.name.n_strx - 4, SEEK_SET) < 0)
5250             goto error_return;
5251
5252           if (bfd_read (&len, 1, 4, abfd) != 4)
5253             goto error_return;
5254
5255           /* Allocate space for the name and null terminate it too.  */
5256           set->name = bfd_zalloc (abfd, len + 1);
5257           if (!set->name)
5258             {
5259               bfd_set_error (bfd_error_no_memory);
5260               goto error_return;
5261             }
5262
5263           if (bfd_read (set->name, 1, len, abfd) != len)
5264             goto error_return;
5265           set->name[len] = 0;
5266
5267           /* Fill in the file offset.  Note that the "location" field points
5268              to the SOM itself, not the ar_hdr in front of it.  */
5269           set->file_offset = som_dict[lst_symbol.som_index].location
5270                                - sizeof (struct ar_hdr);
5271
5272           /* Go on to the next symbol.  */
5273           set++;
5274         }
5275     }
5276   /* If we haven't died by now, then we successfully read the entire 
5277      archive symbol table.  */
5278   if (hash_table != NULL)
5279     free (hash_table);
5280   if (som_dict != NULL)
5281     free (som_dict);
5282   return true;
5283
5284  error_return:
5285   if (hash_table != NULL)
5286     free (hash_table);
5287   if (som_dict != NULL)
5288     free (som_dict);
5289   return false;
5290 }
5291
5292 /* Read in the LST from the archive.  */
5293 static boolean
5294 som_slurp_armap (abfd)
5295      bfd *abfd;
5296 {
5297   struct lst_header lst_header;
5298   struct ar_hdr ar_header;
5299   unsigned int parsed_size;
5300   struct artdata *ardata = bfd_ardata (abfd);
5301   char nextname[17];
5302   int i = bfd_read ((PTR) nextname, 1, 16, abfd);
5303
5304   /* Special cases.  */
5305   if (i == 0)
5306     return true;
5307   if (i != 16)
5308     return false;
5309
5310   if (bfd_seek (abfd, (file_ptr) - 16, SEEK_CUR) < 0)
5311     return false;
5312
5313   /* For archives without .o files there is no symbol table.  */
5314   if (strncmp (nextname, "/               ", 16))
5315     {
5316       bfd_has_map (abfd) = false;
5317       return true;
5318     }
5319
5320   /* Read in and sanity check the archive header.  */
5321   if (bfd_read ((PTR) &ar_header, 1, sizeof (struct ar_hdr), abfd)
5322       != sizeof (struct ar_hdr))
5323     return false;
5324
5325   if (strncmp (ar_header.ar_fmag, ARFMAG, 2))
5326     {
5327       bfd_set_error (bfd_error_malformed_archive);
5328       return false;
5329     }
5330
5331   /* How big is the archive symbol table entry?  */
5332   errno = 0;
5333   parsed_size = strtol (ar_header.ar_size, NULL, 10);
5334   if (errno != 0)
5335     {
5336       bfd_set_error (bfd_error_malformed_archive);
5337       return false;
5338     }
5339
5340   /* Save off the file offset of the first real user data.  */
5341   ardata->first_file_filepos = bfd_tell (abfd) + parsed_size;
5342
5343   /* Read in the library symbol table.  We'll make heavy use of this
5344      in just a minute.  */
5345   if (bfd_read ((PTR) & lst_header, 1, sizeof (struct lst_header), abfd)
5346       != sizeof (struct lst_header))
5347     return false;
5348
5349   /* Sanity check.  */
5350   if (lst_header.a_magic != LIBMAGIC)
5351     {
5352       bfd_set_error (bfd_error_malformed_archive);
5353       return false;
5354     }
5355
5356   /* Count the number of symbols in the library symbol table.  */
5357   if (som_bfd_count_ar_symbols (abfd, &lst_header, &ardata->symdef_count)
5358       == false)
5359     return false;
5360
5361   /* Get back to the start of the library symbol table.  */
5362   if (bfd_seek (abfd, ardata->first_file_filepos - parsed_size 
5363                         + sizeof (struct lst_header), SEEK_SET) < 0)
5364     return false;
5365
5366   /* Initializae the cache and allocate space for the library symbols.  */
5367   ardata->cache = 0;
5368   ardata->symdefs = (carsym *) bfd_alloc (abfd,
5369                                           (ardata->symdef_count
5370                                            * sizeof (carsym)));
5371   if (!ardata->symdefs)
5372     {
5373       bfd_set_error (bfd_error_no_memory);
5374       return false;
5375     }
5376
5377   /* Now fill in the canonical archive symbols.  */
5378   if (som_bfd_fill_in_ar_symbols (abfd, &lst_header, &ardata->symdefs)
5379       == false)
5380     return false;
5381
5382   /* Seek back to the "first" file in the archive.  Note the "first"
5383      file may be the extended name table.  */
5384   if (bfd_seek (abfd, ardata->first_file_filepos, SEEK_SET) < 0)
5385     return false;
5386
5387   /* Notify the generic archive code that we have a symbol map.  */
5388   bfd_has_map (abfd) = true;
5389   return true;
5390 }
5391
5392 /* Begin preparing to write a SOM library symbol table.
5393
5394    As part of the prep work we need to determine the number of symbols
5395    and the size of the associated string section.  */
5396
5397 static boolean
5398 som_bfd_prep_for_ar_write (abfd, num_syms, stringsize)
5399      bfd *abfd;
5400      unsigned int *num_syms, *stringsize;
5401 {
5402   bfd *curr_bfd = abfd->archive_head;
5403
5404   /* Some initialization.  */
5405   *num_syms = 0;
5406   *stringsize = 0;
5407
5408   /* Iterate over each BFD within this archive.  */
5409   while (curr_bfd != NULL)
5410     {
5411       unsigned int curr_count, i;
5412       som_symbol_type *sym;
5413
5414       /* Don't bother for non-SOM objects.  */
5415       if (curr_bfd->format != bfd_object
5416           || curr_bfd->xvec->flavour != bfd_target_som_flavour)
5417         {
5418           curr_bfd = curr_bfd->next;
5419           continue;
5420         }
5421
5422       /* Make sure the symbol table has been read, then snag a pointer
5423          to it.  It's a little slimey to grab the symbols via obj_som_symtab,
5424          but doing so avoids allocating lots of extra memory.  */
5425       if (som_slurp_symbol_table (curr_bfd) == false)
5426         return false;
5427
5428       sym = obj_som_symtab (curr_bfd);
5429       curr_count = bfd_get_symcount (curr_bfd);
5430
5431       /* Examine each symbol to determine if it belongs in the
5432          library symbol table.  */
5433       for (i = 0; i < curr_count; i++, sym++)
5434         {
5435           struct som_misc_symbol_info info;
5436
5437           /* Derive SOM information from the BFD symbol.  */
5438           som_bfd_derive_misc_symbol_info (curr_bfd, &sym->symbol, &info);
5439
5440           /* Should we include this symbol?  */
5441           if (info.symbol_type == ST_NULL
5442               || info.symbol_type == ST_SYM_EXT
5443               || info.symbol_type == ST_ARG_EXT)
5444             continue;
5445
5446           /* Only global symbols and unsatisfied commons.  */
5447           if (info.symbol_scope != SS_UNIVERSAL
5448               && info.symbol_type != ST_STORAGE)
5449             continue;
5450
5451           /* Do no include undefined symbols.  */
5452           if (bfd_is_und_section (sym->symbol.section))
5453             continue;
5454
5455           /* Bump the various counters, being careful to honor
5456              alignment considerations in the string table.  */
5457           (*num_syms)++;
5458           *stringsize = *stringsize + strlen (sym->symbol.name) + 5;
5459           while (*stringsize % 4)
5460             (*stringsize)++;
5461         }
5462
5463       curr_bfd = curr_bfd->next;
5464     }
5465   return true;
5466 }
5467
5468 /* Hash a symbol name based on the hashing algorithm presented in the
5469    SOM ABI.  */
5470 static unsigned int
5471 som_bfd_ar_symbol_hash (symbol)
5472      asymbol *symbol;
5473 {
5474   unsigned int len = strlen (symbol->name);
5475
5476   /* Names with length 1 are special.  */
5477   if (len == 1)
5478     return 0x1000100 | (symbol->name[0] << 16) | symbol->name[0];
5479
5480   return ((len & 0x7f) << 24) | (symbol->name[1] << 16)
5481           | (symbol->name[len-2] << 8) | symbol->name[len-1];
5482 }
5483
5484 static CONST char *
5485 normalize (file)
5486      CONST char *file;
5487 {
5488   CONST char *filename = strrchr (file, '/');
5489
5490   if (filename != NULL)
5491     filename++;
5492   else
5493     filename = file;
5494   return filename;
5495 }
5496
5497 /* Do the bulk of the work required to write the SOM library
5498    symbol table.  */
5499    
5500 static boolean
5501 som_bfd_ar_write_symbol_stuff (abfd, nsyms, string_size, lst)
5502      bfd *abfd;
5503      unsigned int nsyms, string_size;
5504      struct lst_header lst;
5505 {
5506   file_ptr lst_filepos;
5507   char *strings = NULL, *p;
5508   struct lst_symbol_record *lst_syms = NULL, *curr_lst_sym;
5509   bfd *curr_bfd;
5510   unsigned int *hash_table = NULL;
5511   struct som_entry *som_dict = NULL;
5512   struct lst_symbol_record **last_hash_entry = NULL;
5513   unsigned int curr_som_offset, som_index, extended_name_length = 0;
5514   unsigned int maxname = abfd->xvec->ar_max_namelen;
5515
5516   hash_table =
5517     (unsigned int *) malloc (lst.hash_size * sizeof (unsigned int));
5518   if (hash_table == NULL && lst.hash_size != 0)
5519     {
5520       bfd_set_error (bfd_error_no_memory);
5521       goto error_return;
5522     }
5523   som_dict =
5524     (struct som_entry *) malloc (lst.module_count
5525                                  * sizeof (struct som_entry));
5526   if (som_dict == NULL && lst.module_count != 0)
5527     {
5528       bfd_set_error (bfd_error_no_memory);
5529       goto error_return;
5530     }
5531
5532   last_hash_entry =
5533     ((struct lst_symbol_record **)
5534      malloc (lst.hash_size * sizeof (struct lst_symbol_record *)));
5535   if (last_hash_entry == NULL && lst.hash_size != 0)
5536     {
5537       bfd_set_error (bfd_error_no_memory);
5538       goto error_return;
5539     }
5540
5541   /* Lots of fields are file positions relative to the start
5542      of the lst record.  So save its location.  */
5543   lst_filepos = bfd_tell (abfd) - sizeof (struct lst_header);
5544
5545   /* Some initialization.  */
5546   memset (hash_table, 0, 4 * lst.hash_size);
5547   memset (som_dict, 0, lst.module_count * sizeof (struct som_entry));
5548   memset (last_hash_entry, 0,   
5549           lst.hash_size * sizeof (struct lst_symbol_record *));
5550
5551   /* Symbols have som_index fields, so we have to keep track of the
5552      index of each SOM in the archive.
5553
5554      The SOM dictionary has (among other things) the absolute file
5555      position for the SOM which a particular dictionary entry
5556      describes.  We have to compute that information as we iterate
5557      through the SOMs/symbols.  */
5558   som_index = 0;
5559   curr_som_offset = 8 + 2 * sizeof (struct ar_hdr) + lst.file_end;
5560
5561   /* Yow!  We have to know the size of the extended name table
5562      too.  */
5563   for (curr_bfd = abfd->archive_head;
5564        curr_bfd != NULL;
5565        curr_bfd = curr_bfd->next)
5566     {
5567       CONST char *normal = normalize (curr_bfd->filename);
5568       unsigned int thislen;
5569
5570       if (!normal)
5571         {
5572           bfd_set_error (bfd_error_no_memory);
5573           return false;
5574         }
5575       thislen = strlen (normal);
5576       if (thislen > maxname)
5577         extended_name_length += thislen + 1;
5578     }
5579
5580   /* Make room for the archive header and the contents of the
5581      extended string table.  */
5582   if (extended_name_length)
5583     curr_som_offset += extended_name_length + sizeof (struct ar_hdr);
5584
5585   /* Make sure we're properly aligned.  */
5586   curr_som_offset = (curr_som_offset + 0x1) & ~0x1;
5587
5588   /* FIXME should be done with buffers just like everything else... */
5589   lst_syms = malloc (nsyms * sizeof (struct lst_symbol_record));
5590   if (lst_syms == NULL && nsyms != 0)
5591     {
5592       bfd_set_error (bfd_error_no_memory);
5593       goto error_return;
5594     }
5595   strings = malloc (string_size);
5596   if (strings == NULL && string_size != 0)
5597     {
5598       bfd_set_error (bfd_error_no_memory);
5599       goto error_return;
5600     }
5601
5602   p = strings;
5603   curr_lst_sym = lst_syms;
5604
5605   curr_bfd = abfd->archive_head;
5606   while (curr_bfd != NULL)
5607     {
5608       unsigned int curr_count, i;
5609       som_symbol_type *sym;
5610
5611       /* Don't bother for non-SOM objects.  */
5612       if (curr_bfd->format != bfd_object
5613           || curr_bfd->xvec->flavour != bfd_target_som_flavour)
5614         {
5615           curr_bfd = curr_bfd->next;
5616           continue;
5617         }
5618
5619       /* Make sure the symbol table has been read, then snag a pointer
5620          to it.  It's a little slimey to grab the symbols via obj_som_symtab,
5621          but doing so avoids allocating lots of extra memory.  */
5622       if (som_slurp_symbol_table (curr_bfd) == false)
5623         goto error_return;
5624
5625       sym = obj_som_symtab (curr_bfd);
5626       curr_count = bfd_get_symcount (curr_bfd);
5627
5628       for (i = 0; i < curr_count; i++, sym++)
5629         {
5630           struct som_misc_symbol_info info;
5631
5632           /* Derive SOM information from the BFD symbol.  */
5633           som_bfd_derive_misc_symbol_info (curr_bfd, &sym->symbol, &info);
5634
5635           /* Should we include this symbol?  */
5636           if (info.symbol_type == ST_NULL
5637               || info.symbol_type == ST_SYM_EXT
5638               || info.symbol_type == ST_ARG_EXT)
5639             continue;
5640
5641           /* Only global symbols and unsatisfied commons.  */
5642           if (info.symbol_scope != SS_UNIVERSAL
5643               && info.symbol_type != ST_STORAGE)
5644             continue;
5645
5646           /* Do no include undefined symbols.  */
5647           if (bfd_is_und_section (sym->symbol.section))
5648             continue;
5649
5650           /* If this is the first symbol from this SOM, then update
5651              the SOM dictionary too.  */
5652           if (som_dict[som_index].location == 0)
5653             {
5654               som_dict[som_index].location = curr_som_offset;
5655               som_dict[som_index].length = arelt_size (curr_bfd);
5656             }
5657
5658           /* Fill in the lst symbol record.  */
5659           curr_lst_sym->hidden = 0;
5660           curr_lst_sym->secondary_def = 0;
5661           curr_lst_sym->symbol_type = info.symbol_type;
5662           curr_lst_sym->symbol_scope = info.symbol_scope;
5663           curr_lst_sym->check_level = 0;
5664           curr_lst_sym->must_qualify = 0;
5665           curr_lst_sym->initially_frozen = 0;
5666           curr_lst_sym->memory_resident = 0;
5667           curr_lst_sym->is_common = bfd_is_com_section (sym->symbol.section);
5668           curr_lst_sym->dup_common = 0;
5669           curr_lst_sym->xleast = 0;
5670           curr_lst_sym->arg_reloc = info.arg_reloc;
5671           curr_lst_sym->name.n_strx = p - strings + 4;
5672           curr_lst_sym->qualifier_name.n_strx = 0;
5673           curr_lst_sym->symbol_info = info.symbol_info;
5674           curr_lst_sym->symbol_value = info.symbol_value;
5675           curr_lst_sym->symbol_descriptor = 0;
5676           curr_lst_sym->reserved = 0;
5677           curr_lst_sym->som_index = som_index;
5678           curr_lst_sym->symbol_key = som_bfd_ar_symbol_hash (&sym->symbol);
5679           curr_lst_sym->next_entry = 0;
5680
5681           /* Insert into the hash table.  */
5682           if (hash_table[curr_lst_sym->symbol_key % lst.hash_size])
5683             {
5684               struct lst_symbol_record *tmp;
5685
5686               /* There is already something at the head of this hash chain,
5687                  so tack this symbol onto the end of the chain.  */
5688               tmp = last_hash_entry[curr_lst_sym->symbol_key % lst.hash_size];
5689               tmp->next_entry
5690                 = (curr_lst_sym - lst_syms) * sizeof (struct lst_symbol_record)
5691                   + lst.hash_size * 4 
5692                   + lst.module_count * sizeof (struct som_entry)
5693                   + sizeof (struct lst_header);
5694             }
5695           else
5696             {
5697               /* First entry in this hash chain.  */
5698               hash_table[curr_lst_sym->symbol_key % lst.hash_size]
5699                 = (curr_lst_sym - lst_syms) * sizeof (struct lst_symbol_record)
5700                   + lst.hash_size * 4 
5701                   + lst.module_count * sizeof (struct som_entry)
5702                   + sizeof (struct lst_header);
5703             }
5704
5705           /* Keep track of the last symbol we added to this chain so we can
5706              easily update its next_entry pointer.  */
5707           last_hash_entry[curr_lst_sym->symbol_key % lst.hash_size]
5708             = curr_lst_sym;
5709
5710
5711           /* Update the string table.  */
5712           bfd_put_32 (abfd, strlen (sym->symbol.name), p);
5713           p += 4;
5714           strcpy (p, sym->symbol.name);
5715           p += strlen (sym->symbol.name) + 1;
5716           while ((int)p % 4)
5717             {
5718               bfd_put_8 (abfd, 0, p);
5719               p++;
5720             }
5721
5722           /* Head to the next symbol.  */
5723           curr_lst_sym++;
5724         }
5725
5726       /* Keep track of where each SOM will finally reside; then look
5727          at the next BFD.  */
5728       curr_som_offset += arelt_size (curr_bfd) + sizeof (struct ar_hdr);
5729  
5730       /* A particular object in the archive may have an odd length; the
5731          linker requires objects begin on an even boundary.  So round
5732          up the current offset as necessary.  */
5733       curr_som_offset = (curr_som_offset + 0x1) & ~0x1;
5734       curr_bfd = curr_bfd->next;
5735       som_index++;
5736     }
5737
5738   /* Now scribble out the hash table.  */
5739   if (bfd_write ((PTR) hash_table, lst.hash_size, 4, abfd)
5740       != lst.hash_size * 4)
5741     goto error_return;
5742
5743   /* Then the SOM dictionary.  */
5744   if (bfd_write ((PTR) som_dict, lst.module_count,
5745                  sizeof (struct som_entry), abfd)
5746       != lst.module_count * sizeof (struct som_entry))
5747     goto error_return;
5748
5749   /* The library symbols.  */
5750   if (bfd_write ((PTR) lst_syms, nsyms, sizeof (struct lst_symbol_record), abfd)
5751       != nsyms * sizeof (struct lst_symbol_record))
5752     goto error_return;
5753
5754   /* And finally the strings.  */
5755   if (bfd_write ((PTR) strings, string_size, 1, abfd) != string_size)
5756     goto error_return;
5757
5758   if (hash_table != NULL)
5759     free (hash_table);
5760   if (som_dict != NULL)
5761     free (som_dict);
5762   if (last_hash_entry != NULL)
5763     free (last_hash_entry);
5764   if (lst_syms != NULL)
5765     free (lst_syms);
5766   if (strings != NULL)
5767     free (strings);
5768   return true;
5769
5770  error_return:
5771   if (hash_table != NULL)
5772     free (hash_table);
5773   if (som_dict != NULL)
5774     free (som_dict);
5775   if (last_hash_entry != NULL)
5776     free (last_hash_entry);
5777   if (lst_syms != NULL)
5778     free (lst_syms);
5779   if (strings != NULL)
5780     free (strings);
5781
5782   return false;
5783 }
5784
5785 /* SOM almost uses the SVR4 style extended name support, but not
5786    quite.  */
5787
5788 static boolean
5789 som_construct_extended_name_table (abfd, tabloc, tablen, name)
5790      bfd *abfd;
5791      char **tabloc;
5792      bfd_size_type *tablen;
5793      const char **name;
5794 {
5795   *name = "//";
5796   return _bfd_construct_extended_name_table (abfd, false, tabloc, tablen);
5797 }
5798
5799 /* Write out the LST for the archive.
5800
5801    You'll never believe this is really how armaps are handled in SOM...  */
5802
5803 /*ARGSUSED*/
5804 static boolean
5805 som_write_armap (abfd, elength, map, orl_count, stridx)
5806      bfd *abfd;
5807      unsigned int elength;
5808      struct orl *map;
5809      unsigned int orl_count;
5810      int stridx;
5811 {
5812   bfd *curr_bfd;
5813   struct stat statbuf;
5814   unsigned int i, lst_size, nsyms, stringsize;
5815   struct ar_hdr hdr;
5816   struct lst_header lst;
5817   int *p;
5818  
5819   /* We'll use this for the archive's date and mode later.  */
5820   if (stat (abfd->filename, &statbuf) != 0)
5821     {
5822       bfd_set_error (bfd_error_system_call);
5823       return false;
5824     }
5825   /* Fudge factor.  */
5826   bfd_ardata (abfd)->armap_timestamp = statbuf.st_mtime + 60;
5827
5828   /* Account for the lst header first.  */
5829   lst_size = sizeof (struct lst_header);
5830
5831   /* Start building the LST header.  */
5832   /* FIXME:  Do we need to examine each element to determine the
5833      largest id number?  */
5834   lst.system_id = CPU_PA_RISC1_0;
5835   lst.a_magic = LIBMAGIC;
5836   lst.version_id = VERSION_ID;
5837   lst.file_time.secs = 0;
5838   lst.file_time.nanosecs = 0;
5839
5840   lst.hash_loc = lst_size;
5841   lst.hash_size = SOM_LST_HASH_SIZE;
5842
5843   /* Hash table is a SOM_LST_HASH_SIZE 32bit offsets.  */
5844   lst_size += 4 * SOM_LST_HASH_SIZE;
5845
5846   /* We need to count the number of SOMs in this archive.  */
5847   curr_bfd = abfd->archive_head;
5848   lst.module_count = 0;
5849   while (curr_bfd != NULL)
5850     {
5851       /* Only true SOM objects count.  */
5852       if (curr_bfd->format == bfd_object
5853           && curr_bfd->xvec->flavour == bfd_target_som_flavour)
5854         lst.module_count++;
5855       curr_bfd = curr_bfd->next;
5856     }
5857   lst.module_limit = lst.module_count;
5858   lst.dir_loc = lst_size;
5859   lst_size += sizeof (struct som_entry) * lst.module_count;
5860
5861   /* We don't support import/export tables, auxiliary headers,
5862      or free lists yet.  Make the linker work a little harder
5863      to make our life easier.  */
5864
5865   lst.export_loc = 0;
5866   lst.export_count = 0;
5867   lst.import_loc = 0;
5868   lst.aux_loc = 0;
5869   lst.aux_size = 0;
5870
5871   /* Count how many symbols we will have on the hash chains and the
5872      size of the associated string table.  */
5873   if (som_bfd_prep_for_ar_write (abfd, &nsyms, &stringsize) == false)
5874     return false;
5875
5876   lst_size += sizeof (struct lst_symbol_record) * nsyms;
5877
5878   /* For the string table.  One day we might actually use this info
5879      to avoid small seeks/reads when reading archives.  */
5880   lst.string_loc = lst_size;
5881   lst.string_size = stringsize;
5882   lst_size += stringsize;
5883
5884   /* SOM ABI says this must be zero.  */
5885   lst.free_list = 0;
5886   lst.file_end = lst_size;
5887
5888   /* Compute the checksum.  Must happen after the entire lst header
5889      has filled in.  */
5890   p = (int *)&lst;
5891   lst.checksum = 0;
5892   for (i = 0; i < sizeof (struct lst_header)/sizeof (int) - 1; i++)
5893     lst.checksum ^= *p++;
5894
5895   sprintf (hdr.ar_name, "/               ");
5896   sprintf (hdr.ar_date, "%ld", bfd_ardata (abfd)->armap_timestamp);
5897   sprintf (hdr.ar_uid, "%ld", (long) getuid ());
5898   sprintf (hdr.ar_gid, "%ld", (long) getgid ());
5899   sprintf (hdr.ar_mode, "%-8o", (unsigned int) statbuf.st_mode);
5900   sprintf (hdr.ar_size, "%-10d", (int) lst_size);
5901   hdr.ar_fmag[0] = '`';
5902   hdr.ar_fmag[1] = '\012';
5903
5904   /* Turn any nulls into spaces.  */
5905   for (i = 0; i < sizeof (struct ar_hdr); i++)
5906     if (((char *) (&hdr))[i] == '\0')
5907       (((char *) (&hdr))[i]) = ' ';
5908
5909   /* Scribble out the ar header.  */
5910   if (bfd_write ((PTR) &hdr, 1, sizeof (struct ar_hdr), abfd)
5911       != sizeof (struct ar_hdr))
5912     return false;
5913
5914   /* Now scribble out the lst header.  */
5915   if (bfd_write ((PTR) &lst, 1, sizeof (struct lst_header), abfd)
5916       != sizeof (struct lst_header))
5917     return false;
5918
5919   /* Build and write the armap.  */
5920   if (som_bfd_ar_write_symbol_stuff (abfd, nsyms, stringsize, lst) == false)
5921     return false;
5922   
5923   /* Done.  */
5924   return true;
5925 }
5926
5927 /* Free all information we have cached for this BFD.  We can always
5928    read it again later if we need it.  */
5929
5930 static boolean
5931 som_bfd_free_cached_info (abfd)
5932      bfd *abfd;
5933 {
5934   asection *o;
5935
5936   if (bfd_get_format (abfd) != bfd_object)
5937     return true;
5938
5939 #define FREE(x) if (x != NULL) { free (x); x = NULL; }
5940   /* Free the native string and symbol tables.  */
5941   FREE (obj_som_symtab (abfd));
5942   FREE (obj_som_stringtab (abfd));
5943   for (o = abfd->sections; o != (asection *) NULL; o = o->next)
5944     {
5945       /* Free the native relocations.  */
5946       o->reloc_count = -1;
5947       FREE (som_section_data (o)->reloc_stream);
5948       /* Free the generic relocations.  */
5949       FREE (o->relocation);
5950     }
5951 #undef FREE
5952
5953   return true;
5954 }
5955
5956 /* End of miscellaneous support functions. */
5957
5958 /* Linker support functions.  */
5959 static boolean
5960 som_bfd_link_split_section (abfd, sec)
5961      bfd *abfd;
5962      asection *sec;
5963 {
5964   return (som_is_subspace (sec) && sec->_raw_size > 240000);
5965 }
5966
5967 #define som_close_and_cleanup           som_bfd_free_cached_info
5968
5969 #define som_read_ar_hdr                 _bfd_generic_read_ar_hdr
5970 #define som_openr_next_archived_file    bfd_generic_openr_next_archived_file
5971 #define som_generic_stat_arch_elt       bfd_generic_stat_arch_elt
5972 #define som_truncate_arname             bfd_bsd_truncate_arname
5973 #define som_slurp_extended_name_table   _bfd_slurp_extended_name_table
5974 #define som_update_armap_timestamp      bfd_true
5975 #define som_bfd_print_private_bfd_data  _bfd_generic_bfd_print_private_bfd_data
5976
5977 #define som_get_lineno                  _bfd_nosymbols_get_lineno
5978 #define som_bfd_make_debug_symbol       _bfd_nosymbols_bfd_make_debug_symbol
5979 #define som_read_minisymbols            _bfd_generic_read_minisymbols
5980 #define som_minisymbol_to_symbol        _bfd_generic_minisymbol_to_symbol
5981
5982 #define som_bfd_get_relocated_section_contents \
5983  bfd_generic_get_relocated_section_contents
5984 #define som_bfd_relax_section bfd_generic_relax_section
5985 #define som_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
5986 #define som_bfd_link_add_symbols _bfd_generic_link_add_symbols
5987 #define som_bfd_final_link _bfd_generic_final_link
5988
5989 const bfd_target som_vec =
5990 {
5991   "som",                        /* name */
5992   bfd_target_som_flavour,
5993   true,                         /* target byte order */
5994   true,                         /* target headers byte order */
5995   (HAS_RELOC | EXEC_P |         /* object flags */
5996    HAS_LINENO | HAS_DEBUG |
5997    HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED | DYNAMIC),
5998   (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
5999    | SEC_ALLOC | SEC_LOAD | SEC_RELOC),         /* section flags */
6000
6001 /* leading_symbol_char: is the first char of a user symbol
6002    predictable, and if so what is it */
6003   0,
6004   '/',                          /* ar_pad_char */
6005   14,                           /* ar_max_namelen */
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,   /* data */
6009   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
6010   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
6011   bfd_getb16, bfd_getb_signed_16, bfd_putb16,   /* hdrs */
6012   {_bfd_dummy_target,
6013    som_object_p,                /* bfd_check_format */
6014    bfd_generic_archive_p,
6015    _bfd_dummy_target
6016   },
6017   {
6018     bfd_false,
6019     som_mkobject,
6020     _bfd_generic_mkarchive,
6021     bfd_false
6022   },
6023   {
6024     bfd_false,
6025     som_write_object_contents,
6026     _bfd_write_archive_contents,
6027     bfd_false,
6028   },
6029 #undef som
6030
6031   BFD_JUMP_TABLE_GENERIC (som),
6032   BFD_JUMP_TABLE_COPY (som),
6033   BFD_JUMP_TABLE_CORE (_bfd_nocore),
6034   BFD_JUMP_TABLE_ARCHIVE (som),
6035   BFD_JUMP_TABLE_SYMBOLS (som),
6036   BFD_JUMP_TABLE_RELOCS (som),
6037   BFD_JUMP_TABLE_WRITE (som),
6038   BFD_JUMP_TABLE_LINK (som),
6039   BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
6040
6041   (PTR) 0
6042 };
6043
6044 #endif /* HOST_HPPAHPUX || HOST_HPPABSD || HOST_HPPAOSF */