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