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