* som.c (som_begin_writing): Fix braino (one call to align
[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.  Ugh.  Not true for HPUX.
2984
2985                  The HPUX kernel requires the text to always be page aligned
2986                  within the file regardless of the executable's type.  */
2987               if (abfd->flags & D_PAGED
2988                   || (subsection->flags & SEC_CODE)
2989                   || ((abfd->flags & WP_TEXT)
2990                       && (subsection->flags & SEC_DATA)))
2991                 current_offset = SOM_ALIGN (current_offset, PA_PAGESIZE);
2992
2993               /* Update the exec header.  */
2994               if (subsection->flags & SEC_CODE && exec_header.exec_tfile == 0)
2995                 {
2996                   exec_header.exec_tmem = section->vma;
2997                   exec_header.exec_tfile = current_offset;
2998                 }
2999               if (subsection->flags & SEC_DATA && exec_header.exec_dfile == 0)
3000                 {
3001                   exec_header.exec_dmem = section->vma;
3002                   exec_header.exec_dfile = current_offset;
3003                 }
3004
3005               /* Only do this for the first subspace within each space.  */
3006               first_subspace = 0;
3007             }
3008           else if (abfd->flags & EXEC_P)
3009             {
3010               /* Have to keep proper alignments for the subspaces
3011                  in executables too!  */
3012               if (subsection->flags & SEC_CODE)
3013                 {
3014                   unsigned tmp = exec_header.exec_tsize;
3015
3016                   tmp = SOM_ALIGN (tmp, 1 << subsection->alignment_power);
3017                   current_offset += (tmp - exec_header.exec_tsize);
3018                   exec_header.exec_tsize = tmp;
3019                 }
3020               else
3021                 {
3022                   unsigned tmp = exec_header.exec_dsize;
3023
3024                   tmp = SOM_ALIGN (tmp, 1 << subsection->alignment_power);
3025                   current_offset += (tmp - exec_header.exec_dsize);
3026                   exec_header.exec_dsize = tmp;
3027                 }
3028             }
3029
3030           subsection->target_index = total_subspaces++;
3031           /* This is real data to be loaded from the file.  */
3032           if (subsection->flags & SEC_LOAD)
3033             {
3034               /* Update the size of the code & data.  */
3035               if (abfd->flags & EXEC_P
3036                   && subsection->flags & SEC_CODE)
3037                 exec_header.exec_tsize += subsection->_cooked_size;
3038               else if (abfd->flags & EXEC_P
3039                        && subsection->flags & SEC_DATA)
3040                 exec_header.exec_dsize += subsection->_cooked_size;
3041               som_section_data (subsection)->subspace_dict->file_loc_init_value
3042                 = current_offset;
3043               section->filepos = current_offset;
3044               current_offset += bfd_section_size (abfd, subsection); 
3045             }
3046           /* Looks like uninitialized data.  */
3047           else
3048             {
3049               /* Update the size of the bss section.  */
3050               if (abfd->flags & EXEC_P)
3051                 exec_header.exec_bsize += subsection->_cooked_size;
3052
3053               som_section_data (subsection)->subspace_dict->file_loc_init_value
3054                 = 0;
3055               som_section_data (subsection)->subspace_dict->
3056                 initialization_length = 0;
3057             }
3058         }
3059       /* Goto the next section.  */
3060       section = section->next; 
3061     }
3062
3063   /* Finally compute the file positions for unloadable subspaces.
3064      If building an executable, start the unloadable stuff on its
3065      own page.  */
3066
3067   if (abfd->flags & EXEC_P)
3068     current_offset = SOM_ALIGN (current_offset, PA_PAGESIZE);
3069
3070   obj_som_file_hdr (abfd)->unloadable_sp_location = current_offset;
3071   section = abfd->sections;
3072   for (i = 0; i < num_spaces; i++)
3073     {
3074       asection *subsection;
3075
3076       /* Find a space.  */
3077       while (!som_is_space (section))
3078         section = section->next;
3079
3080       if (abfd->flags & EXEC_P)
3081         current_offset = SOM_ALIGN (current_offset, PA_PAGESIZE);
3082
3083       /* Now look for all its subspaces.  */
3084       for (subsection = abfd->sections;
3085            subsection != NULL;
3086            subsection = subsection->next)
3087         {
3088           
3089           if (!som_is_subspace (subsection)
3090               || !som_is_container (section, subsection)
3091               || (subsection->flags & SEC_ALLOC) != 0)
3092             continue;
3093
3094           subsection->target_index = total_subspaces;
3095           /* This is real data to be loaded from the file.  */
3096           if ((subsection->flags & SEC_LOAD) == 0)
3097             {
3098               som_section_data (subsection)->subspace_dict->file_loc_init_value
3099                 = current_offset;
3100               section->filepos = current_offset;
3101               current_offset += bfd_section_size (abfd, subsection); 
3102             }
3103           /* Looks like uninitialized data.  */
3104           else
3105             {
3106               som_section_data (subsection)->subspace_dict->file_loc_init_value
3107                 = 0;
3108               som_section_data (subsection)->subspace_dict->
3109                 initialization_length = bfd_section_size (abfd, subsection);
3110             }
3111         }
3112       /* Goto the next section.  */
3113       section = section->next; 
3114     }
3115
3116   /* If building an executable, then make sure to seek to and write
3117      one byte at the end of the file to make sure any necessary
3118      zeros are filled in.  Ugh.  */
3119   if (abfd->flags & EXEC_P)
3120     current_offset = SOM_ALIGN (current_offset, PA_PAGESIZE);
3121   if (bfd_seek (abfd, current_offset, SEEK_SET) < 0)
3122     {
3123       bfd_set_error (bfd_error_system_call);
3124       return false;
3125     }
3126   if (bfd_write ((PTR) "", 1, 1, abfd) != 1)
3127     {
3128       bfd_set_error (bfd_error_system_call);
3129       return false;
3130     }
3131
3132   obj_som_file_hdr (abfd)->unloadable_sp_size
3133     = current_offset - obj_som_file_hdr (abfd)->unloadable_sp_location;
3134
3135   /* Loader fixups are not supported in any way shape or form.  */
3136   obj_som_file_hdr (abfd)->loader_fixup_location = 0;
3137   obj_som_file_hdr (abfd)->loader_fixup_total = 0;
3138
3139   /* Done.  Store the total size of the SOM.  */
3140   obj_som_file_hdr (abfd)->som_length = current_offset;
3141
3142   /* Now write the exec header.  */
3143   if (abfd->flags & EXEC_P)
3144     {
3145       long tmp;
3146
3147       exec_header.exec_entry = bfd_get_start_address (abfd);
3148       exec_header.exec_flags = obj_som_exec_data (abfd)->exec_flags;
3149
3150       /* Oh joys.  Ram some of the BSS data into the DATA section
3151          to be compatable with how the hp linker makes objects
3152          (saves memory space).  */
3153       tmp = exec_header.exec_dsize;
3154       tmp = SOM_ALIGN (tmp, PA_PAGESIZE);
3155       exec_header.exec_bsize -= (tmp - exec_header.exec_dsize);
3156       if (exec_header.exec_bsize < 0)
3157         exec_header.exec_bsize = 0;
3158       exec_header.exec_dsize = tmp;
3159
3160       bfd_seek (abfd, obj_som_file_hdr (abfd)->aux_header_location, SEEK_SET);
3161
3162       if (bfd_write ((PTR) &exec_header, AUX_HDR_SIZE, 1, abfd)
3163           != AUX_HDR_SIZE)
3164         {
3165           bfd_set_error (bfd_error_system_call);
3166           return false;
3167         }
3168     }
3169   return true;
3170 }
3171
3172 /* Finally, scribble out the various headers to the disk.  */
3173
3174 static boolean
3175 som_write_headers (abfd)
3176      bfd *abfd;
3177 {
3178   int num_spaces = som_count_spaces (abfd);
3179   int i;
3180   int subspace_index = 0;
3181   file_ptr location;
3182   asection *section;
3183
3184   /* Subspaces are written first so that we can set up information
3185      about them in their containing spaces as the subspace is written.  */
3186
3187   /* Seek to the start of the subspace dictionary records.  */
3188   location = obj_som_file_hdr (abfd)->subspace_location;
3189   bfd_seek (abfd, location, SEEK_SET);
3190   section = abfd->sections;
3191   /* Now for each loadable space write out records for its subspaces.  */
3192   for (i = 0; i < num_spaces; i++)
3193     {
3194       asection *subsection;
3195
3196       /* Find a space.  */
3197       while (!som_is_space (section))
3198         section = section->next;
3199
3200       /* Now look for all its subspaces.  */
3201       for (subsection = abfd->sections;
3202            subsection != NULL;
3203            subsection = subsection->next)
3204         {
3205           
3206           /* Skip any section which does not correspond to a space
3207              or subspace.  Or does not have SEC_ALLOC set (and therefore
3208              has no real bits on the disk).  */
3209           if (!som_is_subspace (subsection)
3210               || !som_is_container (section, subsection)
3211               || (subsection->flags & SEC_ALLOC) == 0)
3212             continue;
3213
3214           /* If this is the first subspace for this space, then save
3215              the index of the subspace in its containing space.  Also
3216              set "is_loadable" in the containing space.  */
3217
3218           if (som_section_data (section)->space_dict->subspace_quantity == 0)
3219             {
3220               som_section_data (section)->space_dict->is_loadable = 1;
3221               som_section_data (section)->space_dict->subspace_index
3222                 = subspace_index;
3223             }
3224
3225           /* Increment the number of subspaces seen and the number of
3226              subspaces contained within the current space.  */
3227           subspace_index++;
3228           som_section_data (section)->space_dict->subspace_quantity++;
3229
3230           /* Mark the index of the current space within the subspace's
3231              dictionary record.  */
3232           som_section_data (subsection)->subspace_dict->space_index = i;
3233           
3234           /* Dump the current subspace header.  */
3235           if (bfd_write ((PTR) som_section_data (subsection)->subspace_dict,
3236                          sizeof (struct subspace_dictionary_record), 1, abfd)
3237               != sizeof (struct subspace_dictionary_record))
3238             {
3239               bfd_set_error (bfd_error_system_call);
3240               return false;
3241             }
3242         }
3243       /* Goto the next section.  */
3244       section = section->next; 
3245     }
3246
3247   /* Now repeat the process for unloadable subspaces.  */
3248   section = abfd->sections;
3249   /* Now for each space write out records for its subspaces.  */
3250   for (i = 0; i < num_spaces; i++)
3251     {
3252       asection *subsection;
3253
3254       /* Find a space.  */
3255       while (!som_is_space (section))
3256         section = section->next;
3257
3258       /* Now look for all its subspaces.  */
3259       for (subsection = abfd->sections;
3260            subsection != NULL;
3261            subsection = subsection->next)
3262         {
3263           
3264           /* Skip any section which does not correspond to a space or
3265              subspace, or which SEC_ALLOC set (and therefore handled
3266              in the loadable spaces/subspaces code above.  */
3267
3268           if (!som_is_subspace (subsection)
3269               || !som_is_container (section, subsection)
3270               || (subsection->flags & SEC_ALLOC) != 0)
3271             continue;
3272
3273           /* If this is the first subspace for this space, then save
3274              the index of the subspace in its containing space.  Clear
3275              "is_loadable".  */
3276
3277           if (som_section_data (section)->space_dict->subspace_quantity == 0)
3278             {
3279               som_section_data (section)->space_dict->is_loadable = 0;
3280               som_section_data (section)->space_dict->subspace_index
3281                 = subspace_index;
3282             }
3283
3284           /* Increment the number of subspaces seen and the number of
3285              subspaces contained within the current space.  */
3286           som_section_data (section)->space_dict->subspace_quantity++;
3287           subspace_index++; 
3288
3289           /* Mark the index of the current space within the subspace's
3290              dictionary record.  */
3291           som_section_data (subsection)->subspace_dict->space_index = i;
3292           
3293           /* Dump this subspace header.  */
3294           if (bfd_write ((PTR) som_section_data (subsection)->subspace_dict,
3295                          sizeof (struct subspace_dictionary_record), 1, abfd)
3296               != sizeof (struct subspace_dictionary_record))
3297             {
3298               bfd_set_error (bfd_error_system_call);
3299               return false;
3300             }
3301         }
3302       /* Goto the next section.  */
3303       section = section->next; 
3304     }
3305
3306   /* All the subspace dictiondary records are written, and all the
3307      fields are set up in the space dictionary records.
3308
3309      Seek to the right location and start writing the space
3310      dictionary records.  */
3311   location = obj_som_file_hdr (abfd)->space_location;
3312   bfd_seek (abfd, location, SEEK_SET);
3313
3314   section = abfd->sections;
3315   for (i = 0; i < num_spaces; i++)
3316     {
3317
3318       /* Find a space.  */
3319       while (!som_is_space (section))
3320         section = section->next;
3321
3322       /* Dump its header  */
3323       if (bfd_write ((PTR) som_section_data (section)->space_dict,
3324                      sizeof (struct space_dictionary_record), 1, abfd)
3325           != sizeof (struct space_dictionary_record))
3326         {
3327           bfd_set_error (bfd_error_system_call);
3328           return false;
3329         }
3330
3331       /* Goto the next section.  */
3332       section = section->next;
3333     }
3334
3335   /* Only thing left to do is write out the file header.  It is always
3336      at location zero.  Seek there and write it.  */
3337   bfd_seek (abfd, (file_ptr) 0, SEEK_SET);
3338   if (bfd_write ((PTR) obj_som_file_hdr (abfd),
3339                  sizeof (struct header), 1, abfd)
3340       != sizeof (struct header))
3341     {
3342       bfd_set_error (bfd_error_system_call);
3343       return false;
3344     }
3345   return true;
3346 }
3347
3348 /* Compute and return the checksum for a SOM file header.  */
3349
3350 static unsigned long
3351 som_compute_checksum (abfd)
3352      bfd *abfd;
3353 {
3354   unsigned long checksum, count, i;
3355   unsigned long *buffer = (unsigned long *) obj_som_file_hdr (abfd);
3356
3357   checksum = 0;
3358   count = sizeof (struct header) / sizeof (unsigned long);
3359   for (i = 0; i < count; i++)
3360     checksum ^= *(buffer + i);
3361
3362   return checksum;
3363 }
3364
3365 static void
3366 som_bfd_derive_misc_symbol_info (abfd, sym, info)
3367      bfd *abfd;
3368      asymbol *sym;
3369      struct som_misc_symbol_info *info;
3370 {
3371   /* Initialize.  */
3372   memset (info, 0, sizeof (struct som_misc_symbol_info));
3373
3374   /* The HP SOM linker requires detailed type information about
3375      all symbols (including undefined symbols!).  Unfortunately,
3376      the type specified in an import/export statement does not
3377      always match what the linker wants.  Severe braindamage.  */
3378          
3379   /* Section symbols will not have a SOM symbol type assigned to
3380      them yet.  Assign all section symbols type ST_DATA.  */
3381   if (sym->flags & BSF_SECTION_SYM)
3382     info->symbol_type = ST_DATA;
3383   else
3384     {
3385       /* Common symbols must have scope SS_UNSAT and type
3386          ST_STORAGE or the linker will choke.  */
3387       if (sym->section == &bfd_com_section)
3388         {
3389           info->symbol_scope = SS_UNSAT;
3390           info->symbol_type = ST_STORAGE;
3391         }
3392
3393       /* It is possible to have a symbol without an associated
3394          type.  This happens if the user imported the symbol
3395          without a type and the symbol was never defined
3396          locally.  If BSF_FUNCTION is set for this symbol, then
3397          assign it type ST_CODE (the HP linker requires undefined
3398          external functions to have type ST_CODE rather than ST_ENTRY).  */
3399       else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_UNKNOWN
3400                && sym->section == &bfd_und_section
3401                && sym->flags & BSF_FUNCTION)
3402         info->symbol_type = ST_CODE;
3403
3404       /* Handle function symbols which were defined in this file.
3405          They should have type ST_ENTRY.  Also retrieve the argument
3406          relocation bits from the SOM backend information.  */
3407       else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_ENTRY
3408                || (som_symbol_data (sym)->som_type == SYMBOL_TYPE_CODE
3409                    && (sym->flags & BSF_FUNCTION))
3410                || (som_symbol_data (sym)->som_type == SYMBOL_TYPE_UNKNOWN
3411                    && (sym->flags & BSF_FUNCTION)))
3412         {
3413           info->symbol_type = ST_ENTRY;
3414           info->arg_reloc = som_symbol_data (sym)->tc_data.hppa_arg_reloc;
3415         }
3416
3417       /* If the type is unknown at this point, it should be
3418          ST_DATA (functions were handled as special cases above).  */
3419       else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_UNKNOWN)
3420         info->symbol_type = ST_DATA;
3421
3422       /* From now on it's a very simple mapping.  */
3423       else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_ABSOLUTE)
3424         info->symbol_type = ST_ABSOLUTE;
3425       else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_CODE)
3426         info->symbol_type = ST_CODE;
3427       else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_DATA)
3428         info->symbol_type = ST_DATA;
3429       else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_MILLICODE)
3430         info->symbol_type = ST_MILLICODE;
3431       else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_PLABEL)
3432         info->symbol_type = ST_PLABEL;
3433       else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_PRI_PROG)
3434         info->symbol_type = ST_PRI_PROG;
3435       else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_SEC_PROG)
3436         info->symbol_type = ST_SEC_PROG;
3437     }
3438         
3439   /* Now handle the symbol's scope.  Exported data which is not
3440      in the common section has scope SS_UNIVERSAL.  Note scope
3441      of common symbols was handled earlier!  */
3442   if (sym->flags & BSF_EXPORT && sym->section != &bfd_com_section)
3443     info->symbol_scope = SS_UNIVERSAL;
3444   /* Any undefined symbol at this point has a scope SS_UNSAT.  */
3445   else if (sym->section == &bfd_und_section)
3446     info->symbol_scope = SS_UNSAT;
3447   /* Anything else which is not in the common section has scope
3448      SS_LOCAL.  */
3449   else if (sym->section != &bfd_com_section)
3450     info->symbol_scope = SS_LOCAL;
3451
3452   /* Now set the symbol_info field.  It has no real meaning
3453      for undefined or common symbols, but the HP linker will
3454      choke if it's not set to some "reasonable" value.  We
3455      use zero as a reasonable value.  */
3456   if (sym->section == &bfd_com_section || sym->section == &bfd_und_section
3457       || sym->section == &bfd_abs_section)
3458     info->symbol_info = 0;
3459   /* For all other symbols, the symbol_info field contains the 
3460      subspace index of the space this symbol is contained in.  */
3461   else
3462     info->symbol_info = sym->section->target_index;
3463
3464   /* Set the symbol's value.  */
3465   info->symbol_value = sym->value + sym->section->vma;
3466 }
3467
3468 /* Build and write, in one big chunk, the entire symbol table for
3469    this BFD.  */
3470
3471 static boolean
3472 som_build_and_write_symbol_table (abfd)
3473      bfd *abfd;
3474 {
3475   unsigned int num_syms = bfd_get_symcount (abfd);
3476   file_ptr symtab_location = obj_som_file_hdr (abfd)->symbol_location;
3477   asymbol **bfd_syms = bfd_get_outsymbols (abfd);
3478   struct symbol_dictionary_record *som_symtab = NULL;
3479   int i, symtab_size;
3480
3481   /* Compute total symbol table size and allocate a chunk of memory
3482      to hold the symbol table as we build it.  */
3483   symtab_size = num_syms * sizeof (struct symbol_dictionary_record);
3484   som_symtab = (struct symbol_dictionary_record *) malloc (symtab_size);
3485   if (som_symtab == NULL && symtab_size != 0)
3486     {
3487       bfd_set_error (bfd_error_no_memory);
3488       goto error_return;
3489     }
3490   memset (som_symtab, 0, symtab_size);
3491
3492   /* Walk over each symbol.  */
3493   for (i = 0; i < num_syms; i++)
3494     {
3495       struct som_misc_symbol_info info;
3496
3497       /* This is really an index into the symbol strings table.  
3498          By the time we get here, the index has already been 
3499          computed and stored into the name field in the BFD symbol.  */
3500       som_symtab[i].name.n_strx = (int) bfd_syms[i]->name;
3501
3502       /* Derive SOM information from the BFD symbol.  */
3503       som_bfd_derive_misc_symbol_info (abfd, bfd_syms[i], &info);
3504
3505       /* Now use it.  */
3506       som_symtab[i].symbol_type = info.symbol_type;
3507       som_symtab[i].symbol_scope = info.symbol_scope;
3508       som_symtab[i].arg_reloc = info.arg_reloc;
3509       som_symtab[i].symbol_info = info.symbol_info;
3510       som_symtab[i].symbol_value = info.symbol_value;
3511     }
3512
3513   /* Everything is ready, seek to the right location and
3514      scribble out the symbol table.  */
3515   if (bfd_seek (abfd, symtab_location, SEEK_SET) != 0)
3516     {
3517       bfd_set_error (bfd_error_system_call);
3518       goto error_return;
3519     }
3520
3521   if (bfd_write ((PTR) som_symtab, symtab_size, 1, abfd) != symtab_size)
3522     {
3523       bfd_set_error (bfd_error_system_call);
3524       goto error_return;
3525     }
3526
3527   if (som_symtab != NULL)
3528     free (som_symtab);
3529   return true;
3530  error_return:
3531   if (som_symtab != NULL)
3532     free (som_symtab);
3533   return false;
3534 }
3535
3536 /* Write an object in SOM format.  */  
3537
3538 static boolean
3539 som_write_object_contents (abfd)
3540      bfd *abfd;
3541 {
3542   if (abfd->output_has_begun == false)
3543     {
3544       /* Set up fixed parts of the file, space, and subspace headers.
3545          Notify the world that output has begun.  */
3546       som_prep_headers (abfd);
3547       abfd->output_has_begun = true;
3548       /* Start writing the object file.  This include all the string
3549          tables, fixup streams, and other portions of the object file.  */
3550       som_begin_writing (abfd);
3551     }
3552
3553   /* Now that the symbol table information is complete, build and
3554      write the symbol table.  */
3555   if (som_build_and_write_symbol_table (abfd) == false)
3556     return false;
3557
3558   /* Compute the checksum for the file header just before writing
3559      the header to disk.  */
3560   obj_som_file_hdr (abfd)->checksum = som_compute_checksum (abfd);
3561   return (som_write_headers (abfd));
3562 }
3563
3564 \f
3565 /* Read and save the string table associated with the given BFD.  */
3566
3567 static boolean
3568 som_slurp_string_table (abfd)
3569      bfd *abfd;
3570 {
3571   char *stringtab;
3572
3573   /* Use the saved version if its available.  */
3574   if (obj_som_stringtab (abfd) != NULL)
3575     return true;
3576
3577   /* Allocate and read in the string table.  */
3578   stringtab = bfd_zalloc (abfd, obj_som_stringtab_size (abfd));
3579   if (stringtab == NULL)
3580     {
3581       bfd_set_error (bfd_error_no_memory);
3582       return false;
3583     }
3584
3585   if (bfd_seek (abfd, obj_som_str_filepos (abfd), SEEK_SET) < 0)
3586     {
3587       bfd_set_error (bfd_error_system_call);
3588       return false;
3589     }
3590   
3591   if (bfd_read (stringtab, obj_som_stringtab_size (abfd), 1, abfd)
3592       != obj_som_stringtab_size (abfd))
3593     {
3594       bfd_set_error (bfd_error_system_call);
3595       return false;
3596     }
3597
3598   /* Save our results and return success. */
3599   obj_som_stringtab (abfd) = stringtab;
3600   return true;
3601 }
3602
3603 /* Return the amount of data (in bytes) required to hold the symbol
3604    table for this object.  */
3605
3606 static unsigned int
3607 som_get_symtab_upper_bound (abfd)
3608      bfd *abfd;
3609 {
3610   if (!som_slurp_symbol_table (abfd))
3611     return 0;
3612
3613   return (bfd_get_symcount (abfd) + 1) * (sizeof (asymbol *));
3614 }
3615
3616 /* Convert from a SOM subspace index to a BFD section.  */
3617
3618 static asection *
3619 som_section_from_subspace_index (abfd, index)
3620      bfd *abfd;
3621      unsigned int index;
3622 {
3623   asection *section;
3624
3625   for (section = abfd->sections; section != NULL; section = section->next)
3626     if (section->target_index == index)
3627       return section;
3628
3629   /* Should never happen.  */
3630   abort();
3631 }
3632
3633 /* Read and save the symbol table associated with the given BFD.  */
3634
3635 static unsigned int
3636 som_slurp_symbol_table (abfd)
3637      bfd *abfd;
3638 {
3639   int symbol_count = bfd_get_symcount (abfd);
3640   int symsize = sizeof (struct symbol_dictionary_record);
3641   char *stringtab;
3642   struct symbol_dictionary_record *buf = NULL, *bufp, *endbufp;
3643   som_symbol_type *sym, *symbase;
3644
3645   /* Return saved value if it exists.  */
3646   if (obj_som_symtab (abfd) != NULL)
3647     goto successful_return;
3648
3649   /* Special case.  This is *not* an error.  */
3650   if (symbol_count == 0)
3651     goto successful_return;
3652
3653   if (!som_slurp_string_table (abfd))
3654     goto error_return;
3655
3656   stringtab = obj_som_stringtab (abfd);
3657
3658   symbase = (som_symbol_type *)
3659     bfd_zalloc (abfd, symbol_count * sizeof (som_symbol_type));
3660   if (symbase == NULL)
3661     {
3662       bfd_set_error (bfd_error_no_memory);
3663       goto error_return;
3664     }
3665
3666   /* Read in the external SOM representation.  */
3667   buf = malloc (symbol_count * symsize);
3668   if (buf == NULL && symbol_count * symsize != 0)
3669     {
3670       bfd_set_error (bfd_error_no_memory);
3671       goto error_return;
3672     }
3673   if (bfd_seek (abfd, obj_som_sym_filepos (abfd), SEEK_SET) < 0)
3674     {
3675       bfd_set_error (bfd_error_system_call);
3676       goto error_return;
3677     }
3678   if (bfd_read (buf, symbol_count * symsize, 1, abfd) 
3679       != symbol_count * symsize)
3680     {
3681       bfd_set_error (bfd_error_no_symbols);
3682       goto error_return;
3683     }
3684
3685   /* Iterate over all the symbols and internalize them.  */
3686   endbufp = buf + symbol_count;
3687   for (bufp = buf, sym = symbase; bufp < endbufp; ++bufp)
3688     {
3689
3690       /* I don't think we care about these.  */
3691       if (bufp->symbol_type == ST_SYM_EXT
3692           || bufp->symbol_type == ST_ARG_EXT)
3693         continue;
3694
3695       /* Set some private data we care about.  */
3696       if (bufp->symbol_type == ST_NULL)
3697         som_symbol_data (sym)->som_type = SYMBOL_TYPE_UNKNOWN;
3698       else if (bufp->symbol_type == ST_ABSOLUTE)
3699         som_symbol_data (sym)->som_type = SYMBOL_TYPE_ABSOLUTE;
3700       else if (bufp->symbol_type == ST_DATA)
3701         som_symbol_data (sym)->som_type = SYMBOL_TYPE_DATA;
3702       else if (bufp->symbol_type == ST_CODE)
3703         som_symbol_data (sym)->som_type = SYMBOL_TYPE_CODE;
3704       else if (bufp->symbol_type == ST_PRI_PROG)
3705         som_symbol_data (sym)->som_type = SYMBOL_TYPE_PRI_PROG;
3706       else if (bufp->symbol_type == ST_SEC_PROG)
3707         som_symbol_data (sym)->som_type = SYMBOL_TYPE_SEC_PROG;
3708       else if (bufp->symbol_type == ST_ENTRY)
3709         som_symbol_data (sym)->som_type = SYMBOL_TYPE_ENTRY;
3710       else if (bufp->symbol_type == ST_MILLICODE)
3711         som_symbol_data (sym)->som_type = SYMBOL_TYPE_MILLICODE;
3712       else if (bufp->symbol_type == ST_PLABEL)
3713         som_symbol_data (sym)->som_type = SYMBOL_TYPE_PLABEL;
3714       else
3715         som_symbol_data (sym)->som_type = SYMBOL_TYPE_UNKNOWN;
3716       som_symbol_data (sym)->tc_data.hppa_arg_reloc = bufp->arg_reloc;
3717
3718       /* Some reasonable defaults.  */
3719       sym->symbol.the_bfd = abfd;
3720       sym->symbol.name = bufp->name.n_strx + stringtab;
3721       sym->symbol.value = bufp->symbol_value;
3722       sym->symbol.section = 0;
3723       sym->symbol.flags = 0;
3724
3725       switch (bufp->symbol_type)
3726         {
3727         case ST_ENTRY:
3728         case ST_PRI_PROG:
3729         case ST_SEC_PROG:
3730         case ST_MILLICODE:
3731           sym->symbol.flags |= BSF_FUNCTION;
3732           sym->symbol.value &= ~0x3;
3733           break;
3734
3735         case ST_STUB:
3736         case ST_CODE:
3737           sym->symbol.value &= ~0x3;
3738
3739         default:
3740           break;
3741         }
3742
3743       /* Handle scoping and section information.  */
3744       switch (bufp->symbol_scope)
3745         {
3746         /* symbol_info field is undefined for SS_EXTERNAL and SS_UNSAT symbols,
3747            so the section associated with this symbol can't be known.  */
3748         case SS_EXTERNAL:
3749           if (bufp->symbol_type != ST_STORAGE)
3750             sym->symbol.section = &bfd_und_section;
3751           else
3752             sym->symbol.section = &bfd_com_section;
3753           sym->symbol.flags |= (BSF_EXPORT | BSF_GLOBAL);
3754           break;
3755
3756         case SS_UNSAT:
3757           if (bufp->symbol_type != ST_STORAGE)
3758             sym->symbol.section = &bfd_und_section;
3759           else
3760             sym->symbol.section = &bfd_com_section;
3761           break;
3762
3763         case SS_UNIVERSAL:
3764           sym->symbol.flags |= (BSF_EXPORT | BSF_GLOBAL);
3765           sym->symbol.section
3766             = som_section_from_subspace_index (abfd, bufp->symbol_info);
3767           sym->symbol.value -= sym->symbol.section->vma;
3768           break;
3769
3770 #if 0
3771         /* SS_GLOBAL and SS_LOCAL are two names for the same thing.
3772            Sound dumb?  It is.  */
3773         case SS_GLOBAL:
3774 #endif
3775         case SS_LOCAL:
3776           sym->symbol.flags |= BSF_LOCAL;
3777           sym->symbol.section
3778             = som_section_from_subspace_index (abfd, bufp->symbol_info);
3779           sym->symbol.value -= sym->symbol.section->vma;
3780           break;
3781         }
3782
3783       /* Mark section symbols and symbols used by the debugger.  */
3784       if (sym->symbol.name[0] == '$'
3785           && sym->symbol.name[strlen (sym->symbol.name) - 1] == '$')
3786         sym->symbol.flags |= BSF_SECTION_SYM;
3787       else if (!strncmp (sym->symbol.name, "L$0\002", 4))
3788         {
3789           sym->symbol.flags |= BSF_SECTION_SYM;
3790           sym->symbol.name = sym->symbol.section->name;
3791         }
3792       else if (!strncmp (sym->symbol.name, "L$0\001", 4))
3793         sym->symbol.flags |= BSF_DEBUGGING;
3794
3795       /* Note increment at bottom of loop, since we skip some symbols
3796          we can not include it as part of the for statement.  */
3797       sym++;
3798     }
3799
3800   /* Save our results and return success.  */
3801   obj_som_symtab (abfd) = symbase;
3802  successful_return:
3803   if (buf != NULL)
3804     free (buf);
3805   return (true);
3806
3807  error_return:
3808   if (buf != NULL)
3809     free (buf);
3810   return false;
3811 }
3812
3813 /* Canonicalize a SOM symbol table.  Return the number of entries
3814    in the symbol table.  */
3815
3816 static unsigned int
3817 som_get_symtab (abfd, location)
3818      bfd *abfd;
3819      asymbol **location;
3820 {
3821   int i;
3822   som_symbol_type *symbase;
3823
3824   if (!som_slurp_symbol_table (abfd))
3825     return 0;
3826
3827   i = bfd_get_symcount (abfd);
3828   symbase = obj_som_symtab (abfd);
3829
3830   for (; i > 0; i--, location++, symbase++)
3831     *location = &symbase->symbol;
3832
3833   /* Final null pointer.  */
3834   *location = 0;
3835   return (bfd_get_symcount (abfd));
3836 }
3837
3838 /* Make a SOM symbol.  There is nothing special to do here.  */
3839
3840 static asymbol *
3841 som_make_empty_symbol (abfd)
3842      bfd *abfd;
3843 {
3844   som_symbol_type *new =
3845   (som_symbol_type *) bfd_zalloc (abfd, sizeof (som_symbol_type));
3846   if (new == NULL)
3847     {
3848       bfd_set_error (bfd_error_no_memory);
3849       return 0;
3850     }
3851   new->symbol.the_bfd = abfd;
3852
3853   return &new->symbol;
3854 }
3855
3856 /* Print symbol information.  */
3857
3858 static void
3859 som_print_symbol (ignore_abfd, afile, symbol, how)
3860      bfd *ignore_abfd;
3861      PTR afile;
3862      asymbol *symbol;
3863      bfd_print_symbol_type how;
3864 {
3865   FILE *file = (FILE *) afile;
3866   switch (how)
3867     {
3868     case bfd_print_symbol_name:
3869       fprintf (file, "%s", symbol->name);
3870       break;
3871     case bfd_print_symbol_more:
3872       fprintf (file, "som ");
3873       fprintf_vma (file, symbol->value);
3874       fprintf (file, " %lx", (long) symbol->flags);
3875       break;
3876     case bfd_print_symbol_all:
3877       {
3878         CONST char *section_name;
3879         section_name = symbol->section ? symbol->section->name : "(*none*)";
3880         bfd_print_symbol_vandf ((PTR) file, symbol);
3881         fprintf (file, " %s\t%s", section_name, symbol->name);
3882         break;
3883       }
3884     }
3885 }
3886
3887 static boolean
3888 som_bfd_is_local_label (abfd, sym)
3889      bfd *abfd;
3890      asymbol *sym;
3891 {
3892   return (sym->name[0] == 'L' && sym->name[1] == '$');
3893 }
3894
3895 /* Count or process variable-length SOM fixup records.
3896
3897    To avoid code duplication we use this code both to compute the number
3898    of relocations requested by a stream, and to internalize the stream.
3899
3900    When computing the number of relocations requested by a stream the
3901    variables rptr, section, and symbols have no meaning.
3902
3903    Return the number of relocations requested by the fixup stream.  When
3904    not just counting 
3905
3906    This needs at least two or three more passes to get it cleaned up.  */
3907
3908 static unsigned int
3909 som_set_reloc_info (fixup, end, internal_relocs, section, symbols, just_count)
3910      unsigned char *fixup;
3911      unsigned int end;
3912      arelent *internal_relocs;
3913      asection *section;
3914      asymbol **symbols;
3915      boolean just_count;
3916 {
3917   unsigned int op, varname;
3918   unsigned char *end_fixups = &fixup[end];
3919   const struct fixup_format *fp;
3920   char *cp;
3921   unsigned char *save_fixup;
3922   int variables[26], stack[20], c, v, count, prev_fixup, *sp;
3923   const int *subop;
3924   arelent *rptr= internal_relocs;
3925   unsigned int offset = just_count ? 0 : section->vma;
3926
3927 #define var(c)          variables[(c) - 'A']
3928 #define push(v)         (*sp++ = (v))
3929 #define pop()           (*--sp)
3930 #define emptystack()    (sp == stack)
3931
3932   som_initialize_reloc_queue (reloc_queue);
3933   memset (variables, 0, sizeof (variables));
3934   memset (stack, 0, sizeof (stack));
3935   count = 0;
3936   prev_fixup = 0;
3937   sp = stack;
3938
3939   while (fixup < end_fixups)
3940     {
3941
3942       /* Save pointer to the start of this fixup.  We'll use
3943          it later to determine if it is necessary to put this fixup
3944          on the queue.  */
3945       save_fixup = fixup;
3946
3947       /* Get the fixup code and its associated format.  */
3948       op = *fixup++;
3949       fp = &som_fixup_formats[op];
3950
3951       /* Handle a request for a previous fixup.  */
3952       if (*fp->format == 'P')
3953         {
3954           /* Get pointer to the beginning of the prev fixup, move
3955              the repeated fixup to the head of the queue.  */
3956           fixup = reloc_queue[fp->D].reloc;
3957           som_reloc_queue_fix (reloc_queue, fp->D);
3958           prev_fixup = 1;
3959
3960           /* Get the fixup code and its associated format.  */
3961           op = *fixup++;
3962           fp = &som_fixup_formats[op];
3963         }
3964
3965       /* If we are not just counting, set some reasonable defaults.  */
3966       if (! just_count)
3967         {
3968           rptr->address = offset;
3969           rptr->howto = &som_hppa_howto_table[op];
3970           rptr->addend = 0;
3971           rptr->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;
3972         }
3973
3974       /* Set default input length to 0.  Get the opcode class index
3975          into D.  */
3976       var ('L') = 0;
3977       var ('D') = fp->D;
3978
3979       /* Get the opcode format.  */
3980       cp = fp->format;
3981
3982       /* Process the format string.  Parsing happens in two phases,
3983          parse RHS, then assign to LHS.  Repeat until no more 
3984          characters in the format string.  */
3985       while (*cp)
3986         {
3987           /* The variable this pass is going to compute a value for.  */
3988           varname = *cp++;
3989
3990           /* Start processing RHS.  Continue until a NULL or '=' is found.  */
3991           do
3992             {
3993               c = *cp++;
3994
3995               /* If this is a variable, push it on the stack.  */
3996               if (isupper (c))
3997                 push (var (c));
3998
3999               /* If this is a lower case letter, then it represents
4000                  additional data from the fixup stream to be pushed onto
4001                  the stack.  */
4002               else if (islower (c))
4003                 {
4004                   for (v = 0; c > 'a'; --c)
4005                     v = (v << 8) | *fixup++;
4006                   push (v);
4007                 }
4008
4009               /* A decimal constant.  Push it on the stack.  */
4010               else if (isdigit (c))
4011                 {
4012                   v = c - '0';
4013                   while (isdigit (*cp))
4014                     v = (v * 10) + (*cp++ - '0');
4015                   push (v);
4016                 }
4017               else
4018
4019                 /* An operator.  Pop two two values from the stack and
4020                    use them as operands to the given operation.  Push
4021                    the result of the operation back on the stack.  */
4022                 switch (c)
4023                   {
4024                   case '+':
4025                     v = pop ();
4026                     v += pop ();
4027                     push (v);
4028                     break;
4029                   case '*':
4030                     v = pop ();
4031                     v *= pop ();
4032                     push (v);
4033                     break;
4034                   case '<':
4035                     v = pop ();
4036                     v = pop () << v;
4037                     push (v);
4038                     break;
4039                   default:
4040                     abort ();
4041                   }
4042             }
4043           while (*cp && *cp != '=');
4044
4045           /* Move over the equal operator.  */
4046           cp++;
4047
4048           /* Pop the RHS off the stack.  */
4049           c = pop ();
4050
4051           /* Perform the assignment.  */
4052           var (varname) = c;
4053
4054           /* Handle side effects. and special 'O' stack cases.  */
4055           switch (varname)
4056             {
4057             /* Consume some bytes from the input space.  */
4058             case 'L':
4059               offset += c;
4060               break;
4061             /* A symbol to use in the relocation.  Make a note
4062                of this if we are not just counting.  */
4063             case 'S':
4064               if (! just_count)
4065                 rptr->sym_ptr_ptr = &symbols[c];
4066               break;
4067             /* Handle the linker expression stack.  */
4068             case 'O':
4069               switch (op)
4070                 {
4071                 case R_COMP1:
4072                   subop = comp1_opcodes;
4073                   break;
4074                 case R_COMP2:
4075                   subop = comp2_opcodes;
4076                   break;
4077                 case R_COMP3:
4078                   subop = comp3_opcodes;
4079                   break;
4080                 default:
4081                   abort ();
4082                 }
4083               while (*subop <= (unsigned char) c)
4084                 ++subop;
4085               --subop;
4086               break;
4087             default:
4088               break;
4089             }
4090         }
4091
4092       /* If we used a previous fixup, clean up after it.  */
4093       if (prev_fixup)
4094         {
4095           fixup = save_fixup + 1;
4096           prev_fixup = 0;
4097         }
4098       /* Queue it.  */
4099       else if (fixup > save_fixup + 1)
4100         som_reloc_queue_insert (save_fixup, fixup - save_fixup, reloc_queue);
4101
4102       /* We do not pass R_DATA_OVERRIDE or R_NO_RELOCATION 
4103          fixups to BFD.  */
4104       if (som_hppa_howto_table[op].type != R_DATA_OVERRIDE
4105           && som_hppa_howto_table[op].type != R_NO_RELOCATION)
4106         {
4107           /* Done with a single reloction. Loop back to the top.  */
4108           if (! just_count)
4109             {
4110               rptr->addend = var ('V');
4111               rptr++;
4112             }
4113           count++;
4114           /* Now that we've handled a "full" relocation, reset
4115              some state.  */
4116           memset (variables, 0, sizeof (variables));
4117           memset (stack, 0, sizeof (stack));
4118         }
4119     }
4120   return count;
4121
4122 #undef var
4123 #undef push
4124 #undef pop
4125 #undef emptystack
4126 }
4127
4128 /* Read in the relocs (aka fixups in SOM terms) for a section. 
4129
4130    som_get_reloc_upper_bound calls this routine with JUST_COUNT 
4131    set to true to indicate it only needs a count of the number
4132    of actual relocations.  */
4133
4134 static boolean
4135 som_slurp_reloc_table (abfd, section, symbols, just_count)
4136      bfd *abfd;
4137      asection *section;
4138      asymbol **symbols;
4139      boolean just_count;
4140 {
4141   char *external_relocs;
4142   unsigned int fixup_stream_size;
4143   arelent *internal_relocs;
4144   unsigned int num_relocs;
4145
4146   fixup_stream_size = som_section_data (section)->reloc_size;
4147   /* If there were no relocations, then there is nothing to do.  */
4148   if (section->reloc_count == 0)
4149     return true;
4150
4151   /* If reloc_count is -1, then the relocation stream has not been 
4152      parsed.  We must do so now to know how many relocations exist.  */
4153   if (section->reloc_count == -1)
4154     {
4155       external_relocs = (char *) bfd_zalloc (abfd, fixup_stream_size);
4156       if (external_relocs == (char *) NULL)
4157         {
4158           bfd_set_error (bfd_error_no_memory);
4159           return false;
4160         }
4161       /* Read in the external forms. */
4162       if (bfd_seek (abfd,
4163                     obj_som_reloc_filepos (abfd) + section->rel_filepos,
4164                     SEEK_SET)
4165           != 0)
4166         {
4167           bfd_set_error (bfd_error_system_call);
4168           return false;
4169         }
4170       if (bfd_read (external_relocs, 1, fixup_stream_size, abfd)
4171           != fixup_stream_size)
4172         {
4173           bfd_set_error (bfd_error_system_call);
4174           return false;
4175         }
4176       /* Let callers know how many relocations found.
4177          also save the relocation stream as we will
4178          need it again.  */
4179       section->reloc_count = som_set_reloc_info (external_relocs,
4180                                                  fixup_stream_size,
4181                                                  NULL, NULL, NULL, true);
4182
4183       som_section_data (section)->reloc_stream = external_relocs;
4184     }
4185
4186   /* If the caller only wanted a count, then return now.  */
4187   if (just_count)
4188     return true;
4189
4190   num_relocs = section->reloc_count;
4191   external_relocs = som_section_data (section)->reloc_stream;
4192   /* Return saved information about the relocations if it is available.  */
4193   if (section->relocation != (arelent *) NULL)
4194     return true;
4195
4196   internal_relocs = (arelent *) bfd_zalloc (abfd,
4197                                             num_relocs * sizeof (arelent));
4198   if (internal_relocs == (arelent *) NULL)
4199     {
4200       bfd_set_error (bfd_error_no_memory);
4201       return false;
4202     }
4203
4204   /* Process and internalize the relocations.  */
4205   som_set_reloc_info (external_relocs, fixup_stream_size,
4206                       internal_relocs, section, symbols, false);
4207
4208   /* Save our results and return success.  */
4209   section->relocation = internal_relocs;
4210   return (true);
4211 }
4212
4213 /* Return the number of bytes required to store the relocation
4214    information associated with the given section.  */ 
4215
4216 static unsigned int
4217 som_get_reloc_upper_bound (abfd, asect)
4218      bfd *abfd;
4219      sec_ptr asect;
4220 {
4221   /* If section has relocations, then read in the relocation stream
4222      and parse it to determine how many relocations exist.  */
4223   if (asect->flags & SEC_RELOC)
4224     {
4225       if (som_slurp_reloc_table (abfd, asect, NULL, true))
4226         return (asect->reloc_count + 1) * sizeof (arelent);
4227     }
4228   /* Either there are no relocations or an error occurred while 
4229      reading and parsing the relocation stream.  */ 
4230   return 0;
4231 }
4232
4233 /* Convert relocations from SOM (external) form into BFD internal
4234    form.  Return the number of relocations.  */
4235
4236 static unsigned int
4237 som_canonicalize_reloc (abfd, section, relptr, symbols)
4238      bfd *abfd;
4239      sec_ptr section;
4240      arelent **relptr;
4241      asymbol **symbols;
4242 {
4243   arelent *tblptr;
4244   int count;
4245
4246   if (som_slurp_reloc_table (abfd, section, symbols, false) == false)
4247     return 0;
4248
4249   count = section->reloc_count;
4250   tblptr = section->relocation;
4251   if (tblptr == (arelent *) NULL)
4252     return 0;
4253
4254   while (count--)
4255     *relptr++ = tblptr++;
4256
4257   *relptr = (arelent *) NULL;
4258   return section->reloc_count;
4259 }
4260
4261 extern bfd_target som_vec;
4262
4263 /* A hook to set up object file dependent section information.  */
4264
4265 static boolean
4266 som_new_section_hook (abfd, newsect)
4267      bfd *abfd;
4268      asection *newsect;
4269 {
4270   newsect->used_by_bfd =
4271     (PTR) bfd_zalloc (abfd, sizeof (struct som_section_data_struct));
4272   if (!newsect->used_by_bfd)
4273     {
4274       bfd_set_error (bfd_error_no_memory);
4275       return false;
4276     }
4277   newsect->alignment_power = 3;
4278
4279   /* We allow more than three sections internally */
4280   return true;
4281 }
4282
4283 /* Copy any private info we understand from the input section
4284    to the output section.  */
4285 static boolean
4286 som_bfd_copy_private_section_data (ibfd, isection, obfd, osection)
4287      bfd *ibfd;
4288      asection *isection;
4289      bfd *obfd;
4290      asection *osection;
4291 {
4292   /* One day we may try to grok other private data.  */
4293   if (ibfd->xvec->flavour != bfd_target_som_flavour
4294       || obfd->xvec->flavour != bfd_target_som_flavour
4295       || (!som_is_space (isection) && !som_is_subspace (isection)))
4296     return false;
4297
4298   som_section_data (osection)->copy_data
4299     = (struct som_copyable_section_data_struct *)
4300       bfd_zalloc (obfd, sizeof (struct som_copyable_section_data_struct));
4301   if (som_section_data (osection)->copy_data == NULL)
4302     {
4303       bfd_set_error (bfd_error_no_memory);
4304       return false;
4305     }
4306
4307   memcpy (som_section_data (osection)->copy_data,
4308           som_section_data (isection)->copy_data,
4309           sizeof (struct som_copyable_section_data_struct));
4310
4311   /* Reparent if necessary.  */
4312   if (som_section_data (osection)->copy_data->container)
4313     som_section_data (osection)->copy_data->container =
4314       som_section_data (osection)->copy_data->container->output_section;
4315
4316   return true;
4317 }
4318
4319 /* Copy any private info we understand from the input bfd
4320    to the output bfd.  */
4321
4322 static boolean
4323 som_bfd_copy_private_bfd_data (ibfd, obfd)
4324      bfd *ibfd, *obfd;
4325 {
4326   /* One day we may try to grok other private data.  */
4327   if (ibfd->xvec->flavour != bfd_target_som_flavour
4328       || obfd->xvec->flavour != bfd_target_som_flavour)
4329     return false;
4330
4331   /* Allocate some memory to hold the data we need.  */
4332   obj_som_exec_data (obfd) = (struct som_exec_data *)
4333     bfd_zalloc (obfd, sizeof (struct som_exec_data));
4334   if (obj_som_exec_data (obfd) == NULL)
4335     {
4336       bfd_set_error (bfd_error_no_memory);
4337       return false;
4338     }
4339
4340   /* Now copy the data.  */
4341   memcpy (obj_som_exec_data (obfd), obj_som_exec_data (ibfd),
4342           sizeof (struct som_exec_data));
4343
4344   return true;
4345 }
4346
4347 /* Set backend info for sections which can not be described
4348    in the BFD data structures.  */
4349
4350 boolean
4351 bfd_som_set_section_attributes (section, defined, private, sort_key, spnum)
4352      asection *section;
4353      int defined;
4354      int private;
4355      unsigned int sort_key;
4356      int spnum;
4357 {
4358   /* Allocate memory to hold the magic information.  */
4359   if (som_section_data (section)->copy_data == NULL)
4360     {
4361       som_section_data (section)->copy_data
4362         = (struct som_copyable_section_data_struct *)
4363           bfd_zalloc (section->owner,
4364                       sizeof (struct som_copyable_section_data_struct));
4365       if (som_section_data (section)->copy_data == NULL)
4366         {
4367           bfd_set_error (bfd_error_no_memory);
4368           return false;
4369         }
4370     }
4371   som_section_data (section)->copy_data->sort_key = sort_key;
4372   som_section_data (section)->copy_data->is_defined = defined;
4373   som_section_data (section)->copy_data->is_private = private;
4374   som_section_data (section)->copy_data->container = section;
4375   section->target_index = spnum;
4376   return true;
4377 }
4378
4379 /* Set backend info for subsections which can not be described 
4380    in the BFD data structures.  */
4381
4382 boolean
4383 bfd_som_set_subsection_attributes (section, container, access,
4384                                    sort_key, quadrant)
4385      asection *section;
4386      asection *container;
4387      int access;
4388      unsigned int sort_key;
4389      int quadrant;
4390 {
4391   /* Allocate memory to hold the magic information.  */
4392   if (som_section_data (section)->copy_data == NULL)
4393     {
4394       som_section_data (section)->copy_data
4395         = (struct som_copyable_section_data_struct *)
4396           bfd_zalloc (section->owner,
4397                       sizeof (struct som_copyable_section_data_struct));
4398       if (som_section_data (section)->copy_data == NULL)
4399         {
4400           bfd_set_error (bfd_error_no_memory);
4401           return false;
4402         }
4403     }
4404   som_section_data (section)->copy_data->sort_key = sort_key;
4405   som_section_data (section)->copy_data->access_control_bits = access;
4406   som_section_data (section)->copy_data->quadrant = quadrant;
4407   som_section_data (section)->copy_data->container = container;
4408   return true;
4409 }
4410
4411 /* Set the full SOM symbol type.  SOM needs far more symbol information
4412    than any other object file format I'm aware of.  It is mandatory
4413    to be able to know if a symbol is an entry point, millicode, data,
4414    code, absolute, storage request, or procedure label.  If you get
4415    the symbol type wrong your program will not link.  */
4416
4417 void
4418 bfd_som_set_symbol_type (symbol, type)
4419      asymbol *symbol;
4420      unsigned int type;
4421 {
4422   som_symbol_data (symbol)->som_type = type;
4423 }
4424
4425 /* Attach 64bits of unwind information to a symbol (which hopefully
4426    is a function of some kind!).  It would be better to keep this
4427    in the R_ENTRY relocation, but there is not enough space.  */
4428
4429 void
4430 bfd_som_attach_unwind_info (symbol, unwind_desc)
4431      asymbol *symbol;
4432      char *unwind_desc;
4433 {
4434   som_symbol_data (symbol)->unwind = unwind_desc;
4435 }
4436
4437 /* Attach an auxiliary header to the BFD backend so that it may be
4438    written into the object file.  */
4439 boolean
4440 bfd_som_attach_aux_hdr (abfd, type, string)
4441      bfd *abfd;
4442      int type;
4443      char *string;
4444 {
4445   if (type == VERSION_AUX_ID)
4446     {
4447       int len = strlen (string);
4448       int pad = 0;
4449
4450       if (len % 4)
4451         pad = (4 - (len % 4));
4452       obj_som_version_hdr (abfd) = (struct user_string_aux_hdr *)
4453         bfd_zalloc (abfd, sizeof (struct aux_id)
4454                               + sizeof (unsigned int) + len + pad);
4455       if (!obj_som_version_hdr (abfd))
4456         {
4457           bfd_set_error (bfd_error_no_memory);
4458           return false;
4459         }
4460       obj_som_version_hdr (abfd)->header_id.type = VERSION_AUX_ID;
4461       obj_som_version_hdr (abfd)->header_id.length = len + pad;
4462       obj_som_version_hdr (abfd)->header_id.length += sizeof (int);
4463       obj_som_version_hdr (abfd)->string_length = len;
4464       strncpy (obj_som_version_hdr (abfd)->user_string, string, len);
4465     }
4466   else if (type == COPYRIGHT_AUX_ID)
4467     {
4468       int len = strlen (string);
4469       int pad = 0;
4470
4471       if (len % 4)
4472         pad = (4 - (len % 4));
4473       obj_som_copyright_hdr (abfd) = (struct copyright_aux_hdr *)
4474         bfd_zalloc (abfd, sizeof (struct aux_id)
4475                             + sizeof (unsigned int) + len + pad);
4476       if (!obj_som_copyright_hdr (abfd))
4477         {
4478           bfd_set_error (bfd_error_no_error);
4479           return false;
4480         }
4481       obj_som_copyright_hdr (abfd)->header_id.type = COPYRIGHT_AUX_ID;
4482       obj_som_copyright_hdr (abfd)->header_id.length = len + pad;
4483       obj_som_copyright_hdr (abfd)->header_id.length += sizeof (int);
4484       obj_som_copyright_hdr (abfd)->string_length = len;
4485       strcpy (obj_som_copyright_hdr (abfd)->copyright, string);
4486     }
4487   return true;
4488 }
4489
4490 static boolean
4491 som_set_section_contents (abfd, section, location, offset, count)
4492      bfd *abfd;
4493      sec_ptr section;
4494      PTR location;
4495      file_ptr offset;
4496      bfd_size_type count;
4497 {
4498   if (abfd->output_has_begun == false)
4499     {
4500       /* Set up fixed parts of the file, space, and subspace headers.
4501          Notify the world that output has begun.  */
4502       som_prep_headers (abfd);
4503       abfd->output_has_begun = true;
4504       /* Start writing the object file.  This include all the string
4505          tables, fixup streams, and other portions of the object file.  */
4506       som_begin_writing (abfd);
4507     }
4508
4509   /* Only write subspaces which have "real" contents (eg. the contents
4510      are not generated at run time by the OS).  */
4511   if (!som_is_subspace (section)
4512       || ((section->flags & (SEC_LOAD | SEC_DEBUGGING)) == 0))
4513     return true;
4514
4515   /* Seek to the proper offset within the object file and write the
4516      data.  */
4517   offset += som_section_data (section)->subspace_dict->file_loc_init_value; 
4518   if (bfd_seek (abfd, offset, SEEK_SET) == -1)
4519     {
4520       bfd_set_error (bfd_error_system_call);
4521       return false;
4522     }
4523
4524   if (bfd_write ((PTR) location, 1, count, abfd) != count)
4525     {
4526       bfd_set_error (bfd_error_system_call);
4527       return false;
4528     }
4529   return true;
4530 }
4531
4532 static boolean
4533 som_set_arch_mach (abfd, arch, machine)
4534      bfd *abfd;
4535      enum bfd_architecture arch;
4536      unsigned long machine;
4537 {
4538   /* Allow any architecture to be supported by the SOM backend */
4539   return bfd_default_set_arch_mach (abfd, arch, machine);
4540 }
4541
4542 static boolean
4543 som_find_nearest_line (abfd, section, symbols, offset, filename_ptr,
4544                         functionname_ptr, line_ptr)
4545      bfd *abfd;
4546      asection *section;
4547      asymbol **symbols;
4548      bfd_vma offset;
4549      CONST char **filename_ptr;
4550      CONST char **functionname_ptr;
4551      unsigned int *line_ptr;
4552 {
4553   fprintf (stderr, "som_find_nearest_line unimplemented\n");
4554   fflush (stderr);
4555   abort ();
4556   return (false);
4557 }
4558
4559 static int
4560 som_sizeof_headers (abfd, reloc)
4561      bfd *abfd;
4562      boolean reloc;
4563 {
4564   fprintf (stderr, "som_sizeof_headers unimplemented\n");
4565   fflush (stderr);
4566   abort ();
4567   return (0);
4568 }
4569
4570 /* Return the single-character symbol type corresponding to
4571    SOM section S, or '?' for an unknown SOM section.  */
4572
4573 static char
4574 som_section_type (s)
4575      const char *s;
4576 {
4577   const struct section_to_type *t;
4578
4579   for (t = &stt[0]; t->section; t++)
4580     if (!strcmp (s, t->section))
4581       return t->type;
4582   return '?';
4583 }
4584
4585 static int
4586 som_decode_symclass (symbol)
4587      asymbol *symbol;
4588 {
4589   char c;
4590
4591   if (bfd_is_com_section (symbol->section))
4592     return 'C';
4593   if (symbol->section == &bfd_und_section)
4594     return 'U';
4595   if (symbol->section == &bfd_ind_section)
4596     return 'I';
4597   if (!(symbol->flags & (BSF_GLOBAL|BSF_LOCAL)))
4598     return '?';
4599
4600   if (symbol->section == &bfd_abs_section)
4601     c = 'a';
4602   else if (symbol->section)
4603     c = som_section_type (symbol->section->name);
4604   else
4605     return '?';
4606   if (symbol->flags & BSF_GLOBAL)
4607     c = toupper (c);
4608   return c;
4609 }
4610
4611 /* Return information about SOM symbol SYMBOL in RET.  */
4612
4613 static void
4614 som_get_symbol_info (ignore_abfd, symbol, ret)
4615      bfd *ignore_abfd;
4616      asymbol *symbol;
4617      symbol_info *ret;
4618 {
4619   ret->type = som_decode_symclass (symbol);
4620   if (ret->type != 'U')
4621     ret->value = symbol->value+symbol->section->vma;
4622   else
4623     ret->value = 0;
4624   ret->name = symbol->name;
4625 }
4626
4627 /* Count the number of symbols in the archive symbol table.  Necessary
4628    so that we can allocate space for all the carsyms at once.  */
4629
4630 static boolean
4631 som_bfd_count_ar_symbols (abfd, lst_header, count)
4632      bfd *abfd;
4633      struct lst_header *lst_header;
4634      symindex *count;
4635 {
4636   unsigned int i;
4637   unsigned int *hash_table = NULL;
4638   file_ptr lst_filepos = bfd_tell (abfd) - sizeof (struct lst_header);
4639
4640   hash_table = 
4641     (unsigned int *) malloc (lst_header->hash_size * sizeof (unsigned int));
4642   if (hash_table == NULL && lst_header->hash_size != 0)
4643     {
4644       bfd_set_error (bfd_error_no_memory);
4645       goto error_return;
4646     }
4647
4648   /* Don't forget to initialize the counter!  */
4649   *count = 0;
4650
4651   /* Read in the hash table.  The has table is an array of 32bit file offsets
4652      which point to the hash chains.  */
4653   if (bfd_read ((PTR) hash_table, lst_header->hash_size, 4, abfd)
4654       != lst_header->hash_size * 4)
4655     {
4656       bfd_set_error (bfd_error_system_call);
4657       goto error_return;
4658     }
4659
4660   /* Walk each chain counting the number of symbols found on that particular
4661      chain.  */
4662   for (i = 0; i < lst_header->hash_size; i++)
4663     {
4664       struct lst_symbol_record lst_symbol;
4665
4666       /* An empty chain has zero as it's file offset.  */
4667       if (hash_table[i] == 0)
4668         continue;
4669
4670       /* Seek to the first symbol in this hash chain.  */
4671       if (bfd_seek (abfd, lst_filepos + hash_table[i], SEEK_SET) < 0)
4672         {
4673           bfd_set_error (bfd_error_system_call);
4674           goto error_return;
4675         }
4676
4677       /* Read in this symbol and update the counter.  */
4678       if (bfd_read ((PTR) & lst_symbol, 1, sizeof (lst_symbol), abfd)
4679           != sizeof (lst_symbol))
4680         {
4681           bfd_set_error (bfd_error_system_call);
4682           goto error_return;
4683         }
4684       (*count)++;
4685
4686       /* Now iterate through the rest of the symbols on this chain.  */
4687       while (lst_symbol.next_entry)
4688         {
4689
4690           /* Seek to the next symbol.  */
4691           if (bfd_seek (abfd, lst_filepos + lst_symbol.next_entry, SEEK_SET)
4692               < 0)
4693             {
4694               bfd_set_error (bfd_error_system_call);
4695               goto error_return;
4696             }
4697
4698           /* Read the symbol in and update the counter.  */
4699           if (bfd_read ((PTR) & lst_symbol, 1, sizeof (lst_symbol), abfd)
4700               != sizeof (lst_symbol))
4701             {
4702               bfd_set_error (bfd_error_system_call);
4703               goto error_return;
4704             }
4705           (*count)++;
4706         }
4707     }
4708   if (hash_table != NULL)
4709     free (hash_table);
4710   return true;
4711
4712  error_return:
4713   if (hash_table != NULL)
4714     free (hash_table);
4715   return false;
4716 }
4717
4718 /* Fill in the canonical archive symbols (SYMS) from the archive described
4719    by ABFD and LST_HEADER.  */
4720
4721 static boolean
4722 som_bfd_fill_in_ar_symbols (abfd, lst_header, syms)
4723      bfd *abfd;
4724      struct lst_header *lst_header;
4725      carsym **syms;
4726 {
4727   unsigned int i, len;
4728   carsym *set = syms[0];
4729   unsigned int *hash_table = NULL;
4730   struct som_entry *som_dict = NULL;
4731   file_ptr lst_filepos = bfd_tell (abfd) - sizeof (struct lst_header);
4732
4733   hash_table = 
4734     (unsigned int *) malloc (lst_header->hash_size * sizeof (unsigned int));
4735   if (hash_table == NULL && lst_header->hash_size != 0)
4736     {
4737       bfd_set_error (bfd_error_no_memory);
4738       goto error_return;
4739     }
4740
4741   som_dict =
4742     (struct som_entry *) malloc (lst_header->module_count
4743                                  * sizeof (struct som_entry));
4744   if (som_dict == NULL && lst_header->module_count != 0)
4745     {
4746       bfd_set_error (bfd_error_no_memory);
4747       goto error_return;
4748     }
4749
4750   /* Read in the hash table.  The has table is an array of 32bit file offsets
4751      which point to the hash chains.  */
4752   if (bfd_read ((PTR) hash_table, lst_header->hash_size, 4, abfd)
4753       != lst_header->hash_size * 4)
4754     {
4755       bfd_set_error (bfd_error_system_call);
4756       goto error_return;
4757     }
4758
4759   /* Seek to and read in the SOM dictionary.  We will need this to fill
4760      in the carsym's filepos field.  */
4761   if (bfd_seek (abfd, lst_filepos + lst_header->dir_loc, SEEK_SET) < 0)
4762     {
4763       bfd_set_error (bfd_error_system_call);
4764       goto error_return;
4765     }
4766
4767   if (bfd_read ((PTR) som_dict, lst_header->module_count, 
4768                 sizeof (struct som_entry), abfd)
4769       != lst_header->module_count * sizeof (struct som_entry))
4770     {
4771       bfd_set_error (bfd_error_system_call);
4772       goto error_return;
4773     }
4774
4775   /* Walk each chain filling in the carsyms as we go along.  */
4776   for (i = 0; i < lst_header->hash_size; i++)
4777     {
4778       struct lst_symbol_record lst_symbol;
4779
4780       /* An empty chain has zero as it's file offset.  */
4781       if (hash_table[i] == 0)
4782         continue;
4783
4784       /* Seek to and read the first symbol on the chain.  */
4785       if (bfd_seek (abfd, lst_filepos + hash_table[i], SEEK_SET) < 0)
4786         {
4787           bfd_set_error (bfd_error_system_call);
4788           goto error_return;
4789         }
4790
4791       if (bfd_read ((PTR) & lst_symbol, 1, sizeof (lst_symbol), abfd)
4792           != sizeof (lst_symbol))
4793         {
4794           bfd_set_error (bfd_error_system_call);
4795           goto error_return;
4796         }
4797
4798       /* Get the name of the symbol, first get the length which is stored
4799          as a 32bit integer just before the symbol.
4800
4801          One might ask why we don't just read in the entire string table
4802          and index into it.  Well, according to the SOM ABI the string
4803          index can point *anywhere* in the archive to save space, so just
4804          using the string table would not be safe.  */
4805       if (bfd_seek (abfd, lst_filepos + lst_header->string_loc
4806                             + lst_symbol.name.n_strx - 4, SEEK_SET) < 0)
4807         {
4808           bfd_set_error (bfd_error_system_call);
4809           goto error_return;
4810         }
4811
4812       if (bfd_read (&len, 1, 4, abfd) != 4)
4813         {
4814           bfd_set_error (bfd_error_system_call);
4815           goto error_return;
4816         }
4817
4818       /* Allocate space for the name and null terminate it too.  */
4819       set->name = bfd_zalloc (abfd, len + 1);
4820       if (!set->name)
4821         {
4822           bfd_set_error (bfd_error_no_memory);
4823           goto error_return;
4824         }
4825       if (bfd_read (set->name, 1, len, abfd) != len)
4826         {
4827           bfd_set_error (bfd_error_system_call);
4828           goto error_return;
4829         }
4830       set->name[len] = 0;
4831
4832       /* Fill in the file offset.  Note that the "location" field points
4833          to the SOM itself, not the ar_hdr in front of it.  */
4834       set->file_offset = som_dict[lst_symbol.som_index].location
4835                           - sizeof (struct ar_hdr);
4836
4837       /* Go to the next symbol.  */
4838       set++;
4839
4840       /* Iterate through the rest of the chain.  */
4841       while (lst_symbol.next_entry)
4842         {
4843           /* Seek to the next symbol and read it in.  */
4844           if (bfd_seek (abfd, lst_filepos + lst_symbol.next_entry, SEEK_SET)
4845               < 0)
4846             {
4847               bfd_set_error (bfd_error_system_call);
4848               goto error_return;
4849             }
4850
4851           if (bfd_read ((PTR) & lst_symbol, 1, sizeof (lst_symbol), abfd)
4852               != sizeof (lst_symbol))
4853             {
4854               bfd_set_error (bfd_error_system_call);
4855               goto error_return;
4856             }
4857
4858           /* Seek to the name length & string and read them in.  */
4859           if (bfd_seek (abfd, lst_filepos + lst_header->string_loc 
4860                                 + lst_symbol.name.n_strx - 4, SEEK_SET) < 0)
4861             {
4862               bfd_set_error (bfd_error_system_call);
4863               goto error_return;
4864             }
4865
4866           if (bfd_read (&len, 1, 4, abfd) != 4)
4867             {
4868               bfd_set_error (bfd_error_system_call);
4869               goto error_return;
4870             }
4871
4872           /* Allocate space for the name and null terminate it too.  */
4873           set->name = bfd_zalloc (abfd, len + 1);
4874           if (!set->name)
4875             {
4876               bfd_set_error (bfd_error_no_memory);
4877               goto error_return;
4878             }
4879           if (bfd_read (set->name, 1, len, abfd) != len)
4880             {
4881               bfd_set_error (bfd_error_system_call);
4882               goto error_return;
4883             }
4884           set->name[len] = 0;
4885
4886           /* Fill in the file offset.  Note that the "location" field points
4887              to the SOM itself, not the ar_hdr in front of it.  */
4888           set->file_offset = som_dict[lst_symbol.som_index].location
4889                                - sizeof (struct ar_hdr);
4890
4891           /* Go on to the next symbol.  */
4892           set++;
4893         }
4894     }
4895   /* If we haven't died by now, then we successfully read the entire 
4896      archive symbol table.  */
4897   if (hash_table != NULL)
4898     free (hash_table);
4899   if (som_dict != NULL)
4900     free (som_dict);
4901   return true;
4902
4903  error_return:
4904   if (hash_table != NULL)
4905     free (hash_table);
4906   if (som_dict != NULL)
4907     free (som_dict);
4908   return false;
4909 }
4910
4911 /* Read in the LST from the archive.  */
4912 static boolean
4913 som_slurp_armap (abfd)
4914      bfd *abfd;
4915 {
4916   struct lst_header lst_header;
4917   struct ar_hdr ar_header;
4918   unsigned int parsed_size;
4919   struct artdata *ardata = bfd_ardata (abfd);
4920   char nextname[17];
4921   int i = bfd_read ((PTR) nextname, 1, 16, abfd);
4922
4923   /* Special cases.  */
4924   if (i == 0)
4925     return true;
4926   if (i != 16)
4927     return false;
4928
4929   if (bfd_seek (abfd, (file_ptr) - 16, SEEK_CUR) < 0)
4930     {
4931       bfd_set_error (bfd_error_system_call);
4932       return false;
4933     }
4934
4935   /* For archives without .o files there is no symbol table.  */
4936   if (strncmp (nextname, "/               ", 16))
4937     {
4938       bfd_has_map (abfd) = false;
4939       return true;
4940     }
4941
4942   /* Read in and sanity check the archive header.  */
4943   if (bfd_read ((PTR) &ar_header, 1, sizeof (struct ar_hdr), abfd)
4944       != sizeof (struct ar_hdr))
4945     {
4946       bfd_set_error (bfd_error_system_call);
4947       return false;
4948     }
4949
4950   if (strncmp (ar_header.ar_fmag, ARFMAG, 2))
4951     {
4952       bfd_set_error (bfd_error_malformed_archive);
4953       return false;
4954     }
4955
4956   /* How big is the archive symbol table entry?  */
4957   errno = 0;
4958   parsed_size = strtol (ar_header.ar_size, NULL, 10);
4959   if (errno != 0)
4960     {
4961       bfd_set_error (bfd_error_malformed_archive);
4962       return false;
4963     }
4964
4965   /* Save off the file offset of the first real user data.  */
4966   ardata->first_file_filepos = bfd_tell (abfd) + parsed_size;
4967
4968   /* Read in the library symbol table.  We'll make heavy use of this
4969      in just a minute.  */
4970   if (bfd_read ((PTR) & lst_header, 1, sizeof (struct lst_header), abfd)
4971       != sizeof (struct lst_header))
4972     {
4973       bfd_set_error (bfd_error_system_call);
4974       return false;
4975     }
4976
4977   /* Sanity check.  */
4978   if (lst_header.a_magic != LIBMAGIC)
4979     {
4980       bfd_set_error (bfd_error_malformed_archive);
4981       return false;
4982     }
4983
4984   /* Count the number of symbols in the library symbol table.  */
4985   if (som_bfd_count_ar_symbols (abfd, &lst_header, &ardata->symdef_count)
4986       == false)
4987     return false;
4988
4989   /* Get back to the start of the library symbol table.  */
4990   if (bfd_seek (abfd, ardata->first_file_filepos - parsed_size 
4991                         + sizeof (struct lst_header), SEEK_SET) < 0)
4992     {
4993       bfd_set_error (bfd_error_system_call);
4994       return false;
4995     }
4996
4997   /* Initializae the cache and allocate space for the library symbols.  */
4998   ardata->cache = 0;
4999   ardata->symdefs = (carsym *) bfd_alloc (abfd,
5000                                           (ardata->symdef_count
5001                                            * sizeof (carsym)));
5002   if (!ardata->symdefs)
5003     {
5004       bfd_set_error (bfd_error_no_memory);
5005       return false;
5006     }
5007
5008   /* Now fill in the canonical archive symbols.  */
5009   if (som_bfd_fill_in_ar_symbols (abfd, &lst_header, &ardata->symdefs)
5010       == false)
5011     return false;
5012
5013   /* Seek back to the "first" file in the archive.  Note the "first"
5014      file may be the extended name table.  */
5015   if (bfd_seek (abfd, ardata->first_file_filepos, SEEK_SET) < 0)
5016     {
5017       bfd_set_error (bfd_error_system_call);
5018       return false;
5019     }
5020
5021   /* Notify the generic archive code that we have a symbol map.  */
5022   bfd_has_map (abfd) = true;
5023   return true;
5024 }
5025
5026 /* Begin preparing to write a SOM library symbol table.
5027
5028    As part of the prep work we need to determine the number of symbols
5029    and the size of the associated string section.  */
5030
5031 static boolean
5032 som_bfd_prep_for_ar_write (abfd, num_syms, stringsize)
5033      bfd *abfd;
5034      unsigned int *num_syms, *stringsize;
5035 {
5036   bfd *curr_bfd = abfd->archive_head;
5037
5038   /* Some initialization.  */
5039   *num_syms = 0;
5040   *stringsize = 0;
5041
5042   /* Iterate over each BFD within this archive.  */
5043   while (curr_bfd != NULL)
5044     {
5045       unsigned int curr_count, i;
5046       som_symbol_type *sym;
5047
5048       /* Make sure the symbol table has been read, then snag a pointer
5049          to it.  It's a little slimey to grab the symbols via obj_som_symtab,
5050          but doing so avoids allocating lots of extra memory.  */
5051       if (som_slurp_symbol_table (curr_bfd) == false)
5052         return false;
5053
5054       sym = obj_som_symtab (curr_bfd);
5055       curr_count = bfd_get_symcount (curr_bfd);
5056
5057       /* Examine each symbol to determine if it belongs in the
5058          library symbol table.  */
5059       for (i = 0; i < curr_count; i++, sym++)
5060         {
5061           struct som_misc_symbol_info info;
5062
5063           /* Derive SOM information from the BFD symbol.  */
5064           som_bfd_derive_misc_symbol_info (curr_bfd, &sym->symbol, &info);
5065
5066           /* Should we include this symbol?  */
5067           if (info.symbol_type == ST_NULL
5068               || info.symbol_type == ST_SYM_EXT
5069               || info.symbol_type == ST_ARG_EXT)
5070             continue;
5071
5072           /* Only global symbols and unsatisfied commons.  */
5073           if (info.symbol_scope != SS_UNIVERSAL
5074               && info.symbol_type != ST_STORAGE)
5075             continue;
5076
5077           /* Do no include undefined symbols.  */
5078           if (sym->symbol.section == &bfd_und_section)
5079             continue;
5080
5081           /* Bump the various counters, being careful to honor
5082              alignment considerations in the string table.  */
5083           (*num_syms)++;
5084           *stringsize = *stringsize + strlen (sym->symbol.name) + 5;
5085           while (*stringsize % 4)
5086             (*stringsize)++;
5087         }
5088
5089       curr_bfd = curr_bfd->next;
5090     }
5091   return true;
5092 }
5093
5094 /* Hash a symbol name based on the hashing algorithm presented in the
5095    SOM ABI.  */
5096 static unsigned int
5097 som_bfd_ar_symbol_hash (symbol)
5098      asymbol *symbol;
5099 {
5100   unsigned int len = strlen (symbol->name);
5101
5102   /* Names with length 1 are special.  */
5103   if (len == 1)
5104     return 0x1000100 | (symbol->name[0] << 16) | symbol->name[0];
5105
5106   return ((len & 0x7f) << 24) | (symbol->name[1] << 16)
5107           | (symbol->name[len-2] << 8) | symbol->name[len-1];
5108 }
5109
5110 static CONST char *
5111 normalize (file)
5112      CONST char *file;
5113 {
5114   CONST char *filename = strrchr (file, '/');
5115
5116   if (filename != NULL)
5117     filename++;
5118   else
5119     filename = file;
5120   return filename;
5121 }
5122
5123 /* Do the bulk of the work required to write the SOM library
5124    symbol table.  */
5125    
5126 static boolean
5127 som_bfd_ar_write_symbol_stuff (abfd, nsyms, string_size, lst)
5128      bfd *abfd;
5129      unsigned int nsyms, string_size;
5130      struct lst_header lst;
5131 {
5132   file_ptr lst_filepos;
5133   char *strings = NULL, *p;
5134   struct lst_symbol_record *lst_syms = NULL, *curr_lst_sym;
5135   bfd *curr_bfd;
5136   unsigned int *hash_table = NULL;
5137   struct som_entry *som_dict = NULL;
5138   struct lst_symbol_record **last_hash_entry = NULL;
5139   unsigned int curr_som_offset, som_index, extended_name_length = 0;
5140   unsigned int maxname = abfd->xvec->ar_max_namelen;
5141
5142   hash_table =
5143     (unsigned int *) malloc (lst.hash_size * sizeof (unsigned int));
5144   if (hash_table == NULL && lst.hash_size != 0)
5145     {
5146       bfd_set_error (bfd_error_no_memory);
5147       goto error_return;
5148     }
5149   som_dict =
5150     (struct som_entry *) malloc (lst.module_count
5151                                  * sizeof (struct som_entry));
5152   if (som_dict == NULL && lst.module_count != 0)
5153     {
5154       bfd_set_error (bfd_error_no_memory);
5155       goto error_return;
5156     }
5157
5158   last_hash_entry =
5159     ((struct lst_symbol_record **)
5160      malloc (lst.hash_size * sizeof (struct lst_symbol_record *)));
5161   if (last_hash_entry == NULL && lst.hash_size != 0)
5162     {
5163       bfd_set_error (bfd_error_no_memory);
5164       goto error_return;
5165     }
5166
5167   /* Lots of fields are file positions relative to the start
5168      of the lst record.  So save its location.  */
5169   lst_filepos = bfd_tell (abfd) - sizeof (struct lst_header);
5170
5171   /* Some initialization.  */
5172   memset (hash_table, 0, 4 * lst.hash_size);
5173   memset (som_dict, 0, lst.module_count * sizeof (struct som_entry));
5174   memset (last_hash_entry, 0,   
5175           lst.hash_size * sizeof (struct lst_symbol_record *));
5176
5177   /* Symbols have som_index fields, so we have to keep track of the
5178      index of each SOM in the archive.
5179
5180      The SOM dictionary has (among other things) the absolute file
5181      position for the SOM which a particular dictionary entry
5182      describes.  We have to compute that information as we iterate
5183      through the SOMs/symbols.  */
5184   som_index = 0;
5185   curr_som_offset = 8 + 2 * sizeof (struct ar_hdr) + lst.file_end;
5186
5187   /* Yow!  We have to know the size of the extended name table
5188      too.  */
5189   for (curr_bfd = abfd->archive_head;
5190        curr_bfd != NULL;
5191        curr_bfd = curr_bfd->next)
5192     {
5193       CONST char *normal = normalize (curr_bfd->filename);
5194       unsigned int thislen;
5195
5196       if (!normal)
5197         {
5198           bfd_set_error (bfd_error_no_memory);
5199           return false;
5200         }
5201       thislen = strlen (normal);
5202       if (thislen > maxname)
5203         extended_name_length += thislen + 1;
5204     }
5205
5206   /* Make room for the archive header and the contents of the
5207      extended string table.  */
5208   if (extended_name_length)
5209     curr_som_offset += extended_name_length + sizeof (struct ar_hdr);
5210
5211   /* Make sure we're properly aligned.  */
5212   curr_som_offset = (curr_som_offset + 0x1) & ~0x1;
5213
5214   /* FIXME should be done with buffers just like everything else... */
5215   lst_syms = malloc (nsyms * sizeof (struct lst_symbol_record));
5216   if (lst_syms == NULL && nsyms != 0)
5217     {
5218       bfd_set_error (bfd_error_no_memory);
5219       goto error_return;
5220     }
5221   strings = malloc (string_size);
5222   if (strings == NULL && string_size != 0)
5223     {
5224       bfd_set_error (bfd_error_no_memory);
5225       goto error_return;
5226     }
5227
5228   p = strings;
5229   curr_lst_sym = lst_syms;
5230
5231   curr_bfd = abfd->archive_head;
5232   while (curr_bfd != NULL)
5233     {
5234       unsigned int curr_count, i;
5235       som_symbol_type *sym;
5236
5237       /* Make sure the symbol table has been read, then snag a pointer
5238          to it.  It's a little slimey to grab the symbols via obj_som_symtab,
5239          but doing so avoids allocating lots of extra memory.  */
5240       if (som_slurp_symbol_table (curr_bfd) == false)
5241         goto error_return;
5242
5243       sym = obj_som_symtab (curr_bfd);
5244       curr_count = bfd_get_symcount (curr_bfd);
5245
5246       for (i = 0; i < curr_count; i++, sym++)
5247         {
5248           struct som_misc_symbol_info info;
5249
5250           /* Derive SOM information from the BFD symbol.  */
5251           som_bfd_derive_misc_symbol_info (curr_bfd, &sym->symbol, &info);
5252
5253           /* Should we include this symbol?  */
5254           if (info.symbol_type == ST_NULL
5255               || info.symbol_type == ST_SYM_EXT
5256               || info.symbol_type == ST_ARG_EXT)
5257             continue;
5258
5259           /* Only global symbols and unsatisfied commons.  */
5260           if (info.symbol_scope != SS_UNIVERSAL
5261               && info.symbol_type != ST_STORAGE)
5262             continue;
5263
5264           /* Do no include undefined symbols.  */
5265           if (sym->symbol.section == &bfd_und_section)
5266             continue;
5267
5268           /* If this is the first symbol from this SOM, then update
5269              the SOM dictionary too.  */
5270           if (som_dict[som_index].location == 0)
5271             {
5272               som_dict[som_index].location = curr_som_offset;
5273               som_dict[som_index].length = arelt_size (curr_bfd);
5274             }
5275
5276           /* Fill in the lst symbol record.  */
5277           curr_lst_sym->hidden = 0;
5278           curr_lst_sym->secondary_def = 0;
5279           curr_lst_sym->symbol_type = info.symbol_type;
5280           curr_lst_sym->symbol_scope = info.symbol_scope;
5281           curr_lst_sym->check_level = 0;
5282           curr_lst_sym->must_qualify = 0;
5283           curr_lst_sym->initially_frozen = 0;
5284           curr_lst_sym->memory_resident = 0;
5285           curr_lst_sym->is_common = (sym->symbol.section == &bfd_com_section);
5286           curr_lst_sym->dup_common = 0;
5287           curr_lst_sym->xleast = 0;
5288           curr_lst_sym->arg_reloc = info.arg_reloc;
5289           curr_lst_sym->name.n_strx = p - strings + 4;
5290           curr_lst_sym->qualifier_name.n_strx = 0;
5291           curr_lst_sym->symbol_info = info.symbol_info;
5292           curr_lst_sym->symbol_value = info.symbol_value;
5293           curr_lst_sym->symbol_descriptor = 0;
5294           curr_lst_sym->reserved = 0;
5295           curr_lst_sym->som_index = som_index;
5296           curr_lst_sym->symbol_key = som_bfd_ar_symbol_hash (&sym->symbol);
5297           curr_lst_sym->next_entry = 0;
5298
5299           /* Insert into the hash table.  */
5300           if (hash_table[curr_lst_sym->symbol_key % lst.hash_size])
5301             {
5302               struct lst_symbol_record *tmp;
5303
5304               /* There is already something at the head of this hash chain,
5305                  so tack this symbol onto the end of the chain.  */
5306               tmp = last_hash_entry[curr_lst_sym->symbol_key % lst.hash_size];
5307               tmp->next_entry
5308                 = (curr_lst_sym - lst_syms) * sizeof (struct lst_symbol_record)
5309                   + lst.hash_size * 4 
5310                   + lst.module_count * sizeof (struct som_entry)
5311                   + sizeof (struct lst_header);
5312             }
5313           else
5314             {
5315               /* First entry in this hash chain.  */
5316               hash_table[curr_lst_sym->symbol_key % lst.hash_size]
5317                 = (curr_lst_sym - lst_syms) * sizeof (struct lst_symbol_record)
5318                   + lst.hash_size * 4 
5319                   + lst.module_count * sizeof (struct som_entry)
5320                   + sizeof (struct lst_header);
5321             }
5322
5323           /* Keep track of the last symbol we added to this chain so we can
5324              easily update its next_entry pointer.  */
5325           last_hash_entry[curr_lst_sym->symbol_key % lst.hash_size]
5326             = curr_lst_sym;
5327
5328
5329           /* Update the string table.  */
5330           bfd_put_32 (abfd, strlen (sym->symbol.name), p);
5331           p += 4;
5332           strcpy (p, sym->symbol.name);
5333           p += strlen (sym->symbol.name) + 1;
5334           while ((int)p % 4)
5335             {
5336               bfd_put_8 (abfd, 0, p);
5337               p++;
5338             }
5339
5340           /* Head to the next symbol.  */
5341           curr_lst_sym++;
5342         }
5343
5344       /* Keep track of where each SOM will finally reside; then look
5345          at the next BFD.  */
5346       curr_som_offset += arelt_size (curr_bfd) + sizeof (struct ar_hdr);
5347       curr_bfd = curr_bfd->next;
5348       som_index++;
5349     }
5350
5351   /* Now scribble out the hash table.  */
5352   if (bfd_write ((PTR) hash_table, lst.hash_size, 4, abfd)
5353       != lst.hash_size * 4)
5354     {
5355       bfd_set_error (bfd_error_system_call);
5356       goto error_return;
5357     }
5358
5359   /* Then the SOM dictionary.  */
5360   if (bfd_write ((PTR) som_dict, lst.module_count,
5361                  sizeof (struct som_entry), abfd)
5362       != lst.module_count * sizeof (struct som_entry))
5363     {
5364       bfd_set_error (bfd_error_system_call);
5365       goto error_return;
5366     }
5367
5368   /* The library symbols.  */
5369   if (bfd_write ((PTR) lst_syms, nsyms, sizeof (struct lst_symbol_record), abfd)
5370       != nsyms * sizeof (struct lst_symbol_record))
5371     {
5372       bfd_set_error (bfd_error_system_call);
5373       goto error_return;
5374     }
5375
5376   /* And finally the strings.  */
5377   if (bfd_write ((PTR) strings, string_size, 1, abfd) != string_size)
5378     {
5379       bfd_set_error (bfd_error_system_call);
5380       goto error_return;
5381     }
5382
5383   if (hash_table != NULL)
5384     free (hash_table);
5385   if (som_dict != NULL)
5386     free (som_dict);
5387   if (last_hash_entry != NULL)
5388     free (last_hash_entry);
5389   if (lst_syms != NULL)
5390     free (lst_syms);
5391   if (strings != NULL)
5392     free (strings);
5393   return true;
5394
5395  error_return:
5396   if (hash_table != NULL)
5397     free (hash_table);
5398   if (som_dict != NULL)
5399     free (som_dict);
5400   if (last_hash_entry != NULL)
5401     free (last_hash_entry);
5402   if (lst_syms != NULL)
5403     free (lst_syms);
5404   if (strings != NULL)
5405     free (strings);
5406
5407   return false;
5408 }
5409
5410 /* Write out the LST for the archive.
5411
5412    You'll never believe this is really how armaps are handled in SOM...  */
5413
5414 static boolean
5415 som_write_armap (abfd)
5416      bfd *abfd;
5417 {
5418   bfd *curr_bfd;
5419   struct stat statbuf;
5420   unsigned int i, lst_size, nsyms, stringsize;
5421   struct ar_hdr hdr;
5422   struct lst_header lst;
5423   int *p;
5424  
5425   /* We'll use this for the archive's date and mode later.  */
5426   if (stat (abfd->filename, &statbuf) != 0)
5427     {
5428       bfd_set_error (bfd_error_system_call);
5429       return false;
5430     }
5431   /* Fudge factor.  */
5432   bfd_ardata (abfd)->armap_timestamp = statbuf.st_mtime + 60;
5433
5434   /* Account for the lst header first.  */
5435   lst_size = sizeof (struct lst_header);
5436
5437   /* Start building the LST header.  */
5438   lst.system_id = HP9000S800_ID;
5439   lst.a_magic = LIBMAGIC;
5440   lst.version_id = VERSION_ID;
5441   lst.file_time.secs = 0;
5442   lst.file_time.nanosecs = 0;
5443
5444   lst.hash_loc = lst_size;
5445   lst.hash_size = SOM_LST_HASH_SIZE;
5446
5447   /* Hash table is a SOM_LST_HASH_SIZE 32bit offsets.  */
5448   lst_size += 4 * SOM_LST_HASH_SIZE;
5449
5450   /* We need to count the number of SOMs in this archive.  */
5451   curr_bfd = abfd->archive_head;
5452   lst.module_count = 0;
5453   while (curr_bfd != NULL)
5454     {
5455       lst.module_count++;
5456       curr_bfd = curr_bfd->next;
5457     }
5458   lst.module_limit = lst.module_count;
5459   lst.dir_loc = lst_size;
5460   lst_size += sizeof (struct som_entry) * lst.module_count;
5461
5462   /* We don't support import/export tables, auxiliary headers,
5463      or free lists yet.  Make the linker work a little harder
5464      to make our life easier.  */
5465
5466   lst.export_loc = 0;
5467   lst.export_count = 0;
5468   lst.import_loc = 0;
5469   lst.aux_loc = 0;
5470   lst.aux_size = 0;
5471
5472   /* Count how many symbols we will have on the hash chains and the
5473      size of the associated string table.  */
5474   if (som_bfd_prep_for_ar_write (abfd, &nsyms, &stringsize) == false)
5475     return false;
5476
5477   lst_size += sizeof (struct lst_symbol_record) * nsyms;
5478
5479   /* For the string table.  One day we might actually use this info
5480      to avoid small seeks/reads when reading archives.  */
5481   lst.string_loc = lst_size;
5482   lst.string_size = stringsize;
5483   lst_size += stringsize;
5484
5485   /* SOM ABI says this must be zero.  */
5486   lst.free_list = 0;
5487   lst.file_end = lst_size;
5488
5489   /* Compute the checksum.  Must happen after the entire lst header
5490      has filled in.  */
5491   p = (int *)&lst;
5492   lst.checksum = 0;
5493   for (i = 0; i < sizeof (struct lst_header)/sizeof (int) - 1; i++)
5494     lst.checksum ^= *p++;
5495
5496   sprintf (hdr.ar_name, "/               ");
5497   sprintf (hdr.ar_date, "%ld", bfd_ardata (abfd)->armap_timestamp);
5498   sprintf (hdr.ar_uid, "%d", getuid ());
5499   sprintf (hdr.ar_gid, "%d", getgid ());
5500   sprintf (hdr.ar_mode, "%-8o", (unsigned int) statbuf.st_mode);
5501   sprintf (hdr.ar_size, "%-10d", (int) lst_size);
5502   hdr.ar_fmag[0] = '`';
5503   hdr.ar_fmag[1] = '\012';
5504
5505   /* Turn any nulls into spaces.  */
5506   for (i = 0; i < sizeof (struct ar_hdr); i++)
5507     if (((char *) (&hdr))[i] == '\0')
5508       (((char *) (&hdr))[i]) = ' ';
5509
5510   /* Scribble out the ar header.  */
5511   if (bfd_write ((PTR) &hdr, 1, sizeof (struct ar_hdr), abfd)
5512       != sizeof (struct ar_hdr))
5513     {
5514       bfd_set_error (bfd_error_system_call);
5515       return false;
5516     }
5517
5518   /* Now scribble out the lst header.  */
5519   if (bfd_write ((PTR) &lst, 1, sizeof (struct lst_header), abfd)
5520       != sizeof (struct lst_header))
5521     {
5522       bfd_set_error (bfd_error_system_call);
5523       return false;
5524     }
5525
5526   /* Build and write the armap.  */
5527   if (som_bfd_ar_write_symbol_stuff (abfd, nsyms, stringsize, lst) == false)
5528     return false;
5529   
5530   /* Done.  */
5531   return true;
5532 }
5533
5534 /* End of miscellaneous support functions. */
5535
5536 #define som_bfd_debug_info_start        bfd_void
5537 #define som_bfd_debug_info_end          bfd_void
5538 #define som_bfd_debug_info_accumulate   (PROTO(void,(*),(bfd*, struct sec *))) bfd_void
5539
5540 #define som_openr_next_archived_file    bfd_generic_openr_next_archived_file
5541 #define som_generic_stat_arch_elt       bfd_generic_stat_arch_elt
5542 #define som_truncate_arname             bfd_bsd_truncate_arname
5543 #define som_slurp_extended_name_table   _bfd_slurp_extended_name_table
5544
5545 #define som_get_lineno                   (struct lineno_cache_entry *(*)())bfd_nullvoidptr
5546 #define som_close_and_cleanup              bfd_generic_close_and_cleanup
5547 #define som_get_section_contents          bfd_generic_get_section_contents
5548
5549 #define som_bfd_get_relocated_section_contents \
5550  bfd_generic_get_relocated_section_contents
5551 #define som_bfd_relax_section bfd_generic_relax_section
5552 #define som_bfd_make_debug_symbol \
5553   ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
5554 #define som_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
5555 #define som_bfd_link_add_symbols _bfd_generic_link_add_symbols
5556 #define som_bfd_final_link _bfd_generic_final_link
5557
5558 /* Core file support is in the hpux-core backend.  */
5559 #define som_core_file_failing_command   _bfd_dummy_core_file_failing_command
5560 #define som_core_file_failing_signal    _bfd_dummy_core_file_failing_signal
5561 #define som_core_file_matches_executable_p      _bfd_dummy_core_file_matches_executable_p
5562
5563 bfd_target som_vec =
5564 {
5565   "som",                        /* name */
5566   bfd_target_som_flavour,
5567   true,                         /* target byte order */
5568   true,                         /* target headers byte order */
5569   (HAS_RELOC | EXEC_P |         /* object flags */
5570    HAS_LINENO | HAS_DEBUG |
5571    HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
5572   (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
5573    | SEC_ALLOC | SEC_LOAD | SEC_RELOC),         /* section flags */
5574
5575 /* leading_symbol_char: is the first char of a user symbol
5576    predictable, and if so what is it */
5577   0,
5578   '/',                          /* ar_pad_char */
5579   14,                           /* ar_max_namelen */
5580   3,                            /* minimum alignment */
5581   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
5582   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
5583   bfd_getb16, bfd_getb_signed_16, bfd_putb16,   /* data */
5584   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
5585   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
5586   bfd_getb16, bfd_getb_signed_16, bfd_putb16,   /* hdrs */
5587   {_bfd_dummy_target,
5588    som_object_p,                /* bfd_check_format */
5589    bfd_generic_archive_p,
5590    _bfd_dummy_target
5591   },
5592   {
5593     bfd_false,
5594     som_mkobject,
5595     _bfd_generic_mkarchive,
5596     bfd_false
5597   },
5598   {
5599     bfd_false,
5600     som_write_object_contents,
5601     _bfd_write_archive_contents,
5602     bfd_false,
5603   },
5604 #undef som
5605   JUMP_TABLE (som),
5606   (PTR) 0
5607 };
5608
5609 #endif /* HOST_HPPAHPUX || HOST_HPPABSD || HOST_HPPAOSF */