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