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