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