* som.c (hppa_som_reloc, som_mkobject, som_is_space)
[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
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., 59 Temple Place - Suite 330, Boston, MA
24    02111-1307, 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                 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   unsigned char *tmp_space = alloca (tmp_space_size);
2962   unsigned 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   unsigned char *tmp_space = alloca (tmp_space_size);
3067   unsigned char *p = tmp_space;
3068
3069   unsigned int strings_size = 0;
3070   unsigned 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   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, strings_size;
3580   int subspace_index = 0;
3581   file_ptr location;
3582   asection *section;
3583   unsigned long current_offset;
3584   unsigned int 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 (!strncmp (sym->symbol.name, "L$0\002", 4))
4378         {
4379           sym->symbol.flags |= BSF_SECTION_SYM;
4380           sym->symbol.name = sym->symbol.section->name;
4381         }
4382       else if (!strncmp (sym->symbol.name, "L$0\001", 4))
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   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   bfd_size_type amt = sizeof (struct som_section_data_struct);
4963
4964   newsect->used_by_bfd = bfd_zalloc (abfd, amt);
4965   if (!newsect->used_by_bfd)
4966     return FALSE;
4967   newsect->alignment_power = 3;
4968
4969   /* We allow more than three sections internally.  */
4970   return TRUE;
4971 }
4972
4973 /* Copy any private info we understand from the input symbol
4974    to the output symbol.  */
4975
4976 static bfd_boolean
4977 som_bfd_copy_private_symbol_data (bfd *ibfd,
4978                                   asymbol *isymbol,
4979                                   bfd *obfd,
4980                                   asymbol *osymbol)
4981 {
4982   struct som_symbol *input_symbol = (struct som_symbol *) isymbol;
4983   struct som_symbol *output_symbol = (struct som_symbol *) osymbol;
4984
4985   /* One day we may try to grok other private data.  */
4986   if (ibfd->xvec->flavour != bfd_target_som_flavour
4987       || obfd->xvec->flavour != bfd_target_som_flavour)
4988     return FALSE;
4989
4990   /* The only private information we need to copy is the argument relocation
4991      bits.  */
4992   output_symbol->tc_data.ap.hppa_arg_reloc =
4993     input_symbol->tc_data.ap.hppa_arg_reloc;
4994
4995   return TRUE;
4996 }
4997
4998 /* Copy any private info we understand from the input section
4999    to the output section.  */
5000
5001 static bfd_boolean
5002 som_bfd_copy_private_section_data (bfd *ibfd,
5003                                    asection *isection,
5004                                    bfd *obfd,
5005                                    asection *osection)
5006 {
5007   bfd_size_type amt;
5008
5009   /* One day we may try to grok other private data.  */
5010   if (ibfd->xvec->flavour != bfd_target_som_flavour
5011       || obfd->xvec->flavour != bfd_target_som_flavour
5012       || (!som_is_space (isection) && !som_is_subspace (isection)))
5013     return TRUE;
5014
5015   amt = sizeof (struct som_copyable_section_data_struct);
5016   som_section_data (osection)->copy_data = bfd_zalloc (obfd, amt);
5017   if (som_section_data (osection)->copy_data == NULL)
5018     return FALSE;
5019
5020   memcpy (som_section_data (osection)->copy_data,
5021           som_section_data (isection)->copy_data,
5022           sizeof (struct som_copyable_section_data_struct));
5023
5024   /* Reparent if necessary.  */
5025   if (som_section_data (osection)->copy_data->container)
5026     som_section_data (osection)->copy_data->container =
5027       som_section_data (osection)->copy_data->container->output_section;
5028
5029   return TRUE;
5030 }
5031
5032 /* Copy any private info we understand from the input bfd
5033    to the output bfd.  */
5034
5035 static bfd_boolean
5036 som_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
5037 {
5038   /* One day we may try to grok other private data.  */
5039   if (ibfd->xvec->flavour != bfd_target_som_flavour
5040       || obfd->xvec->flavour != bfd_target_som_flavour)
5041     return TRUE;
5042
5043   /* Allocate some memory to hold the data we need.  */
5044   obj_som_exec_data (obfd) = bfd_zalloc (obfd, (bfd_size_type) sizeof (struct som_exec_data));
5045   if (obj_som_exec_data (obfd) == NULL)
5046     return FALSE;
5047
5048   /* Now copy the data.  */
5049   memcpy (obj_som_exec_data (obfd), obj_som_exec_data (ibfd),
5050           sizeof (struct som_exec_data));
5051
5052   return TRUE;
5053 }
5054
5055 /* Display the SOM header.  */
5056
5057 static bfd_boolean
5058 som_bfd_print_private_bfd_data (bfd *abfd, void *farg)
5059 {
5060   struct som_exec_auxhdr *exec_header;
5061   struct aux_id* auxhdr;
5062   FILE *f;
5063
5064   f = (FILE *) farg;
5065
5066   exec_header = obj_som_exec_hdr (abfd);
5067   if (exec_header)
5068     {
5069       fprintf (f, _("\nExec Auxiliary Header\n"));
5070       fprintf (f, "  flags              ");
5071       auxhdr = &exec_header->som_auxhdr;
5072       if (auxhdr->mandatory)
5073         fprintf (f, "mandatory ");
5074       if (auxhdr->copy)
5075         fprintf (f, "copy ");
5076       if (auxhdr->append)
5077         fprintf (f, "append ");
5078       if (auxhdr->ignore)
5079         fprintf (f, "ignore ");
5080       fprintf (f, "\n");
5081       fprintf (f, "  type               %#x\n", auxhdr->type);
5082       fprintf (f, "  length             %#x\n", auxhdr->length);
5083       fprintf (f, "  text size          %#lx\n", exec_header->exec_tsize);
5084       fprintf (f, "  text memory offset %#lx\n", exec_header->exec_tmem);
5085       fprintf (f, "  text file offset   %#lx\n", exec_header->exec_tfile);
5086       fprintf (f, "  data size          %#lx\n", exec_header->exec_dsize);
5087       fprintf (f, "  data memory offset %#lx\n", exec_header->exec_dmem);
5088       fprintf (f, "  data file offset   %#lx\n", exec_header->exec_dfile);
5089       fprintf (f, "  bss size           %#lx\n", exec_header->exec_bsize);
5090       fprintf (f, "  entry point        %#lx\n", exec_header->exec_entry);
5091       fprintf (f, "  loader flags       %#lx\n", exec_header->exec_flags);
5092       fprintf (f, "  bss initializer    %#lx\n", exec_header->exec_bfill);
5093     }
5094
5095   return TRUE;
5096 }
5097
5098 /* Set backend info for sections which can not be described
5099    in the BFD data structures.  */
5100
5101 bfd_boolean
5102 bfd_som_set_section_attributes (asection *section,
5103                                 int defined,
5104                                 int private,
5105                                 unsigned int sort_key,
5106                                 int spnum)
5107 {
5108   /* Allocate memory to hold the magic information.  */
5109   if (som_section_data (section)->copy_data == NULL)
5110     {
5111       bfd_size_type amt = sizeof (struct som_copyable_section_data_struct);
5112
5113       som_section_data (section)->copy_data = bfd_zalloc (section->owner, amt);
5114       if (som_section_data (section)->copy_data == NULL)
5115         return FALSE;
5116     }
5117   som_section_data (section)->copy_data->sort_key = sort_key;
5118   som_section_data (section)->copy_data->is_defined = defined;
5119   som_section_data (section)->copy_data->is_private = private;
5120   som_section_data (section)->copy_data->container = section;
5121   som_section_data (section)->copy_data->space_number = spnum;
5122   return TRUE;
5123 }
5124
5125 /* Set backend info for subsections which can not be described
5126    in the BFD data structures.  */
5127
5128 bfd_boolean
5129 bfd_som_set_subsection_attributes (asection *section,
5130                                    asection *container,
5131                                    int access,
5132                                    unsigned int sort_key,
5133                                    int quadrant,
5134                                    int comdat,
5135                                    int common,
5136                                    int dup_common)
5137 {
5138   /* Allocate memory to hold the magic information.  */
5139   if (som_section_data (section)->copy_data == NULL)
5140     {
5141       bfd_size_type amt = sizeof (struct som_copyable_section_data_struct);
5142
5143       som_section_data (section)->copy_data = bfd_zalloc (section->owner, amt);
5144       if (som_section_data (section)->copy_data == NULL)
5145         return FALSE;
5146     }
5147   som_section_data (section)->copy_data->sort_key = sort_key;
5148   som_section_data (section)->copy_data->access_control_bits = access;
5149   som_section_data (section)->copy_data->quadrant = quadrant;
5150   som_section_data (section)->copy_data->container = container;
5151   som_section_data (section)->copy_data->is_comdat = comdat;
5152   som_section_data (section)->copy_data->is_common = common;
5153   som_section_data (section)->copy_data->dup_common = dup_common;
5154   return TRUE;
5155 }
5156
5157 /* Set the full SOM symbol type.  SOM needs far more symbol information
5158    than any other object file format I'm aware of.  It is mandatory
5159    to be able to know if a symbol is an entry point, millicode, data,
5160    code, absolute, storage request, or procedure label.  If you get
5161    the symbol type wrong your program will not link.  */
5162
5163 void
5164 bfd_som_set_symbol_type (asymbol *symbol, unsigned int type)
5165 {
5166   som_symbol_data (symbol)->som_type = type;
5167 }
5168
5169 /* Attach an auxiliary header to the BFD backend so that it may be
5170    written into the object file.  */
5171
5172 bfd_boolean
5173 bfd_som_attach_aux_hdr (bfd *abfd, int type, char *string)
5174 {
5175   bfd_size_type amt;
5176
5177   if (type == VERSION_AUX_ID)
5178     {
5179       size_t len = strlen (string);
5180       int pad = 0;
5181
5182       if (len % 4)
5183         pad = (4 - (len % 4));
5184       amt = sizeof (struct aux_id) + sizeof (unsigned int) + len + pad;
5185       obj_som_version_hdr (abfd) = bfd_zalloc (abfd, amt);
5186       if (!obj_som_version_hdr (abfd))
5187         return FALSE;
5188       obj_som_version_hdr (abfd)->header_id.type = VERSION_AUX_ID;
5189       obj_som_version_hdr (abfd)->header_id.length = len + pad;
5190       obj_som_version_hdr (abfd)->header_id.length += sizeof (int);
5191       obj_som_version_hdr (abfd)->string_length = len;
5192       strncpy (obj_som_version_hdr (abfd)->user_string, string, len);
5193     }
5194   else if (type == COPYRIGHT_AUX_ID)
5195     {
5196       int len = strlen (string);
5197       int pad = 0;
5198
5199       if (len % 4)
5200         pad = (4 - (len % 4));
5201       amt = sizeof (struct aux_id) + sizeof (unsigned int) + len + pad;
5202       obj_som_copyright_hdr (abfd) = bfd_zalloc (abfd, amt);
5203       if (!obj_som_copyright_hdr (abfd))
5204         return FALSE;
5205       obj_som_copyright_hdr (abfd)->header_id.type = COPYRIGHT_AUX_ID;
5206       obj_som_copyright_hdr (abfd)->header_id.length = len + pad;
5207       obj_som_copyright_hdr (abfd)->header_id.length += sizeof (int);
5208       obj_som_copyright_hdr (abfd)->string_length = len;
5209       strcpy (obj_som_copyright_hdr (abfd)->copyright, string);
5210     }
5211   return TRUE;
5212 }
5213
5214 /* Attach a compilation unit header to the BFD backend so that it may be
5215    written into the object file.  */
5216
5217 bfd_boolean
5218 bfd_som_attach_compilation_unit (bfd *abfd,
5219                                  const char *name,
5220                                  const char *language_name,
5221                                  const char *product_id,
5222                                  const char *version_id)
5223 {
5224   COMPUNIT *n = (COMPUNIT *) bfd_zalloc (abfd, (bfd_size_type) COMPUNITSZ);
5225
5226   if (n == NULL)
5227     return FALSE;
5228
5229 #define STRDUP(f) \
5230   if (f != NULL) \
5231     { \
5232       n->f.n_name = bfd_alloc (abfd, (bfd_size_type) strlen (f) + 1); \
5233       if (n->f.n_name == NULL) \
5234         return FALSE; \
5235       strcpy (n->f.n_name, f); \
5236     }
5237
5238   STRDUP (name);
5239   STRDUP (language_name);
5240   STRDUP (product_id);
5241   STRDUP (version_id);
5242
5243 #undef STRDUP
5244
5245   obj_som_compilation_unit (abfd) = n;
5246
5247   return TRUE;
5248 }
5249
5250 static bfd_boolean
5251 som_get_section_contents (bfd *abfd,
5252                           sec_ptr section,
5253                           void *location,
5254                           file_ptr offset,
5255                           bfd_size_type count)
5256 {
5257   if (count == 0 || ((section->flags & SEC_HAS_CONTENTS) == 0))
5258     return TRUE;
5259   if ((bfd_size_type) (offset+count) > section->size
5260       || bfd_seek (abfd, (file_ptr) (section->filepos + offset), SEEK_SET) != 0
5261       || bfd_bread (location, count, abfd) != count)
5262     return FALSE; /* On error.  */
5263   return TRUE;
5264 }
5265
5266 static bfd_boolean
5267 som_set_section_contents (bfd *abfd,
5268                           sec_ptr section,
5269                           const void *location,
5270                           file_ptr offset,
5271                           bfd_size_type count)
5272 {
5273   if (! abfd->output_has_begun)
5274     {
5275       /* Set up fixed parts of the file, space, and subspace headers.
5276          Notify the world that output has begun.  */
5277       som_prep_headers (abfd);
5278       abfd->output_has_begun = TRUE;
5279       /* Start writing the object file.  This include all the string
5280          tables, fixup streams, and other portions of the object file.  */
5281       som_begin_writing (abfd);
5282     }
5283
5284   /* Only write subspaces which have "real" contents (eg. the contents
5285      are not generated at run time by the OS).  */
5286   if (!som_is_subspace (section)
5287       || ((section->flags & SEC_HAS_CONTENTS) == 0))
5288     return TRUE;
5289
5290   /* Seek to the proper offset within the object file and write the
5291      data.  */
5292   offset += som_section_data (section)->subspace_dict->file_loc_init_value;
5293   if (bfd_seek (abfd, offset, SEEK_SET) != 0)
5294     return FALSE;
5295
5296   if (bfd_bwrite (location, count, abfd) != count)
5297     return FALSE;
5298   return TRUE;
5299 }
5300
5301 static bfd_boolean
5302 som_set_arch_mach (bfd *abfd,
5303                    enum bfd_architecture arch,
5304                    unsigned long machine)
5305 {
5306   /* Allow any architecture to be supported by the SOM backend.  */
5307   return bfd_default_set_arch_mach (abfd, arch, machine);
5308 }
5309
5310 static bfd_boolean
5311 som_find_nearest_line (bfd *abfd ATTRIBUTE_UNUSED,
5312                        asection *section ATTRIBUTE_UNUSED,
5313                        asymbol **symbols ATTRIBUTE_UNUSED,
5314                        bfd_vma offset ATTRIBUTE_UNUSED,
5315                        const char **filename_ptr ATTRIBUTE_UNUSED,
5316                        const char **functionname_ptr ATTRIBUTE_UNUSED,
5317                        unsigned int *line_ptr ATTRIBUTE_UNUSED)
5318 {
5319   return FALSE;
5320 }
5321
5322 static int
5323 som_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED,
5324                     bfd_boolean reloc ATTRIBUTE_UNUSED)
5325 {
5326   (*_bfd_error_handler) (_("som_sizeof_headers unimplemented"));
5327   fflush (stderr);
5328   abort ();
5329   return 0;
5330 }
5331
5332 /* Return the single-character symbol type corresponding to
5333    SOM section S, or '?' for an unknown SOM section.  */
5334
5335 static char
5336 som_section_type (const char *s)
5337 {
5338   const struct section_to_type *t;
5339
5340   for (t = &stt[0]; t->section; t++)
5341     if (!strcmp (s, t->section))
5342       return t->type;
5343   return '?';
5344 }
5345
5346 static int
5347 som_decode_symclass (asymbol *symbol)
5348 {
5349   char c;
5350
5351   if (bfd_is_com_section (symbol->section))
5352     return 'C';
5353   if (bfd_is_und_section (symbol->section))
5354     return 'U';
5355   if (bfd_is_ind_section (symbol->section))
5356     return 'I';
5357   if (symbol->flags & BSF_WEAK)
5358     return 'W';
5359   if (!(symbol->flags & (BSF_GLOBAL | BSF_LOCAL)))
5360     return '?';
5361
5362   if (bfd_is_abs_section (symbol->section)
5363       || (som_symbol_data (symbol) != NULL
5364           && som_symbol_data (symbol)->som_type == SYMBOL_TYPE_ABSOLUTE))
5365     c = 'a';
5366   else if (symbol->section)
5367     c = som_section_type (symbol->section->name);
5368   else
5369     return '?';
5370   if (symbol->flags & BSF_GLOBAL)
5371     c = TOUPPER (c);
5372   return c;
5373 }
5374
5375 /* Return information about SOM symbol SYMBOL in RET.  */
5376
5377 static void
5378 som_get_symbol_info (bfd *ignore_abfd ATTRIBUTE_UNUSED,
5379                      asymbol *symbol,
5380                      symbol_info *ret)
5381 {
5382   ret->type = som_decode_symclass (symbol);
5383   if (ret->type != 'U')
5384     ret->value = symbol->value + symbol->section->vma;
5385   else
5386     ret->value = 0;
5387   ret->name = symbol->name;
5388 }
5389
5390 /* Count the number of symbols in the archive symbol table.  Necessary
5391    so that we can allocate space for all the carsyms at once.  */
5392
5393 static bfd_boolean
5394 som_bfd_count_ar_symbols (bfd *abfd,
5395                           struct lst_header *lst_header,
5396                           symindex *count)
5397 {
5398   unsigned int i;
5399   unsigned int *hash_table = NULL;
5400   bfd_size_type amt;
5401   file_ptr lst_filepos = bfd_tell (abfd) - sizeof (struct lst_header);
5402
5403   amt = lst_header->hash_size;
5404   amt *= sizeof (unsigned int);
5405   hash_table = bfd_malloc (amt);
5406   if (hash_table == NULL && lst_header->hash_size != 0)
5407     goto error_return;
5408
5409   /* Don't forget to initialize the counter!  */
5410   *count = 0;
5411
5412   /* Read in the hash table.  The has table is an array of 32bit file offsets
5413      which point to the hash chains.  */
5414   if (bfd_bread ((void *) hash_table, amt, abfd) != amt)
5415     goto error_return;
5416
5417   /* Walk each chain counting the number of symbols found on that particular
5418      chain.  */
5419   for (i = 0; i < lst_header->hash_size; i++)
5420     {
5421       struct lst_symbol_record lst_symbol;
5422
5423       /* An empty chain has zero as it's file offset.  */
5424       if (hash_table[i] == 0)
5425         continue;
5426
5427       /* Seek to the first symbol in this hash chain.  */
5428       if (bfd_seek (abfd, lst_filepos + hash_table[i], SEEK_SET) != 0)
5429         goto error_return;
5430
5431       /* Read in this symbol and update the counter.  */
5432       amt = sizeof (lst_symbol);
5433       if (bfd_bread ((void *) &lst_symbol, amt, abfd) != amt)
5434         goto error_return;
5435
5436       (*count)++;
5437
5438       /* Now iterate through the rest of the symbols on this chain.  */
5439       while (lst_symbol.next_entry)
5440         {
5441
5442           /* Seek to the next symbol.  */
5443           if (bfd_seek (abfd, lst_filepos + lst_symbol.next_entry, SEEK_SET)
5444               != 0)
5445             goto error_return;
5446
5447           /* Read the symbol in and update the counter.  */
5448           amt = sizeof (lst_symbol);
5449           if (bfd_bread ((void *) &lst_symbol, amt, abfd) != amt)
5450             goto error_return;
5451
5452           (*count)++;
5453         }
5454     }
5455   if (hash_table != NULL)
5456     free (hash_table);
5457   return TRUE;
5458
5459  error_return:
5460   if (hash_table != NULL)
5461     free (hash_table);
5462   return FALSE;
5463 }
5464
5465 /* Fill in the canonical archive symbols (SYMS) from the archive described
5466    by ABFD and LST_HEADER.  */
5467
5468 static bfd_boolean
5469 som_bfd_fill_in_ar_symbols (bfd *abfd,
5470                             struct lst_header *lst_header,
5471                             carsym **syms)
5472 {
5473   unsigned int i, len;
5474   carsym *set = syms[0];
5475   unsigned int *hash_table = NULL;
5476   struct som_entry *som_dict = NULL;
5477   bfd_size_type amt;
5478   file_ptr lst_filepos = bfd_tell (abfd) - sizeof (struct lst_header);
5479
5480   amt = lst_header->hash_size;
5481   amt *= sizeof (unsigned int);
5482   hash_table = bfd_malloc (amt);
5483   if (hash_table == NULL && lst_header->hash_size != 0)
5484     goto error_return;
5485
5486   /* Read in the hash table.  The has table is an array of 32bit file offsets
5487      which point to the hash chains.  */
5488   if (bfd_bread ((void *) hash_table, amt, abfd) != amt)
5489     goto error_return;
5490
5491   /* Seek to and read in the SOM dictionary.  We will need this to fill
5492      in the carsym's filepos field.  */
5493   if (bfd_seek (abfd, lst_filepos + lst_header->dir_loc, SEEK_SET) != 0)
5494     goto error_return;
5495
5496   amt = lst_header->module_count;
5497   amt *= sizeof (struct som_entry);
5498   som_dict = bfd_malloc (amt);
5499   if (som_dict == NULL && lst_header->module_count != 0)
5500     goto error_return;
5501
5502   if (bfd_bread ((void *) som_dict, amt, abfd) != amt)
5503     goto error_return;
5504
5505   /* Walk each chain filling in the carsyms as we go along.  */
5506   for (i = 0; i < lst_header->hash_size; i++)
5507     {
5508       struct lst_symbol_record lst_symbol;
5509
5510       /* An empty chain has zero as it's file offset.  */
5511       if (hash_table[i] == 0)
5512         continue;
5513
5514       /* Seek to and read the first symbol on the chain.  */
5515       if (bfd_seek (abfd, lst_filepos + hash_table[i], SEEK_SET) != 0)
5516         goto error_return;
5517
5518       amt = sizeof (lst_symbol);
5519       if (bfd_bread ((void *) &lst_symbol, amt, abfd) != amt)
5520         goto error_return;
5521
5522       /* Get the name of the symbol, first get the length which is stored
5523          as a 32bit integer just before the symbol.
5524
5525          One might ask why we don't just read in the entire string table
5526          and index into it.  Well, according to the SOM ABI the string
5527          index can point *anywhere* in the archive to save space, so just
5528          using the string table would not be safe.  */
5529       if (bfd_seek (abfd, lst_filepos + lst_header->string_loc
5530                             + lst_symbol.name.n_strx - 4, SEEK_SET) != 0)
5531         goto error_return;
5532
5533       if (bfd_bread (&len, (bfd_size_type) 4, abfd) != 4)
5534         goto error_return;
5535
5536       /* Allocate space for the name and null terminate it too.  */
5537       set->name = bfd_zalloc (abfd, (bfd_size_type) len + 1);
5538       if (!set->name)
5539         goto error_return;
5540       if (bfd_bread (set->name, (bfd_size_type) len, abfd) != len)
5541         goto error_return;
5542
5543       set->name[len] = 0;
5544
5545       /* Fill in the file offset.  Note that the "location" field points
5546          to the SOM itself, not the ar_hdr in front of it.  */
5547       set->file_offset = som_dict[lst_symbol.som_index].location
5548                           - sizeof (struct ar_hdr);
5549
5550       /* Go to the next symbol.  */
5551       set++;
5552
5553       /* Iterate through the rest of the chain.  */
5554       while (lst_symbol.next_entry)
5555         {
5556           /* Seek to the next symbol and read it in.  */
5557           if (bfd_seek (abfd, lst_filepos + lst_symbol.next_entry, SEEK_SET)
5558               != 0)
5559             goto error_return;
5560
5561           amt = sizeof (lst_symbol);
5562           if (bfd_bread ((void *) &lst_symbol, amt, abfd) != amt)
5563             goto error_return;
5564
5565           /* Seek to the name length & string and read them in.  */
5566           if (bfd_seek (abfd, lst_filepos + lst_header->string_loc
5567                                 + lst_symbol.name.n_strx - 4, SEEK_SET) != 0)
5568             goto error_return;
5569
5570           if (bfd_bread (&len, (bfd_size_type) 4, abfd) != 4)
5571             goto error_return;
5572
5573           /* Allocate space for the name and null terminate it too.  */
5574           set->name = bfd_zalloc (abfd, (bfd_size_type) len + 1);
5575           if (!set->name)
5576             goto error_return;
5577
5578           if (bfd_bread (set->name, (bfd_size_type) len, abfd) != len)
5579             goto error_return;
5580           set->name[len] = 0;
5581
5582           /* Fill in the file offset.  Note that the "location" field points
5583              to the SOM itself, not the ar_hdr in front of it.  */
5584           set->file_offset = som_dict[lst_symbol.som_index].location
5585                                - sizeof (struct ar_hdr);
5586
5587           /* Go on to the next symbol.  */
5588           set++;
5589         }
5590     }
5591   /* If we haven't died by now, then we successfully read the entire
5592      archive symbol table.  */
5593   if (hash_table != NULL)
5594     free (hash_table);
5595   if (som_dict != NULL)
5596     free (som_dict);
5597   return TRUE;
5598
5599  error_return:
5600   if (hash_table != NULL)
5601     free (hash_table);
5602   if (som_dict != NULL)
5603     free (som_dict);
5604   return FALSE;
5605 }
5606
5607 /* Read in the LST from the archive.  */
5608
5609 static bfd_boolean
5610 som_slurp_armap (bfd *abfd)
5611 {
5612   struct lst_header lst_header;
5613   struct ar_hdr ar_header;
5614   unsigned int parsed_size;
5615   struct artdata *ardata = bfd_ardata (abfd);
5616   char nextname[17];
5617   bfd_size_type amt = 16;
5618   int i = bfd_bread ((void *) nextname, amt, abfd);
5619
5620   /* Special cases.  */
5621   if (i == 0)
5622     return TRUE;
5623   if (i != 16)
5624     return FALSE;
5625
5626   if (bfd_seek (abfd, (file_ptr) -16, SEEK_CUR) != 0)
5627     return FALSE;
5628
5629   /* For archives without .o files there is no symbol table.  */
5630   if (strncmp (nextname, "/               ", 16))
5631     {
5632       bfd_has_map (abfd) = FALSE;
5633       return TRUE;
5634     }
5635
5636   /* Read in and sanity check the archive header.  */
5637   amt = sizeof (struct ar_hdr);
5638   if (bfd_bread ((void *) &ar_header, amt, abfd) != amt)
5639     return FALSE;
5640
5641   if (strncmp (ar_header.ar_fmag, ARFMAG, 2))
5642     {
5643       bfd_set_error (bfd_error_malformed_archive);
5644       return FALSE;
5645     }
5646
5647   /* How big is the archive symbol table entry?  */
5648   errno = 0;
5649   parsed_size = strtol (ar_header.ar_size, NULL, 10);
5650   if (errno != 0)
5651     {
5652       bfd_set_error (bfd_error_malformed_archive);
5653       return FALSE;
5654     }
5655
5656   /* Save off the file offset of the first real user data.  */
5657   ardata->first_file_filepos = bfd_tell (abfd) + parsed_size;
5658
5659   /* Read in the library symbol table.  We'll make heavy use of this
5660      in just a minute.  */
5661   amt = sizeof (struct lst_header);
5662   if (bfd_bread ((void *) &lst_header, amt, abfd) != amt)
5663     return FALSE;
5664
5665   /* Sanity check.  */
5666   if (lst_header.a_magic != LIBMAGIC)
5667     {
5668       bfd_set_error (bfd_error_malformed_archive);
5669       return FALSE;
5670     }
5671
5672   /* Count the number of symbols in the library symbol table.  */
5673   if (! som_bfd_count_ar_symbols (abfd, &lst_header, &ardata->symdef_count))
5674     return FALSE;
5675
5676   /* Get back to the start of the library symbol table.  */
5677   if (bfd_seek (abfd, (ardata->first_file_filepos - parsed_size
5678                        + sizeof (struct lst_header)), SEEK_SET) != 0)
5679     return FALSE;
5680
5681   /* Initialize the cache and allocate space for the library symbols.  */
5682   ardata->cache = 0;
5683   amt = ardata->symdef_count;
5684   amt *= sizeof (carsym);
5685   ardata->symdefs = bfd_alloc (abfd, amt);
5686   if (!ardata->symdefs)
5687     return FALSE;
5688
5689   /* Now fill in the canonical archive symbols.  */
5690   if (! som_bfd_fill_in_ar_symbols (abfd, &lst_header, &ardata->symdefs))
5691     return FALSE;
5692
5693   /* Seek back to the "first" file in the archive.  Note the "first"
5694      file may be the extended name table.  */
5695   if (bfd_seek (abfd, ardata->first_file_filepos, SEEK_SET) != 0)
5696     return FALSE;
5697
5698   /* Notify the generic archive code that we have a symbol map.  */
5699   bfd_has_map (abfd) = TRUE;
5700   return TRUE;
5701 }
5702
5703 /* Begin preparing to write a SOM library symbol table.
5704
5705    As part of the prep work we need to determine the number of symbols
5706    and the size of the associated string section.  */
5707
5708 static bfd_boolean
5709 som_bfd_prep_for_ar_write (bfd *abfd,
5710                            unsigned int *num_syms,
5711                            unsigned int *stringsize)
5712 {
5713   bfd *curr_bfd = abfd->archive_head;
5714
5715   /* Some initialization.  */
5716   *num_syms = 0;
5717   *stringsize = 0;
5718
5719   /* Iterate over each BFD within this archive.  */
5720   while (curr_bfd != NULL)
5721     {
5722       unsigned int curr_count, i;
5723       som_symbol_type *sym;
5724
5725       /* Don't bother for non-SOM objects.  */
5726       if (curr_bfd->format != bfd_object
5727           || curr_bfd->xvec->flavour != bfd_target_som_flavour)
5728         {
5729           curr_bfd = curr_bfd->next;
5730           continue;
5731         }
5732
5733       /* Make sure the symbol table has been read, then snag a pointer
5734          to it.  It's a little slimey to grab the symbols via obj_som_symtab,
5735          but doing so avoids allocating lots of extra memory.  */
5736       if (! som_slurp_symbol_table (curr_bfd))
5737         return FALSE;
5738
5739       sym = obj_som_symtab (curr_bfd);
5740       curr_count = bfd_get_symcount (curr_bfd);
5741
5742       /* Examine each symbol to determine if it belongs in the
5743          library symbol table.  */
5744       for (i = 0; i < curr_count; i++, sym++)
5745         {
5746           struct som_misc_symbol_info info;
5747
5748           /* Derive SOM information from the BFD symbol.  */
5749           som_bfd_derive_misc_symbol_info (curr_bfd, &sym->symbol, &info);
5750
5751           /* Should we include this symbol?  */
5752           if (info.symbol_type == ST_NULL
5753               || info.symbol_type == ST_SYM_EXT
5754               || info.symbol_type == ST_ARG_EXT)
5755             continue;
5756
5757           /* Only global symbols and unsatisfied commons.  */
5758           if (info.symbol_scope != SS_UNIVERSAL
5759               && info.symbol_type != ST_STORAGE)
5760             continue;
5761
5762           /* Do no include undefined symbols.  */
5763           if (bfd_is_und_section (sym->symbol.section))
5764             continue;
5765
5766           /* Bump the various counters, being careful to honor
5767              alignment considerations in the string table.  */
5768           (*num_syms)++;
5769           *stringsize = *stringsize + strlen (sym->symbol.name) + 5;
5770           while (*stringsize % 4)
5771             (*stringsize)++;
5772         }
5773
5774       curr_bfd = curr_bfd->next;
5775     }
5776   return TRUE;
5777 }
5778
5779 /* Hash a symbol name based on the hashing algorithm presented in the
5780    SOM ABI.  */
5781
5782 static unsigned int
5783 som_bfd_ar_symbol_hash (asymbol *symbol)
5784 {
5785   unsigned int len = strlen (symbol->name);
5786
5787   /* Names with length 1 are special.  */
5788   if (len == 1)
5789     return 0x1000100 | (symbol->name[0] << 16) | symbol->name[0];
5790
5791   return ((len & 0x7f) << 24) | (symbol->name[1] << 16)
5792           | (symbol->name[len - 2] << 8) | symbol->name[len - 1];
5793 }
5794
5795 /* Do the bulk of the work required to write the SOM library
5796    symbol table.  */
5797
5798 static bfd_boolean
5799 som_bfd_ar_write_symbol_stuff (bfd *abfd,
5800                                unsigned int nsyms,
5801                                unsigned int string_size,
5802                                struct lst_header lst,
5803                                unsigned elength)
5804 {
5805   file_ptr lst_filepos;
5806   char *strings = NULL, *p;
5807   struct lst_symbol_record *lst_syms = NULL, *curr_lst_sym;
5808   bfd *curr_bfd;
5809   unsigned int *hash_table = NULL;
5810   struct som_entry *som_dict = NULL;
5811   struct lst_symbol_record **last_hash_entry = NULL;
5812   unsigned int curr_som_offset, som_index = 0;
5813   bfd_size_type amt;
5814
5815   amt = lst.hash_size;
5816   amt *= sizeof (unsigned int);
5817   hash_table = bfd_zmalloc (amt);
5818   if (hash_table == NULL && lst.hash_size != 0)
5819     goto error_return;
5820
5821   amt = lst.module_count;
5822   amt *= sizeof (struct som_entry);
5823   som_dict = bfd_zmalloc (amt);
5824   if (som_dict == NULL && lst.module_count != 0)
5825     goto error_return;
5826
5827   amt = lst.hash_size;
5828   amt *= sizeof (struct lst_symbol_record *);
5829   last_hash_entry = bfd_zmalloc (amt);
5830   if (last_hash_entry == NULL && lst.hash_size != 0)
5831     goto error_return;
5832
5833   /* Lots of fields are file positions relative to the start
5834      of the lst record.  So save its location.  */
5835   lst_filepos = bfd_tell (abfd) - sizeof (struct lst_header);
5836
5837   /* Symbols have som_index fields, so we have to keep track of the
5838      index of each SOM in the archive.
5839
5840      The SOM dictionary has (among other things) the absolute file
5841      position for the SOM which a particular dictionary entry
5842      describes.  We have to compute that information as we iterate
5843      through the SOMs/symbols.  */
5844   som_index = 0;
5845
5846   /* We add in the size of the archive header twice as the location
5847      in the SOM dictionary is the actual offset of the SOM, not the
5848      archive header before the SOM.  */
5849   curr_som_offset = 8 + 2 * sizeof (struct ar_hdr) + lst.file_end;
5850
5851   /* Make room for the archive header and the contents of the
5852      extended string table.  Note that elength includes the size
5853      of the archive header for the extended name table!  */
5854   if (elength)
5855     curr_som_offset += elength;
5856
5857   /* Make sure we're properly aligned.  */
5858   curr_som_offset = (curr_som_offset + 0x1) & ~0x1;
5859
5860   /* FIXME should be done with buffers just like everything else...  */
5861   amt = nsyms;
5862   amt *= sizeof (struct lst_symbol_record);
5863   lst_syms = bfd_malloc (amt);
5864   if (lst_syms == NULL && nsyms != 0)
5865     goto error_return;
5866   strings = bfd_malloc ((bfd_size_type) string_size);
5867   if (strings == NULL && string_size != 0)
5868     goto error_return;
5869
5870   p = strings;
5871   curr_lst_sym = lst_syms;
5872
5873   curr_bfd = abfd->archive_head;
5874   while (curr_bfd != NULL)
5875     {
5876       unsigned int curr_count, i;
5877       som_symbol_type *sym;
5878
5879       /* Don't bother for non-SOM objects.  */
5880       if (curr_bfd->format != bfd_object
5881           || curr_bfd->xvec->flavour != bfd_target_som_flavour)
5882         {
5883           curr_bfd = curr_bfd->next;
5884           continue;
5885         }
5886
5887       /* Make sure the symbol table has been read, then snag a pointer
5888          to it.  It's a little slimey to grab the symbols via obj_som_symtab,
5889          but doing so avoids allocating lots of extra memory.  */
5890       if (! som_slurp_symbol_table (curr_bfd))
5891         goto error_return;
5892
5893       sym = obj_som_symtab (curr_bfd);
5894       curr_count = bfd_get_symcount (curr_bfd);
5895
5896       for (i = 0; i < curr_count; i++, sym++)
5897         {
5898           struct som_misc_symbol_info info;
5899
5900           /* Derive SOM information from the BFD symbol.  */
5901           som_bfd_derive_misc_symbol_info (curr_bfd, &sym->symbol, &info);
5902
5903           /* Should we include this symbol?  */
5904           if (info.symbol_type == ST_NULL
5905               || info.symbol_type == ST_SYM_EXT
5906               || info.symbol_type == ST_ARG_EXT)
5907             continue;
5908
5909           /* Only global symbols and unsatisfied commons.  */
5910           if (info.symbol_scope != SS_UNIVERSAL
5911               && info.symbol_type != ST_STORAGE)
5912             continue;
5913
5914           /* Do no include undefined symbols.  */
5915           if (bfd_is_und_section (sym->symbol.section))
5916             continue;
5917
5918           /* If this is the first symbol from this SOM, then update
5919              the SOM dictionary too.  */
5920           if (som_dict[som_index].location == 0)
5921             {
5922               som_dict[som_index].location = curr_som_offset;
5923               som_dict[som_index].length = arelt_size (curr_bfd);
5924             }
5925
5926           /* Fill in the lst symbol record.  */
5927           curr_lst_sym->hidden = 0;
5928           curr_lst_sym->secondary_def = info.secondary_def;
5929           curr_lst_sym->symbol_type = info.symbol_type;
5930           curr_lst_sym->symbol_scope = info.symbol_scope;
5931           curr_lst_sym->check_level = 0;
5932           curr_lst_sym->must_qualify = 0;
5933           curr_lst_sym->initially_frozen = 0;
5934           curr_lst_sym->memory_resident = 0;
5935           curr_lst_sym->is_common = bfd_is_com_section (sym->symbol.section);
5936           curr_lst_sym->dup_common = info.dup_common;
5937           curr_lst_sym->xleast = 3;
5938           curr_lst_sym->arg_reloc = info.arg_reloc;
5939           curr_lst_sym->name.n_strx = p - strings + 4;
5940           curr_lst_sym->qualifier_name.n_strx = 0;
5941           curr_lst_sym->symbol_info = info.symbol_info;
5942           curr_lst_sym->symbol_value = info.symbol_value | info.priv_level;
5943           curr_lst_sym->symbol_descriptor = 0;
5944           curr_lst_sym->reserved = 0;
5945           curr_lst_sym->som_index = som_index;
5946           curr_lst_sym->symbol_key = som_bfd_ar_symbol_hash (&sym->symbol);
5947           curr_lst_sym->next_entry = 0;
5948
5949           /* Insert into the hash table.  */
5950           if (hash_table[curr_lst_sym->symbol_key % lst.hash_size])
5951             {
5952               struct lst_symbol_record *tmp;
5953
5954               /* There is already something at the head of this hash chain,
5955                  so tack this symbol onto the end of the chain.  */
5956               tmp = last_hash_entry[curr_lst_sym->symbol_key % lst.hash_size];
5957               tmp->next_entry
5958                 = (curr_lst_sym - lst_syms) * sizeof (struct lst_symbol_record)
5959                   + lst.hash_size * 4
5960                   + lst.module_count * sizeof (struct som_entry)
5961                   + sizeof (struct lst_header);
5962             }
5963           else
5964             /* First entry in this hash chain.  */
5965             hash_table[curr_lst_sym->symbol_key % lst.hash_size]
5966               = (curr_lst_sym - lst_syms) * sizeof (struct lst_symbol_record)
5967               + lst.hash_size * 4
5968               + lst.module_count * sizeof (struct som_entry)
5969               + sizeof (struct lst_header);
5970
5971           /* Keep track of the last symbol we added to this chain so we can
5972              easily update its next_entry pointer.  */
5973           last_hash_entry[curr_lst_sym->symbol_key % lst.hash_size]
5974             = curr_lst_sym;
5975
5976           /* Update the string table.  */
5977           bfd_put_32 (abfd, strlen (sym->symbol.name), p);
5978           p += 4;
5979           strcpy (p, sym->symbol.name);
5980           p += strlen (sym->symbol.name) + 1;
5981           while ((int) p % 4)
5982             {
5983               bfd_put_8 (abfd, 0, p);
5984               p++;
5985             }
5986
5987           /* Head to the next symbol.  */
5988           curr_lst_sym++;
5989         }
5990
5991       /* Keep track of where each SOM will finally reside; then look
5992          at the next BFD.  */
5993       curr_som_offset += arelt_size (curr_bfd) + sizeof (struct ar_hdr);
5994
5995       /* A particular object in the archive may have an odd length; the
5996          linker requires objects begin on an even boundary.  So round
5997          up the current offset as necessary.  */
5998       curr_som_offset = (curr_som_offset + 0x1) &~ (unsigned) 1;
5999       curr_bfd = curr_bfd->next;
6000       som_index++;
6001     }
6002
6003   /* Now scribble out the hash table.  */
6004   amt = lst.hash_size * 4;
6005   if (bfd_bwrite ((void *) hash_table, amt, abfd) != amt)
6006     goto error_return;
6007
6008   /* Then the SOM dictionary.  */
6009   amt = lst.module_count * sizeof (struct som_entry);
6010   if (bfd_bwrite ((void *) som_dict, amt, abfd) != amt)
6011     goto error_return;
6012
6013   /* The library symbols.  */
6014   amt = nsyms * sizeof (struct lst_symbol_record);
6015   if (bfd_bwrite ((void *) lst_syms, amt, abfd) != amt)
6016     goto error_return;
6017
6018   /* And finally the strings.  */
6019   amt = string_size;
6020   if (bfd_bwrite ((void *) strings, amt, abfd) != amt)
6021     goto error_return;
6022
6023   if (hash_table != NULL)
6024     free (hash_table);
6025   if (som_dict != NULL)
6026     free (som_dict);
6027   if (last_hash_entry != NULL)
6028     free (last_hash_entry);
6029   if (lst_syms != NULL)
6030     free (lst_syms);
6031   if (strings != NULL)
6032     free (strings);
6033   return TRUE;
6034
6035  error_return:
6036   if (hash_table != NULL)
6037     free (hash_table);
6038   if (som_dict != NULL)
6039     free (som_dict);
6040   if (last_hash_entry != NULL)
6041     free (last_hash_entry);
6042   if (lst_syms != NULL)
6043     free (lst_syms);
6044   if (strings != NULL)
6045     free (strings);
6046
6047   return FALSE;
6048 }
6049
6050 /* Write out the LST for the archive.
6051
6052    You'll never believe this is really how armaps are handled in SOM...  */
6053
6054 static bfd_boolean
6055 som_write_armap (bfd *abfd,
6056                  unsigned int elength,
6057                  struct orl *map ATTRIBUTE_UNUSED,
6058                  unsigned int orl_count ATTRIBUTE_UNUSED,
6059                  int stridx ATTRIBUTE_UNUSED)
6060 {
6061   bfd *curr_bfd;
6062   struct stat statbuf;
6063   unsigned int i, lst_size, nsyms, stringsize;
6064   struct ar_hdr hdr;
6065   struct lst_header lst;
6066   int *p;
6067   bfd_size_type amt;
6068
6069   /* We'll use this for the archive's date and mode later.  */
6070   if (stat (abfd->filename, &statbuf) != 0)
6071     {
6072       bfd_set_error (bfd_error_system_call);
6073       return FALSE;
6074     }
6075   /* Fudge factor.  */
6076   bfd_ardata (abfd)->armap_timestamp = statbuf.st_mtime + 60;
6077
6078   /* Account for the lst header first.  */
6079   lst_size = sizeof (struct lst_header);
6080
6081   /* Start building the LST header.  */
6082   /* FIXME:  Do we need to examine each element to determine the
6083      largest id number?  */
6084   lst.system_id = CPU_PA_RISC1_0;
6085   lst.a_magic = LIBMAGIC;
6086   lst.version_id = VERSION_ID;
6087   lst.file_time.secs = 0;
6088   lst.file_time.nanosecs = 0;
6089
6090   lst.hash_loc = lst_size;
6091   lst.hash_size = SOM_LST_HASH_SIZE;
6092
6093   /* Hash table is a SOM_LST_HASH_SIZE 32bit offsets.  */
6094   lst_size += 4 * SOM_LST_HASH_SIZE;
6095
6096   /* We need to count the number of SOMs in this archive.  */
6097   curr_bfd = abfd->archive_head;
6098   lst.module_count = 0;
6099   while (curr_bfd != NULL)
6100     {
6101       /* Only true SOM objects count.  */
6102       if (curr_bfd->format == bfd_object
6103           && curr_bfd->xvec->flavour == bfd_target_som_flavour)
6104         lst.module_count++;
6105       curr_bfd = curr_bfd->next;
6106     }
6107   lst.module_limit = lst.module_count;
6108   lst.dir_loc = lst_size;
6109   lst_size += sizeof (struct som_entry) * lst.module_count;
6110
6111   /* We don't support import/export tables, auxiliary headers,
6112      or free lists yet.  Make the linker work a little harder
6113      to make our life easier.  */
6114
6115   lst.export_loc = 0;
6116   lst.export_count = 0;
6117   lst.import_loc = 0;
6118   lst.aux_loc = 0;
6119   lst.aux_size = 0;
6120
6121   /* Count how many symbols we will have on the hash chains and the
6122      size of the associated string table.  */
6123   if (! som_bfd_prep_for_ar_write (abfd, &nsyms, &stringsize))
6124     return FALSE;
6125
6126   lst_size += sizeof (struct lst_symbol_record) * nsyms;
6127
6128   /* For the string table.  One day we might actually use this info
6129      to avoid small seeks/reads when reading archives.  */
6130   lst.string_loc = lst_size;
6131   lst.string_size = stringsize;
6132   lst_size += stringsize;
6133
6134   /* SOM ABI says this must be zero.  */
6135   lst.free_list = 0;
6136   lst.file_end = lst_size;
6137
6138   /* Compute the checksum.  Must happen after the entire lst header
6139      has filled in.  */
6140   p = (int *) &lst;
6141   lst.checksum = 0;
6142   for (i = 0; i < sizeof (struct lst_header) / sizeof (int) - 1; i++)
6143     lst.checksum ^= *p++;
6144
6145   sprintf (hdr.ar_name, "/               ");
6146   sprintf (hdr.ar_date, "%ld", bfd_ardata (abfd)->armap_timestamp);
6147   sprintf (hdr.ar_uid, "%ld", (long) getuid ());
6148   sprintf (hdr.ar_gid, "%ld", (long) getgid ());
6149   sprintf (hdr.ar_mode, "%-8o", (unsigned int) statbuf.st_mode);
6150   sprintf (hdr.ar_size, "%-10d", (int) lst_size);
6151   hdr.ar_fmag[0] = '`';
6152   hdr.ar_fmag[1] = '\012';
6153
6154   /* Turn any nulls into spaces.  */
6155   for (i = 0; i < sizeof (struct ar_hdr); i++)
6156     if (((char *) (&hdr))[i] == '\0')
6157       (((char *) (&hdr))[i]) = ' ';
6158
6159   /* Scribble out the ar header.  */
6160   amt = sizeof (struct ar_hdr);
6161   if (bfd_bwrite ((void *) &hdr, amt, abfd) != amt)
6162     return FALSE;
6163
6164   /* Now scribble out the lst header.  */
6165   amt = sizeof (struct lst_header);
6166   if (bfd_bwrite ((void *) &lst, amt, abfd) != amt)
6167     return FALSE;
6168
6169   /* Build and write the armap.  */
6170   if (!som_bfd_ar_write_symbol_stuff (abfd, nsyms, stringsize, lst, elength))
6171     return FALSE;
6172
6173   /* Done.  */
6174   return TRUE;
6175 }
6176
6177 /* Free all information we have cached for this BFD.  We can always
6178    read it again later if we need it.  */
6179
6180 static bfd_boolean
6181 som_bfd_free_cached_info (bfd *abfd)
6182 {
6183   asection *o;
6184
6185   if (bfd_get_format (abfd) != bfd_object)
6186     return TRUE;
6187
6188 #define FREE(x) if (x != NULL) { free (x); x = NULL; }
6189   /* Free the native string and symbol tables.  */
6190   FREE (obj_som_symtab (abfd));
6191   FREE (obj_som_stringtab (abfd));
6192   for (o = abfd->sections; o != NULL; o = o->next)
6193     {
6194       /* Free the native relocations.  */
6195       o->reloc_count = (unsigned) -1;
6196       FREE (som_section_data (o)->reloc_stream);
6197       /* Free the generic relocations.  */
6198       FREE (o->relocation);
6199     }
6200 #undef FREE
6201
6202   return TRUE;
6203 }
6204
6205 /* End of miscellaneous support functions.  */
6206
6207 /* Linker support functions.  */
6208
6209 static bfd_boolean
6210 som_bfd_link_split_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
6211 {
6212   return som_is_subspace (sec) && sec->size > 240000;
6213 }
6214
6215 #define som_close_and_cleanup                   som_bfd_free_cached_info
6216 #define som_read_ar_hdr                         _bfd_generic_read_ar_hdr
6217 #define som_openr_next_archived_file            bfd_generic_openr_next_archived_file
6218 #define som_get_elt_at_index                    _bfd_generic_get_elt_at_index
6219 #define som_generic_stat_arch_elt               bfd_generic_stat_arch_elt
6220 #define som_truncate_arname                     bfd_bsd_truncate_arname
6221 #define som_slurp_extended_name_table           _bfd_slurp_extended_name_table
6222 #define som_construct_extended_name_table       _bfd_archive_coff_construct_extended_name_table
6223 #define som_update_armap_timestamp              bfd_true
6224 #define som_bfd_is_target_special_symbol   ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
6225 #define som_get_lineno                          _bfd_nosymbols_get_lineno
6226 #define som_bfd_make_debug_symbol               _bfd_nosymbols_bfd_make_debug_symbol
6227 #define som_read_minisymbols                    _bfd_generic_read_minisymbols
6228 #define som_minisymbol_to_symbol                _bfd_generic_minisymbol_to_symbol
6229 #define som_get_section_contents_in_window      _bfd_generic_get_section_contents_in_window
6230 #define som_bfd_get_relocated_section_contents  bfd_generic_get_relocated_section_contents
6231 #define som_bfd_relax_section                   bfd_generic_relax_section
6232 #define som_bfd_link_hash_table_create          _bfd_generic_link_hash_table_create
6233 #define som_bfd_link_hash_table_free            _bfd_generic_link_hash_table_free
6234 #define som_bfd_link_add_symbols                _bfd_generic_link_add_symbols
6235 #define som_bfd_link_just_syms                  _bfd_generic_link_just_syms
6236 #define som_bfd_final_link                      _bfd_generic_final_link
6237 #define som_bfd_gc_sections                     bfd_generic_gc_sections
6238 #define som_bfd_merge_sections                  bfd_generic_merge_sections
6239 #define som_bfd_is_group_section                bfd_generic_is_group_section
6240 #define som_bfd_discard_group                   bfd_generic_discard_group
6241 #define som_section_already_linked              _bfd_generic_section_already_linked
6242 #define som_bfd_merge_private_bfd_data          _bfd_generic_bfd_merge_private_bfd_data
6243 #define som_bfd_copy_private_header_data        _bfd_generic_bfd_copy_private_header_data
6244 #define som_bfd_set_private_flags               _bfd_generic_bfd_set_private_flags
6245
6246 const bfd_target som_vec =
6247 {
6248   "som",                        /* Name.  */
6249   bfd_target_som_flavour,
6250   BFD_ENDIAN_BIG,               /* Target byte order.  */
6251   BFD_ENDIAN_BIG,               /* Target headers byte order.  */
6252   (HAS_RELOC | EXEC_P |         /* Object flags.  */
6253    HAS_LINENO | HAS_DEBUG |
6254    HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED | DYNAMIC),
6255   (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS | SEC_LINK_ONCE
6256    | SEC_ALLOC | SEC_LOAD | SEC_RELOC),         /* Section flags.  */
6257
6258   /* Leading_symbol_char: is the first char of a user symbol
6259      predictable, and if so what is it.  */
6260   0,
6261   '/',                          /* AR_pad_char.  */
6262   14,                           /* AR_max_namelen.  */
6263   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
6264   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
6265   bfd_getb16, bfd_getb_signed_16, bfd_putb16,   /* Data.  */
6266   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
6267   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
6268   bfd_getb16, bfd_getb_signed_16, bfd_putb16,   /* Headers.  */
6269   {_bfd_dummy_target,
6270    som_object_p,                /* bfd_check_format.  */
6271    bfd_generic_archive_p,
6272    _bfd_dummy_target
6273   },
6274   {
6275     bfd_false,
6276     som_mkobject,
6277     _bfd_generic_mkarchive,
6278     bfd_false
6279   },
6280   {
6281     bfd_false,
6282     som_write_object_contents,
6283     _bfd_write_archive_contents,
6284     bfd_false,
6285   },
6286 #undef som
6287
6288   BFD_JUMP_TABLE_GENERIC (som),
6289   BFD_JUMP_TABLE_COPY (som),
6290   BFD_JUMP_TABLE_CORE (_bfd_nocore),
6291   BFD_JUMP_TABLE_ARCHIVE (som),
6292   BFD_JUMP_TABLE_SYMBOLS (som),
6293   BFD_JUMP_TABLE_RELOCS (som),
6294   BFD_JUMP_TABLE_WRITE (som),
6295   BFD_JUMP_TABLE_LINK (som),
6296   BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
6297
6298   NULL,
6299
6300   NULL
6301 };
6302
6303 #endif /* HOST_HPPAHPUX || HOST_HPPABSD || HOST_HPPAOSF */