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