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