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