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