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