OSDN Git Service

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