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