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