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