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