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