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