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