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