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