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