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