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