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