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