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