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