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