* som.c (som_prep_headers): If writing some form of an executable,
[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 >> 16, p + 1);
1191       bfd_put_16 (abfd, skip, 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   bfd_get_start_address (abfd) = aux_hdrp->exec_entry;
1609   bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 0);
1610   bfd_get_symcount (abfd) = file_hdrp->symbol_total;
1611
1612   /* Initialize the saved symbol table and string table to NULL.  
1613      Save important offsets and sizes from the SOM header into
1614      the BFD.  */
1615   obj_som_stringtab (abfd) = (char  *) NULL;
1616   obj_som_symtab (abfd) = (som_symbol_type *) NULL;
1617   obj_som_stringtab_size (abfd) = file_hdrp->symbol_strings_size;
1618   obj_som_sym_filepos (abfd) = file_hdrp->symbol_location;
1619   obj_som_str_filepos (abfd) = file_hdrp->symbol_strings_location;
1620   obj_som_reloc_filepos (abfd) = file_hdrp->fixup_request_location;
1621
1622   obj_som_exec_data (abfd) = (struct som_exec_data *)
1623     bfd_zalloc (abfd, sizeof (struct som_exec_data ));
1624   if (obj_som_exec_data (abfd) == NULL)
1625     {
1626       bfd_set_error (bfd_error_no_memory);
1627       return NULL;
1628     }
1629
1630   obj_som_exec_data (abfd)->system_id = file_hdrp->system_id;
1631   obj_som_exec_data (abfd)->exec_flags = aux_hdrp->exec_flags;
1632   return abfd->xvec;
1633 }
1634
1635 /* Convert all of the space and subspace info into BFD sections.  Each space
1636    contains a number of subspaces, which in turn describe the mapping between
1637    regions of the exec file, and the address space that the program runs in.
1638    BFD sections which correspond to spaces will overlap the sections for the
1639    associated subspaces.  */
1640
1641 static boolean
1642 setup_sections (abfd, file_hdr)
1643      bfd *abfd;
1644      struct header *file_hdr;
1645 {
1646   char *space_strings;
1647   int space_index;
1648   unsigned int total_subspaces = 0;
1649
1650   /* First, read in space names */
1651
1652   space_strings = malloc (file_hdr->space_strings_size);
1653   if (!space_strings && file_hdr->space_strings_size != 0)
1654     {
1655       bfd_set_error (bfd_error_no_memory);
1656       goto error_return;
1657     }
1658
1659   if (bfd_seek (abfd, file_hdr->space_strings_location, SEEK_SET) < 0)
1660     goto error_return;
1661   if (bfd_read (space_strings, 1, file_hdr->space_strings_size, abfd)
1662       != file_hdr->space_strings_size)
1663     goto error_return;
1664
1665   /* Loop over all of the space dictionaries, building up sections */
1666   for (space_index = 0; space_index < file_hdr->space_total; space_index++)
1667     {
1668       struct space_dictionary_record space;
1669       struct subspace_dictionary_record subspace, save_subspace;
1670       int subspace_index;
1671       asection *space_asect;
1672       char *newname;
1673
1674       /* Read the space dictionary element */
1675       if (bfd_seek (abfd, file_hdr->space_location
1676                     + space_index * sizeof space, SEEK_SET) < 0)
1677         goto error_return;
1678       if (bfd_read (&space, 1, sizeof space, abfd) != sizeof space)
1679         goto error_return;
1680
1681       /* Setup the space name string */
1682       space.name.n_name = space.name.n_strx + space_strings;
1683
1684       /* Make a section out of it */
1685       newname = bfd_alloc (abfd, strlen (space.name.n_name) + 1);
1686       if (!newname)
1687         goto error_return;
1688       strcpy (newname, space.name.n_name);
1689                            
1690       space_asect = bfd_make_section_anyway (abfd, newname);
1691       if (!space_asect)
1692         goto error_return;
1693
1694        if (space.is_loadable == 0)
1695         space_asect->flags |= SEC_DEBUGGING;
1696
1697       /* Set up all the attributes for the space.  */
1698       if (bfd_som_set_section_attributes (space_asect, space.is_defined,
1699                                           space.is_private, space.sort_key,
1700                                           space.space_number) == false)
1701         goto error_return;
1702
1703       /* Now, read in the first subspace for this space */
1704       if (bfd_seek (abfd, file_hdr->subspace_location
1705                     + space.subspace_index * sizeof subspace,
1706                     SEEK_SET) < 0)
1707         goto error_return;
1708       if (bfd_read (&subspace, 1, sizeof subspace, abfd) != sizeof subspace)
1709         goto error_return;
1710       /* Seek back to the start of the subspaces for loop below */
1711       if (bfd_seek (abfd, file_hdr->subspace_location
1712                     + space.subspace_index * sizeof subspace,
1713                     SEEK_SET) < 0)
1714         goto error_return;
1715
1716       /* Setup the start address and file loc from the first subspace record */
1717       space_asect->vma = subspace.subspace_start;
1718       space_asect->filepos = subspace.file_loc_init_value;
1719       space_asect->alignment_power = log2 (subspace.alignment);
1720       if (space_asect->alignment_power == -1)
1721         goto error_return;
1722
1723       /* Initialize save_subspace so we can reliably determine if this
1724          loop placed any useful values into it.  */
1725       memset (&save_subspace, 0, sizeof (struct subspace_dictionary_record));
1726
1727       /* Loop over the rest of the subspaces, building up more sections */
1728       for (subspace_index = 0; subspace_index < space.subspace_quantity;
1729            subspace_index++)
1730         {
1731           asection *subspace_asect;
1732
1733           /* Read in the next subspace */
1734           if (bfd_read (&subspace, 1, sizeof subspace, abfd)
1735               != sizeof subspace)
1736             goto error_return;
1737
1738           /* Setup the subspace name string */
1739           subspace.name.n_name = subspace.name.n_strx + space_strings;
1740
1741           newname = bfd_alloc (abfd, strlen (subspace.name.n_name) + 1);
1742           if (!newname)
1743             goto error_return;
1744           strcpy (newname, subspace.name.n_name);
1745
1746           /* Make a section out of this subspace */
1747           subspace_asect = bfd_make_section_anyway (abfd, newname);
1748           if (!subspace_asect)
1749             goto error_return;
1750
1751           /* Store private information about the section.  */
1752           if (bfd_som_set_subsection_attributes (subspace_asect, space_asect,
1753                                                  subspace.access_control_bits,
1754                                                  subspace.sort_key,
1755                                                  subspace.quadrant) == false)
1756             goto error_return;
1757
1758           /* Keep an easy mapping between subspaces and sections.  */
1759           subspace_asect->target_index = total_subspaces++;
1760
1761           /* Set SEC_READONLY and SEC_CODE/SEC_DATA as specified
1762              by the access_control_bits in the subspace header.  */
1763           switch (subspace.access_control_bits >> 4)
1764             {
1765             /* Readonly data.  */  
1766             case 0x0:
1767               subspace_asect->flags |= SEC_DATA | SEC_READONLY;
1768               break;
1769
1770             /* Normal data.  */  
1771             case 0x1:
1772               subspace_asect->flags |= SEC_DATA;
1773               break;
1774
1775             /* Readonly code and the gateways.
1776                Gateways have other attributes which do not map
1777                into anything BFD knows about.  */
1778             case 0x2:
1779             case 0x4:
1780             case 0x5:
1781             case 0x6:
1782             case 0x7:
1783               subspace_asect->flags |= SEC_CODE | SEC_READONLY;
1784               break;
1785
1786             /* dynamic (writable) code.  */
1787             case 0x3:
1788               subspace_asect->flags |= SEC_CODE;
1789               break;
1790             }
1791           
1792           if (subspace.dup_common || subspace.is_common) 
1793             subspace_asect->flags |= SEC_IS_COMMON;
1794           else if (subspace.subspace_length > 0)
1795             subspace_asect->flags |= SEC_HAS_CONTENTS;
1796
1797           if (subspace.is_loadable)
1798             subspace_asect->flags |= SEC_ALLOC | SEC_LOAD;
1799           else
1800             subspace_asect->flags |= SEC_DEBUGGING;
1801
1802           if (subspace.code_only)
1803             subspace_asect->flags |= SEC_CODE;
1804
1805           /* Both file_loc_init_value and initialization_length will
1806              be zero for a BSS like subspace.  */
1807           if (subspace.file_loc_init_value == 0
1808               && subspace.initialization_length == 0)
1809             subspace_asect->flags &= ~(SEC_DATA | SEC_LOAD);
1810
1811           /* This subspace has relocations.
1812              The fixup_request_quantity is a byte count for the number of
1813              entries in the relocation stream; it is not the actual number
1814              of relocations in the subspace.  */
1815           if (subspace.fixup_request_quantity != 0)
1816             {
1817               subspace_asect->flags |= SEC_RELOC;
1818               subspace_asect->rel_filepos = subspace.fixup_request_index;
1819               som_section_data (subspace_asect)->reloc_size
1820                 = subspace.fixup_request_quantity;
1821               /* We can not determine this yet.  When we read in the 
1822                  relocation table the correct value will be filled in.  */
1823               subspace_asect->reloc_count = -1;
1824             }
1825
1826           /* Update save_subspace if appropriate.  */
1827           if (subspace.file_loc_init_value > save_subspace.file_loc_init_value)
1828             save_subspace = subspace;
1829
1830           subspace_asect->vma = subspace.subspace_start;
1831           subspace_asect->_cooked_size = subspace.subspace_length;
1832           subspace_asect->_raw_size = subspace.subspace_length;
1833           subspace_asect->filepos = subspace.file_loc_init_value;
1834           subspace_asect->alignment_power = log2 (subspace.alignment);
1835           if (subspace_asect->alignment_power == -1)
1836             goto error_return;
1837         }
1838
1839       /* Yow! there is no subspace within the space which actually 
1840          has initialized information in it; this should never happen
1841          as far as I know.  */
1842       if (!save_subspace.file_loc_init_value)
1843         goto error_return;
1844
1845       /* Setup the sizes for the space section based upon the info in the
1846          last subspace of the space.  */
1847       space_asect->_cooked_size = save_subspace.subspace_start
1848         - space_asect->vma + save_subspace.subspace_length;
1849       space_asect->_raw_size = save_subspace.file_loc_init_value
1850         - space_asect->filepos + save_subspace.initialization_length;
1851     }
1852   if (space_strings != NULL)
1853     free (space_strings);
1854   return true;
1855
1856  error_return:
1857   if (space_strings != NULL)
1858     free (space_strings);
1859   return false;
1860 }
1861
1862 /* Read in a SOM object and make it into a BFD.  */
1863
1864 static const bfd_target *
1865 som_object_p (abfd)
1866      bfd *abfd;
1867 {
1868   struct header file_hdr;
1869   struct som_exec_auxhdr aux_hdr;
1870
1871   if (bfd_read ((PTR) & file_hdr, 1, FILE_HDR_SIZE, abfd) != FILE_HDR_SIZE)
1872     {
1873       if (bfd_get_error () != bfd_error_system_call)
1874         bfd_set_error (bfd_error_wrong_format);
1875       return 0;
1876     }
1877
1878   if (!_PA_RISC_ID (file_hdr.system_id))
1879     {
1880       bfd_set_error (bfd_error_wrong_format);
1881       return 0;
1882     }
1883
1884   switch (file_hdr.a_magic)
1885     {
1886     case RELOC_MAGIC:
1887     case EXEC_MAGIC:
1888     case SHARE_MAGIC:
1889     case DEMAND_MAGIC:
1890 #ifdef DL_MAGIC
1891     case DL_MAGIC:
1892 #endif
1893 #ifdef SHL_MAGIC
1894     case SHL_MAGIC:
1895 #endif
1896 #ifdef EXECLIBMAGIC
1897     case EXECLIBMAGIC:
1898 #endif
1899 #ifdef SHARED_MAGIC_CNX
1900     case SHARED_MAGIC_CNX:
1901 #endif
1902       break;
1903     default:
1904       bfd_set_error (bfd_error_wrong_format);
1905       return 0;
1906     }
1907
1908   if (file_hdr.version_id != VERSION_ID
1909       && file_hdr.version_id != NEW_VERSION_ID)
1910     {
1911       bfd_set_error (bfd_error_wrong_format);
1912       return 0;
1913     }
1914
1915   /* If the aux_header_size field in the file header is zero, then this
1916      object is an incomplete executable (a .o file).  Do not try to read
1917      a non-existant auxiliary header.  */
1918   memset (&aux_hdr, 0, sizeof (struct som_exec_auxhdr));
1919   if (file_hdr.aux_header_size != 0)
1920     {
1921       if (bfd_read ((PTR) & aux_hdr, 1, AUX_HDR_SIZE, abfd) != AUX_HDR_SIZE)
1922         {
1923           if (bfd_get_error () != bfd_error_system_call)
1924             bfd_set_error (bfd_error_wrong_format);
1925           return 0;
1926         }
1927     }
1928
1929   if (!setup_sections (abfd, &file_hdr))
1930     {
1931       /* setup_sections does not bubble up a bfd error code.  */
1932       bfd_set_error (bfd_error_bad_value);
1933       return 0;
1934     }
1935
1936   /* This appears to be a valid SOM object.  Do some initialization.  */
1937   return som_object_setup (abfd, &file_hdr, &aux_hdr);
1938 }
1939
1940 /* Create a SOM object.  */
1941
1942 static boolean
1943 som_mkobject (abfd)
1944      bfd *abfd;
1945 {
1946   /* Allocate memory to hold backend information.  */
1947   abfd->tdata.som_data = (struct som_data_struct *)
1948     bfd_zalloc (abfd, sizeof (struct som_data_struct));
1949   if (abfd->tdata.som_data == NULL)
1950     {
1951       bfd_set_error (bfd_error_no_memory);
1952       return false;
1953     }
1954   return true;
1955 }
1956
1957 /* Initialize some information in the file header.  This routine makes
1958    not attempt at doing the right thing for a full executable; it
1959    is only meant to handle relocatable objects.  */
1960
1961 static boolean
1962 som_prep_headers (abfd)
1963      bfd *abfd;
1964 {
1965   struct header *file_hdr;
1966   asection *section;
1967
1968   /* Make and attach a file header to the BFD.  */
1969   file_hdr = (struct header *) bfd_zalloc (abfd, sizeof (struct header));
1970   if (file_hdr == NULL)
1971
1972     {
1973       bfd_set_error (bfd_error_no_memory);
1974       return false;
1975     }
1976   obj_som_file_hdr (abfd) = file_hdr;
1977
1978   if (abfd->flags & (EXEC_P | DYNAMIC))
1979     {
1980
1981       /* Make and attach an exec header to the BFD.  */
1982       obj_som_exec_hdr (abfd) = (struct som_exec_auxhdr *)
1983         bfd_zalloc (abfd, sizeof (struct som_exec_auxhdr));
1984       if (obj_som_exec_hdr (abfd) == NULL)
1985         {
1986           bfd_set_error (bfd_error_no_memory);
1987           return false;
1988         }
1989
1990       if (abfd->flags & D_PAGED)
1991         file_hdr->a_magic = DEMAND_MAGIC;
1992       else if (abfd->flags & WP_TEXT)
1993         file_hdr->a_magic = SHARE_MAGIC;
1994 #ifdef SHL_MAGIC
1995       else if (abfd->flags & DYNAMIC)
1996         file_hdr->a_magic = SHL_MAGIC;
1997 #endif
1998       else
1999         file_hdr->a_magic = EXEC_MAGIC;
2000     }
2001   else
2002     file_hdr->a_magic = RELOC_MAGIC;
2003
2004   /* Only new format SOM is supported.  */
2005   file_hdr->version_id = NEW_VERSION_ID;
2006
2007   /* These fields are optional, and embedding timestamps is not always
2008      a wise thing to do, it makes comparing objects during a multi-stage
2009      bootstrap difficult.  */
2010   file_hdr->file_time.secs = 0;
2011   file_hdr->file_time.nanosecs = 0; 
2012
2013   file_hdr->entry_space = 0;
2014   file_hdr->entry_subspace = 0;
2015   file_hdr->entry_offset = 0;
2016   file_hdr->presumed_dp = 0;
2017
2018   /* Now iterate over the sections translating information from
2019      BFD sections to SOM spaces/subspaces.  */
2020
2021   for (section = abfd->sections; section != NULL; section = section->next)
2022     {
2023       /* Ignore anything which has not been marked as a space or
2024          subspace.  */
2025       if (!som_is_space (section) && !som_is_subspace (section))
2026         continue;
2027       
2028       if (som_is_space (section))
2029         {
2030           /* Allocate space for the space dictionary.  */
2031           som_section_data (section)->space_dict
2032             = (struct space_dictionary_record *)
2033               bfd_zalloc (abfd, sizeof (struct space_dictionary_record));
2034           if (som_section_data (section)->space_dict == NULL)
2035             {
2036               bfd_set_error (bfd_error_no_memory);
2037               return false;
2038             }
2039           /* Set space attributes.  Note most attributes of SOM spaces
2040              are set based on the subspaces it contains.  */
2041           som_section_data (section)->space_dict->loader_fix_index = -1;
2042           som_section_data (section)->space_dict->init_pointer_index = -1;
2043
2044           /* Set more attributes that were stuffed away in private data.  */
2045           som_section_data (section)->space_dict->sort_key = 
2046             som_section_data (section)->copy_data->sort_key;
2047           som_section_data (section)->space_dict->is_defined = 
2048             som_section_data (section)->copy_data->is_defined;
2049           som_section_data (section)->space_dict->is_private = 
2050             som_section_data (section)->copy_data->is_private;
2051           som_section_data (section)->space_dict->space_number =
2052             som_section_data (section)->copy_data->space_number;
2053         }
2054       else
2055         {
2056           /* Allocate space for the subspace dictionary.  */
2057           som_section_data (section)->subspace_dict
2058             = (struct subspace_dictionary_record *)
2059               bfd_zalloc (abfd, sizeof (struct subspace_dictionary_record));
2060           if (som_section_data (section)->subspace_dict == NULL)
2061             {
2062               bfd_set_error (bfd_error_no_memory);
2063               return false;
2064             }
2065
2066           /* Set subspace attributes.  Basic stuff is done here, additional
2067              attributes are filled in later as more information becomes
2068              available.  */
2069           if (section->flags & SEC_IS_COMMON)
2070             {
2071               som_section_data (section)->subspace_dict->dup_common = 1;
2072               som_section_data (section)->subspace_dict->is_common = 1;
2073             }
2074
2075           if (section->flags & SEC_ALLOC)
2076             som_section_data (section)->subspace_dict->is_loadable = 1;
2077
2078           if (section->flags & SEC_CODE)
2079             som_section_data (section)->subspace_dict->code_only = 1;
2080
2081           som_section_data (section)->subspace_dict->subspace_start = 
2082             section->vma;
2083           som_section_data (section)->subspace_dict->subspace_length =
2084             bfd_section_size (abfd, section);
2085           som_section_data (section)->subspace_dict->initialization_length =
2086             bfd_section_size (abfd, section);
2087           som_section_data (section)->subspace_dict->alignment = 
2088             1 << section->alignment_power;
2089
2090           /* Set more attributes that were stuffed away in private data.  */
2091           som_section_data (section)->subspace_dict->sort_key =
2092             som_section_data (section)->copy_data->sort_key;
2093           som_section_data (section)->subspace_dict->access_control_bits =
2094             som_section_data (section)->copy_data->access_control_bits;
2095           som_section_data (section)->subspace_dict->quadrant =
2096             som_section_data (section)->copy_data->quadrant;
2097         }
2098     }
2099   return true;
2100 }
2101
2102 /* Return true if the given section is a SOM space, false otherwise.  */
2103
2104 static boolean
2105 som_is_space (section)
2106      asection *section;
2107 {
2108   /* If no copy data is available, then it's neither a space nor a
2109      subspace.  */
2110   if (som_section_data (section)->copy_data == NULL)
2111     return false;
2112
2113   /* If the containing space isn't the same as the given section,
2114      then this isn't a space.  */
2115   if (som_section_data (section)->copy_data->container != section)
2116     return false;
2117
2118   /* OK.  Must be a space.  */
2119   return true;
2120 }
2121
2122 /* Return true if the given section is a SOM subspace, false otherwise.  */
2123
2124 static boolean
2125 som_is_subspace (section)
2126      asection *section;
2127 {
2128   /* If no copy data is available, then it's neither a space nor a
2129      subspace.  */
2130   if (som_section_data (section)->copy_data == NULL)
2131     return false;
2132
2133   /* If the containing space is the same as the given section,
2134      then this isn't a subspace.  */
2135   if (som_section_data (section)->copy_data->container == section)
2136     return false;
2137
2138   /* OK.  Must be a subspace.  */
2139   return true;
2140 }
2141
2142 /* Return true if the given space containins the given subspace.  It
2143    is safe to assume space really is a space, and subspace really
2144    is a subspace.  */
2145
2146 static boolean
2147 som_is_container (space, subspace)
2148      asection *space, *subspace;
2149 {
2150   return som_section_data (subspace)->copy_data->container == space;
2151 }
2152
2153 /* Count and return the number of spaces attached to the given BFD.  */
2154
2155 static unsigned long
2156 som_count_spaces (abfd)
2157      bfd *abfd;
2158 {
2159   int count = 0;
2160   asection *section;
2161
2162   for (section = abfd->sections; section != NULL; section = section->next)
2163       count += som_is_space (section);
2164
2165   return count;
2166 }
2167
2168 /* Count the number of subspaces attached to the given BFD.  */
2169
2170 static unsigned long
2171 som_count_subspaces (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_subspace (section);
2179
2180   return count;
2181 }
2182
2183 /* Return -1, 0, 1 indicating the relative ordering of sym1 and sym2.
2184
2185    We desire symbols to be ordered starting with the symbol with the
2186    highest relocation count down to the symbol with the lowest relocation
2187    count.  Doing so compacts the relocation stream.  */
2188
2189 static int
2190 compare_syms (arg1, arg2)
2191      const PTR arg1;
2192      const PTR arg2;
2193
2194 {
2195   asymbol **sym1 = (asymbol **) arg1;
2196   asymbol **sym2 = (asymbol **) arg2;
2197   unsigned int count1, count2;
2198   
2199   /* Get relocation count for each symbol.  Note that the count
2200      is stored in the udata pointer for section symbols!  */
2201   if ((*sym1)->flags & BSF_SECTION_SYM)
2202     count1 = (int)(*sym1)->udata;
2203   else
2204     count1 = som_symbol_data (*sym1)->reloc_count;
2205
2206   if ((*sym2)->flags & BSF_SECTION_SYM)
2207     count2 = (int)(*sym2)->udata;
2208   else
2209     count2 = som_symbol_data (*sym2)->reloc_count;
2210
2211   /* Return the appropriate value.  */
2212   if (count1 < count2)
2213     return 1;
2214   else if (count1 > count2)
2215     return -1;
2216   return 0;
2217 }
2218
2219 /* Perform various work in preparation for emitting the fixup stream.  */
2220
2221 static void
2222 som_prep_for_fixups (abfd, syms, num_syms)
2223      bfd *abfd;
2224      asymbol **syms;
2225      unsigned long num_syms;
2226 {
2227   int i;
2228   asection *section;
2229
2230   /* Most SOM relocations involving a symbol have a length which is
2231      dependent on the index of the symbol.  So symbols which are
2232      used often in relocations should have a small index.  */
2233
2234   /* First initialize the counters for each symbol.  */
2235   for (i = 0; i < num_syms; i++)
2236     {
2237       /* Handle a section symbol; these have no pointers back to the 
2238          SOM symbol info.  So we just use the pointer field (udata)
2239          to hold the relocation count.  */
2240       if (som_symbol_data (syms[i]) == NULL
2241           || syms[i]->flags & BSF_SECTION_SYM)
2242         {
2243           syms[i]->flags |= BSF_SECTION_SYM;
2244           syms[i]->udata = (PTR) 0;
2245         }
2246       else
2247         som_symbol_data (syms[i])->reloc_count = 0;
2248     }
2249
2250   /* Now that the counters are initialized, make a weighted count
2251      of how often a given symbol is used in a relocation.  */
2252   for (section = abfd->sections; section != NULL; section = section->next)
2253     {
2254       int i;
2255
2256       /* Does this section have any relocations?  */
2257       if (section->reloc_count <= 0)
2258         continue;
2259
2260       /* Walk through each relocation for this section.  */
2261       for (i = 1; i < section->reloc_count; i++)
2262         {
2263           arelent *reloc = section->orelocation[i];
2264           int scale;
2265
2266           /* A relocation against a symbol in the *ABS* section really
2267              does not have a symbol.  Likewise if the symbol isn't associated
2268              with any section.  */
2269           if (reloc->sym_ptr_ptr == NULL
2270               || bfd_is_abs_section ((*reloc->sym_ptr_ptr)->section))
2271             continue;
2272
2273           /* Scaling to encourage symbols involved in R_DP_RELATIVE 
2274              and R_CODE_ONE_SYMBOL relocations to come first.  These
2275              two relocations have single byte versions if the symbol
2276              index is very small.  */
2277           if (reloc->howto->type == R_DP_RELATIVE
2278               || reloc->howto->type == R_CODE_ONE_SYMBOL)
2279             scale = 2;
2280           else
2281             scale = 1;
2282
2283           /* Handle section symbols by ramming the count in the udata
2284              field.  It will not be used and the count is very important
2285              for these symbols.  */
2286           if ((*reloc->sym_ptr_ptr)->flags & BSF_SECTION_SYM)
2287             {
2288               (*reloc->sym_ptr_ptr)->udata =
2289                 (PTR) ((int) (*reloc->sym_ptr_ptr)->udata + scale);
2290               continue;
2291             }
2292
2293           /* A normal symbol.  Increment the count.  */
2294           som_symbol_data (*reloc->sym_ptr_ptr)->reloc_count += scale;
2295         }
2296     }
2297
2298   /* Now sort the symbols.  */
2299   qsort (syms, num_syms, sizeof (asymbol *), compare_syms);
2300
2301   /* Compute the symbol indexes, they will be needed by the relocation
2302      code.  */
2303   for (i = 0; i < num_syms; i++)
2304     {
2305       /* A section symbol.  Again, there is no pointer to backend symbol
2306          information, so we reuse (abuse) the udata field again.  */
2307       if (syms[i]->flags & BSF_SECTION_SYM)
2308         syms[i]->udata = (PTR) i;
2309       else
2310         som_symbol_data (syms[i])->index = i;
2311     }
2312 }
2313
2314 static boolean
2315 som_write_fixups (abfd, current_offset, total_reloc_sizep)
2316      bfd *abfd;
2317      unsigned long current_offset;
2318      unsigned int *total_reloc_sizep;
2319 {
2320   unsigned int i, j;
2321   /* Chunk of memory that we can use as buffer space, then throw
2322      away.  */
2323   unsigned char tmp_space[SOM_TMP_BUFSIZE];
2324   unsigned char *p;
2325   unsigned int total_reloc_size = 0;
2326   unsigned int subspace_reloc_size = 0;
2327   unsigned int num_spaces = obj_som_file_hdr (abfd)->space_total;
2328   asection *section = abfd->sections;
2329
2330   memset (tmp_space, 0, SOM_TMP_BUFSIZE);
2331   p = tmp_space;
2332
2333   /* All the fixups for a particular subspace are emitted in a single
2334      stream.  All the subspaces for a particular space are emitted
2335      as a single stream.
2336
2337      So, to get all the locations correct one must iterate through all the
2338      spaces, for each space iterate through its subspaces and output a
2339      fixups stream.  */
2340   for (i = 0; i < num_spaces; i++)
2341     {
2342       asection *subsection;
2343
2344       /* Find a space.  */
2345       while (!som_is_space (section))
2346         section = section->next;
2347
2348       /* Now iterate through each of its subspaces.  */
2349       for (subsection = abfd->sections;
2350            subsection != NULL;
2351            subsection = subsection->next)
2352         {
2353           int reloc_offset, current_rounding_mode;
2354
2355           /* Find a subspace of this space.  */
2356           if (!som_is_subspace (subsection)
2357               || !som_is_container (section, subsection))
2358             continue;
2359
2360           /* If this subspace does not have real data, then we are
2361              finised with it.  */
2362           if ((subsection->flags & (SEC_LOAD | SEC_DEBUGGING)) == 0)
2363             {
2364               som_section_data (subsection)->subspace_dict->fixup_request_index
2365                 = -1;
2366               continue;
2367             }
2368
2369           /* This subspace has some relocations.  Put the relocation stream
2370              index into the subspace record.  */
2371           som_section_data (subsection)->subspace_dict->fixup_request_index
2372             = total_reloc_size;
2373
2374           /* To make life easier start over with a clean slate for 
2375              each subspace.  Seek to the start of the relocation stream
2376              for this subspace in preparation for writing out its fixup
2377              stream.  */
2378           if (bfd_seek (abfd, current_offset + total_reloc_size, SEEK_SET) < 0)
2379             return false;
2380
2381           /* Buffer space has already been allocated.  Just perform some
2382              initialization here.  */
2383           p = tmp_space;
2384           subspace_reloc_size = 0;
2385           reloc_offset = 0;
2386           som_initialize_reloc_queue (reloc_queue);
2387           current_rounding_mode = R_N_MODE;
2388
2389           /* Translate each BFD relocation into one or more SOM 
2390              relocations.  */
2391           for (j = 0; j < subsection->reloc_count; j++)
2392             {
2393               arelent *bfd_reloc = subsection->orelocation[j];
2394               unsigned int skip;
2395               int sym_num;
2396
2397               /* Get the symbol number.  Remember it's stored in a 
2398                  special place for section symbols.  */
2399               if ((*bfd_reloc->sym_ptr_ptr)->flags & BSF_SECTION_SYM)
2400                 sym_num = (int) (*bfd_reloc->sym_ptr_ptr)->udata;
2401               else
2402                 sym_num = som_symbol_data (*bfd_reloc->sym_ptr_ptr)->index;
2403               
2404               /* If there is not enough room for the next couple relocations,
2405                  then dump the current buffer contents now.  Also reinitialize
2406                  the relocation queue. 
2407
2408                  No single BFD relocation could ever translate into more
2409                  than 100 bytes of SOM relocations (20bytes is probably the
2410                  upper limit, but leave lots of space for growth).  */
2411               if (p - tmp_space + 100 > SOM_TMP_BUFSIZE)
2412                 {
2413                   if (bfd_write ((PTR) tmp_space, p - tmp_space, 1, abfd)
2414                       != p - tmp_space)
2415                     return false;
2416
2417                   p = tmp_space;
2418                   som_initialize_reloc_queue (reloc_queue);
2419                 }
2420
2421               /* Emit R_NO_RELOCATION fixups to map any bytes which were
2422                  skipped.  */
2423               skip = bfd_reloc->address - reloc_offset;
2424               p = som_reloc_skip (abfd, skip, p,
2425                                   &subspace_reloc_size, reloc_queue);
2426
2427               /* Update reloc_offset for the next iteration.
2428
2429                  Many relocations do not consume input bytes.  They
2430                  are markers, or set state necessary to perform some
2431                  later relocation.  */
2432               switch (bfd_reloc->howto->type)
2433                 {
2434                 /* This only needs to handle relocations that may be
2435                    made by hppa_som_gen_reloc.  */
2436                 case R_ENTRY:
2437                 case R_EXIT:
2438                 case R_N_MODE:
2439                 case R_S_MODE:
2440                 case R_D_MODE:
2441                 case R_R_MODE:
2442                 case R_FSEL:
2443                 case R_LSEL:
2444                 case R_RSEL:
2445                   reloc_offset = bfd_reloc->address;
2446                   break;
2447
2448                 default:
2449                   reloc_offset = bfd_reloc->address + 4;
2450                   break;
2451                 }
2452
2453               /* Now the actual relocation we care about.  */
2454               switch (bfd_reloc->howto->type)
2455                 {
2456                 case R_PCREL_CALL:
2457                 case R_ABS_CALL:
2458                   p = som_reloc_call (abfd, p, &subspace_reloc_size,
2459                                       bfd_reloc, sym_num, reloc_queue);
2460                   break;
2461
2462                 case R_CODE_ONE_SYMBOL:
2463                 case R_DP_RELATIVE:
2464                   /* Account for any addend.  */
2465                   if (bfd_reloc->addend)
2466                     p = som_reloc_addend (abfd, bfd_reloc->addend, p, 
2467                                           &subspace_reloc_size, reloc_queue);
2468
2469                   if (sym_num < 0x20)
2470                     {
2471                       bfd_put_8 (abfd, bfd_reloc->howto->type + sym_num, p);
2472                       subspace_reloc_size += 1;
2473                       p += 1;
2474                     }
2475                   else if (sym_num < 0x100)
2476                     {
2477                       bfd_put_8 (abfd, bfd_reloc->howto->type + 32, p);
2478                       bfd_put_8 (abfd, sym_num, p + 1);
2479                       p = try_prev_fixup (abfd, &subspace_reloc_size, p,
2480                                           2, reloc_queue);
2481                     }
2482                   else if (sym_num < 0x10000000)
2483                     {
2484                       bfd_put_8 (abfd, bfd_reloc->howto->type + 33, p);
2485                       bfd_put_8 (abfd, sym_num >> 16, p + 1);
2486                       bfd_put_16 (abfd, sym_num, p + 2); 
2487                       p = try_prev_fixup (abfd, &subspace_reloc_size,
2488                                           p, 4, reloc_queue);
2489                     }
2490                   else
2491                     abort ();
2492                   break;
2493
2494                 case R_DATA_ONE_SYMBOL:
2495                 case R_DATA_PLABEL:
2496                 case R_CODE_PLABEL:
2497                 case R_DLT_REL:
2498                   /* Account for any addend.  */
2499                   if (bfd_reloc->addend)
2500                     p = som_reloc_addend (abfd, bfd_reloc->addend, p, 
2501                                           &subspace_reloc_size, reloc_queue);
2502
2503                   if (sym_num < 0x100)
2504                     {
2505                       bfd_put_8 (abfd, bfd_reloc->howto->type, p);
2506                       bfd_put_8 (abfd, sym_num, p + 1);
2507                       p = try_prev_fixup (abfd, &subspace_reloc_size, p,
2508                                           2, reloc_queue);
2509                     }
2510                   else if (sym_num < 0x10000000)
2511                     {
2512                       bfd_put_8 (abfd, bfd_reloc->howto->type + 1, p);
2513                       bfd_put_8 (abfd, sym_num >> 16, p + 1);
2514                       bfd_put_16 (abfd, sym_num, p + 2); 
2515                       p = try_prev_fixup (abfd, &subspace_reloc_size,
2516                                           p, 4, reloc_queue);
2517                     }
2518                   else
2519                     abort ();
2520                   break;
2521
2522                 case R_ENTRY:
2523                   {
2524                     int *descp
2525                        = (int *) som_symbol_data (*bfd_reloc->sym_ptr_ptr)->unwind;
2526                     bfd_put_8 (abfd, R_ENTRY, p);
2527                     bfd_put_32 (abfd, descp[0], p + 1);
2528                     bfd_put_32 (abfd, descp[1], p + 5);
2529                     p = try_prev_fixup (abfd, &subspace_reloc_size,
2530                                         p, 9, reloc_queue);
2531                     break;
2532                   }
2533                   
2534                 case R_EXIT:
2535                   bfd_put_8 (abfd, R_EXIT, p);
2536                   subspace_reloc_size += 1;
2537                   p += 1;
2538                   break;
2539
2540                 case R_N_MODE:
2541                 case R_S_MODE:
2542                 case R_D_MODE:
2543                 case R_R_MODE:
2544                   /* If this relocation requests the current rounding
2545                      mode, then it is redundant.  */
2546                   if (bfd_reloc->howto->type != current_rounding_mode)
2547                     {
2548                       bfd_put_8 (abfd, bfd_reloc->howto->type, p);
2549                       subspace_reloc_size += 1;
2550                       p += 1;
2551                       current_rounding_mode = bfd_reloc->howto->type;
2552                     }
2553                   break;
2554
2555                 case R_FSEL:
2556                 case R_LSEL:
2557                 case R_RSEL:
2558                   bfd_put_8 (abfd, bfd_reloc->howto->type, p);
2559                   subspace_reloc_size += 1;
2560                   p += 1;
2561                   break;
2562
2563                 /* Put a "R_RESERVED" relocation in the stream if
2564                    we hit something we do not understand.  The linker
2565                    will complain loudly if this ever happens.  */
2566                 default:
2567                   bfd_put_8 (abfd, 0xff, p);
2568                   subspace_reloc_size += 1;
2569                   p += 1;
2570                   break;
2571                 }
2572             }
2573
2574           /* Last BFD relocation for a subspace has been processed.
2575              Map the rest of the subspace with R_NO_RELOCATION fixups.  */
2576           p = som_reloc_skip (abfd, bfd_section_size (abfd, subsection) 
2577                                       - reloc_offset,
2578                               p, &subspace_reloc_size, reloc_queue);
2579
2580           /* Scribble out the relocations.  */
2581           if (bfd_write ((PTR) tmp_space, p - tmp_space, 1, abfd)
2582               != p - tmp_space)
2583             return false;
2584           p = tmp_space;
2585
2586           total_reloc_size += subspace_reloc_size;
2587           som_section_data (subsection)->subspace_dict->fixup_request_quantity
2588             = subspace_reloc_size;
2589         }
2590       section = section->next;
2591     }
2592   *total_reloc_sizep = total_reloc_size;
2593   return true;
2594 }
2595
2596 /* Write out the space/subspace string table.  */
2597
2598 static boolean
2599 som_write_space_strings (abfd, current_offset, string_sizep)
2600      bfd *abfd;
2601      unsigned long current_offset;
2602      unsigned int *string_sizep;
2603 {
2604   /* Chunk of memory that we can use as buffer space, then throw
2605      away.  */
2606   unsigned char tmp_space[SOM_TMP_BUFSIZE];
2607   unsigned char *p;
2608   unsigned int strings_size = 0;
2609   asection *section;
2610
2611   memset (tmp_space, 0, SOM_TMP_BUFSIZE);
2612   p = tmp_space;
2613
2614   /* Seek to the start of the space strings in preparation for writing
2615      them out.  */
2616   if (bfd_seek (abfd, current_offset, SEEK_SET) < 0)
2617     return false;
2618
2619   /* Walk through all the spaces and subspaces (order is not important)
2620      building up and writing string table entries for their names.  */
2621   for (section = abfd->sections; section != NULL; section = section->next)
2622     {
2623       int length;
2624
2625       /* Only work with space/subspaces; avoid any other sections
2626          which might have been made (.text for example).  */
2627       if (!som_is_space (section) && !som_is_subspace (section))
2628         continue;
2629
2630       /* Get the length of the space/subspace name.  */
2631       length = strlen (section->name);
2632
2633       /* If there is not enough room for the next entry, then dump the
2634          current buffer contents now.  Each entry will take 4 bytes to
2635          hold the string length + the string itself + null terminator.  */
2636       if (p - tmp_space + 5 + length > SOM_TMP_BUFSIZE)
2637         {
2638           if (bfd_write ((PTR) &tmp_space[0], p - tmp_space, 1, abfd)
2639               != p - tmp_space) 
2640             return false;
2641           /* Reset to beginning of the buffer space.  */
2642           p = tmp_space;
2643         }
2644
2645       /* First element in a string table entry is the length of the
2646          string.  Alignment issues are already handled.  */
2647       bfd_put_32 (abfd, length, p);
2648       p += 4;
2649       strings_size += 4;
2650
2651       /* Record the index in the space/subspace records.  */
2652       if (som_is_space (section))
2653         som_section_data (section)->space_dict->name.n_strx = strings_size;
2654       else
2655         som_section_data (section)->subspace_dict->name.n_strx = strings_size;
2656
2657       /* Next comes the string itself + a null terminator.  */
2658       strcpy (p, section->name);
2659       p += length + 1;
2660       strings_size += length + 1;
2661
2662       /* Always align up to the next word boundary.  */
2663       while (strings_size % 4)
2664         {
2665           bfd_put_8 (abfd, 0, p);
2666           p++;
2667           strings_size++;
2668         }
2669     }
2670
2671   /* Done with the space/subspace strings.  Write out any information
2672      contained in a partial block.  */
2673   if (bfd_write ((PTR) &tmp_space[0], p - tmp_space, 1, abfd) != p - tmp_space)
2674     return false;
2675   *string_sizep = strings_size;
2676   return true;
2677 }
2678
2679 /* Write out the symbol string table.  */
2680
2681 static boolean
2682 som_write_symbol_strings (abfd, current_offset, syms, num_syms, string_sizep)
2683      bfd *abfd;
2684      unsigned long current_offset;
2685      asymbol **syms;
2686      unsigned int num_syms;
2687      unsigned int *string_sizep;
2688 {
2689   unsigned int i;
2690   
2691   /* Chunk of memory that we can use as buffer space, then throw
2692      away.  */
2693   unsigned char tmp_space[SOM_TMP_BUFSIZE];
2694   unsigned char *p;
2695   unsigned int strings_size = 0;
2696
2697   memset (tmp_space, 0, SOM_TMP_BUFSIZE);
2698   p = tmp_space;
2699
2700   /* Seek to the start of the space strings in preparation for writing
2701      them out.  */
2702   if (bfd_seek (abfd, current_offset, SEEK_SET) < 0)
2703     return false;
2704
2705   for (i = 0; i < num_syms; i++)
2706     {
2707       int length = strlen (syms[i]->name);
2708
2709       /* If there is not enough room for the next entry, then dump the
2710          current buffer contents now.  */
2711      if (p - tmp_space + 5 + length > SOM_TMP_BUFSIZE)
2712         {
2713           if (bfd_write ((PTR) &tmp_space[0], p - tmp_space, 1, abfd)
2714               != p - tmp_space)
2715             return false;
2716           /* Reset to beginning of the buffer space.  */
2717           p = tmp_space;
2718         }
2719
2720       /* First element in a string table entry is the length of the
2721          string.  This must always be 4 byte aligned.  This is also
2722          an appropriate time to fill in the string index field in the
2723          symbol table entry.  */
2724       bfd_put_32 (abfd, length, p);
2725       strings_size += 4;
2726       p += 4;
2727
2728       /* Next comes the string itself + a null terminator.  */
2729       strcpy (p, syms[i]->name);
2730
2731       /* ACK.  FIXME.  */
2732       syms[i]->name = (char *)strings_size;
2733       p += length + 1;
2734       strings_size += length + 1;
2735
2736       /* Always align up to the next word boundary.  */
2737       while (strings_size % 4)
2738         {
2739           bfd_put_8 (abfd, 0, p);
2740           strings_size++;
2741           p++;
2742         }
2743     }
2744
2745   /* Scribble out any partial block.  */
2746   if (bfd_write ((PTR) &tmp_space[0], p - tmp_space, 1, abfd) != p - tmp_space)
2747     return false;
2748
2749   *string_sizep = strings_size;
2750   return true;
2751 }
2752
2753 /* Compute variable information to be placed in the SOM headers, 
2754    space/subspace dictionaries, relocation streams, etc.  Begin
2755    writing parts of the object file.  */
2756
2757 static boolean 
2758 som_begin_writing (abfd)
2759      bfd *abfd;
2760 {
2761   unsigned long current_offset = 0;
2762   int strings_size = 0;
2763   unsigned int total_reloc_size = 0;
2764   unsigned long num_spaces, num_subspaces, num_syms, i;
2765   asection *section;
2766   asymbol **syms = bfd_get_outsymbols (abfd);
2767   unsigned int total_subspaces = 0;
2768   struct som_exec_auxhdr *exec_header;
2769
2770   /* The file header will always be first in an object file, 
2771      everything else can be in random locations.  To keep things
2772      "simple" BFD will lay out the object file in the manner suggested
2773      by the PRO ABI for PA-RISC Systems.  */
2774
2775   /* Before any output can really begin offsets for all the major
2776      portions of the object file must be computed.  So, starting
2777      with the initial file header compute (and sometimes write)
2778      each portion of the object file.  */
2779
2780   /* Make room for the file header, it's contents are not complete
2781      yet, so it can not be written at this time.  */
2782   current_offset += sizeof (struct header);  
2783
2784   /* Any auxiliary headers will follow the file header.  Right now
2785      we support only the copyright and version headers.  */
2786   obj_som_file_hdr (abfd)->aux_header_location = current_offset;
2787   obj_som_file_hdr (abfd)->aux_header_size = 0;
2788   if (abfd->flags & (EXEC_P | DYNAMIC))
2789     {
2790       /* Parts of the exec header will be filled in later, so
2791          delay writing the header itself.  Fill in the defaults,
2792          and write it later.  */
2793       current_offset += sizeof (struct som_exec_auxhdr);
2794       obj_som_file_hdr (abfd)->aux_header_size
2795         += sizeof (struct som_exec_auxhdr);
2796       exec_header = obj_som_exec_hdr (abfd);
2797       exec_header->som_auxhdr.type = EXEC_AUX_ID;
2798       exec_header->som_auxhdr.length = 40;
2799     }
2800   if (obj_som_version_hdr (abfd) != NULL)
2801     {
2802       unsigned int len;
2803
2804       if (bfd_seek (abfd, current_offset, SEEK_SET) < 0)
2805         return false;
2806
2807       /* Write the aux_id structure and the string length.  */
2808       len = sizeof (struct aux_id) + sizeof (unsigned int);
2809       obj_som_file_hdr (abfd)->aux_header_size += len;
2810       current_offset += len;
2811       if (bfd_write ((PTR) obj_som_version_hdr (abfd), len, 1, abfd) != len)
2812         return false;
2813
2814       /* Write the version string.  */
2815       len = obj_som_version_hdr (abfd)->header_id.length - sizeof (int);
2816       obj_som_file_hdr (abfd)->aux_header_size += len;
2817       current_offset += len;
2818       if (bfd_write ((PTR) obj_som_version_hdr (abfd)->user_string,
2819                      len, 1, abfd) != len)
2820         return false;
2821     }
2822
2823   if (obj_som_copyright_hdr (abfd) != NULL)
2824     {
2825       unsigned int len;
2826
2827       if (bfd_seek (abfd, current_offset, SEEK_SET) < 0)
2828         return false;
2829
2830       /* Write the aux_id structure and the string length.  */
2831       len = sizeof (struct aux_id) + sizeof (unsigned int);
2832       obj_som_file_hdr (abfd)->aux_header_size += len;
2833       current_offset += len;
2834       if (bfd_write ((PTR) obj_som_copyright_hdr (abfd), len, 1, abfd) != len)
2835         return false;
2836
2837       /* Write the copyright string.  */
2838       len = obj_som_copyright_hdr (abfd)->header_id.length - sizeof (int);
2839       obj_som_file_hdr (abfd)->aux_header_size += len;
2840       current_offset += len;
2841       if (bfd_write ((PTR) obj_som_copyright_hdr (abfd)->copyright,
2842                      len, 1, abfd) != len)
2843         return false;
2844     }
2845
2846   /* Next comes the initialization pointers; we have no initialization
2847      pointers, so current offset does not change.  */
2848   obj_som_file_hdr (abfd)->init_array_location = current_offset;
2849   obj_som_file_hdr (abfd)->init_array_total = 0;
2850
2851   /* Next are the space records.  These are fixed length records.
2852
2853      Count the number of spaces to determine how much room is needed
2854      in the object file for the space records.
2855
2856      The names of the spaces are stored in a separate string table,
2857      and the index for each space into the string table is computed
2858      below.  Therefore, it is not possible to write the space headers
2859      at this time.  */
2860   num_spaces = som_count_spaces (abfd);
2861   obj_som_file_hdr (abfd)->space_location = current_offset;
2862   obj_som_file_hdr (abfd)->space_total = num_spaces;
2863   current_offset += num_spaces * sizeof (struct space_dictionary_record);
2864
2865   /* Next are the subspace records.  These are fixed length records.
2866
2867      Count the number of subspaes to determine how much room is needed
2868      in the object file for the subspace records.
2869
2870      A variety if fields in the subspace record are still unknown at
2871      this time (index into string table, fixup stream location/size, etc).  */
2872   num_subspaces = som_count_subspaces (abfd);
2873   obj_som_file_hdr (abfd)->subspace_location = current_offset;
2874   obj_som_file_hdr (abfd)->subspace_total = num_subspaces;
2875   current_offset += num_subspaces * sizeof (struct subspace_dictionary_record);
2876
2877   /* Next is the string table for the space/subspace names.  We will
2878      build and write the string table on the fly.  At the same time
2879      we will fill in the space/subspace name index fields.  */
2880
2881   /* The string table needs to be aligned on a word boundary.  */
2882   if (current_offset % 4)
2883     current_offset += (4 - (current_offset % 4));
2884
2885   /* Mark the offset of the space/subspace string table in the 
2886      file header.  */
2887   obj_som_file_hdr (abfd)->space_strings_location = current_offset;
2888
2889   /* Scribble out the space strings.  */
2890   if (som_write_space_strings (abfd, current_offset, &strings_size) == false)
2891     return false;
2892
2893   /* Record total string table size in the header and update the
2894      current offset.  */
2895   obj_som_file_hdr (abfd)->space_strings_size = strings_size;
2896   current_offset += strings_size;
2897
2898   /* Next is the symbol table.  These are fixed length records.
2899
2900      Count the number of symbols to determine how much room is needed
2901      in the object file for the symbol table.
2902
2903      The names of the symbols are stored in a separate string table,
2904      and the index for each symbol name into the string table is computed
2905      below.  Therefore, it is not possible to write the symobl table
2906      at this time.  */
2907   num_syms = bfd_get_symcount (abfd);
2908   obj_som_file_hdr (abfd)->symbol_location = current_offset;
2909   obj_som_file_hdr (abfd)->symbol_total = num_syms;
2910   current_offset += num_syms * sizeof (struct symbol_dictionary_record);
2911
2912   /* Do prep work before handling fixups.  */
2913   som_prep_for_fixups (abfd, syms, num_syms);
2914
2915   /* Next comes the fixup stream which starts on a word boundary.  */
2916   if (current_offset % 4)
2917     current_offset += (4 - (current_offset % 4)); 
2918   obj_som_file_hdr (abfd)->fixup_request_location = current_offset;
2919
2920   /* Write the fixups and update fields in subspace headers which
2921      relate to the fixup stream.  */
2922   if (som_write_fixups (abfd, current_offset, &total_reloc_size) == false)
2923     return false;
2924
2925   /* Record the total size of the fixup stream in the file header.  */
2926   obj_som_file_hdr (abfd)->fixup_request_total = total_reloc_size;
2927   current_offset += total_reloc_size;
2928
2929   /* Next are the symbol strings.
2930      Align them to a word boundary.  */
2931   if (current_offset % 4)
2932     current_offset += (4 - (current_offset % 4));
2933   obj_som_file_hdr (abfd)->symbol_strings_location = current_offset;
2934
2935   /* Scribble out the symbol strings.  */
2936   if (som_write_symbol_strings (abfd, current_offset, syms, 
2937                                 num_syms, &strings_size)
2938       == false)
2939     return false;
2940
2941   /* Record total string table size in header and update the
2942      current offset.  */
2943   obj_som_file_hdr (abfd)->symbol_strings_size = strings_size;
2944   current_offset += strings_size;
2945
2946   /* Next is the compiler records.  We do not use these.  */
2947   obj_som_file_hdr (abfd)->compiler_location = current_offset;
2948   obj_som_file_hdr (abfd)->compiler_total = 0;
2949
2950   /* Now compute the file positions for the loadable subspaces, taking
2951      care to make sure everything stays properly aligned.  */
2952
2953   section = abfd->sections;
2954   for (i = 0; i < num_spaces; i++)
2955     {
2956       asection *subsection;
2957       int first_subspace;
2958       unsigned int subspace_offset = 0;
2959
2960       /* Find a space.  */
2961       while (!som_is_space (section))
2962         section = section->next;
2963
2964       first_subspace = 1;
2965       /* Now look for all its subspaces.  */
2966       for (subsection = abfd->sections;
2967            subsection != NULL;
2968            subsection = subsection->next)
2969         {
2970
2971           if (!som_is_subspace (subsection)
2972               || !som_is_container (section, subsection)
2973               || (subsection->flags & SEC_ALLOC) == 0)
2974             continue;
2975
2976           /* If this is the first subspace in the space, and we are
2977              building an executable, then take care to make sure all
2978              the alignments are correct and update the exec header.  */
2979           if (first_subspace
2980               && (abfd->flags & (EXEC_P | DYNAMIC)))
2981             {
2982               /* Demand paged executables have each space aligned to a
2983                  page boundary.  Sharable executables (write-protected
2984                  text) have just the private (aka data & bss) space aligned
2985                  to a page boundary.  Ugh.  Not true for HPUX.
2986
2987                  The HPUX kernel requires the text to always be page aligned
2988                  within the file regardless of the executable's type.  */
2989               if (abfd->flags & (D_PAGED | DYNAMIC)
2990                   || (subsection->flags & SEC_CODE)
2991                   || ((abfd->flags & WP_TEXT)
2992                       && (subsection->flags & SEC_DATA)))
2993                 current_offset = SOM_ALIGN (current_offset, PA_PAGESIZE);
2994
2995               /* Update the exec header.  */
2996               if (subsection->flags & SEC_CODE && exec_header->exec_tfile == 0)
2997                 {
2998                   exec_header->exec_tmem = section->vma;
2999                   exec_header->exec_tfile = current_offset;
3000                 }
3001               if (subsection->flags & SEC_DATA && exec_header->exec_dfile == 0)
3002                 {
3003                   exec_header->exec_dmem = section->vma;
3004                   exec_header->exec_dfile = current_offset;
3005                 }
3006
3007               /* Keep track of exactly where we are within a particular
3008                  space.  This is necessary as the braindamaged HPUX
3009                  loader will create holes between subspaces *and* 
3010                  subspace alignments are *NOT* preserved.  What a crock.  */
3011               subspace_offset = subsection->vma;
3012
3013               /* Only do this for the first subspace within each space.  */
3014               first_subspace = 0;
3015             }
3016           else if (abfd->flags & (EXEC_P | DYNAMIC))
3017             {
3018               /* The braindamaged HPUX loader may have created a hole
3019                  between two subspaces.  It is *not* sufficient to use
3020                  the alignment specifications within the subspaces to
3021                  account for these holes -- I've run into at least one
3022                  case where the loader left one code subspace unaligned
3023                  in a final executable.
3024
3025                  To combat this we keep a current offset within each space,
3026                  and use the subspace vma fields to detect and preserve
3027                  holes.  What a crock!
3028
3029                  ps.  This is not necessary for unloadable space/subspaces.  */
3030               current_offset += subsection->vma - subspace_offset;
3031               if (subsection->flags & SEC_CODE)
3032                 exec_header->exec_tsize += subsection->vma - subspace_offset;
3033               else
3034                 exec_header->exec_dsize += subsection->vma - subspace_offset;
3035               subspace_offset += subsection->vma - subspace_offset;
3036             }
3037
3038
3039           subsection->target_index = total_subspaces++;
3040           /* This is real data to be loaded from the file.  */
3041           if (subsection->flags & SEC_LOAD)
3042             {
3043               /* Update the size of the code & data.  */
3044               if (abfd->flags & (EXEC_P | DYNAMIC)
3045                   && subsection->flags & SEC_CODE)
3046                 exec_header->exec_tsize += subsection->_cooked_size;
3047               else if (abfd->flags & (EXEC_P | DYNAMIC)
3048                        && subsection->flags & SEC_DATA)
3049                 exec_header->exec_dsize += subsection->_cooked_size;
3050               som_section_data (subsection)->subspace_dict->file_loc_init_value
3051                 = current_offset;
3052               subsection->filepos = current_offset;
3053               current_offset += bfd_section_size (abfd, subsection); 
3054               subspace_offset += bfd_section_size (abfd, subsection);
3055             }
3056           /* Looks like uninitialized data.  */
3057           else
3058             {
3059               /* Update the size of the bss section.  */
3060               if (abfd->flags & (EXEC_P | DYNAMIC))
3061                 exec_header->exec_bsize += subsection->_cooked_size;
3062
3063               som_section_data (subsection)->subspace_dict->file_loc_init_value
3064                 = 0;
3065               som_section_data (subsection)->subspace_dict->
3066                 initialization_length = 0;
3067             }
3068         }
3069       /* Goto the next section.  */
3070       section = section->next; 
3071     }
3072
3073   /* Finally compute the file positions for unloadable subspaces.
3074      If building an executable, start the unloadable stuff on its
3075      own page.  */
3076
3077   if (abfd->flags & (EXEC_P | DYNAMIC))
3078     current_offset = SOM_ALIGN (current_offset, PA_PAGESIZE);
3079
3080   obj_som_file_hdr (abfd)->unloadable_sp_location = current_offset;
3081   section = abfd->sections;
3082   for (i = 0; i < num_spaces; i++)
3083     {
3084       asection *subsection;
3085
3086       /* Find a space.  */
3087       while (!som_is_space (section))
3088         section = section->next;
3089
3090       if (abfd->flags & (EXEC_P | DYNAMIC))
3091         current_offset = SOM_ALIGN (current_offset, PA_PAGESIZE);
3092
3093       /* Now look for all its subspaces.  */
3094       for (subsection = abfd->sections;
3095            subsection != NULL;
3096            subsection = subsection->next)
3097         {
3098           
3099           if (!som_is_subspace (subsection)
3100               || !som_is_container (section, subsection)
3101               || (subsection->flags & SEC_ALLOC) != 0)
3102             continue;
3103
3104           subsection->target_index = total_subspaces;
3105           /* This is real data to be loaded from the file.  */
3106           if ((subsection->flags & SEC_LOAD) == 0)
3107             {
3108               som_section_data (subsection)->subspace_dict->file_loc_init_value
3109                 = current_offset;
3110               subsection->filepos = current_offset;
3111               current_offset += bfd_section_size (abfd, subsection); 
3112             }
3113           /* Looks like uninitialized data.  */
3114           else
3115             {
3116               som_section_data (subsection)->subspace_dict->file_loc_init_value
3117                 = 0;
3118               som_section_data (subsection)->subspace_dict->
3119                 initialization_length = bfd_section_size (abfd, subsection);
3120             }
3121         }
3122       /* Goto the next section.  */
3123       section = section->next; 
3124     }
3125
3126   /* If building an executable, then make sure to seek to and write
3127      one byte at the end of the file to make sure any necessary
3128      zeros are filled in.  Ugh.  */
3129   if (abfd->flags & (EXEC_P | DYNAMIC))
3130     current_offset = SOM_ALIGN (current_offset, PA_PAGESIZE);
3131   if (bfd_seek (abfd, current_offset - 1, SEEK_SET) < 0)
3132     return false;
3133   if (bfd_write ((PTR) "", 1, 1, abfd) != 1)
3134     return false;
3135
3136   obj_som_file_hdr (abfd)->unloadable_sp_size
3137     = current_offset - obj_som_file_hdr (abfd)->unloadable_sp_location;
3138
3139   /* Loader fixups are not supported in any way shape or form.  */
3140   obj_som_file_hdr (abfd)->loader_fixup_location = 0;
3141   obj_som_file_hdr (abfd)->loader_fixup_total = 0;
3142
3143   /* Done.  Store the total size of the SOM.  */
3144   obj_som_file_hdr (abfd)->som_length = current_offset;
3145
3146   return true;
3147 }
3148
3149 /* Finally, scribble out the various headers to the disk.  */
3150
3151 static boolean
3152 som_write_headers (abfd)
3153      bfd *abfd;
3154 {
3155   int num_spaces = som_count_spaces (abfd);
3156   int i;
3157   int subspace_index = 0;
3158   file_ptr location;
3159   asection *section;
3160
3161   /* Subspaces are written first so that we can set up information
3162      about them in their containing spaces as the subspace is written.  */
3163
3164   /* Seek to the start of the subspace dictionary records.  */
3165   location = obj_som_file_hdr (abfd)->subspace_location;
3166   if (bfd_seek (abfd, location, SEEK_SET) < 0)
3167     return false;
3168
3169   section = abfd->sections;
3170   /* Now for each loadable space write out records for its subspaces.  */
3171   for (i = 0; i < num_spaces; i++)
3172     {
3173       asection *subsection;
3174
3175       /* Find a space.  */
3176       while (!som_is_space (section))
3177         section = section->next;
3178
3179       /* Now look for all its subspaces.  */
3180       for (subsection = abfd->sections;
3181            subsection != NULL;
3182            subsection = subsection->next)
3183         {
3184           
3185           /* Skip any section which does not correspond to a space
3186              or subspace.  Or does not have SEC_ALLOC set (and therefore
3187              has no real bits on the disk).  */
3188           if (!som_is_subspace (subsection)
3189               || !som_is_container (section, subsection)
3190               || (subsection->flags & SEC_ALLOC) == 0)
3191             continue;
3192
3193           /* If this is the first subspace for this space, then save
3194              the index of the subspace in its containing space.  Also
3195              set "is_loadable" in the containing space.  */
3196
3197           if (som_section_data (section)->space_dict->subspace_quantity == 0)
3198             {
3199               som_section_data (section)->space_dict->is_loadable = 1;
3200               som_section_data (section)->space_dict->subspace_index
3201                 = subspace_index;
3202             }
3203
3204           /* Increment the number of subspaces seen and the number of
3205              subspaces contained within the current space.  */
3206           subspace_index++;
3207           som_section_data (section)->space_dict->subspace_quantity++;
3208
3209           /* Mark the index of the current space within the subspace's
3210              dictionary record.  */
3211           som_section_data (subsection)->subspace_dict->space_index = i;
3212           
3213           /* Dump the current subspace header.  */
3214           if (bfd_write ((PTR) som_section_data (subsection)->subspace_dict,
3215                          sizeof (struct subspace_dictionary_record), 1, abfd)
3216               != sizeof (struct subspace_dictionary_record))
3217             return false;
3218         }
3219       /* Goto the next section.  */
3220       section = section->next; 
3221     }
3222
3223   /* Now repeat the process for unloadable subspaces.  */
3224   section = abfd->sections;
3225   /* Now for each space write out records for its subspaces.  */
3226   for (i = 0; i < num_spaces; i++)
3227     {
3228       asection *subsection;
3229
3230       /* Find a space.  */
3231       while (!som_is_space (section))
3232         section = section->next;
3233
3234       /* Now look for all its subspaces.  */
3235       for (subsection = abfd->sections;
3236            subsection != NULL;
3237            subsection = subsection->next)
3238         {
3239           
3240           /* Skip any section which does not correspond to a space or
3241              subspace, or which SEC_ALLOC set (and therefore handled
3242              in the loadable spaces/subspaces code above).  */
3243
3244           if (!som_is_subspace (subsection)
3245               || !som_is_container (section, subsection)
3246               || (subsection->flags & SEC_ALLOC) != 0)
3247             continue;
3248
3249           /* If this is the first subspace for this space, then save
3250              the index of the subspace in its containing space.  Clear
3251              "is_loadable".  */
3252
3253           if (som_section_data (section)->space_dict->subspace_quantity == 0)
3254             {
3255               som_section_data (section)->space_dict->is_loadable = 0;
3256               som_section_data (section)->space_dict->subspace_index
3257                 = subspace_index;
3258             }
3259
3260           /* Increment the number of subspaces seen and the number of
3261              subspaces contained within the current space.  */
3262           som_section_data (section)->space_dict->subspace_quantity++;
3263           subspace_index++; 
3264
3265           /* Mark the index of the current space within the subspace's
3266              dictionary record.  */
3267           som_section_data (subsection)->subspace_dict->space_index = i;
3268           
3269           /* Dump this subspace header.  */
3270           if (bfd_write ((PTR) som_section_data (subsection)->subspace_dict,
3271                          sizeof (struct subspace_dictionary_record), 1, abfd)
3272               != sizeof (struct subspace_dictionary_record))
3273             return false;
3274         }
3275       /* Goto the next section.  */
3276       section = section->next; 
3277     }
3278
3279   /* All the subspace dictiondary records are written, and all the
3280      fields are set up in the space dictionary records.
3281
3282      Seek to the right location and start writing the space
3283      dictionary records.  */
3284   location = obj_som_file_hdr (abfd)->space_location;
3285   if (bfd_seek (abfd, location, SEEK_SET) < 0)
3286     return false;
3287
3288   section = abfd->sections;
3289   for (i = 0; i < num_spaces; i++)
3290     {
3291
3292       /* Find a space.  */
3293       while (!som_is_space (section))
3294         section = section->next;
3295
3296       /* Dump its header  */
3297       if (bfd_write ((PTR) som_section_data (section)->space_dict,
3298                      sizeof (struct space_dictionary_record), 1, abfd)
3299           != sizeof (struct space_dictionary_record))
3300         return false;
3301
3302       /* Goto the next section.  */
3303       section = section->next;
3304     }
3305
3306   /* FIXME.  This should really be conditional based on whether or not
3307      PA1.1 instructions/registers have been used. 
3308
3309      Setting of the system_id has to happen very late now that copying of
3310      BFD private data happens *after* section contents are set.  */
3311   if (abfd->flags & (EXEC_P | DYNAMIC))
3312     obj_som_file_hdr(abfd)->system_id = obj_som_exec_data (abfd)->system_id;
3313   else
3314     obj_som_file_hdr(abfd)->system_id = CPU_PA_RISC1_0;
3315
3316   /* Compute the checksum for the file header just before writing
3317      the header to disk.  */
3318   obj_som_file_hdr (abfd)->checksum = som_compute_checksum (abfd);
3319
3320   /* Only thing left to do is write out the file header.  It is always
3321      at location zero.  Seek there and write it.  */
3322   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) < 0)
3323     return false;
3324   if (bfd_write ((PTR) obj_som_file_hdr (abfd),
3325                  sizeof (struct header), 1, abfd)
3326       != sizeof (struct header))
3327     return false;
3328
3329   /* Now write the exec header.  */
3330   if (abfd->flags & (EXEC_P | DYNAMIC))
3331     {
3332       long tmp;
3333       struct som_exec_auxhdr *exec_header;
3334
3335       exec_header = obj_som_exec_hdr (abfd);
3336       exec_header->exec_entry = bfd_get_start_address (abfd);
3337       exec_header->exec_flags = obj_som_exec_data (abfd)->exec_flags;
3338
3339       /* Oh joys.  Ram some of the BSS data into the DATA section
3340          to be compatable with how the hp linker makes objects
3341          (saves memory space).  */
3342       tmp = exec_header->exec_dsize;
3343       tmp = SOM_ALIGN (tmp, PA_PAGESIZE);
3344       exec_header->exec_bsize -= (tmp - exec_header->exec_dsize);
3345       if (exec_header->exec_bsize < 0)
3346         exec_header->exec_bsize = 0;
3347       exec_header->exec_dsize = tmp;
3348
3349       if (bfd_seek (abfd, obj_som_file_hdr (abfd)->aux_header_location,
3350                     SEEK_SET) < 0)
3351         return false;
3352
3353       if (bfd_write ((PTR) exec_header, AUX_HDR_SIZE, 1, abfd)
3354           != AUX_HDR_SIZE)
3355         return false;
3356     }
3357   return true;
3358 }
3359
3360 /* Compute and return the checksum for a SOM file header.  */
3361
3362 static unsigned long
3363 som_compute_checksum (abfd)
3364      bfd *abfd;
3365 {
3366   unsigned long checksum, count, i;
3367   unsigned long *buffer = (unsigned long *) obj_som_file_hdr (abfd);
3368
3369   checksum = 0;
3370   count = sizeof (struct header) / sizeof (unsigned long);
3371   for (i = 0; i < count; i++)
3372     checksum ^= *(buffer + i);
3373
3374   return checksum;
3375 }
3376
3377 static void
3378 som_bfd_derive_misc_symbol_info (abfd, sym, info)
3379      bfd *abfd;
3380      asymbol *sym;
3381      struct som_misc_symbol_info *info;
3382 {
3383   /* Initialize.  */
3384   memset (info, 0, sizeof (struct som_misc_symbol_info));
3385
3386   /* The HP SOM linker requires detailed type information about
3387      all symbols (including undefined symbols!).  Unfortunately,
3388      the type specified in an import/export statement does not
3389      always match what the linker wants.  Severe braindamage.  */
3390          
3391   /* Section symbols will not have a SOM symbol type assigned to
3392      them yet.  Assign all section symbols type ST_DATA.  */
3393   if (sym->flags & BSF_SECTION_SYM)
3394     info->symbol_type = ST_DATA;
3395   else
3396     {
3397       /* Common symbols must have scope SS_UNSAT and type
3398          ST_STORAGE or the linker will choke.  */
3399       if (bfd_is_com_section (sym->section))
3400         {
3401           info->symbol_scope = SS_UNSAT;
3402           info->symbol_type = ST_STORAGE;
3403         }
3404
3405       /* It is possible to have a symbol without an associated
3406          type.  This happens if the user imported the symbol
3407          without a type and the symbol was never defined
3408          locally.  If BSF_FUNCTION is set for this symbol, then
3409          assign it type ST_CODE (the HP linker requires undefined
3410          external functions to have type ST_CODE rather than ST_ENTRY).  */
3411       else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_UNKNOWN
3412                && bfd_is_und_section (sym->section)
3413                && sym->flags & BSF_FUNCTION)
3414         info->symbol_type = ST_CODE;
3415
3416       /* Handle function symbols which were defined in this file.
3417          They should have type ST_ENTRY.  Also retrieve the argument
3418          relocation bits from the SOM backend information.  */
3419       else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_ENTRY
3420                || (som_symbol_data (sym)->som_type == SYMBOL_TYPE_CODE
3421                    && (sym->flags & BSF_FUNCTION))
3422                || (som_symbol_data (sym)->som_type == SYMBOL_TYPE_UNKNOWN
3423                    && (sym->flags & BSF_FUNCTION)))
3424         {
3425           info->symbol_type = ST_ENTRY;
3426           info->arg_reloc = som_symbol_data (sym)->tc_data.hppa_arg_reloc;
3427         }
3428
3429       /* If the type is unknown at this point, it should be
3430          ST_DATA (functions were handled as special cases above).  */
3431       else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_UNKNOWN)
3432         info->symbol_type = ST_DATA;
3433
3434       /* From now on it's a very simple mapping.  */
3435       else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_ABSOLUTE)
3436         info->symbol_type = ST_ABSOLUTE;
3437       else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_CODE)
3438         info->symbol_type = ST_CODE;
3439       else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_DATA)
3440         info->symbol_type = ST_DATA;
3441       else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_MILLICODE)
3442         info->symbol_type = ST_MILLICODE;
3443       else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_PLABEL)
3444         info->symbol_type = ST_PLABEL;
3445       else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_PRI_PROG)
3446         info->symbol_type = ST_PRI_PROG;
3447       else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_SEC_PROG)
3448         info->symbol_type = ST_SEC_PROG;
3449     }
3450         
3451   /* Now handle the symbol's scope.  Exported data which is not
3452      in the common section has scope SS_UNIVERSAL.  Note scope
3453      of common symbols was handled earlier!  */
3454   if (sym->flags & BSF_EXPORT && ! bfd_is_com_section (sym->section))
3455     info->symbol_scope = SS_UNIVERSAL;
3456   /* Any undefined symbol at this point has a scope SS_UNSAT.  */
3457   else if (bfd_is_und_section (sym->section))
3458     info->symbol_scope = SS_UNSAT;
3459   /* Anything else which is not in the common section has scope
3460      SS_LOCAL.  */
3461   else if (! bfd_is_com_section (sym->section))
3462     info->symbol_scope = SS_LOCAL;
3463
3464   /* Now set the symbol_info field.  It has no real meaning
3465      for undefined or common symbols, but the HP linker will
3466      choke if it's not set to some "reasonable" value.  We
3467      use zero as a reasonable value.  */
3468   if (bfd_is_com_section (sym->section)
3469       || bfd_is_und_section (sym->section)
3470       || bfd_is_abs_section (sym->section))
3471     info->symbol_info = 0;
3472   /* For all other symbols, the symbol_info field contains the 
3473      subspace index of the space this symbol is contained in.  */
3474   else
3475     info->symbol_info = sym->section->target_index;
3476
3477   /* Set the symbol's value.  */
3478   info->symbol_value = sym->value + sym->section->vma;
3479 }
3480
3481 /* Build and write, in one big chunk, the entire symbol table for
3482    this BFD.  */
3483
3484 static boolean
3485 som_build_and_write_symbol_table (abfd)
3486      bfd *abfd;
3487 {
3488   unsigned int num_syms = bfd_get_symcount (abfd);
3489   file_ptr symtab_location = obj_som_file_hdr (abfd)->symbol_location;
3490   asymbol **bfd_syms = bfd_get_outsymbols (abfd);
3491   struct symbol_dictionary_record *som_symtab = NULL;
3492   int i, symtab_size;
3493
3494   /* Compute total symbol table size and allocate a chunk of memory
3495      to hold the symbol table as we build it.  */
3496   symtab_size = num_syms * sizeof (struct symbol_dictionary_record);
3497   som_symtab = (struct symbol_dictionary_record *) malloc (symtab_size);
3498   if (som_symtab == NULL && symtab_size != 0)
3499     {
3500       bfd_set_error (bfd_error_no_memory);
3501       goto error_return;
3502     }
3503   memset (som_symtab, 0, symtab_size);
3504
3505   /* Walk over each symbol.  */
3506   for (i = 0; i < num_syms; i++)
3507     {
3508       struct som_misc_symbol_info info;
3509
3510       /* This is really an index into the symbol strings table.  
3511          By the time we get here, the index has already been 
3512          computed and stored into the name field in the BFD symbol.  */
3513       som_symtab[i].name.n_strx = (int) bfd_syms[i]->name;
3514
3515       /* Derive SOM information from the BFD symbol.  */
3516       som_bfd_derive_misc_symbol_info (abfd, bfd_syms[i], &info);
3517
3518       /* Now use it.  */
3519       som_symtab[i].symbol_type = info.symbol_type;
3520       som_symtab[i].symbol_scope = info.symbol_scope;
3521       som_symtab[i].arg_reloc = info.arg_reloc;
3522       som_symtab[i].symbol_info = info.symbol_info;
3523       som_symtab[i].symbol_value = info.symbol_value;
3524     }
3525
3526   /* Everything is ready, seek to the right location and
3527      scribble out the symbol table.  */
3528   if (bfd_seek (abfd, symtab_location, SEEK_SET) != 0)
3529     return false;
3530
3531   if (bfd_write ((PTR) som_symtab, symtab_size, 1, abfd) != symtab_size)
3532     goto error_return;
3533
3534   if (som_symtab != NULL)
3535     free (som_symtab);
3536   return true;
3537  error_return:
3538   if (som_symtab != NULL)
3539     free (som_symtab);
3540   return false;
3541 }
3542
3543 /* Write an object in SOM format.  */  
3544
3545 static boolean
3546 som_write_object_contents (abfd)
3547      bfd *abfd;
3548 {
3549   if (abfd->output_has_begun == false)
3550     {
3551       /* Set up fixed parts of the file, space, and subspace headers.
3552          Notify the world that output has begun.  */
3553       som_prep_headers (abfd);
3554       abfd->output_has_begun = true;
3555       /* Start writing the object file.  This include all the string
3556          tables, fixup streams, and other portions of the object file.  */
3557       som_begin_writing (abfd);
3558     }
3559
3560   /* Now that the symbol table information is complete, build and
3561      write the symbol table.  */
3562   if (som_build_and_write_symbol_table (abfd) == false)
3563     return false;
3564
3565   return (som_write_headers (abfd));
3566 }
3567
3568 \f
3569 /* Read and save the string table associated with the given BFD.  */
3570
3571 static boolean
3572 som_slurp_string_table (abfd)
3573      bfd *abfd;
3574 {
3575   char *stringtab;
3576
3577   /* Use the saved version if its available.  */
3578   if (obj_som_stringtab (abfd) != NULL)
3579     return true;
3580
3581   /* I don't think this can currently happen, and I'm not sure it should
3582      really be an error, but it's better than getting unpredictable results
3583      from the host's malloc when passed a size of zero.  */
3584   if (obj_som_stringtab_size (abfd) == 0)
3585     {
3586       bfd_set_error (bfd_error_no_symbols);
3587       return false;
3588     }
3589
3590   /* Allocate and read in the string table.  */
3591   stringtab = malloc (obj_som_stringtab_size (abfd));
3592   if (stringtab == NULL)
3593     {
3594       bfd_set_error (bfd_error_no_memory);
3595       return false;
3596     }
3597
3598   if (bfd_seek (abfd, obj_som_str_filepos (abfd), SEEK_SET) < 0)
3599     return false;
3600   
3601   if (bfd_read (stringtab, obj_som_stringtab_size (abfd), 1, abfd)
3602       != obj_som_stringtab_size (abfd))
3603     return false;
3604
3605   /* Save our results and return success. */
3606   obj_som_stringtab (abfd) = stringtab;
3607   return true;
3608 }
3609
3610 /* Return the amount of data (in bytes) required to hold the symbol
3611    table for this object.  */
3612
3613 static long
3614 som_get_symtab_upper_bound (abfd)
3615      bfd *abfd;
3616 {
3617   if (!som_slurp_symbol_table (abfd))
3618     return -1;
3619
3620   return (bfd_get_symcount (abfd) + 1) * (sizeof (asymbol *));
3621 }
3622
3623 /* Convert from a SOM subspace index to a BFD section.  */
3624
3625 static asection *
3626 bfd_section_from_som_symbol (abfd, symbol)
3627      bfd *abfd;
3628      struct symbol_dictionary_record *symbol;
3629 {
3630   asection *section;
3631
3632   /* The meaning of the symbol_info field changes for functions
3633      within executables.  So only use the quick symbol_info mapping for
3634      incomplete objects and non-function symbols in executables.  */
3635   if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0
3636       || (symbol->symbol_type != ST_ENTRY
3637           && symbol->symbol_type != ST_PRI_PROG
3638           && symbol->symbol_type != ST_SEC_PROG
3639           && symbol->symbol_type != ST_MILLICODE))
3640     {
3641       unsigned int index = symbol->symbol_info;
3642       for (section = abfd->sections; section != NULL; section = section->next)
3643         if (section->target_index == index)
3644           return section;
3645
3646       /* Should never happen.  */
3647       abort();
3648     }
3649   else
3650     {
3651       unsigned int value = symbol->symbol_value;
3652
3653       /* For executables we will have to use the symbol's address and
3654          find out what section would contain that address.   Yuk.  */
3655       for (section = abfd->sections; section; section = section->next)
3656         {
3657           if (value >= section->vma
3658               && value <= section->vma + section->_cooked_size)
3659             return section;
3660         }
3661
3662       /* Should never happen.  */
3663       abort ();
3664     }
3665 }
3666
3667 /* Read and save the symbol table associated with the given BFD.  */
3668
3669 static unsigned int
3670 som_slurp_symbol_table (abfd)
3671      bfd *abfd;
3672 {
3673   int symbol_count = bfd_get_symcount (abfd);
3674   int symsize = sizeof (struct symbol_dictionary_record);
3675   char *stringtab;
3676   struct symbol_dictionary_record *buf = NULL, *bufp, *endbufp;
3677   som_symbol_type *sym, *symbase;
3678
3679   /* Return saved value if it exists.  */
3680   if (obj_som_symtab (abfd) != NULL)
3681     goto successful_return;
3682
3683   /* Special case.  This is *not* an error.  */
3684   if (symbol_count == 0)
3685     goto successful_return;
3686
3687   if (!som_slurp_string_table (abfd))
3688     goto error_return;
3689
3690   stringtab = obj_som_stringtab (abfd);
3691
3692   symbase = (som_symbol_type *)
3693     malloc (symbol_count * sizeof (som_symbol_type));
3694   if (symbase == NULL)
3695     {
3696       bfd_set_error (bfd_error_no_memory);
3697       goto error_return;
3698     }
3699
3700   /* Read in the external SOM representation.  */
3701   buf = malloc (symbol_count * symsize);
3702   if (buf == NULL && symbol_count * symsize != 0)
3703     {
3704       bfd_set_error (bfd_error_no_memory);
3705       goto error_return;
3706     }
3707   if (bfd_seek (abfd, obj_som_sym_filepos (abfd), SEEK_SET) < 0)
3708     goto error_return;
3709   if (bfd_read (buf, symbol_count * symsize, 1, abfd) 
3710       != symbol_count * symsize)
3711     goto error_return;
3712
3713   /* Iterate over all the symbols and internalize them.  */
3714   endbufp = buf + symbol_count;
3715   for (bufp = buf, sym = symbase; bufp < endbufp; ++bufp)
3716     {
3717
3718       /* I don't think we care about these.  */
3719       if (bufp->symbol_type == ST_SYM_EXT
3720           || bufp->symbol_type == ST_ARG_EXT)
3721         continue;
3722
3723       /* Set some private data we care about.  */
3724       if (bufp->symbol_type == ST_NULL)
3725         som_symbol_data (sym)->som_type = SYMBOL_TYPE_UNKNOWN;
3726       else if (bufp->symbol_type == ST_ABSOLUTE)
3727         som_symbol_data (sym)->som_type = SYMBOL_TYPE_ABSOLUTE;
3728       else if (bufp->symbol_type == ST_DATA)
3729         som_symbol_data (sym)->som_type = SYMBOL_TYPE_DATA;
3730       else if (bufp->symbol_type == ST_CODE)
3731         som_symbol_data (sym)->som_type = SYMBOL_TYPE_CODE;
3732       else if (bufp->symbol_type == ST_PRI_PROG)
3733         som_symbol_data (sym)->som_type = SYMBOL_TYPE_PRI_PROG;
3734       else if (bufp->symbol_type == ST_SEC_PROG)
3735         som_symbol_data (sym)->som_type = SYMBOL_TYPE_SEC_PROG;
3736       else if (bufp->symbol_type == ST_ENTRY)
3737         som_symbol_data (sym)->som_type = SYMBOL_TYPE_ENTRY;
3738       else if (bufp->symbol_type == ST_MILLICODE)
3739         som_symbol_data (sym)->som_type = SYMBOL_TYPE_MILLICODE;
3740       else if (bufp->symbol_type == ST_PLABEL)
3741         som_symbol_data (sym)->som_type = SYMBOL_TYPE_PLABEL;
3742       else
3743         som_symbol_data (sym)->som_type = SYMBOL_TYPE_UNKNOWN;
3744       som_symbol_data (sym)->tc_data.hppa_arg_reloc = bufp->arg_reloc;
3745
3746       /* Some reasonable defaults.  */
3747       sym->symbol.the_bfd = abfd;
3748       sym->symbol.name = bufp->name.n_strx + stringtab;
3749       sym->symbol.value = bufp->symbol_value;
3750       sym->symbol.section = 0;
3751       sym->symbol.flags = 0;
3752
3753       switch (bufp->symbol_type)
3754         {
3755         case ST_ENTRY:
3756         case ST_PRI_PROG:
3757         case ST_SEC_PROG:
3758         case ST_MILLICODE:
3759           sym->symbol.flags |= BSF_FUNCTION;
3760           sym->symbol.value &= ~0x3;
3761           break;
3762
3763         case ST_STUB:
3764         case ST_CODE:
3765           sym->symbol.value &= ~0x3;
3766
3767         default:
3768           break;
3769         }
3770
3771       /* Handle scoping and section information.  */
3772       switch (bufp->symbol_scope)
3773         {
3774         /* symbol_info field is undefined for SS_EXTERNAL and SS_UNSAT symbols,
3775            so the section associated with this symbol can't be known.  */
3776         case SS_EXTERNAL:
3777           if (bufp->symbol_type != ST_STORAGE)
3778             sym->symbol.section = bfd_und_section_ptr;
3779           else
3780             sym->symbol.section = bfd_com_section_ptr;
3781           sym->symbol.flags |= (BSF_EXPORT | BSF_GLOBAL);
3782           break;
3783
3784         case SS_UNSAT:
3785           if (bufp->symbol_type != ST_STORAGE)
3786             sym->symbol.section = bfd_und_section_ptr;
3787           else
3788             sym->symbol.section = bfd_com_section_ptr;
3789           break;
3790
3791         case SS_UNIVERSAL:
3792           sym->symbol.flags |= (BSF_EXPORT | BSF_GLOBAL);
3793           sym->symbol.section = bfd_section_from_som_symbol (abfd, bufp);
3794           sym->symbol.value -= sym->symbol.section->vma;
3795           break;
3796
3797 #if 0
3798         /* SS_GLOBAL and SS_LOCAL are two names for the same thing.
3799            Sound dumb?  It is.  */
3800         case SS_GLOBAL:
3801 #endif
3802         case SS_LOCAL:
3803           sym->symbol.flags |= BSF_LOCAL;
3804           sym->symbol.section = bfd_section_from_som_symbol (abfd, bufp);
3805           sym->symbol.value -= sym->symbol.section->vma;
3806           break;
3807         }
3808
3809       /* Mark section symbols and symbols used by the debugger.  */
3810       if (sym->symbol.name[0] == '$'
3811           && sym->symbol.name[strlen (sym->symbol.name) - 1] == '$')
3812         sym->symbol.flags |= BSF_SECTION_SYM;
3813       else if (!strncmp (sym->symbol.name, "L$0\002", 4))
3814         {
3815           sym->symbol.flags |= BSF_SECTION_SYM;
3816           sym->symbol.name = sym->symbol.section->name;
3817         }
3818       else if (!strncmp (sym->symbol.name, "L$0\001", 4))
3819         sym->symbol.flags |= BSF_DEBUGGING;
3820
3821       /* Note increment at bottom of loop, since we skip some symbols
3822          we can not include it as part of the for statement.  */
3823       sym++;
3824     }
3825
3826   /* Save our results and return success.  */
3827   obj_som_symtab (abfd) = symbase;
3828  successful_return:
3829   if (buf != NULL)
3830     free (buf);
3831   return (true);
3832
3833  error_return:
3834   if (buf != NULL)
3835     free (buf);
3836   return false;
3837 }
3838
3839 /* Canonicalize a SOM symbol table.  Return the number of entries
3840    in the symbol table.  */
3841
3842 static long
3843 som_get_symtab (abfd, location)
3844      bfd *abfd;
3845      asymbol **location;
3846 {
3847   int i;
3848   som_symbol_type *symbase;
3849
3850   if (!som_slurp_symbol_table (abfd))
3851     return -1;
3852
3853   i = bfd_get_symcount (abfd);
3854   symbase = obj_som_symtab (abfd);
3855
3856   for (; i > 0; i--, location++, symbase++)
3857     *location = &symbase->symbol;
3858
3859   /* Final null pointer.  */
3860   *location = 0;
3861   return (bfd_get_symcount (abfd));
3862 }
3863
3864 /* Make a SOM symbol.  There is nothing special to do here.  */
3865
3866 static asymbol *
3867 som_make_empty_symbol (abfd)
3868      bfd *abfd;
3869 {
3870   som_symbol_type *new =
3871   (som_symbol_type *) bfd_zalloc (abfd, sizeof (som_symbol_type));
3872   if (new == NULL)
3873     {
3874       bfd_set_error (bfd_error_no_memory);
3875       return 0;
3876     }
3877   new->symbol.the_bfd = abfd;
3878
3879   return &new->symbol;
3880 }
3881
3882 /* Print symbol information.  */
3883
3884 static void
3885 som_print_symbol (ignore_abfd, afile, symbol, how)
3886      bfd *ignore_abfd;
3887      PTR afile;
3888      asymbol *symbol;
3889      bfd_print_symbol_type how;
3890 {
3891   FILE *file = (FILE *) afile;
3892   switch (how)
3893     {
3894     case bfd_print_symbol_name:
3895       fprintf (file, "%s", symbol->name);
3896       break;
3897     case bfd_print_symbol_more:
3898       fprintf (file, "som ");
3899       fprintf_vma (file, symbol->value);
3900       fprintf (file, " %lx", (long) symbol->flags);
3901       break;
3902     case bfd_print_symbol_all:
3903       {
3904         CONST char *section_name;
3905         section_name = symbol->section ? symbol->section->name : "(*none*)";
3906         bfd_print_symbol_vandf ((PTR) file, symbol);
3907         fprintf (file, " %s\t%s", section_name, symbol->name);
3908         break;
3909       }
3910     }
3911 }
3912
3913 static boolean
3914 som_bfd_is_local_label (abfd, sym)
3915      bfd *abfd;
3916      asymbol *sym;
3917 {
3918   return (sym->name[0] == 'L' && sym->name[1] == '$');
3919 }
3920
3921 /* Count or process variable-length SOM fixup records.
3922
3923    To avoid code duplication we use this code both to compute the number
3924    of relocations requested by a stream, and to internalize the stream.
3925
3926    When computing the number of relocations requested by a stream the
3927    variables rptr, section, and symbols have no meaning.
3928
3929    Return the number of relocations requested by the fixup stream.  When
3930    not just counting 
3931
3932    This needs at least two or three more passes to get it cleaned up.  */
3933
3934 static unsigned int
3935 som_set_reloc_info (fixup, end, internal_relocs, section, symbols, just_count)
3936      unsigned char *fixup;
3937      unsigned int end;
3938      arelent *internal_relocs;
3939      asection *section;
3940      asymbol **symbols;
3941      boolean just_count;
3942 {
3943   unsigned int op, varname;
3944   unsigned char *end_fixups = &fixup[end];
3945   const struct fixup_format *fp;
3946   char *cp;
3947   unsigned char *save_fixup;
3948   int variables[26], stack[20], c, v, count, prev_fixup, *sp;
3949   const int *subop;
3950   arelent *rptr= internal_relocs;
3951   unsigned int offset = just_count ? 0 : section->vma;
3952
3953 #define var(c)          variables[(c) - 'A']
3954 #define push(v)         (*sp++ = (v))
3955 #define pop()           (*--sp)
3956 #define emptystack()    (sp == stack)
3957
3958   som_initialize_reloc_queue (reloc_queue);
3959   memset (variables, 0, sizeof (variables));
3960   memset (stack, 0, sizeof (stack));
3961   count = 0;
3962   prev_fixup = 0;
3963   sp = stack;
3964
3965   while (fixup < end_fixups)
3966     {
3967
3968       /* Save pointer to the start of this fixup.  We'll use
3969          it later to determine if it is necessary to put this fixup
3970          on the queue.  */
3971       save_fixup = fixup;
3972
3973       /* Get the fixup code and its associated format.  */
3974       op = *fixup++;
3975       fp = &som_fixup_formats[op];
3976
3977       /* Handle a request for a previous fixup.  */
3978       if (*fp->format == 'P')
3979         {
3980           /* Get pointer to the beginning of the prev fixup, move
3981              the repeated fixup to the head of the queue.  */
3982           fixup = reloc_queue[fp->D].reloc;
3983           som_reloc_queue_fix (reloc_queue, fp->D);
3984           prev_fixup = 1;
3985
3986           /* Get the fixup code and its associated format.  */
3987           op = *fixup++;
3988           fp = &som_fixup_formats[op];
3989         }
3990
3991       /* If this fixup will be passed to BFD, set some reasonable defaults.  */
3992       if (! just_count
3993           && som_hppa_howto_table[op].type != R_NO_RELOCATION
3994           && som_hppa_howto_table[op].type != R_DATA_OVERRIDE)
3995         {
3996           rptr->address = offset;
3997           rptr->howto = &som_hppa_howto_table[op];
3998           rptr->addend = 0;
3999           rptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
4000         }
4001
4002       /* Set default input length to 0.  Get the opcode class index
4003          into D.  */
4004       var ('L') = 0;
4005       var ('D') = fp->D;
4006
4007       /* Get the opcode format.  */
4008       cp = fp->format;
4009
4010       /* Process the format string.  Parsing happens in two phases,
4011          parse RHS, then assign to LHS.  Repeat until no more 
4012          characters in the format string.  */
4013       while (*cp)
4014         {
4015           /* The variable this pass is going to compute a value for.  */
4016           varname = *cp++;
4017
4018           /* Start processing RHS.  Continue until a NULL or '=' is found.  */
4019           do
4020             {
4021               c = *cp++;
4022
4023               /* If this is a variable, push it on the stack.  */
4024               if (isupper (c))
4025                 push (var (c));
4026
4027               /* If this is a lower case letter, then it represents
4028                  additional data from the fixup stream to be pushed onto
4029                  the stack.  */
4030               else if (islower (c))
4031                 {
4032                   for (v = 0; c > 'a'; --c)
4033                     v = (v << 8) | *fixup++;
4034                   push (v);
4035                 }
4036
4037               /* A decimal constant.  Push it on the stack.  */
4038               else if (isdigit (c))
4039                 {
4040                   v = c - '0';
4041                   while (isdigit (*cp))
4042                     v = (v * 10) + (*cp++ - '0');
4043                   push (v);
4044                 }
4045               else
4046
4047                 /* An operator.  Pop two two values from the stack and
4048                    use them as operands to the given operation.  Push
4049                    the result of the operation back on the stack.  */
4050                 switch (c)
4051                   {
4052                   case '+':
4053                     v = pop ();
4054                     v += pop ();
4055                     push (v);
4056                     break;
4057                   case '*':
4058                     v = pop ();
4059                     v *= pop ();
4060                     push (v);
4061                     break;
4062                   case '<':
4063                     v = pop ();
4064                     v = pop () << v;
4065                     push (v);
4066                     break;
4067                   default:
4068                     abort ();
4069                   }
4070             }
4071           while (*cp && *cp != '=');
4072
4073           /* Move over the equal operator.  */
4074           cp++;
4075
4076           /* Pop the RHS off the stack.  */
4077           c = pop ();
4078
4079           /* Perform the assignment.  */
4080           var (varname) = c;
4081
4082           /* Handle side effects. and special 'O' stack cases.  */
4083           switch (varname)
4084             {
4085             /* Consume some bytes from the input space.  */
4086             case 'L':
4087               offset += c;
4088               break;
4089             /* A symbol to use in the relocation.  Make a note
4090                of this if we are not just counting.  */
4091             case 'S':
4092               if (! just_count)
4093                 rptr->sym_ptr_ptr = &symbols[c];
4094               break;
4095             /* Handle the linker expression stack.  */
4096             case 'O':
4097               switch (op)
4098                 {
4099                 case R_COMP1:
4100                   subop = comp1_opcodes;
4101                   break;
4102                 case R_COMP2:
4103                   subop = comp2_opcodes;
4104                   break;
4105                 case R_COMP3:
4106                   subop = comp3_opcodes;
4107                   break;
4108                 default:
4109                   abort ();
4110                 }
4111               while (*subop <= (unsigned char) c)
4112                 ++subop;
4113               --subop;
4114               break;
4115             default:
4116               break;
4117             }
4118         }
4119
4120       /* If we used a previous fixup, clean up after it.  */
4121       if (prev_fixup)
4122         {
4123           fixup = save_fixup + 1;
4124           prev_fixup = 0;
4125         }
4126       /* Queue it.  */
4127       else if (fixup > save_fixup + 1)
4128         som_reloc_queue_insert (save_fixup, fixup - save_fixup, reloc_queue);
4129
4130       /* We do not pass R_DATA_OVERRIDE or R_NO_RELOCATION 
4131          fixups to BFD.  */
4132       if (som_hppa_howto_table[op].type != R_DATA_OVERRIDE
4133           && som_hppa_howto_table[op].type != R_NO_RELOCATION)
4134         {
4135           /* Done with a single reloction. Loop back to the top.  */
4136           if (! just_count)
4137             {
4138               rptr->addend = var ('V');
4139               rptr++;
4140             }
4141           count++;
4142           /* Now that we've handled a "full" relocation, reset
4143              some state.  */
4144           memset (variables, 0, sizeof (variables));
4145           memset (stack, 0, sizeof (stack));
4146         }
4147     }
4148   return count;
4149
4150 #undef var
4151 #undef push
4152 #undef pop
4153 #undef emptystack
4154 }
4155
4156 /* Read in the relocs (aka fixups in SOM terms) for a section. 
4157
4158    som_get_reloc_upper_bound calls this routine with JUST_COUNT 
4159    set to true to indicate it only needs a count of the number
4160    of actual relocations.  */
4161
4162 static boolean
4163 som_slurp_reloc_table (abfd, section, symbols, just_count)
4164      bfd *abfd;
4165      asection *section;
4166      asymbol **symbols;
4167      boolean just_count;
4168 {
4169   char *external_relocs;
4170   unsigned int fixup_stream_size;
4171   arelent *internal_relocs;
4172   unsigned int num_relocs;
4173
4174   fixup_stream_size = som_section_data (section)->reloc_size;
4175   /* If there were no relocations, then there is nothing to do.  */
4176   if (section->reloc_count == 0)
4177     return true;
4178
4179   /* If reloc_count is -1, then the relocation stream has not been 
4180      parsed.  We must do so now to know how many relocations exist.  */
4181   if (section->reloc_count == -1)
4182     {
4183       external_relocs = (char *) malloc (fixup_stream_size);
4184       if (external_relocs == (char *) NULL)
4185         {
4186           bfd_set_error (bfd_error_no_memory);
4187           return false;
4188         }
4189       /* Read in the external forms. */
4190       if (bfd_seek (abfd,
4191                     obj_som_reloc_filepos (abfd) + section->rel_filepos,
4192                     SEEK_SET)
4193           != 0)
4194         return false;
4195       if (bfd_read (external_relocs, 1, fixup_stream_size, abfd)
4196           != fixup_stream_size)
4197         return false;
4198
4199       /* Let callers know how many relocations found.
4200          also save the relocation stream as we will
4201          need it again.  */
4202       section->reloc_count = som_set_reloc_info (external_relocs,
4203                                                  fixup_stream_size,
4204                                                  NULL, NULL, NULL, true);
4205
4206       som_section_data (section)->reloc_stream = external_relocs;
4207     }
4208
4209   /* If the caller only wanted a count, then return now.  */
4210   if (just_count)
4211     return true;
4212
4213   num_relocs = section->reloc_count;
4214   external_relocs = som_section_data (section)->reloc_stream;
4215   /* Return saved information about the relocations if it is available.  */
4216   if (section->relocation != (arelent *) NULL)
4217     return true;
4218
4219   internal_relocs = (arelent *) malloc (num_relocs * sizeof (arelent));
4220   if (internal_relocs == (arelent *) NULL)
4221     {
4222       bfd_set_error (bfd_error_no_memory);
4223       return false;
4224     }
4225
4226   /* Process and internalize the relocations.  */
4227   som_set_reloc_info (external_relocs, fixup_stream_size,
4228                       internal_relocs, section, symbols, false);
4229
4230   /* Save our results and return success.  */
4231   section->relocation = internal_relocs;
4232   return (true);
4233 }
4234
4235 /* Return the number of bytes required to store the relocation
4236    information associated with the given section.  */ 
4237
4238 static long
4239 som_get_reloc_upper_bound (abfd, asect)
4240      bfd *abfd;
4241      sec_ptr asect;
4242 {
4243   /* If section has relocations, then read in the relocation stream
4244      and parse it to determine how many relocations exist.  */
4245   if (asect->flags & SEC_RELOC)
4246     {
4247       if (! som_slurp_reloc_table (abfd, asect, NULL, true))
4248         return false;
4249       return (asect->reloc_count + 1) * sizeof (arelent);
4250     }
4251   /* There are no relocations.  */
4252   return 0;
4253 }
4254
4255 /* Convert relocations from SOM (external) form into BFD internal
4256    form.  Return the number of relocations.  */
4257
4258 static long
4259 som_canonicalize_reloc (abfd, section, relptr, symbols)
4260      bfd *abfd;
4261      sec_ptr section;
4262      arelent **relptr;
4263      asymbol **symbols;
4264 {
4265   arelent *tblptr;
4266   int count;
4267
4268   if (som_slurp_reloc_table (abfd, section, symbols, false) == false)
4269     return -1;
4270
4271   count = section->reloc_count;
4272   tblptr = section->relocation;
4273
4274   while (count--)
4275     *relptr++ = tblptr++;
4276
4277   *relptr = (arelent *) NULL;
4278   return section->reloc_count;
4279 }
4280
4281 extern const bfd_target som_vec;
4282
4283 /* A hook to set up object file dependent section information.  */
4284
4285 static boolean
4286 som_new_section_hook (abfd, newsect)
4287      bfd *abfd;
4288      asection *newsect;
4289 {
4290   newsect->used_by_bfd =
4291     (PTR) bfd_zalloc (abfd, sizeof (struct som_section_data_struct));
4292   if (!newsect->used_by_bfd)
4293     {
4294       bfd_set_error (bfd_error_no_memory);
4295       return false;
4296     }
4297   newsect->alignment_power = 3;
4298
4299   /* We allow more than three sections internally */
4300   return true;
4301 }
4302
4303 /* Copy any private info we understand from the input section
4304    to the output section.  */
4305 static boolean
4306 som_bfd_copy_private_section_data (ibfd, isection, obfd, osection)
4307      bfd *ibfd;
4308      asection *isection;
4309      bfd *obfd;
4310      asection *osection;
4311 {
4312   /* One day we may try to grok other private data.  */
4313   if (ibfd->xvec->flavour != bfd_target_som_flavour
4314       || obfd->xvec->flavour != bfd_target_som_flavour
4315       || (!som_is_space (isection) && !som_is_subspace (isection)))
4316     return false;
4317
4318   som_section_data (osection)->copy_data
4319     = (struct som_copyable_section_data_struct *)
4320       bfd_zalloc (obfd, sizeof (struct som_copyable_section_data_struct));
4321   if (som_section_data (osection)->copy_data == NULL)
4322     {
4323       bfd_set_error (bfd_error_no_memory);
4324       return false;
4325     }
4326
4327   memcpy (som_section_data (osection)->copy_data,
4328           som_section_data (isection)->copy_data,
4329           sizeof (struct som_copyable_section_data_struct));
4330
4331   /* Reparent if necessary.  */
4332   if (som_section_data (osection)->copy_data->container)
4333     som_section_data (osection)->copy_data->container =
4334       som_section_data (osection)->copy_data->container->output_section;
4335
4336   return true;
4337 }
4338
4339 /* Copy any private info we understand from the input bfd
4340    to the output bfd.  */
4341
4342 static boolean
4343 som_bfd_copy_private_bfd_data (ibfd, obfd)
4344      bfd *ibfd, *obfd;
4345 {
4346   /* One day we may try to grok other private data.  */
4347   if (ibfd->xvec->flavour != bfd_target_som_flavour
4348       || obfd->xvec->flavour != bfd_target_som_flavour)
4349     return false;
4350
4351   /* Allocate some memory to hold the data we need.  */
4352   obj_som_exec_data (obfd) = (struct som_exec_data *)
4353     bfd_zalloc (obfd, sizeof (struct som_exec_data));
4354   if (obj_som_exec_data (obfd) == NULL)
4355     {
4356       bfd_set_error (bfd_error_no_memory);
4357       return false;
4358     }
4359
4360   /* Now copy the data.  */
4361   memcpy (obj_som_exec_data (obfd), obj_som_exec_data (ibfd),
4362           sizeof (struct som_exec_data));
4363
4364   return true;
4365 }
4366
4367 /* Set backend info for sections which can not be described
4368    in the BFD data structures.  */
4369
4370 boolean
4371 bfd_som_set_section_attributes (section, defined, private, sort_key, spnum)
4372      asection *section;
4373      int defined;
4374      int private;
4375      unsigned int sort_key;
4376      int spnum;
4377 {
4378   /* Allocate memory to hold the magic information.  */
4379   if (som_section_data (section)->copy_data == NULL)
4380     {
4381       som_section_data (section)->copy_data
4382         = (struct som_copyable_section_data_struct *)
4383           bfd_zalloc (section->owner,
4384                       sizeof (struct som_copyable_section_data_struct));
4385       if (som_section_data (section)->copy_data == NULL)
4386         {
4387           bfd_set_error (bfd_error_no_memory);
4388           return false;
4389         }
4390     }
4391   som_section_data (section)->copy_data->sort_key = sort_key;
4392   som_section_data (section)->copy_data->is_defined = defined;
4393   som_section_data (section)->copy_data->is_private = private;
4394   som_section_data (section)->copy_data->container = section;
4395   som_section_data (section)->copy_data->space_number = spnum;
4396   return true;
4397 }
4398
4399 /* Set backend info for subsections which can not be described 
4400    in the BFD data structures.  */
4401
4402 boolean
4403 bfd_som_set_subsection_attributes (section, container, access,
4404                                    sort_key, quadrant)
4405      asection *section;
4406      asection *container;
4407      int access;
4408      unsigned int sort_key;
4409      int quadrant;
4410 {
4411   /* Allocate memory to hold the magic information.  */
4412   if (som_section_data (section)->copy_data == NULL)
4413     {
4414       som_section_data (section)->copy_data
4415         = (struct som_copyable_section_data_struct *)
4416           bfd_zalloc (section->owner,
4417                       sizeof (struct som_copyable_section_data_struct));
4418       if (som_section_data (section)->copy_data == NULL)
4419         {
4420           bfd_set_error (bfd_error_no_memory);
4421           return false;
4422         }
4423     }
4424   som_section_data (section)->copy_data->sort_key = sort_key;
4425   som_section_data (section)->copy_data->access_control_bits = access;
4426   som_section_data (section)->copy_data->quadrant = quadrant;
4427   som_section_data (section)->copy_data->container = container;
4428   return true;
4429 }
4430
4431 /* Set the full SOM symbol type.  SOM needs far more symbol information
4432    than any other object file format I'm aware of.  It is mandatory
4433    to be able to know if a symbol is an entry point, millicode, data,
4434    code, absolute, storage request, or procedure label.  If you get
4435    the symbol type wrong your program will not link.  */
4436
4437 void
4438 bfd_som_set_symbol_type (symbol, type)
4439      asymbol *symbol;
4440      unsigned int type;
4441 {
4442   som_symbol_data (symbol)->som_type = type;
4443 }
4444
4445 /* Attach 64bits of unwind information to a symbol (which hopefully
4446    is a function of some kind!).  It would be better to keep this
4447    in the R_ENTRY relocation, but there is not enough space.  */
4448
4449 void
4450 bfd_som_attach_unwind_info (symbol, unwind_desc)
4451      asymbol *symbol;
4452      char *unwind_desc;
4453 {
4454   som_symbol_data (symbol)->unwind = unwind_desc;
4455 }
4456
4457 /* Attach an auxiliary header to the BFD backend so that it may be
4458    written into the object file.  */
4459 boolean
4460 bfd_som_attach_aux_hdr (abfd, type, string)
4461      bfd *abfd;
4462      int type;
4463      char *string;
4464 {
4465   if (type == VERSION_AUX_ID)
4466     {
4467       int len = strlen (string);
4468       int pad = 0;
4469
4470       if (len % 4)
4471         pad = (4 - (len % 4));
4472       obj_som_version_hdr (abfd) = (struct user_string_aux_hdr *)
4473         bfd_zalloc (abfd, sizeof (struct aux_id)
4474                               + sizeof (unsigned int) + len + pad);
4475       if (!obj_som_version_hdr (abfd))
4476         {
4477           bfd_set_error (bfd_error_no_memory);
4478           return false;
4479         }
4480       obj_som_version_hdr (abfd)->header_id.type = VERSION_AUX_ID;
4481       obj_som_version_hdr (abfd)->header_id.length = len + pad;
4482       obj_som_version_hdr (abfd)->header_id.length += sizeof (int);
4483       obj_som_version_hdr (abfd)->string_length = len;
4484       strncpy (obj_som_version_hdr (abfd)->user_string, string, len);
4485     }
4486   else if (type == COPYRIGHT_AUX_ID)
4487     {
4488       int len = strlen (string);
4489       int pad = 0;
4490
4491       if (len % 4)
4492         pad = (4 - (len % 4));
4493       obj_som_copyright_hdr (abfd) = (struct copyright_aux_hdr *)
4494         bfd_zalloc (abfd, sizeof (struct aux_id)
4495                             + sizeof (unsigned int) + len + pad);
4496       if (!obj_som_copyright_hdr (abfd))
4497         {
4498           bfd_set_error (bfd_error_no_memory);
4499           return false;
4500         }
4501       obj_som_copyright_hdr (abfd)->header_id.type = COPYRIGHT_AUX_ID;
4502       obj_som_copyright_hdr (abfd)->header_id.length = len + pad;
4503       obj_som_copyright_hdr (abfd)->header_id.length += sizeof (int);
4504       obj_som_copyright_hdr (abfd)->string_length = len;
4505       strcpy (obj_som_copyright_hdr (abfd)->copyright, string);
4506     }
4507   return true;
4508 }
4509
4510 static boolean
4511 som_get_section_contents (abfd, section, location, offset, count)
4512      bfd *abfd;
4513      sec_ptr section;
4514      PTR location;
4515      file_ptr offset;
4516      bfd_size_type count;
4517 {
4518   if (count == 0 || ((section->flags & (SEC_LOAD | SEC_DEBUGGING)) == 0))
4519     return true;
4520   if ((bfd_size_type)(offset+count) > section->_raw_size
4521       || bfd_seek (abfd, (file_ptr)(section->filepos + offset), SEEK_SET) == -1
4522       || bfd_read (location, (bfd_size_type)1, count, abfd) != count)
4523     return (false); /* on error */
4524   return (true);
4525 }
4526
4527 static boolean
4528 som_set_section_contents (abfd, section, location, offset, count)
4529      bfd *abfd;
4530      sec_ptr section;
4531      PTR location;
4532      file_ptr offset;
4533      bfd_size_type count;
4534 {
4535   if (abfd->output_has_begun == false)
4536     {
4537       /* Set up fixed parts of the file, space, and subspace headers.
4538          Notify the world that output has begun.  */
4539       som_prep_headers (abfd);
4540       abfd->output_has_begun = true;
4541       /* Start writing the object file.  This include all the string
4542          tables, fixup streams, and other portions of the object file.  */
4543       som_begin_writing (abfd);
4544     }
4545
4546   /* Only write subspaces which have "real" contents (eg. the contents
4547      are not generated at run time by the OS).  */
4548   if (!som_is_subspace (section)
4549       || ((section->flags & (SEC_LOAD | SEC_DEBUGGING)) == 0))
4550     return true;
4551
4552   /* Seek to the proper offset within the object file and write the
4553      data.  */
4554   offset += som_section_data (section)->subspace_dict->file_loc_init_value; 
4555   if (bfd_seek (abfd, offset, SEEK_SET) == -1)
4556     return false;
4557
4558   if (bfd_write ((PTR) location, 1, count, abfd) != count)
4559     return false;
4560   return true;
4561 }
4562
4563 static boolean
4564 som_set_arch_mach (abfd, arch, machine)
4565      bfd *abfd;
4566      enum bfd_architecture arch;
4567      unsigned long machine;
4568 {
4569   /* Allow any architecture to be supported by the SOM backend */
4570   return bfd_default_set_arch_mach (abfd, arch, machine);
4571 }
4572
4573 static boolean
4574 som_find_nearest_line (abfd, section, symbols, offset, filename_ptr,
4575                         functionname_ptr, line_ptr)
4576      bfd *abfd;
4577      asection *section;
4578      asymbol **symbols;
4579      bfd_vma offset;
4580      CONST char **filename_ptr;
4581      CONST char **functionname_ptr;
4582      unsigned int *line_ptr;
4583 {
4584   fprintf (stderr, "som_find_nearest_line unimplemented\n");
4585   fflush (stderr);
4586   abort ();
4587   return (false);
4588 }
4589
4590 static int
4591 som_sizeof_headers (abfd, reloc)
4592      bfd *abfd;
4593      boolean reloc;
4594 {
4595   fprintf (stderr, "som_sizeof_headers unimplemented\n");
4596   fflush (stderr);
4597   abort ();
4598   return (0);
4599 }
4600
4601 /* Return the single-character symbol type corresponding to
4602    SOM section S, or '?' for an unknown SOM section.  */
4603
4604 static char
4605 som_section_type (s)
4606      const char *s;
4607 {
4608   const struct section_to_type *t;
4609
4610   for (t = &stt[0]; t->section; t++)
4611     if (!strcmp (s, t->section))
4612       return t->type;
4613   return '?';
4614 }
4615
4616 static int
4617 som_decode_symclass (symbol)
4618      asymbol *symbol;
4619 {
4620   char c;
4621
4622   if (bfd_is_com_section (symbol->section))
4623     return 'C';
4624   if (bfd_is_und_section (symbol->section))
4625     return 'U';
4626   if (bfd_is_ind_section (symbol->section))
4627     return 'I';
4628   if (!(symbol->flags & (BSF_GLOBAL|BSF_LOCAL)))
4629     return '?';
4630
4631   if (bfd_is_abs_section (symbol->section))
4632     c = 'a';
4633   else if (symbol->section)
4634     c = som_section_type (symbol->section->name);
4635   else
4636     return '?';
4637   if (symbol->flags & BSF_GLOBAL)
4638     c = toupper (c);
4639   return c;
4640 }
4641
4642 /* Return information about SOM symbol SYMBOL in RET.  */
4643
4644 static void
4645 som_get_symbol_info (ignore_abfd, symbol, ret)
4646      bfd *ignore_abfd;
4647      asymbol *symbol;
4648      symbol_info *ret;
4649 {
4650   ret->type = som_decode_symclass (symbol);
4651   if (ret->type != 'U')
4652     ret->value = symbol->value+symbol->section->vma;
4653   else
4654     ret->value = 0;
4655   ret->name = symbol->name;
4656 }
4657
4658 /* Count the number of symbols in the archive symbol table.  Necessary
4659    so that we can allocate space for all the carsyms at once.  */
4660
4661 static boolean
4662 som_bfd_count_ar_symbols (abfd, lst_header, count)
4663      bfd *abfd;
4664      struct lst_header *lst_header;
4665      symindex *count;
4666 {
4667   unsigned int i;
4668   unsigned int *hash_table = NULL;
4669   file_ptr lst_filepos = bfd_tell (abfd) - sizeof (struct lst_header);
4670
4671   hash_table = 
4672     (unsigned int *) malloc (lst_header->hash_size * sizeof (unsigned int));
4673   if (hash_table == NULL && lst_header->hash_size != 0)
4674     {
4675       bfd_set_error (bfd_error_no_memory);
4676       goto error_return;
4677     }
4678
4679   /* Don't forget to initialize the counter!  */
4680   *count = 0;
4681
4682   /* Read in the hash table.  The has table is an array of 32bit file offsets
4683      which point to the hash chains.  */
4684   if (bfd_read ((PTR) hash_table, lst_header->hash_size, 4, abfd)
4685       != lst_header->hash_size * 4)
4686     goto error_return;
4687
4688   /* Walk each chain counting the number of symbols found on that particular
4689      chain.  */
4690   for (i = 0; i < lst_header->hash_size; i++)
4691     {
4692       struct lst_symbol_record lst_symbol;
4693
4694       /* An empty chain has zero as it's file offset.  */
4695       if (hash_table[i] == 0)
4696         continue;
4697
4698       /* Seek to the first symbol in this hash chain.  */
4699       if (bfd_seek (abfd, lst_filepos + hash_table[i], SEEK_SET) < 0)
4700         goto error_return;
4701
4702       /* Read in this symbol and update the counter.  */
4703       if (bfd_read ((PTR) & lst_symbol, 1, sizeof (lst_symbol), abfd)
4704           != sizeof (lst_symbol))
4705         goto error_return;
4706
4707       (*count)++;
4708
4709       /* Now iterate through the rest of the symbols on this chain.  */
4710       while (lst_symbol.next_entry)
4711         {
4712
4713           /* Seek to the next symbol.  */
4714           if (bfd_seek (abfd, lst_filepos + lst_symbol.next_entry, SEEK_SET)
4715               < 0)
4716             goto error_return;
4717
4718           /* Read the symbol in and update the counter.  */
4719           if (bfd_read ((PTR) & lst_symbol, 1, sizeof (lst_symbol), abfd)
4720               != sizeof (lst_symbol))
4721             goto error_return;
4722
4723           (*count)++;
4724         }
4725     }
4726   if (hash_table != NULL)
4727     free (hash_table);
4728   return true;
4729
4730  error_return:
4731   if (hash_table != NULL)
4732     free (hash_table);
4733   return false;
4734 }
4735
4736 /* Fill in the canonical archive symbols (SYMS) from the archive described
4737    by ABFD and LST_HEADER.  */
4738
4739 static boolean
4740 som_bfd_fill_in_ar_symbols (abfd, lst_header, syms)
4741      bfd *abfd;
4742      struct lst_header *lst_header;
4743      carsym **syms;
4744 {
4745   unsigned int i, len;
4746   carsym *set = syms[0];
4747   unsigned int *hash_table = NULL;
4748   struct som_entry *som_dict = NULL;
4749   file_ptr lst_filepos = bfd_tell (abfd) - sizeof (struct lst_header);
4750
4751   hash_table = 
4752     (unsigned int *) malloc (lst_header->hash_size * sizeof (unsigned int));
4753   if (hash_table == NULL && lst_header->hash_size != 0)
4754     {
4755       bfd_set_error (bfd_error_no_memory);
4756       goto error_return;
4757     }
4758
4759   som_dict =
4760     (struct som_entry *) malloc (lst_header->module_count
4761                                  * sizeof (struct som_entry));
4762   if (som_dict == NULL && lst_header->module_count != 0)
4763     {
4764       bfd_set_error (bfd_error_no_memory);
4765       goto error_return;
4766     }
4767
4768   /* Read in the hash table.  The has table is an array of 32bit file offsets
4769      which point to the hash chains.  */
4770   if (bfd_read ((PTR) hash_table, lst_header->hash_size, 4, abfd)
4771       != lst_header->hash_size * 4)
4772     goto error_return;
4773
4774   /* Seek to and read in the SOM dictionary.  We will need this to fill
4775      in the carsym's filepos field.  */
4776   if (bfd_seek (abfd, lst_filepos + lst_header->dir_loc, SEEK_SET) < 0)
4777     goto error_return;
4778
4779   if (bfd_read ((PTR) som_dict, lst_header->module_count, 
4780                 sizeof (struct som_entry), abfd)
4781       != lst_header->module_count * sizeof (struct som_entry))
4782     goto error_return;
4783
4784   /* Walk each chain filling in the carsyms as we go along.  */
4785   for (i = 0; i < lst_header->hash_size; i++)
4786     {
4787       struct lst_symbol_record lst_symbol;
4788
4789       /* An empty chain has zero as it's file offset.  */
4790       if (hash_table[i] == 0)
4791         continue;
4792
4793       /* Seek to and read the first symbol on the chain.  */
4794       if (bfd_seek (abfd, lst_filepos + hash_table[i], SEEK_SET) < 0)
4795         goto error_return;
4796
4797       if (bfd_read ((PTR) & lst_symbol, 1, sizeof (lst_symbol), abfd)
4798           != sizeof (lst_symbol))
4799         goto error_return;
4800
4801       /* Get the name of the symbol, first get the length which is stored
4802          as a 32bit integer just before the symbol.
4803
4804          One might ask why we don't just read in the entire string table
4805          and index into it.  Well, according to the SOM ABI the string
4806          index can point *anywhere* in the archive to save space, so just
4807          using the string table would not be safe.  */
4808       if (bfd_seek (abfd, lst_filepos + lst_header->string_loc
4809                             + lst_symbol.name.n_strx - 4, SEEK_SET) < 0)
4810         goto error_return;
4811
4812       if (bfd_read (&len, 1, 4, abfd) != 4)
4813         goto error_return;
4814
4815       /* Allocate space for the name and null terminate it too.  */
4816       set->name = bfd_zalloc (abfd, len + 1);
4817       if (!set->name)
4818         {
4819           bfd_set_error (bfd_error_no_memory);
4820           goto error_return;
4821         }
4822       if (bfd_read (set->name, 1, len, abfd) != len)
4823         goto error_return;
4824
4825       set->name[len] = 0;
4826
4827       /* Fill in the file offset.  Note that the "location" field points
4828          to the SOM itself, not the ar_hdr in front of it.  */
4829       set->file_offset = som_dict[lst_symbol.som_index].location
4830                           - sizeof (struct ar_hdr);
4831
4832       /* Go to the next symbol.  */
4833       set++;
4834
4835       /* Iterate through the rest of the chain.  */
4836       while (lst_symbol.next_entry)
4837         {
4838           /* Seek to the next symbol and read it in.  */
4839           if (bfd_seek (abfd, lst_filepos + lst_symbol.next_entry, SEEK_SET) <0)
4840             goto error_return;
4841
4842           if (bfd_read ((PTR) & lst_symbol, 1, sizeof (lst_symbol), abfd)
4843               != sizeof (lst_symbol))
4844             goto error_return;
4845
4846           /* Seek to the name length & string and read them in.  */
4847           if (bfd_seek (abfd, lst_filepos + lst_header->string_loc 
4848                                 + lst_symbol.name.n_strx - 4, SEEK_SET) < 0)
4849             goto error_return;
4850
4851           if (bfd_read (&len, 1, 4, abfd) != 4)
4852             goto error_return;
4853
4854           /* Allocate space for the name and null terminate it too.  */
4855           set->name = bfd_zalloc (abfd, len + 1);
4856           if (!set->name)
4857             {
4858               bfd_set_error (bfd_error_no_memory);
4859               goto error_return;
4860             }
4861
4862           if (bfd_read (set->name, 1, len, abfd) != len)
4863             goto error_return;
4864           set->name[len] = 0;
4865
4866           /* Fill in the file offset.  Note that the "location" field points
4867              to the SOM itself, not the ar_hdr in front of it.  */
4868           set->file_offset = som_dict[lst_symbol.som_index].location
4869                                - sizeof (struct ar_hdr);
4870
4871           /* Go on to the next symbol.  */
4872           set++;
4873         }
4874     }
4875   /* If we haven't died by now, then we successfully read the entire 
4876      archive symbol table.  */
4877   if (hash_table != NULL)
4878     free (hash_table);
4879   if (som_dict != NULL)
4880     free (som_dict);
4881   return true;
4882
4883  error_return:
4884   if (hash_table != NULL)
4885     free (hash_table);
4886   if (som_dict != NULL)
4887     free (som_dict);
4888   return false;
4889 }
4890
4891 /* Read in the LST from the archive.  */
4892 static boolean
4893 som_slurp_armap (abfd)
4894      bfd *abfd;
4895 {
4896   struct lst_header lst_header;
4897   struct ar_hdr ar_header;
4898   unsigned int parsed_size;
4899   struct artdata *ardata = bfd_ardata (abfd);
4900   char nextname[17];
4901   int i = bfd_read ((PTR) nextname, 1, 16, abfd);
4902
4903   /* Special cases.  */
4904   if (i == 0)
4905     return true;
4906   if (i != 16)
4907     return false;
4908
4909   if (bfd_seek (abfd, (file_ptr) - 16, SEEK_CUR) < 0)
4910     return false;
4911
4912   /* For archives without .o files there is no symbol table.  */
4913   if (strncmp (nextname, "/               ", 16))
4914     {
4915       bfd_has_map (abfd) = false;
4916       return true;
4917     }
4918
4919   /* Read in and sanity check the archive header.  */
4920   if (bfd_read ((PTR) &ar_header, 1, sizeof (struct ar_hdr), abfd)
4921       != sizeof (struct ar_hdr))
4922     return false;
4923
4924   if (strncmp (ar_header.ar_fmag, ARFMAG, 2))
4925     {
4926       bfd_set_error (bfd_error_malformed_archive);
4927       return false;
4928     }
4929
4930   /* How big is the archive symbol table entry?  */
4931   errno = 0;
4932   parsed_size = strtol (ar_header.ar_size, NULL, 10);
4933   if (errno != 0)
4934     {
4935       bfd_set_error (bfd_error_malformed_archive);
4936       return false;
4937     }
4938
4939   /* Save off the file offset of the first real user data.  */
4940   ardata->first_file_filepos = bfd_tell (abfd) + parsed_size;
4941
4942   /* Read in the library symbol table.  We'll make heavy use of this
4943      in just a minute.  */
4944   if (bfd_read ((PTR) & lst_header, 1, sizeof (struct lst_header), abfd)
4945       != sizeof (struct lst_header))
4946     return false;
4947
4948   /* Sanity check.  */
4949   if (lst_header.a_magic != LIBMAGIC)
4950     {
4951       bfd_set_error (bfd_error_malformed_archive);
4952       return false;
4953     }
4954
4955   /* Count the number of symbols in the library symbol table.  */
4956   if (som_bfd_count_ar_symbols (abfd, &lst_header, &ardata->symdef_count)
4957       == false)
4958     return false;
4959
4960   /* Get back to the start of the library symbol table.  */
4961   if (bfd_seek (abfd, ardata->first_file_filepos - parsed_size 
4962                         + sizeof (struct lst_header), SEEK_SET) < 0)
4963     return false;
4964
4965   /* Initializae the cache and allocate space for the library symbols.  */
4966   ardata->cache = 0;
4967   ardata->symdefs = (carsym *) bfd_alloc (abfd,
4968                                           (ardata->symdef_count
4969                                            * sizeof (carsym)));
4970   if (!ardata->symdefs)
4971     {
4972       bfd_set_error (bfd_error_no_memory);
4973       return false;
4974     }
4975
4976   /* Now fill in the canonical archive symbols.  */
4977   if (som_bfd_fill_in_ar_symbols (abfd, &lst_header, &ardata->symdefs)
4978       == false)
4979     return false;
4980
4981   /* Seek back to the "first" file in the archive.  Note the "first"
4982      file may be the extended name table.  */
4983   if (bfd_seek (abfd, ardata->first_file_filepos, SEEK_SET) < 0)
4984     return false;
4985
4986   /* Notify the generic archive code that we have a symbol map.  */
4987   bfd_has_map (abfd) = true;
4988   return true;
4989 }
4990
4991 /* Begin preparing to write a SOM library symbol table.
4992
4993    As part of the prep work we need to determine the number of symbols
4994    and the size of the associated string section.  */
4995
4996 static boolean
4997 som_bfd_prep_for_ar_write (abfd, num_syms, stringsize)
4998      bfd *abfd;
4999      unsigned int *num_syms, *stringsize;
5000 {
5001   bfd *curr_bfd = abfd->archive_head;
5002
5003   /* Some initialization.  */
5004   *num_syms = 0;
5005   *stringsize = 0;
5006
5007   /* Iterate over each BFD within this archive.  */
5008   while (curr_bfd != NULL)
5009     {
5010       unsigned int curr_count, i;
5011       som_symbol_type *sym;
5012
5013       /* Don't bother for non-SOM objects.  */
5014       if (curr_bfd->format != bfd_object
5015           || curr_bfd->xvec->flavour != bfd_target_som_flavour)
5016         {
5017           curr_bfd = curr_bfd->next;
5018           continue;
5019         }
5020
5021       /* Make sure the symbol table has been read, then snag a pointer
5022          to it.  It's a little slimey to grab the symbols via obj_som_symtab,
5023          but doing so avoids allocating lots of extra memory.  */
5024       if (som_slurp_symbol_table (curr_bfd) == false)
5025         return false;
5026
5027       sym = obj_som_symtab (curr_bfd);
5028       curr_count = bfd_get_symcount (curr_bfd);
5029
5030       /* Examine each symbol to determine if it belongs in the
5031          library symbol table.  */
5032       for (i = 0; i < curr_count; i++, sym++)
5033         {
5034           struct som_misc_symbol_info info;
5035
5036           /* Derive SOM information from the BFD symbol.  */
5037           som_bfd_derive_misc_symbol_info (curr_bfd, &sym->symbol, &info);
5038
5039           /* Should we include this symbol?  */
5040           if (info.symbol_type == ST_NULL
5041               || info.symbol_type == ST_SYM_EXT
5042               || info.symbol_type == ST_ARG_EXT)
5043             continue;
5044
5045           /* Only global symbols and unsatisfied commons.  */
5046           if (info.symbol_scope != SS_UNIVERSAL
5047               && info.symbol_type != ST_STORAGE)
5048             continue;
5049
5050           /* Do no include undefined symbols.  */
5051           if (bfd_is_und_section (sym->symbol.section))
5052             continue;
5053
5054           /* Bump the various counters, being careful to honor
5055              alignment considerations in the string table.  */
5056           (*num_syms)++;
5057           *stringsize = *stringsize + strlen (sym->symbol.name) + 5;
5058           while (*stringsize % 4)
5059             (*stringsize)++;
5060         }
5061
5062       curr_bfd = curr_bfd->next;
5063     }
5064   return true;
5065 }
5066
5067 /* Hash a symbol name based on the hashing algorithm presented in the
5068    SOM ABI.  */
5069 static unsigned int
5070 som_bfd_ar_symbol_hash (symbol)
5071      asymbol *symbol;
5072 {
5073   unsigned int len = strlen (symbol->name);
5074
5075   /* Names with length 1 are special.  */
5076   if (len == 1)
5077     return 0x1000100 | (symbol->name[0] << 16) | symbol->name[0];
5078
5079   return ((len & 0x7f) << 24) | (symbol->name[1] << 16)
5080           | (symbol->name[len-2] << 8) | symbol->name[len-1];
5081 }
5082
5083 static CONST char *
5084 normalize (file)
5085      CONST char *file;
5086 {
5087   CONST char *filename = strrchr (file, '/');
5088
5089   if (filename != NULL)
5090     filename++;
5091   else
5092     filename = file;
5093   return filename;
5094 }
5095
5096 /* Do the bulk of the work required to write the SOM library
5097    symbol table.  */
5098    
5099 static boolean
5100 som_bfd_ar_write_symbol_stuff (abfd, nsyms, string_size, lst)
5101      bfd *abfd;
5102      unsigned int nsyms, string_size;
5103      struct lst_header lst;
5104 {
5105   file_ptr lst_filepos;
5106   char *strings = NULL, *p;
5107   struct lst_symbol_record *lst_syms = NULL, *curr_lst_sym;
5108   bfd *curr_bfd;
5109   unsigned int *hash_table = NULL;
5110   struct som_entry *som_dict = NULL;
5111   struct lst_symbol_record **last_hash_entry = NULL;
5112   unsigned int curr_som_offset, som_index, extended_name_length = 0;
5113   unsigned int maxname = abfd->xvec->ar_max_namelen;
5114
5115   hash_table =
5116     (unsigned int *) malloc (lst.hash_size * sizeof (unsigned int));
5117   if (hash_table == NULL && lst.hash_size != 0)
5118     {
5119       bfd_set_error (bfd_error_no_memory);
5120       goto error_return;
5121     }
5122   som_dict =
5123     (struct som_entry *) malloc (lst.module_count
5124                                  * sizeof (struct som_entry));
5125   if (som_dict == NULL && lst.module_count != 0)
5126     {
5127       bfd_set_error (bfd_error_no_memory);
5128       goto error_return;
5129     }
5130
5131   last_hash_entry =
5132     ((struct lst_symbol_record **)
5133      malloc (lst.hash_size * sizeof (struct lst_symbol_record *)));
5134   if (last_hash_entry == NULL && lst.hash_size != 0)
5135     {
5136       bfd_set_error (bfd_error_no_memory);
5137       goto error_return;
5138     }
5139
5140   /* Lots of fields are file positions relative to the start
5141      of the lst record.  So save its location.  */
5142   lst_filepos = bfd_tell (abfd) - sizeof (struct lst_header);
5143
5144   /* Some initialization.  */
5145   memset (hash_table, 0, 4 * lst.hash_size);
5146   memset (som_dict, 0, lst.module_count * sizeof (struct som_entry));
5147   memset (last_hash_entry, 0,   
5148           lst.hash_size * sizeof (struct lst_symbol_record *));
5149
5150   /* Symbols have som_index fields, so we have to keep track of the
5151      index of each SOM in the archive.
5152
5153      The SOM dictionary has (among other things) the absolute file
5154      position for the SOM which a particular dictionary entry
5155      describes.  We have to compute that information as we iterate
5156      through the SOMs/symbols.  */
5157   som_index = 0;
5158   curr_som_offset = 8 + 2 * sizeof (struct ar_hdr) + lst.file_end;
5159
5160   /* Yow!  We have to know the size of the extended name table
5161      too.  */
5162   for (curr_bfd = abfd->archive_head;
5163        curr_bfd != NULL;
5164        curr_bfd = curr_bfd->next)
5165     {
5166       CONST char *normal = normalize (curr_bfd->filename);
5167       unsigned int thislen;
5168
5169       if (!normal)
5170         {
5171           bfd_set_error (bfd_error_no_memory);
5172           return false;
5173         }
5174       thislen = strlen (normal);
5175       if (thislen > maxname)
5176         extended_name_length += thislen + 1;
5177     }
5178
5179   /* Make room for the archive header and the contents of the
5180      extended string table.  */
5181   if (extended_name_length)
5182     curr_som_offset += extended_name_length + sizeof (struct ar_hdr);
5183
5184   /* Make sure we're properly aligned.  */
5185   curr_som_offset = (curr_som_offset + 0x1) & ~0x1;
5186
5187   /* FIXME should be done with buffers just like everything else... */
5188   lst_syms = malloc (nsyms * sizeof (struct lst_symbol_record));
5189   if (lst_syms == NULL && nsyms != 0)
5190     {
5191       bfd_set_error (bfd_error_no_memory);
5192       goto error_return;
5193     }
5194   strings = malloc (string_size);
5195   if (strings == NULL && string_size != 0)
5196     {
5197       bfd_set_error (bfd_error_no_memory);
5198       goto error_return;
5199     }
5200
5201   p = strings;
5202   curr_lst_sym = lst_syms;
5203
5204   curr_bfd = abfd->archive_head;
5205   while (curr_bfd != NULL)
5206     {
5207       unsigned int curr_count, i;
5208       som_symbol_type *sym;
5209
5210       /* Don't bother for non-SOM objects.  */
5211       if (curr_bfd->format != bfd_object
5212           || curr_bfd->xvec->flavour != bfd_target_som_flavour)
5213         {
5214           curr_bfd = curr_bfd->next;
5215           continue;
5216         }
5217
5218       /* Make sure the symbol table has been read, then snag a pointer
5219          to it.  It's a little slimey to grab the symbols via obj_som_symtab,
5220          but doing so avoids allocating lots of extra memory.  */
5221       if (som_slurp_symbol_table (curr_bfd) == false)
5222         goto error_return;
5223
5224       sym = obj_som_symtab (curr_bfd);
5225       curr_count = bfd_get_symcount (curr_bfd);
5226
5227       for (i = 0; i < curr_count; i++, sym++)
5228         {
5229           struct som_misc_symbol_info info;
5230
5231           /* Derive SOM information from the BFD symbol.  */
5232           som_bfd_derive_misc_symbol_info (curr_bfd, &sym->symbol, &info);
5233
5234           /* Should we include this symbol?  */
5235           if (info.symbol_type == ST_NULL
5236               || info.symbol_type == ST_SYM_EXT
5237               || info.symbol_type == ST_ARG_EXT)
5238             continue;
5239
5240           /* Only global symbols and unsatisfied commons.  */
5241           if (info.symbol_scope != SS_UNIVERSAL
5242               && info.symbol_type != ST_STORAGE)
5243             continue;
5244
5245           /* Do no include undefined symbols.  */
5246           if (bfd_is_und_section (sym->symbol.section))
5247             continue;
5248
5249           /* If this is the first symbol from this SOM, then update
5250              the SOM dictionary too.  */
5251           if (som_dict[som_index].location == 0)
5252             {
5253               som_dict[som_index].location = curr_som_offset;
5254               som_dict[som_index].length = arelt_size (curr_bfd);
5255             }
5256
5257           /* Fill in the lst symbol record.  */
5258           curr_lst_sym->hidden = 0;
5259           curr_lst_sym->secondary_def = 0;
5260           curr_lst_sym->symbol_type = info.symbol_type;
5261           curr_lst_sym->symbol_scope = info.symbol_scope;
5262           curr_lst_sym->check_level = 0;
5263           curr_lst_sym->must_qualify = 0;
5264           curr_lst_sym->initially_frozen = 0;
5265           curr_lst_sym->memory_resident = 0;
5266           curr_lst_sym->is_common = bfd_is_com_section (sym->symbol.section);
5267           curr_lst_sym->dup_common = 0;
5268           curr_lst_sym->xleast = 0;
5269           curr_lst_sym->arg_reloc = info.arg_reloc;
5270           curr_lst_sym->name.n_strx = p - strings + 4;
5271           curr_lst_sym->qualifier_name.n_strx = 0;
5272           curr_lst_sym->symbol_info = info.symbol_info;
5273           curr_lst_sym->symbol_value = info.symbol_value;
5274           curr_lst_sym->symbol_descriptor = 0;
5275           curr_lst_sym->reserved = 0;
5276           curr_lst_sym->som_index = som_index;
5277           curr_lst_sym->symbol_key = som_bfd_ar_symbol_hash (&sym->symbol);
5278           curr_lst_sym->next_entry = 0;
5279
5280           /* Insert into the hash table.  */
5281           if (hash_table[curr_lst_sym->symbol_key % lst.hash_size])
5282             {
5283               struct lst_symbol_record *tmp;
5284
5285               /* There is already something at the head of this hash chain,
5286                  so tack this symbol onto the end of the chain.  */
5287               tmp = last_hash_entry[curr_lst_sym->symbol_key % lst.hash_size];
5288               tmp->next_entry
5289                 = (curr_lst_sym - lst_syms) * sizeof (struct lst_symbol_record)
5290                   + lst.hash_size * 4 
5291                   + lst.module_count * sizeof (struct som_entry)
5292                   + sizeof (struct lst_header);
5293             }
5294           else
5295             {
5296               /* First entry in this hash chain.  */
5297               hash_table[curr_lst_sym->symbol_key % lst.hash_size]
5298                 = (curr_lst_sym - lst_syms) * sizeof (struct lst_symbol_record)
5299                   + lst.hash_size * 4 
5300                   + lst.module_count * sizeof (struct som_entry)
5301                   + sizeof (struct lst_header);
5302             }
5303
5304           /* Keep track of the last symbol we added to this chain so we can
5305              easily update its next_entry pointer.  */
5306           last_hash_entry[curr_lst_sym->symbol_key % lst.hash_size]
5307             = curr_lst_sym;
5308
5309
5310           /* Update the string table.  */
5311           bfd_put_32 (abfd, strlen (sym->symbol.name), p);
5312           p += 4;
5313           strcpy (p, sym->symbol.name);
5314           p += strlen (sym->symbol.name) + 1;
5315           while ((int)p % 4)
5316             {
5317               bfd_put_8 (abfd, 0, p);
5318               p++;
5319             }
5320
5321           /* Head to the next symbol.  */
5322           curr_lst_sym++;
5323         }
5324
5325       /* Keep track of where each SOM will finally reside; then look
5326          at the next BFD.  */
5327       curr_som_offset += arelt_size (curr_bfd) + sizeof (struct ar_hdr);
5328       curr_bfd = curr_bfd->next;
5329       som_index++;
5330     }
5331
5332   /* Now scribble out the hash table.  */
5333   if (bfd_write ((PTR) hash_table, lst.hash_size, 4, abfd)
5334       != lst.hash_size * 4)
5335     goto error_return;
5336
5337   /* Then the SOM dictionary.  */
5338   if (bfd_write ((PTR) som_dict, lst.module_count,
5339                  sizeof (struct som_entry), abfd)
5340       != lst.module_count * sizeof (struct som_entry))
5341     goto error_return;
5342
5343   /* The library symbols.  */
5344   if (bfd_write ((PTR) lst_syms, nsyms, sizeof (struct lst_symbol_record), abfd)
5345       != nsyms * sizeof (struct lst_symbol_record))
5346     goto error_return;
5347
5348   /* And finally the strings.  */
5349   if (bfd_write ((PTR) strings, string_size, 1, abfd) != string_size)
5350     goto error_return;
5351
5352   if (hash_table != NULL)
5353     free (hash_table);
5354   if (som_dict != NULL)
5355     free (som_dict);
5356   if (last_hash_entry != NULL)
5357     free (last_hash_entry);
5358   if (lst_syms != NULL)
5359     free (lst_syms);
5360   if (strings != NULL)
5361     free (strings);
5362   return true;
5363
5364  error_return:
5365   if (hash_table != NULL)
5366     free (hash_table);
5367   if (som_dict != NULL)
5368     free (som_dict);
5369   if (last_hash_entry != NULL)
5370     free (last_hash_entry);
5371   if (lst_syms != NULL)
5372     free (lst_syms);
5373   if (strings != NULL)
5374     free (strings);
5375
5376   return false;
5377 }
5378
5379 /* Write out the LST for the archive.
5380
5381    You'll never believe this is really how armaps are handled in SOM...  */
5382
5383 /*ARGSUSED*/
5384 static boolean
5385 som_write_armap (abfd, elength, map, orl_count, stridx)
5386      bfd *abfd;
5387      unsigned int elength;
5388      struct orl *map;
5389      unsigned int orl_count;
5390      int stridx;
5391 {
5392   bfd *curr_bfd;
5393   struct stat statbuf;
5394   unsigned int i, lst_size, nsyms, stringsize;
5395   struct ar_hdr hdr;
5396   struct lst_header lst;
5397   int *p;
5398  
5399   /* We'll use this for the archive's date and mode later.  */
5400   if (stat (abfd->filename, &statbuf) != 0)
5401     {
5402       bfd_set_error (bfd_error_system_call);
5403       return false;
5404     }
5405   /* Fudge factor.  */
5406   bfd_ardata (abfd)->armap_timestamp = statbuf.st_mtime + 60;
5407
5408   /* Account for the lst header first.  */
5409   lst_size = sizeof (struct lst_header);
5410
5411   /* Start building the LST header.  */
5412   lst.system_id = CPU_PA_RISC1_0;
5413   lst.a_magic = LIBMAGIC;
5414   lst.version_id = VERSION_ID;
5415   lst.file_time.secs = 0;
5416   lst.file_time.nanosecs = 0;
5417
5418   lst.hash_loc = lst_size;
5419   lst.hash_size = SOM_LST_HASH_SIZE;
5420
5421   /* Hash table is a SOM_LST_HASH_SIZE 32bit offsets.  */
5422   lst_size += 4 * SOM_LST_HASH_SIZE;
5423
5424   /* We need to count the number of SOMs in this archive.  */
5425   curr_bfd = abfd->archive_head;
5426   lst.module_count = 0;
5427   while (curr_bfd != NULL)
5428     {
5429       /* Only true SOM objects count.  */
5430       if (curr_bfd->format == bfd_object
5431           && curr_bfd->xvec->flavour == bfd_target_som_flavour)
5432         lst.module_count++;
5433       curr_bfd = curr_bfd->next;
5434     }
5435   lst.module_limit = lst.module_count;
5436   lst.dir_loc = lst_size;
5437   lst_size += sizeof (struct som_entry) * lst.module_count;
5438
5439   /* We don't support import/export tables, auxiliary headers,
5440      or free lists yet.  Make the linker work a little harder
5441      to make our life easier.  */
5442
5443   lst.export_loc = 0;
5444   lst.export_count = 0;
5445   lst.import_loc = 0;
5446   lst.aux_loc = 0;
5447   lst.aux_size = 0;
5448
5449   /* Count how many symbols we will have on the hash chains and the
5450      size of the associated string table.  */
5451   if (som_bfd_prep_for_ar_write (abfd, &nsyms, &stringsize) == false)
5452     return false;
5453
5454   lst_size += sizeof (struct lst_symbol_record) * nsyms;
5455
5456   /* For the string table.  One day we might actually use this info
5457      to avoid small seeks/reads when reading archives.  */
5458   lst.string_loc = lst_size;
5459   lst.string_size = stringsize;
5460   lst_size += stringsize;
5461
5462   /* SOM ABI says this must be zero.  */
5463   lst.free_list = 0;
5464   lst.file_end = lst_size;
5465
5466   /* Compute the checksum.  Must happen after the entire lst header
5467      has filled in.  */
5468   p = (int *)&lst;
5469   lst.checksum = 0;
5470   for (i = 0; i < sizeof (struct lst_header)/sizeof (int) - 1; i++)
5471     lst.checksum ^= *p++;
5472
5473   sprintf (hdr.ar_name, "/               ");
5474   sprintf (hdr.ar_date, "%ld", bfd_ardata (abfd)->armap_timestamp);
5475   sprintf (hdr.ar_uid, "%ld", (long) getuid ());
5476   sprintf (hdr.ar_gid, "%ld", (long) getgid ());
5477   sprintf (hdr.ar_mode, "%-8o", (unsigned int) statbuf.st_mode);
5478   sprintf (hdr.ar_size, "%-10d", (int) lst_size);
5479   hdr.ar_fmag[0] = '`';
5480   hdr.ar_fmag[1] = '\012';
5481
5482   /* Turn any nulls into spaces.  */
5483   for (i = 0; i < sizeof (struct ar_hdr); i++)
5484     if (((char *) (&hdr))[i] == '\0')
5485       (((char *) (&hdr))[i]) = ' ';
5486
5487   /* Scribble out the ar header.  */
5488   if (bfd_write ((PTR) &hdr, 1, sizeof (struct ar_hdr), abfd)
5489       != sizeof (struct ar_hdr))
5490     return false;
5491
5492   /* Now scribble out the lst header.  */
5493   if (bfd_write ((PTR) &lst, 1, sizeof (struct lst_header), abfd)
5494       != sizeof (struct lst_header))
5495     return false;
5496
5497   /* Build and write the armap.  */
5498   if (som_bfd_ar_write_symbol_stuff (abfd, nsyms, stringsize, lst) == false)
5499     return false;
5500   
5501   /* Done.  */
5502   return true;
5503 }
5504
5505 /* Free all information we have cached for this BFD.  We can always
5506    read it again later if we need it.  */
5507
5508 static boolean
5509 som_bfd_free_cached_info (abfd)
5510      bfd *abfd;
5511 {
5512   asection *o;
5513
5514   if (bfd_get_format (abfd) != bfd_object)
5515     return true;
5516
5517 #define FREE(x) if (x != NULL) { free (x); x = NULL; }
5518   /* Free the native string and symbol tables.  */
5519   FREE (obj_som_symtab (abfd));
5520   FREE (obj_som_stringtab (abfd));
5521   for (o = abfd->sections; o != (asection *) NULL; o = o->next)
5522     {
5523       /* Free the native relocations.  */
5524       o->reloc_count = -1;
5525       FREE (som_section_data (o)->reloc_stream);
5526       /* Free the generic relocations.  */
5527       FREE (o->relocation);
5528     }
5529 #undef FREE
5530
5531   return true;
5532 }
5533
5534 /* End of miscellaneous support functions. */
5535
5536 #define som_close_and_cleanup           som_bfd_free_cached_info
5537
5538 #define som_openr_next_archived_file    bfd_generic_openr_next_archived_file
5539 #define som_generic_stat_arch_elt       bfd_generic_stat_arch_elt
5540 #define som_truncate_arname             bfd_bsd_truncate_arname
5541 #define som_slurp_extended_name_table   _bfd_slurp_extended_name_table
5542
5543 #define som_get_lineno                  _bfd_nosymbols_get_lineno
5544 #define som_bfd_make_debug_symbol       _bfd_nosymbols_bfd_make_debug_symbol
5545
5546 #define som_bfd_get_relocated_section_contents \
5547  bfd_generic_get_relocated_section_contents
5548 #define som_bfd_relax_section bfd_generic_relax_section
5549 #define som_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
5550 #define som_bfd_link_add_symbols _bfd_generic_link_add_symbols
5551 #define som_bfd_final_link _bfd_generic_final_link
5552
5553 const bfd_target som_vec =
5554 {
5555   "som",                        /* name */
5556   bfd_target_som_flavour,
5557   true,                         /* target byte order */
5558   true,                         /* target headers byte order */
5559   (HAS_RELOC | EXEC_P |         /* object flags */
5560    HAS_LINENO | HAS_DEBUG |
5561    HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED | DYNAMIC),
5562   (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
5563    | SEC_ALLOC | SEC_LOAD | SEC_RELOC),         /* section flags */
5564
5565 /* leading_symbol_char: is the first char of a user symbol
5566    predictable, and if so what is it */
5567   0,
5568   '/',                          /* ar_pad_char */
5569   14,                           /* ar_max_namelen */
5570   3,                            /* minimum alignment */
5571   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
5572   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
5573   bfd_getb16, bfd_getb_signed_16, bfd_putb16,   /* data */
5574   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
5575   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
5576   bfd_getb16, bfd_getb_signed_16, bfd_putb16,   /* hdrs */
5577   {_bfd_dummy_target,
5578    som_object_p,                /* bfd_check_format */
5579    bfd_generic_archive_p,
5580    _bfd_dummy_target
5581   },
5582   {
5583     bfd_false,
5584     som_mkobject,
5585     _bfd_generic_mkarchive,
5586     bfd_false
5587   },
5588   {
5589     bfd_false,
5590     som_write_object_contents,
5591     _bfd_write_archive_contents,
5592     bfd_false,
5593   },
5594 #undef som
5595
5596   BFD_JUMP_TABLE_GENERIC (som),
5597   BFD_JUMP_TABLE_COPY (som),
5598   BFD_JUMP_TABLE_CORE (_bfd_nocore),
5599   BFD_JUMP_TABLE_ARCHIVE (som),
5600   BFD_JUMP_TABLE_SYMBOLS (som),
5601   BFD_JUMP_TABLE_RELOCS (som),
5602   BFD_JUMP_TABLE_WRITE (som),
5603   BFD_JUMP_TABLE_LINK (som),
5604   BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
5605
5606   (PTR) 0
5607 };
5608
5609 #endif /* HOST_HPPAHPUX || HOST_HPPABSD || HOST_HPPAOSF */