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