PR 5146
[platform/upstream/binutils.git] / bfd / som.c
1 /* bfd back-end for HP PA-RISC SOM objects.
2    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3    2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
4    Free Software Foundation, Inc.
5
6    Contributed by the Center for Software Science at the
7    University of Utah.
8
9    This file is part of BFD, the Binary File Descriptor library.
10
11    This program is free software; you can redistribute it and/or modify
12    it under the terms of the GNU General Public License as published by
13    the Free Software Foundation; either version 3 of the License, or
14    (at your option) any later version.
15
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19    GNU General Public License for more details.
20
21    You should have received a copy of the GNU General Public License
22    along with this program; if not, write to the Free Software
23    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
24    02110-1301, USA.  */
25
26 #include "sysdep.h"
27 #include "bfd.h"
28
29 #if defined (HOST_HPPAHPUX) || defined (HOST_HPPABSD) || defined (HOST_HPPAOSF) || defined(HOST_HPPAMPEIX)
30
31 #include "libbfd.h"
32 #include "som.h"
33 #include "safe-ctype.h"
34
35 #include <sys/param.h>
36 #include <signal.h>
37 #include <machine/reg.h>
38 #include <sys/file.h>
39
40 /* This is the code recommended in the autoconf documentation, almost
41    verbatim.  */
42
43 #ifndef __GNUC__
44 # if HAVE_ALLOCA_H
45 #  include <alloca.h>
46 # else
47 #  ifdef _AIX
48 /* Indented so that pre-ansi C compilers will ignore it, rather than
49    choke on it.  Some versions of AIX require this to be the first
50    thing in the file.  */
51  #pragma alloca
52 #  else
53 #   ifndef alloca /* predefined by HP cc +Olibcalls */
54 #    if !defined (__STDC__) && !defined (__hpux)
55 extern char *alloca ();
56 #    else
57 extern void *alloca ();
58 #    endif /* __STDC__, __hpux */
59 #   endif /* alloca */
60 #  endif /* _AIX */
61 # endif /* HAVE_ALLOCA_H */
62 #endif /* __GNUC__ */
63
64 static bfd_reloc_status_type hppa_som_reloc
65   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
66 static bfd_boolean som_mkobject (bfd *);
67 static bfd_boolean som_is_space (asection *);
68 static bfd_boolean som_is_subspace (asection *);
69 static int compare_subspaces (const void *, const void *);
70 static unsigned long som_compute_checksum (bfd *);
71 static bfd_boolean som_build_and_write_symbol_table (bfd *);
72 static unsigned int som_slurp_symbol_table (bfd *);
73
74 /* Magic not defined in standard HP-UX header files until 8.0.  */
75
76 #ifndef CPU_PA_RISC1_0
77 #define CPU_PA_RISC1_0 0x20B
78 #endif /* CPU_PA_RISC1_0 */
79
80 #ifndef CPU_PA_RISC1_1
81 #define CPU_PA_RISC1_1 0x210
82 #endif /* CPU_PA_RISC1_1 */
83
84 #ifndef CPU_PA_RISC2_0
85 #define CPU_PA_RISC2_0 0x214
86 #endif /* CPU_PA_RISC2_0 */
87
88 #ifndef _PA_RISC1_0_ID
89 #define _PA_RISC1_0_ID CPU_PA_RISC1_0
90 #endif /* _PA_RISC1_0_ID */
91
92 #ifndef _PA_RISC1_1_ID
93 #define _PA_RISC1_1_ID CPU_PA_RISC1_1
94 #endif /* _PA_RISC1_1_ID */
95
96 #ifndef _PA_RISC2_0_ID
97 #define _PA_RISC2_0_ID CPU_PA_RISC2_0
98 #endif /* _PA_RISC2_0_ID */
99
100 #ifndef _PA_RISC_MAXID
101 #define _PA_RISC_MAXID  0x2FF
102 #endif /* _PA_RISC_MAXID */
103
104 #ifndef _PA_RISC_ID
105 #define _PA_RISC_ID(__m_num)            \
106     (((__m_num) == _PA_RISC1_0_ID) ||   \
107      ((__m_num) >= _PA_RISC1_1_ID && (__m_num) <= _PA_RISC_MAXID))
108 #endif /* _PA_RISC_ID */
109
110 /* HIUX in it's infinite stupidity changed the names for several "well
111    known" constants.  Work around such braindamage.  Try the HPUX version
112    first, then the HIUX version, and finally provide a default.  */
113 #ifdef HPUX_AUX_ID
114 #define EXEC_AUX_ID HPUX_AUX_ID
115 #endif
116
117 #if !defined (EXEC_AUX_ID) && defined (HIUX_AUX_ID)
118 #define EXEC_AUX_ID HIUX_AUX_ID
119 #endif
120
121 #ifndef EXEC_AUX_ID
122 #define EXEC_AUX_ID 0
123 #endif
124
125 /* Size (in chars) of the temporary buffers used during fixup and string
126    table writes.   */
127
128 #define SOM_TMP_BUFSIZE 8192
129
130 /* Size of the hash table in archives.  */
131 #define SOM_LST_HASH_SIZE 31
132
133 /* Max number of SOMs to be found in an archive.  */
134 #define SOM_LST_MODULE_LIMIT 1024
135
136 /* Generic alignment macro.  */
137 #define SOM_ALIGN(val, alignment) \
138   (((val) + (alignment) - 1) &~ ((unsigned long) (alignment) - 1))
139
140 /* SOM allows any one of the four previous relocations to be reused
141    with a "R_PREV_FIXUP" relocation entry.  Since R_PREV_FIXUP
142    relocations are always a single byte, using a R_PREV_FIXUP instead
143    of some multi-byte relocation makes object files smaller.
144
145    Note one side effect of using a R_PREV_FIXUP is the relocation that
146    is being repeated moves to the front of the queue.  */
147 struct reloc_queue
148 {
149   unsigned char *reloc;
150   unsigned int size;
151 } reloc_queue[4];
152
153 /* This fully describes the symbol types which may be attached to
154    an EXPORT or IMPORT directive.  Only SOM uses this formation
155    (ELF has no need for it).  */
156 typedef enum
157 {
158   SYMBOL_TYPE_UNKNOWN,
159   SYMBOL_TYPE_ABSOLUTE,
160   SYMBOL_TYPE_CODE,
161   SYMBOL_TYPE_DATA,
162   SYMBOL_TYPE_ENTRY,
163   SYMBOL_TYPE_MILLICODE,
164   SYMBOL_TYPE_PLABEL,
165   SYMBOL_TYPE_PRI_PROG,
166   SYMBOL_TYPE_SEC_PROG,
167 } pa_symbol_type;
168
169 struct section_to_type
170 {
171   char *section;
172   char type;
173 };
174
175 /* Assorted symbol information that needs to be derived from the BFD symbol
176    and/or the BFD backend private symbol data.  */
177 struct som_misc_symbol_info
178 {
179   unsigned int symbol_type;
180   unsigned int symbol_scope;
181   unsigned int arg_reloc;
182   unsigned int symbol_info;
183   unsigned int symbol_value;
184   unsigned int priv_level;
185   unsigned int secondary_def;
186   unsigned int is_comdat;
187   unsigned int is_common;
188   unsigned int dup_common;
189 };
190
191 /* Map SOM section names to POSIX/BSD single-character symbol types.
192
193    This table includes all the standard subspaces as defined in the
194    current "PRO ABI for PA-RISC Systems", $UNWIND$ which for
195    some reason was left out, and sections specific to embedded stabs.  */
196
197 static const struct section_to_type stt[] =
198 {
199   {"$TEXT$", 't'},
200   {"$SHLIB_INFO$", 't'},
201   {"$MILLICODE$", 't'},
202   {"$LIT$", 't'},
203   {"$CODE$", 't'},
204   {"$UNWIND_START$", 't'},
205   {"$UNWIND$", 't'},
206   {"$PRIVATE$", 'd'},
207   {"$PLT$", 'd'},
208   {"$SHLIB_DATA$", 'd'},
209   {"$DATA$", 'd'},
210   {"$SHORTDATA$", 'g'},
211   {"$DLT$", 'd'},
212   {"$GLOBAL$", 'g'},
213   {"$SHORTBSS$", 's'},
214   {"$BSS$", 'b'},
215   {"$GDB_STRINGS$", 'N'},
216   {"$GDB_SYMBOLS$", 'N'},
217   {0, 0}
218 };
219
220 /* About the relocation formatting table...
221
222    There are 256 entries in the table, one for each possible
223    relocation opcode available in SOM.  We index the table by
224    the relocation opcode.  The names and operations are those
225    defined by a.out_800 (4).
226
227    Right now this table is only used to count and perform minimal
228    processing on relocation streams so that they can be internalized
229    into BFD and symbolically printed by utilities.  To make actual use
230    of them would be much more difficult, BFD's concept of relocations
231    is far too simple to handle SOM relocations.  The basic assumption
232    that a relocation can be completely processed independent of other
233    relocations before an object file is written is invalid for SOM.
234
235    The SOM relocations are meant to be processed as a stream, they
236    specify copying of data from the input section to the output section
237    while possibly modifying the data in some manner.  They also can
238    specify that a variable number of zeros or uninitialized data be
239    inserted on in the output segment at the current offset.  Some
240    relocations specify that some previous relocation be re-applied at
241    the current location in the input/output sections.  And finally a number
242    of relocations have effects on other sections (R_ENTRY, R_EXIT,
243    R_UNWIND_AUX and a variety of others).  There isn't even enough room
244    in the BFD relocation data structure to store enough information to
245    perform all the relocations.
246
247    Each entry in the table has three fields.
248
249    The first entry is an index into this "class" of relocations.  This
250    index can then be used as a variable within the relocation itself.
251
252    The second field is a format string which actually controls processing
253    of the relocation.  It uses a simple postfix machine to do calculations
254    based on variables/constants found in the string and the relocation
255    stream.
256
257    The third field specifys whether or not this relocation may use
258    a constant (V) from the previous R_DATA_OVERRIDE rather than a constant
259    stored in the instruction.
260
261    Variables:
262
263    L = input space byte count
264    D = index into class of relocations
265    M = output space byte count
266    N = statement number (unused?)
267    O = stack operation
268    R = parameter relocation bits
269    S = symbol index
270    T = first 32 bits of stack unwind information
271    U = second 32 bits of stack unwind information
272    V = a literal constant (usually used in the next relocation)
273    P = a previous relocation
274
275    Lower case letters (starting with 'b') refer to following
276    bytes in the relocation stream.  'b' is the next 1 byte,
277    c is the next 2 bytes, d is the next 3 bytes, etc...
278    This is the variable part of the relocation entries that
279    makes our life a living hell.
280
281    numerical constants are also used in the format string.  Note
282    the constants are represented in decimal.
283
284    '+', "*" and "=" represents the obvious postfix operators.
285    '<' represents a left shift.
286
287    Stack Operations:
288
289    Parameter Relocation Bits:
290
291    Unwind Entries:
292
293    Previous Relocations:  The index field represents which in the queue
294    of 4 previous fixups should be re-applied.
295
296    Literal Constants:  These are generally used to represent addend
297    parts of relocations when these constants are not stored in the
298    fields of the instructions themselves.  For example the instruction
299    addil foo-$global$-0x1234 would use an override for "0x1234" rather
300    than storing it into the addil itself.  */
301
302 struct fixup_format
303 {
304   int D;
305   const char *format;
306 };
307
308 static const struct fixup_format som_fixup_formats[256] =
309 {
310   /* R_NO_RELOCATION.  */
311   {  0, "LD1+4*=" },            /* 0x00 */
312   {  1, "LD1+4*=" },            /* 0x01 */
313   {  2, "LD1+4*=" },            /* 0x02 */
314   {  3, "LD1+4*=" },            /* 0x03 */
315   {  4, "LD1+4*=" },            /* 0x04 */
316   {  5, "LD1+4*=" },            /* 0x05 */
317   {  6, "LD1+4*=" },            /* 0x06 */
318   {  7, "LD1+4*=" },            /* 0x07 */
319   {  8, "LD1+4*=" },            /* 0x08 */
320   {  9, "LD1+4*=" },            /* 0x09 */
321   { 10, "LD1+4*=" },            /* 0x0a */
322   { 11, "LD1+4*=" },            /* 0x0b */
323   { 12, "LD1+4*=" },            /* 0x0c */
324   { 13, "LD1+4*=" },            /* 0x0d */
325   { 14, "LD1+4*=" },            /* 0x0e */
326   { 15, "LD1+4*=" },            /* 0x0f */
327   { 16, "LD1+4*=" },            /* 0x10 */
328   { 17, "LD1+4*=" },            /* 0x11 */
329   { 18, "LD1+4*=" },            /* 0x12 */
330   { 19, "LD1+4*=" },            /* 0x13 */
331   { 20, "LD1+4*=" },            /* 0x14 */
332   { 21, "LD1+4*=" },            /* 0x15 */
333   { 22, "LD1+4*=" },            /* 0x16 */
334   { 23, "LD1+4*=" },            /* 0x17 */
335   {  0, "LD8<b+1+4*=" },        /* 0x18 */
336   {  1, "LD8<b+1+4*=" },        /* 0x19 */
337   {  2, "LD8<b+1+4*=" },        /* 0x1a */
338   {  3, "LD8<b+1+4*=" },        /* 0x1b */
339   {  0, "LD16<c+1+4*=" },       /* 0x1c */
340   {  1, "LD16<c+1+4*=" },       /* 0x1d */
341   {  2, "LD16<c+1+4*=" },       /* 0x1e */
342   {  0, "Ld1+=" },              /* 0x1f */
343   /* R_ZEROES.  */
344   {  0, "Lb1+4*=" },            /* 0x20 */
345   {  1, "Ld1+=" },              /* 0x21 */
346   /* R_UNINIT.  */
347   {  0, "Lb1+4*=" },            /* 0x22 */
348   {  1, "Ld1+=" },              /* 0x23 */
349   /* R_RELOCATION.  */
350   {  0, "L4=" },                /* 0x24 */
351   /* R_DATA_ONE_SYMBOL.  */
352   {  0, "L4=Sb=" },             /* 0x25 */
353   {  1, "L4=Sd=" },             /* 0x26 */
354   /* R_DATA_PLEBEL.  */
355   {  0, "L4=Sb=" },             /* 0x27 */
356   {  1, "L4=Sd=" },             /* 0x28 */
357   /* R_SPACE_REF.  */
358   {  0, "L4=" },                /* 0x29 */
359   /* R_REPEATED_INIT.  */
360   {  0, "L4=Mb1+4*=" },         /* 0x2a */
361   {  1, "Lb4*=Mb1+L*=" },       /* 0x2b */
362   {  2, "Lb4*=Md1+4*=" },       /* 0x2c */
363   {  3, "Ld1+=Me1+=" },         /* 0x2d */
364   {  0, "" },                   /* 0x2e */
365   {  0, "" },                   /* 0x2f */
366   /* R_PCREL_CALL.  */
367   {  0, "L4=RD=Sb=" },          /* 0x30 */
368   {  1, "L4=RD=Sb=" },          /* 0x31 */
369   {  2, "L4=RD=Sb=" },          /* 0x32 */
370   {  3, "L4=RD=Sb=" },          /* 0x33 */
371   {  4, "L4=RD=Sb=" },          /* 0x34 */
372   {  5, "L4=RD=Sb=" },          /* 0x35 */
373   {  6, "L4=RD=Sb=" },          /* 0x36 */
374   {  7, "L4=RD=Sb=" },          /* 0x37 */
375   {  8, "L4=RD=Sb=" },          /* 0x38 */
376   {  9, "L4=RD=Sb=" },          /* 0x39 */
377   {  0, "L4=RD8<b+=Sb=" },      /* 0x3a */
378   {  1, "L4=RD8<b+=Sb=" },      /* 0x3b */
379   {  0, "L4=RD8<b+=Sd=" },      /* 0x3c */
380   {  1, "L4=RD8<b+=Sd=" },      /* 0x3d */
381   /* R_SHORT_PCREL_MODE.  */
382   {  0, "" },                   /* 0x3e */
383   /* R_LONG_PCREL_MODE.  */
384   {  0, "" },                   /* 0x3f */
385   /* R_ABS_CALL.  */
386   {  0, "L4=RD=Sb=" },          /* 0x40 */
387   {  1, "L4=RD=Sb=" },          /* 0x41 */
388   {  2, "L4=RD=Sb=" },          /* 0x42 */
389   {  3, "L4=RD=Sb=" },          /* 0x43 */
390   {  4, "L4=RD=Sb=" },          /* 0x44 */
391   {  5, "L4=RD=Sb=" },          /* 0x45 */
392   {  6, "L4=RD=Sb=" },          /* 0x46 */
393   {  7, "L4=RD=Sb=" },          /* 0x47 */
394   {  8, "L4=RD=Sb=" },          /* 0x48 */
395   {  9, "L4=RD=Sb=" },          /* 0x49 */
396   {  0, "L4=RD8<b+=Sb=" },      /* 0x4a */
397   {  1, "L4=RD8<b+=Sb=" },      /* 0x4b */
398   {  0, "L4=RD8<b+=Sd=" },      /* 0x4c */
399   {  1, "L4=RD8<b+=Sd=" },      /* 0x4d */
400   /* R_RESERVED.  */
401   {  0, "" },                   /* 0x4e */
402   {  0, "" },                   /* 0x4f */
403   /* R_DP_RELATIVE.  */
404   {  0, "L4=SD=" },             /* 0x50 */
405   {  1, "L4=SD=" },             /* 0x51 */
406   {  2, "L4=SD=" },             /* 0x52 */
407   {  3, "L4=SD=" },             /* 0x53 */
408   {  4, "L4=SD=" },             /* 0x54 */
409   {  5, "L4=SD=" },             /* 0x55 */
410   {  6, "L4=SD=" },             /* 0x56 */
411   {  7, "L4=SD=" },             /* 0x57 */
412   {  8, "L4=SD=" },             /* 0x58 */
413   {  9, "L4=SD=" },             /* 0x59 */
414   { 10, "L4=SD=" },             /* 0x5a */
415   { 11, "L4=SD=" },             /* 0x5b */
416   { 12, "L4=SD=" },             /* 0x5c */
417   { 13, "L4=SD=" },             /* 0x5d */
418   { 14, "L4=SD=" },             /* 0x5e */
419   { 15, "L4=SD=" },             /* 0x5f */
420   { 16, "L4=SD=" },             /* 0x60 */
421   { 17, "L4=SD=" },             /* 0x61 */
422   { 18, "L4=SD=" },             /* 0x62 */
423   { 19, "L4=SD=" },             /* 0x63 */
424   { 20, "L4=SD=" },             /* 0x64 */
425   { 21, "L4=SD=" },             /* 0x65 */
426   { 22, "L4=SD=" },             /* 0x66 */
427   { 23, "L4=SD=" },             /* 0x67 */
428   { 24, "L4=SD=" },             /* 0x68 */
429   { 25, "L4=SD=" },             /* 0x69 */
430   { 26, "L4=SD=" },             /* 0x6a */
431   { 27, "L4=SD=" },             /* 0x6b */
432   { 28, "L4=SD=" },             /* 0x6c */
433   { 29, "L4=SD=" },             /* 0x6d */
434   { 30, "L4=SD=" },             /* 0x6e */
435   { 31, "L4=SD=" },             /* 0x6f */
436   { 32, "L4=Sb=" },             /* 0x70 */
437   { 33, "L4=Sd=" },             /* 0x71 */
438   /* R_RESERVED.  */
439   {  0, "" },                   /* 0x72 */
440   {  0, "" },                   /* 0x73 */
441   {  0, "" },                   /* 0x74 */
442   {  0, "" },                   /* 0x75 */
443   {  0, "" },                   /* 0x76 */
444   {  0, "" },                   /* 0x77 */
445   /* R_DLT_REL.  */
446   {  0, "L4=Sb=" },             /* 0x78 */
447   {  1, "L4=Sd=" },             /* 0x79 */
448   /* R_RESERVED.  */
449   {  0, "" },                   /* 0x7a */
450   {  0, "" },                   /* 0x7b */
451   {  0, "" },                   /* 0x7c */
452   {  0, "" },                   /* 0x7d */
453   {  0, "" },                   /* 0x7e */
454   {  0, "" },                   /* 0x7f */
455   /* R_CODE_ONE_SYMBOL.  */
456   {  0, "L4=SD=" },             /* 0x80 */
457   {  1, "L4=SD=" },             /* 0x81 */
458   {  2, "L4=SD=" },             /* 0x82 */
459   {  3, "L4=SD=" },             /* 0x83 */
460   {  4, "L4=SD=" },             /* 0x84 */
461   {  5, "L4=SD=" },             /* 0x85 */
462   {  6, "L4=SD=" },             /* 0x86 */
463   {  7, "L4=SD=" },             /* 0x87 */
464   {  8, "L4=SD=" },             /* 0x88 */
465   {  9, "L4=SD=" },             /* 0x89 */
466   { 10, "L4=SD=" },             /* 0x8q */
467   { 11, "L4=SD=" },             /* 0x8b */
468   { 12, "L4=SD=" },             /* 0x8c */
469   { 13, "L4=SD=" },             /* 0x8d */
470   { 14, "L4=SD=" },             /* 0x8e */
471   { 15, "L4=SD=" },             /* 0x8f */
472   { 16, "L4=SD=" },             /* 0x90 */
473   { 17, "L4=SD=" },             /* 0x91 */
474   { 18, "L4=SD=" },             /* 0x92 */
475   { 19, "L4=SD=" },             /* 0x93 */
476   { 20, "L4=SD=" },             /* 0x94 */
477   { 21, "L4=SD=" },             /* 0x95 */
478   { 22, "L4=SD=" },             /* 0x96 */
479   { 23, "L4=SD=" },             /* 0x97 */
480   { 24, "L4=SD=" },             /* 0x98 */
481   { 25, "L4=SD=" },             /* 0x99 */
482   { 26, "L4=SD=" },             /* 0x9a */
483   { 27, "L4=SD=" },             /* 0x9b */
484   { 28, "L4=SD=" },             /* 0x9c */
485   { 29, "L4=SD=" },             /* 0x9d */
486   { 30, "L4=SD=" },             /* 0x9e */
487   { 31, "L4=SD=" },             /* 0x9f */
488   { 32, "L4=Sb=" },             /* 0xa0 */
489   { 33, "L4=Sd=" },             /* 0xa1 */
490   /* R_RESERVED.  */
491   {  0, "" },                   /* 0xa2 */
492   {  0, "" },                   /* 0xa3 */
493   {  0, "" },                   /* 0xa4 */
494   {  0, "" },                   /* 0xa5 */
495   {  0, "" },                   /* 0xa6 */
496   {  0, "" },                   /* 0xa7 */
497   {  0, "" },                   /* 0xa8 */
498   {  0, "" },                   /* 0xa9 */
499   {  0, "" },                   /* 0xaa */
500   {  0, "" },                   /* 0xab */
501   {  0, "" },                   /* 0xac */
502   {  0, "" },                   /* 0xad */
503   /* R_MILLI_REL.  */
504   {  0, "L4=Sb=" },             /* 0xae */
505   {  1, "L4=Sd=" },             /* 0xaf */
506   /* R_CODE_PLABEL.  */
507   {  0, "L4=Sb=" },             /* 0xb0 */
508   {  1, "L4=Sd=" },             /* 0xb1 */
509   /* R_BREAKPOINT.  */
510   {  0, "L4=" },                /* 0xb2 */
511   /* R_ENTRY.  */
512   {  0, "Te=Ue=" },             /* 0xb3 */
513   {  1, "Uf=" },                /* 0xb4 */
514   /* R_ALT_ENTRY.  */
515   {  0, "" },                   /* 0xb5 */
516   /* R_EXIT.  */
517   {  0, "" },                   /* 0xb6 */
518   /* R_BEGIN_TRY.  */
519   {  0, "" },                   /* 0xb7 */
520   /* R_END_TRY.  */
521   {  0, "R0=" },                /* 0xb8 */
522   {  1, "Rb4*=" },              /* 0xb9 */
523   {  2, "Rd4*=" },              /* 0xba */
524   /* R_BEGIN_BRTAB.  */
525   {  0, "" },                   /* 0xbb */
526   /* R_END_BRTAB.  */
527   {  0, "" },                   /* 0xbc */
528   /* R_STATEMENT.  */
529   {  0, "Nb=" },                /* 0xbd */
530   {  1, "Nc=" },                /* 0xbe */
531   {  2, "Nd=" },                /* 0xbf */
532   /* R_DATA_EXPR.  */
533   {  0, "L4=" },                /* 0xc0 */
534   /* R_CODE_EXPR.  */
535   {  0, "L4=" },                /* 0xc1 */
536   /* R_FSEL.  */
537   {  0, "" },                   /* 0xc2 */
538   /* R_LSEL.  */
539   {  0, "" },                   /* 0xc3 */
540   /* R_RSEL.  */
541   {  0, "" },                   /* 0xc4 */
542   /* R_N_MODE.  */
543   {  0, "" },                   /* 0xc5 */
544   /* R_S_MODE.  */
545   {  0, "" },                   /* 0xc6 */
546   /* R_D_MODE.  */
547   {  0, "" },                   /* 0xc7 */
548   /* R_R_MODE.  */
549   {  0, "" },                   /* 0xc8 */
550   /* R_DATA_OVERRIDE.  */
551   {  0, "V0=" },                /* 0xc9 */
552   {  1, "Vb=" },                /* 0xca */
553   {  2, "Vc=" },                /* 0xcb */
554   {  3, "Vd=" },                /* 0xcc */
555   {  4, "Ve=" },                /* 0xcd */
556   /* R_TRANSLATED.  */
557   {  0, "" },                   /* 0xce */
558   /* R_AUX_UNWIND.  */
559   {  0,"Sd=Ve=Ee=" },          /* 0xcf */
560   /* R_COMP1.  */
561   {  0, "Ob=" },                /* 0xd0 */
562   /* R_COMP2.  */
563   {  0, "Ob=Sd=" },             /* 0xd1 */
564   /* R_COMP3.  */
565   {  0, "Ob=Ve=" },             /* 0xd2 */
566   /* R_PREV_FIXUP.  */
567   {  0, "P" },                  /* 0xd3 */
568   {  1, "P" },                  /* 0xd4 */
569   {  2, "P" },                  /* 0xd5 */
570   {  3, "P" },                  /* 0xd6 */
571   /* R_SEC_STMT.  */
572   {  0, "" },                   /* 0xd7 */
573   /* R_N0SEL.  */
574   {  0, "" },                   /* 0xd8 */
575   /* R_N1SEL.  */
576   {  0, "" },                   /* 0xd9 */
577   /* R_LINETAB.  */
578   {  0, "Eb=Sd=Ve=" },          /* 0xda */
579   /* R_LINETAB_ESC.  */
580   {  0, "Eb=Mb=" },             /* 0xdb */
581   /* R_LTP_OVERRIDE.  */
582   {  0, "" },                   /* 0xdc */
583   /* R_COMMENT.  */
584   {  0, "Ob=Vf=" },             /* 0xdd */
585   /* R_RESERVED.  */
586   {  0, "" },                   /* 0xde */
587   {  0, "" },                   /* 0xdf */
588   {  0, "" },                   /* 0xe0 */
589   {  0, "" },                   /* 0xe1 */
590   {  0, "" },                   /* 0xe2 */
591   {  0, "" },                   /* 0xe3 */
592   {  0, "" },                   /* 0xe4 */
593   {  0, "" },                   /* 0xe5 */
594   {  0, "" },                   /* 0xe6 */
595   {  0, "" },                   /* 0xe7 */
596   {  0, "" },                   /* 0xe8 */
597   {  0, "" },                   /* 0xe9 */
598   {  0, "" },                   /* 0xea */
599   {  0, "" },                   /* 0xeb */
600   {  0, "" },                   /* 0xec */
601   {  0, "" },                   /* 0xed */
602   {  0, "" },                   /* 0xee */
603   {  0, "" },                   /* 0xef */
604   {  0, "" },                   /* 0xf0 */
605   {  0, "" },                   /* 0xf1 */
606   {  0, "" },                   /* 0xf2 */
607   {  0, "" },                   /* 0xf3 */
608   {  0, "" },                   /* 0xf4 */
609   {  0, "" },                   /* 0xf5 */
610   {  0, "" },                   /* 0xf6 */
611   {  0, "" },                   /* 0xf7 */
612   {  0, "" },                   /* 0xf8 */
613   {  0, "" },                   /* 0xf9 */
614   {  0, "" },                   /* 0xfa */
615   {  0, "" },                   /* 0xfb */
616   {  0, "" },                   /* 0xfc */
617   {  0, "" },                   /* 0xfd */
618   {  0, "" },                   /* 0xfe */
619   {  0, "" },                   /* 0xff */
620 };
621
622 static const int comp1_opcodes[] =
623 {
624   0x00,
625   0x40,
626   0x41,
627   0x42,
628   0x43,
629   0x44,
630   0x45,
631   0x46,
632   0x47,
633   0x48,
634   0x49,
635   0x4a,
636   0x4b,
637   0x60,
638   0x80,
639   0xa0,
640   0xc0,
641   -1
642 };
643
644 static const int comp2_opcodes[] =
645 {
646   0x00,
647   0x80,
648   0x82,
649   0xc0,
650   -1
651 };
652
653 static const int comp3_opcodes[] =
654 {
655   0x00,
656   0x02,
657   -1
658 };
659
660 /* These apparently are not in older versions of hpux reloc.h (hpux7).  */
661 #ifndef R_DLT_REL
662 #define R_DLT_REL 0x78
663 #endif
664
665 #ifndef R_AUX_UNWIND
666 #define R_AUX_UNWIND 0xcf
667 #endif
668
669 #ifndef R_SEC_STMT
670 #define R_SEC_STMT 0xd7
671 #endif
672
673 /* And these first appeared in hpux10.  */
674 #ifndef R_SHORT_PCREL_MODE
675 #define NO_PCREL_MODES
676 #define R_SHORT_PCREL_MODE 0x3e
677 #endif
678
679 #ifndef R_LONG_PCREL_MODE
680 #define R_LONG_PCREL_MODE 0x3f
681 #endif
682
683 #ifndef R_N0SEL
684 #define R_N0SEL 0xd8
685 #endif
686
687 #ifndef R_N1SEL
688 #define R_N1SEL 0xd9
689 #endif
690
691 #ifndef R_LINETAB
692 #define R_LINETAB 0xda
693 #endif
694
695 #ifndef R_LINETAB_ESC
696 #define R_LINETAB_ESC 0xdb
697 #endif
698
699 #ifndef R_LTP_OVERRIDE
700 #define R_LTP_OVERRIDE 0xdc
701 #endif
702
703 #ifndef R_COMMENT
704 #define R_COMMENT 0xdd
705 #endif
706
707 #define SOM_HOWTO(TYPE, NAME)   \
708   HOWTO(TYPE, 0, 0, 32, FALSE, 0, 0, hppa_som_reloc, NAME, FALSE, 0, 0, FALSE)
709
710 static reloc_howto_type som_hppa_howto_table[] =
711 {
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_NO_RELOCATION, "R_NO_RELOCATION"),
723   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
724   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
725   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
726   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
727   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
728   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
729   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
730   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
731   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
732   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
733   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
734   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
735   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
736   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
737   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
738   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
739   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
740   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
741   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
742   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
743   SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
744   SOM_HOWTO (R_ZEROES, "R_ZEROES"),
745   SOM_HOWTO (R_ZEROES, "R_ZEROES"),
746   SOM_HOWTO (R_UNINIT, "R_UNINIT"),
747   SOM_HOWTO (R_UNINIT, "R_UNINIT"),
748   SOM_HOWTO (R_RELOCATION, "R_RELOCATION"),
749   SOM_HOWTO (R_DATA_ONE_SYMBOL, "R_DATA_ONE_SYMBOL"),
750   SOM_HOWTO (R_DATA_ONE_SYMBOL, "R_DATA_ONE_SYMBOL"),
751   SOM_HOWTO (R_DATA_PLABEL, "R_DATA_PLABEL"),
752   SOM_HOWTO (R_DATA_PLABEL, "R_DATA_PLABEL"),
753   SOM_HOWTO (R_SPACE_REF, "R_SPACE_REF"),
754   SOM_HOWTO (R_REPEATED_INIT, "REPEATED_INIT"),
755   SOM_HOWTO (R_REPEATED_INIT, "REPEATED_INIT"),
756   SOM_HOWTO (R_REPEATED_INIT, "REPEATED_INIT"),
757   SOM_HOWTO (R_REPEATED_INIT, "REPEATED_INIT"),
758   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
759   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
760   SOM_HOWTO (R_PCREL_CALL, "R_PCREL_CALL"),
761   SOM_HOWTO (R_PCREL_CALL, "R_PCREL_CALL"),
762   SOM_HOWTO (R_PCREL_CALL, "R_PCREL_CALL"),
763   SOM_HOWTO (R_PCREL_CALL, "R_PCREL_CALL"),
764   SOM_HOWTO (R_PCREL_CALL, "R_PCREL_CALL"),
765   SOM_HOWTO (R_PCREL_CALL, "R_PCREL_CALL"),
766   SOM_HOWTO (R_PCREL_CALL, "R_PCREL_CALL"),
767   SOM_HOWTO (R_PCREL_CALL, "R_PCREL_CALL"),
768   SOM_HOWTO (R_PCREL_CALL, "R_PCREL_CALL"),
769   SOM_HOWTO (R_PCREL_CALL, "R_PCREL_CALL"),
770   SOM_HOWTO (R_PCREL_CALL, "R_PCREL_CALL"),
771   SOM_HOWTO (R_PCREL_CALL, "R_PCREL_CALL"),
772   SOM_HOWTO (R_PCREL_CALL, "R_PCREL_CALL"),
773   SOM_HOWTO (R_PCREL_CALL, "R_PCREL_CALL"),
774   SOM_HOWTO (R_SHORT_PCREL_MODE, "R_SHORT_PCREL_MODE"),
775   SOM_HOWTO (R_LONG_PCREL_MODE, "R_LONG_PCREL_MODE"),
776   SOM_HOWTO (R_ABS_CALL, "R_ABS_CALL"),
777   SOM_HOWTO (R_ABS_CALL, "R_ABS_CALL"),
778   SOM_HOWTO (R_ABS_CALL, "R_ABS_CALL"),
779   SOM_HOWTO (R_ABS_CALL, "R_ABS_CALL"),
780   SOM_HOWTO (R_ABS_CALL, "R_ABS_CALL"),
781   SOM_HOWTO (R_ABS_CALL, "R_ABS_CALL"),
782   SOM_HOWTO (R_ABS_CALL, "R_ABS_CALL"),
783   SOM_HOWTO (R_ABS_CALL, "R_ABS_CALL"),
784   SOM_HOWTO (R_ABS_CALL, "R_ABS_CALL"),
785   SOM_HOWTO (R_ABS_CALL, "R_ABS_CALL"),
786   SOM_HOWTO (R_ABS_CALL, "R_ABS_CALL"),
787   SOM_HOWTO (R_ABS_CALL, "R_ABS_CALL"),
788   SOM_HOWTO (R_ABS_CALL, "R_ABS_CALL"),
789   SOM_HOWTO (R_ABS_CALL, "R_ABS_CALL"),
790   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
791   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
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_DP_RELATIVE, "R_DP_RELATIVE"),
805   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
806   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
807   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
808   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
809   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
810   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
811   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
812   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
813   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
814   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
815   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
816   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
817   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
818   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
819   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
820   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
821   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
822   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
823   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
824   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
825   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
826   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
827   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
828   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
829   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
830   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
831   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
832   SOM_HOWTO (R_DLT_REL, "R_DLT_REL"),
833   SOM_HOWTO (R_DLT_REL, "R_DLT_REL"),
834   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
835   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
836   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
837   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
838   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
839   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
840   SOM_HOWTO (R_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_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
854   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
855   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
856   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
857   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
858   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
859   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
860   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
861   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
862   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
863   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
864   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
865   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
866   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
867   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
868   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
869   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
870   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
871   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
872   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
873   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
874   SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
875   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
876   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
877   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
878   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
879   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
880   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
881   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
882   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
883   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
884   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
885   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
886   SOM_HOWTO (R_MILLI_REL, "R_MILLI_REL"),
887   SOM_HOWTO (R_MILLI_REL, "R_MILLI_REL"),
888   SOM_HOWTO (R_CODE_PLABEL, "R_CODE_PLABEL"),
889   SOM_HOWTO (R_CODE_PLABEL, "R_CODE_PLABEL"),
890   SOM_HOWTO (R_BREAKPOINT, "R_BREAKPOINT"),
891   SOM_HOWTO (R_ENTRY, "R_ENTRY"),
892   SOM_HOWTO (R_ENTRY, "R_ENTRY"),
893   SOM_HOWTO (R_ALT_ENTRY, "R_ALT_ENTRY"),
894   SOM_HOWTO (R_EXIT, "R_EXIT"),
895   SOM_HOWTO (R_BEGIN_TRY, "R_BEGIN_TRY"),
896   SOM_HOWTO (R_END_TRY, "R_END_TRY"),
897   SOM_HOWTO (R_END_TRY, "R_END_TRY"),
898   SOM_HOWTO (R_END_TRY, "R_END_TRY"),
899   SOM_HOWTO (R_BEGIN_BRTAB, "R_BEGIN_BRTAB"),
900   SOM_HOWTO (R_END_BRTAB, "R_END_BRTAB"),
901   SOM_HOWTO (R_STATEMENT, "R_STATEMENT"),
902   SOM_HOWTO (R_STATEMENT, "R_STATEMENT"),
903   SOM_HOWTO (R_STATEMENT, "R_STATEMENT"),
904   SOM_HOWTO (R_DATA_EXPR, "R_DATA_EXPR"),
905   SOM_HOWTO (R_CODE_EXPR, "R_CODE_EXPR"),
906   SOM_HOWTO (R_FSEL, "R_FSEL"),
907   SOM_HOWTO (R_LSEL, "R_LSEL"),
908   SOM_HOWTO (R_RSEL, "R_RSEL"),
909   SOM_HOWTO (R_N_MODE, "R_N_MODE"),
910   SOM_HOWTO (R_S_MODE, "R_S_MODE"),
911   SOM_HOWTO (R_D_MODE, "R_D_MODE"),
912   SOM_HOWTO (R_R_MODE, "R_R_MODE"),
913   SOM_HOWTO (R_DATA_OVERRIDE, "R_DATA_OVERRIDE"),
914   SOM_HOWTO (R_DATA_OVERRIDE, "R_DATA_OVERRIDE"),
915   SOM_HOWTO (R_DATA_OVERRIDE, "R_DATA_OVERRIDE"),
916   SOM_HOWTO (R_DATA_OVERRIDE, "R_DATA_OVERRIDE"),
917   SOM_HOWTO (R_DATA_OVERRIDE, "R_DATA_OVERRIDE"),
918   SOM_HOWTO (R_TRANSLATED, "R_TRANSLATED"),
919   SOM_HOWTO (R_AUX_UNWIND, "R_AUX_UNWIND"),
920   SOM_HOWTO (R_COMP1, "R_COMP1"),
921   SOM_HOWTO (R_COMP2, "R_COMP2"),
922   SOM_HOWTO (R_COMP3, "R_COMP3"),
923   SOM_HOWTO (R_PREV_FIXUP, "R_PREV_FIXUP"),
924   SOM_HOWTO (R_PREV_FIXUP, "R_PREV_FIXUP"),
925   SOM_HOWTO (R_PREV_FIXUP, "R_PREV_FIXUP"),
926   SOM_HOWTO (R_PREV_FIXUP, "R_PREV_FIXUP"),
927   SOM_HOWTO (R_SEC_STMT, "R_SEC_STMT"),
928   SOM_HOWTO (R_N0SEL, "R_N0SEL"),
929   SOM_HOWTO (R_N1SEL, "R_N1SEL"),
930   SOM_HOWTO (R_LINETAB, "R_LINETAB"),
931   SOM_HOWTO (R_LINETAB_ESC, "R_LINETAB_ESC"),
932   SOM_HOWTO (R_LTP_OVERRIDE, "R_LTP_OVERRIDE"),
933   SOM_HOWTO (R_COMMENT, "R_COMMENT"),
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   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
947   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
948   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
949   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
950   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
951   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
952   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
953   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
954   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
955   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
956   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
957   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
958   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
959   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
960   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
961   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
962   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
963   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
964   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
965   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
966   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
967   SOM_HOWTO (R_RESERVED, "R_RESERVED")
968 };
969
970 /* Initialize the SOM relocation queue.  By definition the queue holds
971    the last four multibyte fixups.  */
972
973 static void
974 som_initialize_reloc_queue (struct reloc_queue *queue)
975 {
976   queue[0].reloc = NULL;
977   queue[0].size = 0;
978   queue[1].reloc = NULL;
979   queue[1].size = 0;
980   queue[2].reloc = NULL;
981   queue[2].size = 0;
982   queue[3].reloc = NULL;
983   queue[3].size = 0;
984 }
985
986 /* Insert a new relocation into the relocation queue.  */
987
988 static void
989 som_reloc_queue_insert (unsigned char *p,
990                         unsigned int size,
991                         struct reloc_queue *queue)
992 {
993   queue[3].reloc = queue[2].reloc;
994   queue[3].size = queue[2].size;
995   queue[2].reloc = queue[1].reloc;
996   queue[2].size = queue[1].size;
997   queue[1].reloc = queue[0].reloc;
998   queue[1].size = queue[0].size;
999   queue[0].reloc = p;
1000   queue[0].size = size;
1001 }
1002
1003 /* When an entry in the relocation queue is reused, the entry moves
1004    to the front of the queue.  */
1005
1006 static void
1007 som_reloc_queue_fix (struct reloc_queue *queue, unsigned int index)
1008 {
1009   if (index == 0)
1010     return;
1011
1012   if (index == 1)
1013     {
1014       unsigned char *tmp1 = queue[0].reloc;
1015       unsigned int tmp2 = queue[0].size;
1016
1017       queue[0].reloc = queue[1].reloc;
1018       queue[0].size = queue[1].size;
1019       queue[1].reloc = tmp1;
1020       queue[1].size = tmp2;
1021       return;
1022     }
1023
1024   if (index == 2)
1025     {
1026       unsigned char *tmp1 = queue[0].reloc;
1027       unsigned int tmp2 = queue[0].size;
1028
1029       queue[0].reloc = queue[2].reloc;
1030       queue[0].size = queue[2].size;
1031       queue[2].reloc = queue[1].reloc;
1032       queue[2].size = queue[1].size;
1033       queue[1].reloc = tmp1;
1034       queue[1].size = tmp2;
1035       return;
1036     }
1037
1038   if (index == 3)
1039     {
1040       unsigned char *tmp1 = queue[0].reloc;
1041       unsigned int tmp2 = queue[0].size;
1042
1043       queue[0].reloc = queue[3].reloc;
1044       queue[0].size = queue[3].size;
1045       queue[3].reloc = queue[2].reloc;
1046       queue[3].size = queue[2].size;
1047       queue[2].reloc = queue[1].reloc;
1048       queue[2].size = queue[1].size;
1049       queue[1].reloc = tmp1;
1050       queue[1].size = tmp2;
1051       return;
1052     }
1053   abort ();
1054 }
1055
1056 /* Search for a particular relocation in the relocation queue.  */
1057
1058 static int
1059 som_reloc_queue_find (unsigned char *p,
1060                       unsigned int size,
1061                       struct reloc_queue *queue)
1062 {
1063   if (queue[0].reloc && !memcmp (p, queue[0].reloc, size)
1064       && size == queue[0].size)
1065     return 0;
1066   if (queue[1].reloc && !memcmp (p, queue[1].reloc, size)
1067       && size == queue[1].size)
1068     return 1;
1069   if (queue[2].reloc && !memcmp (p, queue[2].reloc, size)
1070       && size == queue[2].size)
1071     return 2;
1072   if (queue[3].reloc && !memcmp (p, queue[3].reloc, size)
1073       && size == queue[3].size)
1074     return 3;
1075   return -1;
1076 }
1077
1078 static unsigned char *
1079 try_prev_fixup (bfd *abfd ATTRIBUTE_UNUSED,
1080                 unsigned int *subspace_reloc_sizep,
1081                 unsigned char *p,
1082                 unsigned int size,
1083                 struct reloc_queue *queue)
1084 {
1085   int queue_index = som_reloc_queue_find (p, size, queue);
1086
1087   if (queue_index != -1)
1088     {
1089       /* Found this in a previous fixup.  Undo the fixup we
1090          just built and use R_PREV_FIXUP instead.  We saved
1091          a total of size - 1 bytes in the fixup stream.  */
1092       bfd_put_8 (abfd, R_PREV_FIXUP + queue_index, p);
1093       p += 1;
1094       *subspace_reloc_sizep += 1;
1095       som_reloc_queue_fix (queue, queue_index);
1096     }
1097   else
1098     {
1099       som_reloc_queue_insert (p, size, queue);
1100       *subspace_reloc_sizep += size;
1101       p += size;
1102     }
1103   return p;
1104 }
1105
1106 /* Emit the proper R_NO_RELOCATION fixups to map the next SKIP
1107    bytes without any relocation.  Update the size of the subspace
1108    relocation stream via SUBSPACE_RELOC_SIZE_P; also return the
1109    current pointer into the relocation stream.  */
1110
1111 static unsigned char *
1112 som_reloc_skip (bfd *abfd,
1113                 unsigned int skip,
1114                 unsigned char *p,
1115                 unsigned int *subspace_reloc_sizep,
1116                 struct reloc_queue *queue)
1117 {
1118   /* Use a 4 byte R_NO_RELOCATION entry with a maximal value
1119      then R_PREV_FIXUPs to get the difference down to a
1120      reasonable size.  */
1121   if (skip >= 0x1000000)
1122     {
1123       skip -= 0x1000000;
1124       bfd_put_8 (abfd, R_NO_RELOCATION + 31, p);
1125       bfd_put_8 (abfd, 0xff, p + 1);
1126       bfd_put_16 (abfd, (bfd_vma) 0xffff, p + 2);
1127       p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 4, queue);
1128       while (skip >= 0x1000000)
1129         {
1130           skip -= 0x1000000;
1131           bfd_put_8 (abfd, R_PREV_FIXUP, p);
1132           p++;
1133           *subspace_reloc_sizep += 1;
1134           /* No need to adjust queue here since we are repeating the
1135              most recent fixup.  */
1136         }
1137     }
1138
1139   /* The difference must be less than 0x1000000.  Use one
1140      more R_NO_RELOCATION entry to get to the right difference.  */
1141   if ((skip & 3) == 0 && skip <= 0xc0000 && skip > 0)
1142     {
1143       /* Difference can be handled in a simple single-byte
1144          R_NO_RELOCATION entry.  */
1145       if (skip <= 0x60)
1146         {
1147           bfd_put_8 (abfd, R_NO_RELOCATION + (skip >> 2) - 1, p);
1148           *subspace_reloc_sizep += 1;
1149           p++;
1150         }
1151       /* Handle it with a two byte R_NO_RELOCATION entry.  */
1152       else if (skip <= 0x1000)
1153         {
1154           bfd_put_8 (abfd, R_NO_RELOCATION + 24 + (((skip >> 2) - 1) >> 8), p);
1155           bfd_put_8 (abfd, (skip >> 2) - 1, p + 1);
1156           p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 2, queue);
1157         }
1158       /* Handle it with a three byte R_NO_RELOCATION entry.  */
1159       else
1160         {
1161           bfd_put_8 (abfd, R_NO_RELOCATION + 28 + (((skip >> 2) - 1) >> 16), p);
1162           bfd_put_16 (abfd, (bfd_vma) (skip >> 2) - 1, p + 1);
1163           p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 3, queue);
1164         }
1165     }
1166   /* Ugh.  Punt and use a 4 byte entry.  */
1167   else if (skip > 0)
1168     {
1169       bfd_put_8 (abfd, R_NO_RELOCATION + 31, p);
1170       bfd_put_8 (abfd, (skip - 1) >> 16, p + 1);
1171       bfd_put_16 (abfd, (bfd_vma) skip - 1, p + 2);
1172       p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 4, queue);
1173     }
1174   return p;
1175 }
1176
1177 /* Emit the proper R_DATA_OVERRIDE fixups to handle a nonzero addend
1178    from a BFD relocation.  Update the size of the subspace relocation
1179    stream via SUBSPACE_RELOC_SIZE_P; also return the current pointer
1180    into the relocation stream.  */
1181
1182 static unsigned char *
1183 som_reloc_addend (bfd *abfd,
1184                   bfd_vma addend,
1185                   unsigned char *p,
1186                   unsigned int *subspace_reloc_sizep,
1187                   struct reloc_queue *queue)
1188 {
1189   if (addend + 0x80 < 0x100)
1190     {
1191       bfd_put_8 (abfd, R_DATA_OVERRIDE + 1, p);
1192       bfd_put_8 (abfd, addend, p + 1);
1193       p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 2, queue);
1194     }
1195   else if (addend + 0x8000 < 0x10000)
1196     {
1197       bfd_put_8 (abfd, R_DATA_OVERRIDE + 2, p);
1198       bfd_put_16 (abfd, addend, p + 1);
1199       p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 3, queue);
1200     }
1201   else if (addend + 0x800000 < 0x1000000)
1202     {
1203       bfd_put_8 (abfd, R_DATA_OVERRIDE + 3, p);
1204       bfd_put_8 (abfd, addend >> 16, p + 1);
1205       bfd_put_16 (abfd, addend, p + 2);
1206       p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 4, queue);
1207     }
1208   else
1209     {
1210       bfd_put_8 (abfd, R_DATA_OVERRIDE + 4, p);
1211       bfd_put_32 (abfd, addend, p + 1);
1212       p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 5, queue);
1213     }
1214   return p;
1215 }
1216
1217 /* Handle a single function call relocation.  */
1218
1219 static unsigned char *
1220 som_reloc_call (bfd *abfd,
1221                 unsigned char *p,
1222                 unsigned int *subspace_reloc_sizep,
1223                 arelent *bfd_reloc,
1224                 int sym_num,
1225                 struct reloc_queue *queue)
1226 {
1227   int arg_bits = HPPA_R_ARG_RELOC (bfd_reloc->addend);
1228   int rtn_bits = arg_bits & 0x3;
1229   int type, done = 0;
1230
1231   /* You'll never believe all this is necessary to handle relocations
1232      for function calls.  Having to compute and pack the argument
1233      relocation bits is the real nightmare.
1234
1235      If you're interested in how this works, just forget it.  You really
1236      do not want to know about this braindamage.  */
1237
1238   /* First see if this can be done with a "simple" relocation.  Simple
1239      relocations have a symbol number < 0x100 and have simple encodings
1240      of argument relocations.  */
1241
1242   if (sym_num < 0x100)
1243     {
1244       switch (arg_bits)
1245         {
1246         case 0:
1247         case 1:
1248           type = 0;
1249           break;
1250         case 1 << 8:
1251         case 1 << 8 | 1:
1252           type = 1;
1253           break;
1254         case 1 << 8 | 1 << 6:
1255         case 1 << 8 | 1 << 6 | 1:
1256           type = 2;
1257           break;
1258         case 1 << 8 | 1 << 6 | 1 << 4:
1259         case 1 << 8 | 1 << 6 | 1 << 4 | 1:
1260           type = 3;
1261           break;
1262         case 1 << 8 | 1 << 6 | 1 << 4 | 1 << 2:
1263         case 1 << 8 | 1 << 6 | 1 << 4 | 1 << 2 | 1:
1264           type = 4;
1265           break;
1266         default:
1267           /* Not one of the easy encodings.  This will have to be
1268              handled by the more complex code below.  */
1269           type = -1;
1270           break;
1271         }
1272       if (type != -1)
1273         {
1274           /* Account for the return value too.  */
1275           if (rtn_bits)
1276             type += 5;
1277
1278           /* Emit a 2 byte relocation.  Then see if it can be handled
1279              with a relocation which is already in the relocation queue.  */
1280           bfd_put_8 (abfd, bfd_reloc->howto->type + type, p);
1281           bfd_put_8 (abfd, sym_num, p + 1);
1282           p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 2, queue);
1283           done = 1;
1284         }
1285     }
1286
1287   /* If this could not be handled with a simple relocation, then do a hard
1288      one.  Hard relocations occur if the symbol number was too high or if
1289      the encoding of argument relocation bits is too complex.  */
1290   if (! done)
1291     {
1292       /* Don't ask about these magic sequences.  I took them straight
1293          from gas-1.36 which took them from the a.out man page.  */
1294       type = rtn_bits;
1295       if ((arg_bits >> 6 & 0xf) == 0xe)
1296         type += 9 * 40;
1297       else
1298         type += (3 * (arg_bits >> 8 & 3) + (arg_bits >> 6 & 3)) * 40;
1299       if ((arg_bits >> 2 & 0xf) == 0xe)
1300         type += 9 * 4;
1301       else
1302         type += (3 * (arg_bits >> 4 & 3) + (arg_bits >> 2 & 3)) * 4;
1303
1304       /* Output the first two bytes of the relocation.  These describe
1305          the length of the relocation and encoding style.  */
1306       bfd_put_8 (abfd, bfd_reloc->howto->type + 10
1307                  + 2 * (sym_num >= 0x100) + (type >= 0x100),
1308                  p);
1309       bfd_put_8 (abfd, type, p + 1);
1310
1311       /* Now output the symbol index and see if this bizarre relocation
1312          just happened to be in the relocation queue.  */
1313       if (sym_num < 0x100)
1314         {
1315           bfd_put_8 (abfd, sym_num, p + 2);
1316           p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 3, queue);
1317         }
1318       else
1319         {
1320           bfd_put_8 (abfd, sym_num >> 16, p + 2);
1321           bfd_put_16 (abfd, (bfd_vma) sym_num, p + 3);
1322           p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 5, queue);
1323         }
1324     }
1325   return p;
1326 }
1327
1328 /* Return the logarithm of X, base 2, considering X unsigned,
1329    if X is a power of 2.  Otherwise, returns -1.  */
1330
1331 static int
1332 exact_log2 (unsigned int x)
1333 {
1334   int log = 0;
1335
1336   /* Test for 0 or a power of 2.  */
1337   if (x == 0 || x != (x & -x))
1338     return -1;
1339
1340   while ((x >>= 1) != 0)
1341     log++;
1342   return log;
1343 }
1344
1345 static bfd_reloc_status_type
1346 hppa_som_reloc (bfd *abfd ATTRIBUTE_UNUSED,
1347                 arelent *reloc_entry,
1348                 asymbol *symbol_in ATTRIBUTE_UNUSED,
1349                 void *data ATTRIBUTE_UNUSED,
1350                 asection *input_section,
1351                 bfd *output_bfd,
1352                 char **error_message ATTRIBUTE_UNUSED)
1353 {
1354   if (output_bfd)
1355     reloc_entry->address += input_section->output_offset;
1356
1357   return bfd_reloc_ok;
1358 }
1359
1360 /* Given a generic HPPA relocation type, the instruction format,
1361    and a field selector, return one or more appropriate SOM relocations.  */
1362
1363 int **
1364 hppa_som_gen_reloc_type (bfd *abfd,
1365                          int base_type,
1366                          int format,
1367                          enum hppa_reloc_field_selector_type_alt field,
1368                          int sym_diff,
1369                          asymbol *sym)
1370 {
1371   int *final_type, **final_types;
1372
1373   final_types = bfd_alloc (abfd, (bfd_size_type) sizeof (int *) * 6);
1374   final_type = bfd_alloc (abfd, (bfd_size_type) sizeof (int));
1375   if (!final_types || !final_type)
1376     return NULL;
1377
1378   /* The field selector may require additional relocations to be
1379      generated.  It's impossible to know at this moment if additional
1380      relocations will be needed, so we make them.  The code to actually
1381      write the relocation/fixup stream is responsible for removing
1382      any redundant relocations.  */
1383   switch (field)
1384     {
1385     case e_fsel:
1386     case e_psel:
1387     case e_lpsel:
1388     case e_rpsel:
1389       final_types[0] = final_type;
1390       final_types[1] = NULL;
1391       final_types[2] = NULL;
1392       *final_type = base_type;
1393       break;
1394
1395     case e_tsel:
1396     case e_ltsel:
1397     case e_rtsel:
1398       final_types[0] = bfd_alloc (abfd, (bfd_size_type) sizeof (int));
1399       if (!final_types[0])
1400         return NULL;
1401       if (field == e_tsel)
1402         *final_types[0] = R_FSEL;
1403       else if (field == e_ltsel)
1404         *final_types[0] = R_LSEL;
1405       else
1406         *final_types[0] = R_RSEL;
1407       final_types[1] = final_type;
1408       final_types[2] = NULL;
1409       *final_type = base_type;
1410       break;
1411
1412     case e_lssel:
1413     case e_rssel:
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_S_MODE;
1418       final_types[1] = final_type;
1419       final_types[2] = NULL;
1420       *final_type = base_type;
1421       break;
1422
1423     case e_lsel:
1424     case e_rsel:
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_N_MODE;
1429       final_types[1] = final_type;
1430       final_types[2] = NULL;
1431       *final_type = base_type;
1432       break;
1433
1434     case e_ldsel:
1435     case e_rdsel:
1436       final_types[0] = bfd_alloc (abfd, (bfd_size_type) sizeof (int));
1437       if (!final_types[0])
1438         return NULL;
1439       *final_types[0] = R_D_MODE;
1440       final_types[1] = final_type;
1441       final_types[2] = NULL;
1442       *final_type = base_type;
1443       break;
1444
1445     case e_lrsel:
1446     case e_rrsel:
1447       final_types[0] = bfd_alloc (abfd, (bfd_size_type) sizeof (int));
1448       if (!final_types[0])
1449         return NULL;
1450       *final_types[0] = R_R_MODE;
1451       final_types[1] = final_type;
1452       final_types[2] = NULL;
1453       *final_type = base_type;
1454       break;
1455
1456     case e_nsel:
1457       final_types[0] = bfd_alloc (abfd, (bfd_size_type) sizeof (int));
1458       if (!final_types[0])
1459         return NULL;
1460       *final_types[0] = R_N1SEL;
1461       final_types[1] = final_type;
1462       final_types[2] = NULL;
1463       *final_type = base_type;
1464       break;
1465
1466     case e_nlsel:
1467     case e_nlrsel:
1468       final_types[0] = bfd_alloc (abfd, (bfd_size_type) sizeof (int));
1469       if (!final_types[0])
1470         return NULL;
1471       *final_types[0] = R_N0SEL;
1472       final_types[1] = bfd_alloc (abfd, (bfd_size_type) sizeof (int));
1473       if (!final_types[1])
1474         return NULL;
1475       if (field == e_nlsel)
1476         *final_types[1] = R_N_MODE;
1477       else
1478         *final_types[1] = R_R_MODE;
1479       final_types[2] = final_type;
1480       final_types[3] = NULL;
1481       *final_type = base_type;
1482       break;
1483
1484     /* FIXME: These two field selectors are not currently supported.  */
1485     case e_ltpsel:
1486     case e_rtpsel:
1487       abort ();
1488     }
1489
1490   switch (base_type)
1491     {
1492     case R_HPPA:
1493       /* The difference of two symbols needs *very* special handling.  */
1494       if (sym_diff)
1495         {
1496           bfd_size_type amt = sizeof (int);
1497
1498           final_types[0] = bfd_alloc (abfd, amt);
1499           final_types[1] = bfd_alloc (abfd, amt);
1500           final_types[2] = bfd_alloc (abfd, amt);
1501           final_types[3] = bfd_alloc (abfd, amt);
1502           if (!final_types[0] || !final_types[1] || !final_types[2])
1503             return NULL;
1504           if (field == e_fsel)
1505             *final_types[0] = R_FSEL;
1506           else if (field == e_rsel)
1507             *final_types[0] = R_RSEL;
1508           else if (field == e_lsel)
1509             *final_types[0] = R_LSEL;
1510           *final_types[1] = R_COMP2;
1511           *final_types[2] = R_COMP2;
1512           *final_types[3] = R_COMP1;
1513           final_types[4] = final_type;
1514           if (format == 32)
1515             *final_types[4] = R_DATA_EXPR;
1516           else
1517             *final_types[4] = R_CODE_EXPR;
1518           final_types[5] = NULL;
1519           break;
1520         }
1521       /* PLABELs get their own relocation type.  */
1522       else if (field == e_psel
1523                || field == e_lpsel
1524                || field == e_rpsel)
1525         {
1526           /* A PLABEL relocation that has a size of 32 bits must
1527              be a R_DATA_PLABEL.  All others are R_CODE_PLABELs.  */
1528           if (format == 32)
1529             *final_type = R_DATA_PLABEL;
1530           else
1531             *final_type = R_CODE_PLABEL;
1532         }
1533       /* PIC stuff.  */
1534       else if (field == e_tsel
1535                || field == e_ltsel
1536                || field == e_rtsel)
1537         *final_type = R_DLT_REL;
1538       /* A relocation in the data space is always a full 32bits.  */
1539       else if (format == 32)
1540         {
1541           *final_type = R_DATA_ONE_SYMBOL;
1542
1543           /* If there's no SOM symbol type associated with this BFD
1544              symbol, then set the symbol type to ST_DATA.
1545
1546              Only do this if the type is going to default later when
1547              we write the object file.
1548
1549              This is done so that the linker never encounters an
1550              R_DATA_ONE_SYMBOL reloc involving an ST_CODE symbol.
1551
1552              This allows the compiler to generate exception handling
1553              tables.
1554
1555              Note that one day we may need to also emit BEGIN_BRTAB and
1556              END_BRTAB to prevent the linker from optimizing away insns
1557              in exception handling regions.  */
1558           if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_UNKNOWN
1559               && (sym->flags & BSF_SECTION_SYM) == 0
1560               && (sym->flags & BSF_FUNCTION) == 0
1561               && ! bfd_is_com_section (sym->section))
1562             som_symbol_data (sym)->som_type = SYMBOL_TYPE_DATA;
1563         }
1564       break;
1565
1566     case R_HPPA_GOTOFF:
1567       /* More PLABEL special cases.  */
1568       if (field == e_psel
1569           || field == e_lpsel
1570           || field == e_rpsel)
1571         *final_type = R_DATA_PLABEL;
1572       break;
1573
1574     case R_HPPA_COMPLEX:
1575       /* The difference of two symbols needs *very* special handling.  */
1576       if (sym_diff)
1577         {
1578           bfd_size_type amt = sizeof (int);
1579
1580           final_types[0] = bfd_alloc (abfd, amt);
1581           final_types[1] = bfd_alloc (abfd, amt);
1582           final_types[2] = bfd_alloc (abfd, amt);
1583           final_types[3] = bfd_alloc (abfd, amt);
1584           if (!final_types[0] || !final_types[1] || !final_types[2])
1585             return NULL;
1586           if (field == e_fsel)
1587             *final_types[0] = R_FSEL;
1588           else if (field == e_rsel)
1589             *final_types[0] = R_RSEL;
1590           else if (field == e_lsel)
1591             *final_types[0] = R_LSEL;
1592           *final_types[1] = R_COMP2;
1593           *final_types[2] = R_COMP2;
1594           *final_types[3] = R_COMP1;
1595           final_types[4] = final_type;
1596           if (format == 32)
1597             *final_types[4] = R_DATA_EXPR;
1598           else
1599             *final_types[4] = R_CODE_EXPR;
1600           final_types[5] = NULL;
1601           break;
1602         }
1603       else
1604         break;
1605
1606     case R_HPPA_NONE:
1607     case R_HPPA_ABS_CALL:
1608       /* Right now we can default all these.  */
1609       break;
1610
1611     case R_HPPA_PCREL_CALL:
1612       {
1613 #ifndef NO_PCREL_MODES
1614         /* If we have short and long pcrel modes, then generate the proper
1615            mode selector, then the pcrel relocation.  Redundant selectors
1616            will be eliminated as the relocs are sized and emitted.  */
1617         bfd_size_type amt = sizeof (int);
1618
1619         final_types[0] = bfd_alloc (abfd, amt);
1620         if (!final_types[0])
1621           return NULL;
1622         if (format == 17)
1623           *final_types[0] = R_SHORT_PCREL_MODE;
1624         else
1625           *final_types[0] = R_LONG_PCREL_MODE;
1626         final_types[1] = final_type;
1627         final_types[2] = NULL;
1628         *final_type = base_type;
1629 #endif
1630         break;
1631       }
1632     }
1633   return final_types;
1634 }
1635
1636 /* Return the address of the correct entry in the PA SOM relocation
1637    howto table.  */
1638
1639 static reloc_howto_type *
1640 som_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1641                            bfd_reloc_code_real_type code)
1642 {
1643   if ((int) code < (int) R_NO_RELOCATION + 255)
1644     {
1645       BFD_ASSERT ((int) som_hppa_howto_table[(int) code].type == (int) code);
1646       return &som_hppa_howto_table[(int) code];
1647     }
1648
1649   return NULL;
1650 }
1651
1652 static reloc_howto_type *
1653 som_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1654                            const char *r_name)
1655 {
1656   unsigned int i;
1657
1658   for (i = 0;
1659        i < sizeof (som_hppa_howto_table) / sizeof (som_hppa_howto_table[0]);
1660        i++)
1661     if (som_hppa_howto_table[i].name != NULL
1662         && strcasecmp (som_hppa_howto_table[i].name, r_name) == 0)
1663       return &som_hppa_howto_table[i];
1664
1665   return NULL;
1666 }
1667
1668 /* Perform some initialization for an object.  Save results of this
1669    initialization in the BFD.  */
1670
1671 static const bfd_target *
1672 som_object_setup (bfd *abfd,
1673                   struct header *file_hdrp,
1674                   struct som_exec_auxhdr *aux_hdrp,
1675                   unsigned long current_offset)
1676 {
1677   asection *section;
1678
1679   /* som_mkobject will set bfd_error if som_mkobject fails.  */
1680   if (! som_mkobject (abfd))
1681     return NULL;
1682
1683   /* Set BFD flags based on what information is available in the SOM.  */
1684   abfd->flags = BFD_NO_FLAGS;
1685   if (file_hdrp->symbol_total)
1686     abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
1687
1688   switch (file_hdrp->a_magic)
1689     {
1690     case DEMAND_MAGIC:
1691       abfd->flags |= (D_PAGED | WP_TEXT | EXEC_P);
1692       break;
1693     case SHARE_MAGIC:
1694       abfd->flags |= (WP_TEXT | EXEC_P);
1695       break;
1696     case EXEC_MAGIC:
1697       abfd->flags |= (EXEC_P);
1698       break;
1699     case RELOC_MAGIC:
1700       abfd->flags |= HAS_RELOC;
1701       break;
1702 #ifdef SHL_MAGIC
1703     case SHL_MAGIC:
1704 #endif
1705 #ifdef DL_MAGIC
1706     case DL_MAGIC:
1707 #endif
1708       abfd->flags |= DYNAMIC;
1709       break;
1710
1711     default:
1712       break;
1713     }
1714
1715   /* Save the auxiliary header.  */
1716   obj_som_exec_hdr (abfd) = aux_hdrp;
1717
1718   /* Allocate space to hold the saved exec header information.  */
1719   obj_som_exec_data (abfd) = bfd_zalloc (abfd, (bfd_size_type) sizeof (struct som_exec_data));
1720   if (obj_som_exec_data (abfd) == NULL)
1721     return NULL;
1722
1723   /* The braindamaged OSF1 linker switched exec_flags and exec_entry!
1724
1725      We used to identify OSF1 binaries based on NEW_VERSION_ID, but
1726      apparently the latest HPUX linker is using NEW_VERSION_ID now.
1727
1728      It's about time, OSF has used the new id since at least 1992;
1729      HPUX didn't start till nearly 1995!.
1730
1731      The new approach examines the entry field for an executable.  If
1732      it is not 4-byte aligned then it's not a proper code address and
1733      we guess it's really the executable flags.  For a main program,
1734      we also consider zero to be indicative of a buggy linker, since
1735      that is not a valid entry point.  The entry point for a shared
1736      library, however, can be zero so we do not consider that to be
1737      indicative of a buggy linker.  */
1738   if (aux_hdrp)
1739     {
1740       int found = 0;
1741
1742       for (section = abfd->sections; section; section = section->next)
1743         {
1744           bfd_vma entry;
1745
1746           if ((section->flags & SEC_CODE) == 0)
1747             continue;
1748           entry = aux_hdrp->exec_entry + aux_hdrp->exec_tmem;
1749           if (entry >= section->vma
1750               && entry < section->vma + section->size)
1751             found = 1;
1752         }
1753       if ((aux_hdrp->exec_entry == 0 && !(abfd->flags & DYNAMIC))
1754           || (aux_hdrp->exec_entry & 0x3) != 0
1755           || ! found)
1756         {
1757           bfd_get_start_address (abfd) = aux_hdrp->exec_flags;
1758           obj_som_exec_data (abfd)->exec_flags = aux_hdrp->exec_entry;
1759         }
1760       else
1761         {
1762           bfd_get_start_address (abfd) = aux_hdrp->exec_entry + current_offset;
1763           obj_som_exec_data (abfd)->exec_flags = aux_hdrp->exec_flags;
1764         }
1765     }
1766
1767   obj_som_exec_data (abfd)->version_id = file_hdrp->version_id;
1768
1769   bfd_default_set_arch_mach (abfd, bfd_arch_hppa, pa10);
1770   bfd_get_symcount (abfd) = file_hdrp->symbol_total;
1771
1772   /* Initialize the saved symbol table and string table to NULL.
1773      Save important offsets and sizes from the SOM header into
1774      the BFD.  */
1775   obj_som_stringtab (abfd) = NULL;
1776   obj_som_symtab (abfd) = NULL;
1777   obj_som_sorted_syms (abfd) = NULL;
1778   obj_som_stringtab_size (abfd) = file_hdrp->symbol_strings_size;
1779   obj_som_sym_filepos (abfd) = file_hdrp->symbol_location + current_offset;
1780   obj_som_str_filepos (abfd) = (file_hdrp->symbol_strings_location
1781                                 + current_offset);
1782   obj_som_reloc_filepos (abfd) = (file_hdrp->fixup_request_location
1783                                   + current_offset);
1784   obj_som_exec_data (abfd)->system_id = file_hdrp->system_id;
1785
1786   return abfd->xvec;
1787 }
1788
1789 /* Convert all of the space and subspace info into BFD sections.  Each space
1790    contains a number of subspaces, which in turn describe the mapping between
1791    regions of the exec file, and the address space that the program runs in.
1792    BFD sections which correspond to spaces will overlap the sections for the
1793    associated subspaces.  */
1794
1795 static bfd_boolean
1796 setup_sections (bfd *abfd,
1797                 struct header *file_hdr,
1798                 unsigned long current_offset)
1799 {
1800   char *space_strings;
1801   unsigned int space_index, i;
1802   unsigned int total_subspaces = 0;
1803   asection **subspace_sections = NULL;
1804   asection *section;
1805   bfd_size_type amt;
1806
1807   /* First, read in space names.  */
1808   amt = file_hdr->space_strings_size;
1809   space_strings = bfd_malloc (amt);
1810   if (!space_strings && amt != 0)
1811     goto error_return;
1812
1813   if (bfd_seek (abfd, current_offset + file_hdr->space_strings_location,
1814                 SEEK_SET) != 0)
1815     goto error_return;
1816   if (bfd_bread (space_strings, amt, abfd) != amt)
1817     goto error_return;
1818
1819   /* Loop over all of the space dictionaries, building up sections.  */
1820   for (space_index = 0; space_index < file_hdr->space_total; space_index++)
1821     {
1822       struct space_dictionary_record space;
1823       struct som_subspace_dictionary_record subspace, save_subspace;
1824       unsigned int subspace_index;
1825       asection *space_asect;
1826       bfd_size_type space_size = 0;
1827       char *newname;
1828
1829       /* Read the space dictionary element.  */
1830       if (bfd_seek (abfd,
1831                     (current_offset + file_hdr->space_location
1832                      + space_index * sizeof space),
1833                     SEEK_SET) != 0)
1834         goto error_return;
1835       amt = sizeof space;
1836       if (bfd_bread (&space, amt, abfd) != amt)
1837         goto error_return;
1838
1839       /* Setup the space name string.  */
1840       space.name.n_name = space.name.n_strx + space_strings;
1841
1842       /* Make a section out of it.  */
1843       amt = strlen (space.name.n_name) + 1;
1844       newname = bfd_alloc (abfd, amt);
1845       if (!newname)
1846         goto error_return;
1847       strcpy (newname, space.name.n_name);
1848
1849       space_asect = bfd_make_section_anyway (abfd, newname);
1850       if (!space_asect)
1851         goto error_return;
1852
1853       if (space.is_loadable == 0)
1854         space_asect->flags |= SEC_DEBUGGING;
1855
1856       /* Set up all the attributes for the space.  */
1857       if (! bfd_som_set_section_attributes (space_asect, space.is_defined,
1858                                             space.is_private, space.sort_key,
1859                                             space.space_number))
1860         goto error_return;
1861
1862       /* If the space has no subspaces, then we're done.  */
1863       if (space.subspace_quantity == 0)
1864         continue;
1865
1866       /* Now, read in the first subspace for this space.  */
1867       if (bfd_seek (abfd,
1868                     (current_offset + file_hdr->subspace_location
1869                      + space.subspace_index * sizeof subspace),
1870                     SEEK_SET) != 0)
1871         goto error_return;
1872       amt = sizeof subspace;
1873       if (bfd_bread (&subspace, amt, abfd) != amt)
1874         goto error_return;
1875       /* Seek back to the start of the subspaces for loop below.  */
1876       if (bfd_seek (abfd,
1877                     (current_offset + file_hdr->subspace_location
1878                      + space.subspace_index * sizeof subspace),
1879                     SEEK_SET) != 0)
1880         goto error_return;
1881
1882       /* Setup the start address and file loc from the first subspace
1883          record.  */
1884       space_asect->vma = subspace.subspace_start;
1885       space_asect->filepos = subspace.file_loc_init_value + current_offset;
1886       space_asect->alignment_power = exact_log2 (subspace.alignment);
1887       if (space_asect->alignment_power == (unsigned) -1)
1888         goto error_return;
1889
1890       /* Initialize save_subspace so we can reliably determine if this
1891          loop placed any useful values into it.  */
1892       memset (&save_subspace, 0, sizeof (save_subspace));
1893
1894       /* Loop over the rest of the subspaces, building up more sections.  */
1895       for (subspace_index = 0; subspace_index < space.subspace_quantity;
1896            subspace_index++)
1897         {
1898           asection *subspace_asect;
1899
1900           /* Read in the next subspace.  */
1901           amt = sizeof subspace;
1902           if (bfd_bread (&subspace, amt, abfd) != amt)
1903             goto error_return;
1904
1905           /* Setup the subspace name string.  */
1906           subspace.name.n_name = subspace.name.n_strx + space_strings;
1907
1908           amt = strlen (subspace.name.n_name) + 1;
1909           newname = bfd_alloc (abfd, amt);
1910           if (!newname)
1911             goto error_return;
1912           strcpy (newname, subspace.name.n_name);
1913
1914           /* Make a section out of this subspace.  */
1915           subspace_asect = bfd_make_section_anyway (abfd, newname);
1916           if (!subspace_asect)
1917             goto error_return;
1918
1919           /* Store private information about the section.  */
1920           if (! bfd_som_set_subsection_attributes (subspace_asect, space_asect,
1921                                                    subspace.access_control_bits,
1922                                                    subspace.sort_key,
1923                                                    subspace.quadrant,
1924                                                    subspace.is_comdat,
1925                                                    subspace.is_common,
1926                                                    subspace.dup_common))
1927             goto error_return;
1928
1929           /* Keep an easy mapping between subspaces and sections.
1930              Note we do not necessarily read the subspaces in the
1931              same order in which they appear in the object file.
1932
1933              So to make the target index come out correctly, we
1934              store the location of the subspace header in target
1935              index, then sort using the location of the subspace
1936              header as the key.  Then we can assign correct
1937              subspace indices.  */
1938           total_subspaces++;
1939           subspace_asect->target_index = bfd_tell (abfd) - sizeof (subspace);
1940
1941           /* Set SEC_READONLY and SEC_CODE/SEC_DATA as specified
1942              by the access_control_bits in the subspace header.  */
1943           switch (subspace.access_control_bits >> 4)
1944             {
1945             /* Readonly data.  */
1946             case 0x0:
1947               subspace_asect->flags |= SEC_DATA | SEC_READONLY;
1948               break;
1949
1950             /* Normal data.  */
1951             case 0x1:
1952               subspace_asect->flags |= SEC_DATA;
1953               break;
1954
1955             /* Readonly code and the gateways.
1956                Gateways have other attributes which do not map
1957                into anything BFD knows about.  */
1958             case 0x2:
1959             case 0x4:
1960             case 0x5:
1961             case 0x6:
1962             case 0x7:
1963               subspace_asect->flags |= SEC_CODE | SEC_READONLY;
1964               break;
1965
1966             /* dynamic (writable) code.  */
1967             case 0x3:
1968               subspace_asect->flags |= SEC_CODE;
1969               break;
1970             }
1971
1972           if (subspace.is_comdat || subspace.is_common || subspace.dup_common)
1973             subspace_asect->flags |= SEC_LINK_ONCE;
1974
1975           if (subspace.subspace_length > 0)
1976             subspace_asect->flags |= SEC_HAS_CONTENTS;
1977
1978           if (subspace.is_loadable)
1979             subspace_asect->flags |= SEC_ALLOC | SEC_LOAD;
1980           else
1981             subspace_asect->flags |= SEC_DEBUGGING;
1982
1983           if (subspace.code_only)
1984             subspace_asect->flags |= SEC_CODE;
1985
1986           /* Both file_loc_init_value and initialization_length will
1987              be zero for a BSS like subspace.  */
1988           if (subspace.file_loc_init_value == 0
1989               && subspace.initialization_length == 0)
1990             subspace_asect->flags &= ~(SEC_DATA | SEC_LOAD | SEC_HAS_CONTENTS);
1991
1992           /* This subspace has relocations.
1993              The fixup_request_quantity is a byte count for the number of
1994              entries in the relocation stream; it is not the actual number
1995              of relocations in the subspace.  */
1996           if (subspace.fixup_request_quantity != 0)
1997             {
1998               subspace_asect->flags |= SEC_RELOC;
1999               subspace_asect->rel_filepos = subspace.fixup_request_index;
2000               som_section_data (subspace_asect)->reloc_size
2001                 = subspace.fixup_request_quantity;
2002               /* We can not determine this yet.  When we read in the
2003                  relocation table the correct value will be filled in.  */
2004               subspace_asect->reloc_count = (unsigned) -1;
2005             }
2006
2007           /* Update save_subspace if appropriate.  */
2008           if (subspace.file_loc_init_value > save_subspace.file_loc_init_value)
2009             save_subspace = subspace;
2010
2011           subspace_asect->vma = subspace.subspace_start;
2012           subspace_asect->size = subspace.subspace_length;
2013           subspace_asect->filepos = (subspace.file_loc_init_value
2014                                      + current_offset);
2015           subspace_asect->alignment_power = exact_log2 (subspace.alignment);
2016           if (subspace_asect->alignment_power == (unsigned) -1)
2017             goto error_return;
2018
2019           /* Keep track of the accumulated sizes of the sections.  */
2020           space_size += subspace.subspace_length;
2021         }
2022
2023       /* This can happen for a .o which defines symbols in otherwise
2024          empty subspaces.  */
2025       if (!save_subspace.file_loc_init_value)
2026         space_asect->size = 0;
2027       else
2028         {
2029           if (file_hdr->a_magic != RELOC_MAGIC)
2030             {
2031               /* Setup the size for the space section based upon the info
2032                  in the last subspace of the space.  */
2033               space_asect->size = (save_subspace.subspace_start
2034                                    - space_asect->vma
2035                                    + save_subspace.subspace_length);
2036             }
2037           else
2038             {
2039               /* The subspace_start field is not initialised in relocatable
2040                  only objects, so it cannot be used for length calculations.
2041                  Instead we use the space_size value which we have been
2042                  accumulating.  This isn't an accurate estimate since it
2043                  ignores alignment and ordering issues.  */
2044               space_asect->size = space_size;
2045             }
2046         }
2047     }
2048   /* Now that we've read in all the subspace records, we need to assign
2049      a target index to each subspace.  */
2050   amt = total_subspaces;
2051   amt *= sizeof (asection *);
2052   subspace_sections = bfd_malloc (amt);
2053   if (subspace_sections == NULL)
2054     goto error_return;
2055
2056   for (i = 0, section = abfd->sections; section; section = section->next)
2057     {
2058       if (!som_is_subspace (section))
2059         continue;
2060
2061       subspace_sections[i] = section;
2062       i++;
2063     }
2064   qsort (subspace_sections, total_subspaces,
2065          sizeof (asection *), compare_subspaces);
2066
2067   /* subspace_sections is now sorted in the order in which the subspaces
2068      appear in the object file.  Assign an index to each one now.  */
2069   for (i = 0; i < total_subspaces; i++)
2070     subspace_sections[i]->target_index = i;
2071
2072   if (space_strings != NULL)
2073     free (space_strings);
2074
2075   if (subspace_sections != NULL)
2076     free (subspace_sections);
2077
2078   return TRUE;
2079
2080  error_return:
2081   if (space_strings != NULL)
2082     free (space_strings);
2083
2084   if (subspace_sections != NULL)
2085     free (subspace_sections);
2086   return FALSE;
2087 }
2088
2089 /* Read in a SOM object and make it into a BFD.  */
2090
2091 static const bfd_target *
2092 som_object_p (bfd *abfd)
2093 {
2094   struct header file_hdr;
2095   struct som_exec_auxhdr *aux_hdr_ptr = NULL;
2096   unsigned long current_offset = 0;
2097   struct lst_header lst_header;
2098   struct som_entry som_entry;
2099   bfd_size_type amt;
2100 #define ENTRY_SIZE sizeof (struct som_entry)
2101
2102   amt = FILE_HDR_SIZE;
2103   if (bfd_bread ((void *) &file_hdr, amt, abfd) != amt)
2104     {
2105       if (bfd_get_error () != bfd_error_system_call)
2106         bfd_set_error (bfd_error_wrong_format);
2107       return NULL;
2108     }
2109
2110   if (!_PA_RISC_ID (file_hdr.system_id))
2111     {
2112       bfd_set_error (bfd_error_wrong_format);
2113       return NULL;
2114     }
2115
2116   switch (file_hdr.a_magic)
2117     {
2118     case RELOC_MAGIC:
2119     case EXEC_MAGIC:
2120     case SHARE_MAGIC:
2121     case DEMAND_MAGIC:
2122 #ifdef DL_MAGIC
2123     case DL_MAGIC:
2124 #endif
2125 #ifdef SHL_MAGIC
2126     case SHL_MAGIC:
2127 #endif
2128 #ifdef SHARED_MAGIC_CNX
2129     case SHARED_MAGIC_CNX:
2130 #endif
2131       break;
2132
2133 #ifdef EXECLIBMAGIC
2134     case EXECLIBMAGIC:
2135       /* Read the lst header and determine where the SOM directory begins.  */
2136
2137       if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
2138         {
2139           if (bfd_get_error () != bfd_error_system_call)
2140             bfd_set_error (bfd_error_wrong_format);
2141           return NULL;
2142         }
2143
2144       amt = SLSTHDR;
2145       if (bfd_bread ((void *) &lst_header, amt, abfd) != amt)
2146         {
2147           if (bfd_get_error () != bfd_error_system_call)
2148             bfd_set_error (bfd_error_wrong_format);
2149           return NULL;
2150         }
2151
2152       /* Position to and read the first directory entry.  */
2153
2154       if (bfd_seek (abfd, lst_header.dir_loc, SEEK_SET) != 0)
2155         {
2156           if (bfd_get_error () != bfd_error_system_call)
2157             bfd_set_error (bfd_error_wrong_format);
2158           return NULL;
2159         }
2160
2161       amt = ENTRY_SIZE;
2162       if (bfd_bread ((void *) &som_entry, 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       /* Now position to the first SOM.  */
2170
2171       if (bfd_seek (abfd, som_entry.location, SEEK_SET) != 0)
2172         {
2173           if (bfd_get_error () != bfd_error_system_call)
2174             bfd_set_error (bfd_error_wrong_format);
2175           return NULL;
2176         }
2177
2178       current_offset = som_entry.location;
2179
2180       /* And finally, re-read the som header.  */
2181       amt = FILE_HDR_SIZE;
2182       if (bfd_bread ((void *) &file_hdr, amt, abfd) != amt)
2183         {
2184           if (bfd_get_error () != bfd_error_system_call)
2185             bfd_set_error (bfd_error_wrong_format);
2186           return NULL;
2187         }
2188
2189       break;
2190 #endif
2191
2192     default:
2193       bfd_set_error (bfd_error_wrong_format);
2194       return NULL;
2195     }
2196
2197   if (file_hdr.version_id != VERSION_ID
2198       && file_hdr.version_id != NEW_VERSION_ID)
2199     {
2200       bfd_set_error (bfd_error_wrong_format);
2201       return NULL;
2202     }
2203
2204   /* If the aux_header_size field in the file header is zero, then this
2205      object is an incomplete executable (a .o file).  Do not try to read
2206      a non-existant auxiliary header.  */
2207   if (file_hdr.aux_header_size != 0)
2208     {
2209       aux_hdr_ptr = bfd_zalloc (abfd, 
2210                                 (bfd_size_type) sizeof (*aux_hdr_ptr));
2211       if (aux_hdr_ptr == NULL)
2212         return NULL;
2213       amt = AUX_HDR_SIZE;
2214       if (bfd_bread ((void *) aux_hdr_ptr, amt, abfd) != amt)
2215         {
2216           if (bfd_get_error () != bfd_error_system_call)
2217             bfd_set_error (bfd_error_wrong_format);
2218           return NULL;
2219         }
2220     }
2221
2222   if (!setup_sections (abfd, &file_hdr, current_offset))
2223     {
2224       /* setup_sections does not bubble up a bfd error code.  */
2225       bfd_set_error (bfd_error_bad_value);
2226       return NULL;
2227     }
2228
2229   /* This appears to be a valid SOM object.  Do some initialization.  */
2230   return som_object_setup (abfd, &file_hdr, aux_hdr_ptr, current_offset);
2231 }
2232
2233 /* Create a SOM object.  */
2234
2235 static bfd_boolean
2236 som_mkobject (bfd *abfd)
2237 {
2238   /* Allocate memory to hold backend information.  */
2239   abfd->tdata.som_data = bfd_zalloc (abfd, (bfd_size_type) sizeof (struct som_data_struct));
2240   if (abfd->tdata.som_data == NULL)
2241     return FALSE;
2242   return TRUE;
2243 }
2244
2245 /* Initialize some information in the file header.  This routine makes
2246    not attempt at doing the right thing for a full executable; it
2247    is only meant to handle relocatable objects.  */
2248
2249 static bfd_boolean
2250 som_prep_headers (bfd *abfd)
2251 {
2252   struct header *file_hdr;
2253   asection *section;
2254   bfd_size_type amt = sizeof (struct header);
2255
2256   /* Make and attach a file header to the BFD.  */
2257   file_hdr = bfd_zalloc (abfd, amt);
2258   if (file_hdr == NULL)
2259     return FALSE;
2260   obj_som_file_hdr (abfd) = file_hdr;
2261
2262   if (abfd->flags & (EXEC_P | DYNAMIC))
2263     {
2264       /* Make and attach an exec header to the BFD.  */
2265       amt = sizeof (struct som_exec_auxhdr);
2266       obj_som_exec_hdr (abfd) = bfd_zalloc (abfd, amt);
2267       if (obj_som_exec_hdr (abfd) == NULL)
2268         return FALSE;
2269
2270       if (abfd->flags & D_PAGED)
2271         file_hdr->a_magic = DEMAND_MAGIC;
2272       else if (abfd->flags & WP_TEXT)
2273         file_hdr->a_magic = SHARE_MAGIC;
2274 #ifdef SHL_MAGIC
2275       else if (abfd->flags & DYNAMIC)
2276         file_hdr->a_magic = SHL_MAGIC;
2277 #endif
2278       else
2279         file_hdr->a_magic = EXEC_MAGIC;
2280     }
2281   else
2282     file_hdr->a_magic = RELOC_MAGIC;
2283
2284   /* These fields are optional, and embedding timestamps is not always
2285      a wise thing to do, it makes comparing objects during a multi-stage
2286      bootstrap difficult.  */
2287   file_hdr->file_time.secs = 0;
2288   file_hdr->file_time.nanosecs = 0;
2289
2290   file_hdr->entry_space = 0;
2291   file_hdr->entry_subspace = 0;
2292   file_hdr->entry_offset = 0;
2293   file_hdr->presumed_dp = 0;
2294
2295   /* Now iterate over the sections translating information from
2296      BFD sections to SOM spaces/subspaces.  */
2297   for (section = abfd->sections; section != NULL; section = section->next)
2298     {
2299       /* Ignore anything which has not been marked as a space or
2300          subspace.  */
2301       if (!som_is_space (section) && !som_is_subspace (section))
2302         continue;
2303
2304       if (som_is_space (section))
2305         {
2306           /* Allocate space for the space dictionary.  */
2307           amt = sizeof (struct space_dictionary_record);
2308           som_section_data (section)->space_dict = bfd_zalloc (abfd, amt);
2309           if (som_section_data (section)->space_dict == NULL)
2310             return FALSE;
2311           /* Set space attributes.  Note most attributes of SOM spaces
2312              are set based on the subspaces it contains.  */
2313           som_section_data (section)->space_dict->loader_fix_index = -1;
2314           som_section_data (section)->space_dict->init_pointer_index = -1;
2315
2316           /* Set more attributes that were stuffed away in private data.  */
2317           som_section_data (section)->space_dict->sort_key =
2318             som_section_data (section)->copy_data->sort_key;
2319           som_section_data (section)->space_dict->is_defined =
2320             som_section_data (section)->copy_data->is_defined;
2321           som_section_data (section)->space_dict->is_private =
2322             som_section_data (section)->copy_data->is_private;
2323           som_section_data (section)->space_dict->space_number =
2324             som_section_data (section)->copy_data->space_number;
2325         }
2326       else
2327         {
2328           /* Allocate space for the subspace dictionary.  */
2329           amt = sizeof (struct som_subspace_dictionary_record);
2330           som_section_data (section)->subspace_dict = bfd_zalloc (abfd, amt);
2331           if (som_section_data (section)->subspace_dict == NULL)
2332             return FALSE;
2333
2334           /* Set subspace attributes.  Basic stuff is done here, additional
2335              attributes are filled in later as more information becomes
2336              available.  */
2337           if (section->flags & SEC_ALLOC)
2338             som_section_data (section)->subspace_dict->is_loadable = 1;
2339
2340           if (section->flags & SEC_CODE)
2341             som_section_data (section)->subspace_dict->code_only = 1;
2342
2343           som_section_data (section)->subspace_dict->subspace_start =
2344             section->vma;
2345           som_section_data (section)->subspace_dict->subspace_length =
2346             section->size;
2347           som_section_data (section)->subspace_dict->initialization_length =
2348             section->size;
2349           som_section_data (section)->subspace_dict->alignment =
2350             1 << section->alignment_power;
2351
2352           /* Set more attributes that were stuffed away in private data.  */
2353           som_section_data (section)->subspace_dict->sort_key =
2354             som_section_data (section)->copy_data->sort_key;
2355           som_section_data (section)->subspace_dict->access_control_bits =
2356             som_section_data (section)->copy_data->access_control_bits;
2357           som_section_data (section)->subspace_dict->quadrant =
2358             som_section_data (section)->copy_data->quadrant;
2359           som_section_data (section)->subspace_dict->is_comdat =
2360             som_section_data (section)->copy_data->is_comdat;
2361           som_section_data (section)->subspace_dict->is_common =
2362             som_section_data (section)->copy_data->is_common;
2363           som_section_data (section)->subspace_dict->dup_common =
2364             som_section_data (section)->copy_data->dup_common;
2365         }
2366     }
2367   return TRUE;
2368 }
2369
2370 /* Return TRUE if the given section is a SOM space, FALSE otherwise.  */
2371
2372 static bfd_boolean
2373 som_is_space (asection *section)
2374 {
2375   /* If no copy data is available, then it's neither a space nor a
2376      subspace.  */
2377   if (som_section_data (section)->copy_data == NULL)
2378     return FALSE;
2379
2380   /* If the containing space isn't the same as the given section,
2381      then this isn't a space.  */
2382   if (som_section_data (section)->copy_data->container != section
2383       && (som_section_data (section)->copy_data->container->output_section
2384           != section))
2385     return FALSE;
2386
2387   /* OK.  Must be a space.  */
2388   return TRUE;
2389 }
2390
2391 /* Return TRUE if the given section is a SOM subspace, FALSE otherwise.  */
2392
2393 static bfd_boolean
2394 som_is_subspace (asection *section)
2395 {
2396   /* If no copy data is available, then it's neither a space nor a
2397      subspace.  */
2398   if (som_section_data (section)->copy_data == NULL)
2399     return FALSE;
2400
2401   /* If the containing space is the same as the given section,
2402      then this isn't a subspace.  */
2403   if (som_section_data (section)->copy_data->container == section
2404       || (som_section_data (section)->copy_data->container->output_section
2405           == section))
2406     return FALSE;
2407
2408   /* OK.  Must be a subspace.  */
2409   return TRUE;
2410 }
2411
2412 /* Return TRUE if the given space contains the given subspace.  It
2413    is safe to assume space really is a space, and subspace really
2414    is a subspace.  */
2415
2416 static bfd_boolean
2417 som_is_container (asection *space, asection *subspace)
2418 {
2419   return (som_section_data (subspace)->copy_data->container == space)
2420     || (som_section_data (subspace)->copy_data->container->output_section
2421         == space);
2422 }
2423
2424 /* Count and return the number of spaces attached to the given BFD.  */
2425
2426 static unsigned long
2427 som_count_spaces (bfd *abfd)
2428 {
2429   int count = 0;
2430   asection *section;
2431
2432   for (section = abfd->sections; section != NULL; section = section->next)
2433     count += som_is_space (section);
2434
2435   return count;
2436 }
2437
2438 /* Count the number of subspaces attached to the given BFD.  */
2439
2440 static unsigned long
2441 som_count_subspaces (bfd *abfd)
2442 {
2443   int count = 0;
2444   asection *section;
2445
2446   for (section = abfd->sections; section != NULL; section = section->next)
2447     count += som_is_subspace (section);
2448
2449   return count;
2450 }
2451
2452 /* Return -1, 0, 1 indicating the relative ordering of sym1 and sym2.
2453
2454    We desire symbols to be ordered starting with the symbol with the
2455    highest relocation count down to the symbol with the lowest relocation
2456    count.  Doing so compacts the relocation stream.  */
2457
2458 static int
2459 compare_syms (const void *arg1, const void *arg2)
2460 {
2461   asymbol **sym1 = (asymbol **) arg1;
2462   asymbol **sym2 = (asymbol **) arg2;
2463   unsigned int count1, count2;
2464
2465   /* Get relocation count for each symbol.  Note that the count
2466      is stored in the udata pointer for section symbols!  */
2467   if ((*sym1)->flags & BSF_SECTION_SYM)
2468     count1 = (*sym1)->udata.i;
2469   else
2470     count1 = som_symbol_data (*sym1)->reloc_count;
2471
2472   if ((*sym2)->flags & BSF_SECTION_SYM)
2473     count2 = (*sym2)->udata.i;
2474   else
2475     count2 = som_symbol_data (*sym2)->reloc_count;
2476
2477   /* Return the appropriate value.  */
2478   if (count1 < count2)
2479     return 1;
2480   else if (count1 > count2)
2481     return -1;
2482   return 0;
2483 }
2484
2485 /* Return -1, 0, 1 indicating the relative ordering of subspace1
2486    and subspace.  */
2487
2488 static int
2489 compare_subspaces (const void *arg1, const void *arg2)
2490 {
2491   asection **subspace1 = (asection **) arg1;
2492   asection **subspace2 = (asection **) arg2;
2493
2494   if ((*subspace1)->target_index < (*subspace2)->target_index)
2495     return -1;
2496   else if ((*subspace2)->target_index < (*subspace1)->target_index)
2497     return 1;
2498   else
2499     return 0;
2500 }
2501
2502 /* Perform various work in preparation for emitting the fixup stream.  */
2503
2504 static void
2505 som_prep_for_fixups (bfd *abfd, asymbol **syms, unsigned long num_syms)
2506 {
2507   unsigned long i;
2508   asection *section;
2509   asymbol **sorted_syms;
2510   bfd_size_type amt;
2511
2512   /* Most SOM relocations involving a symbol have a length which is
2513      dependent on the index of the symbol.  So symbols which are
2514      used often in relocations should have a small index.  */
2515
2516   /* First initialize the counters for each symbol.  */
2517   for (i = 0; i < num_syms; i++)
2518     {
2519       /* Handle a section symbol; these have no pointers back to the
2520          SOM symbol info.  So we just use the udata field to hold the
2521          relocation count.  */
2522       if (som_symbol_data (syms[i]) == NULL
2523           || syms[i]->flags & BSF_SECTION_SYM)
2524         {
2525           syms[i]->flags |= BSF_SECTION_SYM;
2526           syms[i]->udata.i = 0;
2527         }
2528       else
2529         som_symbol_data (syms[i])->reloc_count = 0;
2530     }
2531
2532   /* Now that the counters are initialized, make a weighted count
2533      of how often a given symbol is used in a relocation.  */
2534   for (section = abfd->sections; section != NULL; section = section->next)
2535     {
2536       int j;
2537
2538       /* Does this section have any relocations?  */
2539       if ((int) section->reloc_count <= 0)
2540         continue;
2541
2542       /* Walk through each relocation for this section.  */
2543       for (j = 1; j < (int) section->reloc_count; j++)
2544         {
2545           arelent *reloc = section->orelocation[j];
2546           int scale;
2547
2548           /* A relocation against a symbol in the *ABS* section really
2549              does not have a symbol.  Likewise if the symbol isn't associated
2550              with any section.  */
2551           if (reloc->sym_ptr_ptr == NULL
2552               || bfd_is_abs_section ((*reloc->sym_ptr_ptr)->section))
2553             continue;
2554
2555           /* Scaling to encourage symbols involved in R_DP_RELATIVE
2556              and R_CODE_ONE_SYMBOL relocations to come first.  These
2557              two relocations have single byte versions if the symbol
2558              index is very small.  */
2559           if (reloc->howto->type == R_DP_RELATIVE
2560               || reloc->howto->type == R_CODE_ONE_SYMBOL)
2561             scale = 2;
2562           else
2563             scale = 1;
2564
2565           /* Handle section symbols by storing the count in the udata
2566              field.  It will not be used and the count is very important
2567              for these symbols.  */
2568           if ((*reloc->sym_ptr_ptr)->flags & BSF_SECTION_SYM)
2569             {
2570               (*reloc->sym_ptr_ptr)->udata.i =
2571                 (*reloc->sym_ptr_ptr)->udata.i + scale;
2572               continue;
2573             }
2574
2575           /* A normal symbol.  Increment the count.  */
2576           som_symbol_data (*reloc->sym_ptr_ptr)->reloc_count += scale;
2577         }
2578     }
2579
2580   /* Sort a copy of the symbol table, rather than the canonical
2581      output symbol table.  */
2582   amt = num_syms;
2583   amt *= sizeof (asymbol *);
2584   sorted_syms = bfd_zalloc (abfd, amt);
2585   memcpy (sorted_syms, syms, num_syms * sizeof (asymbol *));
2586   qsort (sorted_syms, num_syms, sizeof (asymbol *), compare_syms);
2587   obj_som_sorted_syms (abfd) = sorted_syms;
2588
2589   /* Compute the symbol indexes, they will be needed by the relocation
2590      code.  */
2591   for (i = 0; i < num_syms; i++)
2592     {
2593       /* A section symbol.  Again, there is no pointer to backend symbol
2594          information, so we reuse the udata field again.  */
2595       if (sorted_syms[i]->flags & BSF_SECTION_SYM)
2596         sorted_syms[i]->udata.i = i;
2597       else
2598         som_symbol_data (sorted_syms[i])->index = i;
2599     }
2600 }
2601
2602 static bfd_boolean
2603 som_write_fixups (bfd *abfd,
2604                   unsigned long current_offset,
2605                   unsigned int *total_reloc_sizep)
2606 {
2607   unsigned int i, j;
2608   /* Chunk of memory that we can use as buffer space, then throw
2609      away.  */
2610   unsigned char tmp_space[SOM_TMP_BUFSIZE];
2611   unsigned char *p;
2612   unsigned int total_reloc_size = 0;
2613   unsigned int subspace_reloc_size = 0;
2614   unsigned int num_spaces = obj_som_file_hdr (abfd)->space_total;
2615   asection *section = abfd->sections;
2616   bfd_size_type amt;
2617
2618   memset (tmp_space, 0, SOM_TMP_BUFSIZE);
2619   p = tmp_space;
2620
2621   /* All the fixups for a particular subspace are emitted in a single
2622      stream.  All the subspaces for a particular space are emitted
2623      as a single stream.
2624
2625      So, to get all the locations correct one must iterate through all the
2626      spaces, for each space iterate through its subspaces and output a
2627      fixups stream.  */
2628   for (i = 0; i < num_spaces; i++)
2629     {
2630       asection *subsection;
2631
2632       /* Find a space.  */
2633       while (!som_is_space (section))
2634         section = section->next;
2635
2636       /* Now iterate through each of its subspaces.  */
2637       for (subsection = abfd->sections;
2638            subsection != NULL;
2639            subsection = subsection->next)
2640         {
2641           int reloc_offset;
2642           unsigned int current_rounding_mode;
2643 #ifndef NO_PCREL_MODES
2644           unsigned int current_call_mode;
2645 #endif
2646
2647           /* Find a subspace of this space.  */
2648           if (!som_is_subspace (subsection)
2649               || !som_is_container (section, subsection))
2650             continue;
2651
2652           /* If this subspace does not have real data, then we are
2653              finished with it.  */
2654           if ((subsection->flags & SEC_HAS_CONTENTS) == 0)
2655             {
2656               som_section_data (subsection)->subspace_dict->fixup_request_index
2657                 = -1;
2658               continue;
2659             }
2660
2661           /* This subspace has some relocations.  Put the relocation stream
2662              index into the subspace record.  */
2663           som_section_data (subsection)->subspace_dict->fixup_request_index
2664             = total_reloc_size;
2665
2666           /* To make life easier start over with a clean slate for
2667              each subspace.  Seek to the start of the relocation stream
2668              for this subspace in preparation for writing out its fixup
2669              stream.  */
2670           if (bfd_seek (abfd, current_offset + total_reloc_size, SEEK_SET) != 0)
2671             return FALSE;
2672
2673           /* Buffer space has already been allocated.  Just perform some
2674              initialization here.  */
2675           p = tmp_space;
2676           subspace_reloc_size = 0;
2677           reloc_offset = 0;
2678           som_initialize_reloc_queue (reloc_queue);
2679           current_rounding_mode = R_N_MODE;
2680 #ifndef NO_PCREL_MODES
2681           current_call_mode = R_SHORT_PCREL_MODE;
2682 #endif
2683
2684           /* Translate each BFD relocation into one or more SOM
2685              relocations.  */
2686           for (j = 0; j < subsection->reloc_count; j++)
2687             {
2688               arelent *bfd_reloc = subsection->orelocation[j];
2689               unsigned int skip;
2690               int sym_num;
2691
2692               /* Get the symbol number.  Remember it's stored in a
2693                  special place for section symbols.  */
2694               if ((*bfd_reloc->sym_ptr_ptr)->flags & BSF_SECTION_SYM)
2695                 sym_num = (*bfd_reloc->sym_ptr_ptr)->udata.i;
2696               else
2697                 sym_num = som_symbol_data (*bfd_reloc->sym_ptr_ptr)->index;
2698
2699               /* If there is not enough room for the next couple relocations,
2700                  then dump the current buffer contents now.  Also reinitialize
2701                  the relocation queue.
2702
2703                  No single BFD relocation could ever translate into more
2704                  than 100 bytes of SOM relocations (20bytes is probably the
2705                  upper limit, but leave lots of space for growth).  */
2706               if (p - tmp_space + 100 > SOM_TMP_BUFSIZE)
2707                 {
2708                   amt = p - tmp_space;
2709                   if (bfd_bwrite ((void *) tmp_space, amt, abfd) != amt)
2710                     return FALSE;
2711
2712                   p = tmp_space;
2713                   som_initialize_reloc_queue (reloc_queue);
2714                 }
2715
2716               /* Emit R_NO_RELOCATION fixups to map any bytes which were
2717                  skipped.  */
2718               skip = bfd_reloc->address - reloc_offset;
2719               p = som_reloc_skip (abfd, skip, p,
2720                                   &subspace_reloc_size, reloc_queue);
2721
2722               /* Update reloc_offset for the next iteration.
2723
2724                  Many relocations do not consume input bytes.  They
2725                  are markers, or set state necessary to perform some
2726                  later relocation.  */
2727               switch (bfd_reloc->howto->type)
2728                 {
2729                 case R_ENTRY:
2730                 case R_ALT_ENTRY:
2731                 case R_EXIT:
2732                 case R_N_MODE:
2733                 case R_S_MODE:
2734                 case R_D_MODE:
2735                 case R_R_MODE:
2736                 case R_FSEL:
2737                 case R_LSEL:
2738                 case R_RSEL:
2739                 case R_COMP1:
2740                 case R_COMP2:
2741                 case R_BEGIN_BRTAB:
2742                 case R_END_BRTAB:
2743                 case R_BEGIN_TRY:
2744                 case R_END_TRY:
2745                 case R_N0SEL:
2746                 case R_N1SEL:
2747 #ifndef NO_PCREL_MODES
2748                 case R_SHORT_PCREL_MODE:
2749                 case R_LONG_PCREL_MODE:
2750 #endif
2751                   reloc_offset = bfd_reloc->address;
2752                   break;
2753
2754                 default:
2755                   reloc_offset = bfd_reloc->address + 4;
2756                   break;
2757                 }
2758
2759               /* Now the actual relocation we care about.  */
2760               switch (bfd_reloc->howto->type)
2761                 {
2762                 case R_PCREL_CALL:
2763                 case R_ABS_CALL:
2764                   p = som_reloc_call (abfd, p, &subspace_reloc_size,
2765                                       bfd_reloc, sym_num, reloc_queue);
2766                   break;
2767
2768                 case R_CODE_ONE_SYMBOL:
2769                 case R_DP_RELATIVE:
2770                   /* Account for any addend.  */
2771                   if (bfd_reloc->addend)
2772                     p = som_reloc_addend (abfd, bfd_reloc->addend, p,
2773                                           &subspace_reloc_size, reloc_queue);
2774
2775                   if (sym_num < 0x20)
2776                     {
2777                       bfd_put_8 (abfd, bfd_reloc->howto->type + sym_num, p);
2778                       subspace_reloc_size += 1;
2779                       p += 1;
2780                     }
2781                   else if (sym_num < 0x100)
2782                     {
2783                       bfd_put_8 (abfd, bfd_reloc->howto->type + 32, p);
2784                       bfd_put_8 (abfd, sym_num, p + 1);
2785                       p = try_prev_fixup (abfd, &subspace_reloc_size, p,
2786                                           2, reloc_queue);
2787                     }
2788                   else if (sym_num < 0x10000000)
2789                     {
2790                       bfd_put_8 (abfd, bfd_reloc->howto->type + 33, p);
2791                       bfd_put_8 (abfd, sym_num >> 16, p + 1);
2792                       bfd_put_16 (abfd, (bfd_vma) sym_num, p + 2);
2793                       p = try_prev_fixup (abfd, &subspace_reloc_size,
2794                                           p, 4, reloc_queue);
2795                     }
2796                   else
2797                     abort ();
2798                   break;
2799
2800                 case R_DATA_ONE_SYMBOL:
2801                 case R_DATA_PLABEL:
2802                 case R_CODE_PLABEL:
2803                 case R_DLT_REL:
2804                   /* Account for any addend using R_DATA_OVERRIDE.  */
2805                   if (bfd_reloc->howto->type != R_DATA_ONE_SYMBOL
2806                       && bfd_reloc->addend)
2807                     p = som_reloc_addend (abfd, bfd_reloc->addend, p,
2808                                           &subspace_reloc_size, reloc_queue);
2809
2810                   if (sym_num < 0x100)
2811                     {
2812                       bfd_put_8 (abfd, bfd_reloc->howto->type, p);
2813                       bfd_put_8 (abfd, sym_num, p + 1);
2814                       p = try_prev_fixup (abfd, &subspace_reloc_size, p,
2815                                           2, reloc_queue);
2816                     }
2817                   else if (sym_num < 0x10000000)
2818                     {
2819                       bfd_put_8 (abfd, bfd_reloc->howto->type + 1, p);
2820                       bfd_put_8 (abfd, sym_num >> 16, p + 1);
2821                       bfd_put_16 (abfd, (bfd_vma) sym_num, p + 2);
2822                       p = try_prev_fixup (abfd, &subspace_reloc_size,
2823                                           p, 4, reloc_queue);
2824                     }
2825                   else
2826                     abort ();
2827                   break;
2828
2829                 case R_ENTRY:
2830                   {
2831                     unsigned int tmp;
2832                     arelent *tmp_reloc = NULL;
2833                     bfd_put_8 (abfd, R_ENTRY, p);
2834
2835                     /* R_ENTRY relocations have 64 bits of associated
2836                        data.  Unfortunately the addend field of a bfd
2837                        relocation is only 32 bits.  So, we split up
2838                        the 64bit unwind information and store part in
2839                        the R_ENTRY relocation, and the rest in the R_EXIT
2840                        relocation.  */
2841                     bfd_put_32 (abfd, bfd_reloc->addend, p + 1);
2842
2843                     /* Find the next R_EXIT relocation.  */
2844                     for (tmp = j; tmp < subsection->reloc_count; tmp++)
2845                       {
2846                         tmp_reloc = subsection->orelocation[tmp];
2847                         if (tmp_reloc->howto->type == R_EXIT)
2848                           break;
2849                       }
2850
2851                     if (tmp == subsection->reloc_count)
2852                       abort ();
2853
2854                     bfd_put_32 (abfd, tmp_reloc->addend, p + 5);
2855                     p = try_prev_fixup (abfd, &subspace_reloc_size,
2856                                         p, 9, reloc_queue);
2857                     break;
2858                   }
2859
2860                 case R_N_MODE:
2861                 case R_S_MODE:
2862                 case R_D_MODE:
2863                 case R_R_MODE:
2864                   /* If this relocation requests the current rounding
2865                      mode, then it is redundant.  */
2866                   if (bfd_reloc->howto->type != current_rounding_mode)
2867                     {
2868                       bfd_put_8 (abfd, bfd_reloc->howto->type, p);
2869                       subspace_reloc_size += 1;
2870                       p += 1;
2871                       current_rounding_mode = bfd_reloc->howto->type;
2872                     }
2873                   break;
2874
2875 #ifndef NO_PCREL_MODES
2876                 case R_LONG_PCREL_MODE:
2877                 case R_SHORT_PCREL_MODE:
2878                   if (bfd_reloc->howto->type != current_call_mode)
2879                     {
2880                       bfd_put_8 (abfd, bfd_reloc->howto->type, p);
2881                       subspace_reloc_size += 1;
2882                       p += 1;
2883                       current_call_mode = bfd_reloc->howto->type;
2884                     }
2885                   break;
2886 #endif
2887
2888                 case R_EXIT:
2889                 case R_ALT_ENTRY:
2890                 case R_FSEL:
2891                 case R_LSEL:
2892                 case R_RSEL:
2893                 case R_BEGIN_BRTAB:
2894                 case R_END_BRTAB:
2895                 case R_BEGIN_TRY:
2896                 case R_N0SEL:
2897                 case R_N1SEL:
2898                   bfd_put_8 (abfd, bfd_reloc->howto->type, p);
2899                   subspace_reloc_size += 1;
2900                   p += 1;
2901                   break;
2902
2903                 case R_END_TRY:
2904                   /* The end of an exception handling region.  The reloc's
2905                      addend contains the offset of the exception handling
2906                      code.  */
2907                   if (bfd_reloc->addend == 0)
2908                     bfd_put_8 (abfd, bfd_reloc->howto->type, p);
2909                   else if (bfd_reloc->addend < 1024)
2910                     {
2911                       bfd_put_8 (abfd, bfd_reloc->howto->type + 1, p);
2912                       bfd_put_8 (abfd, bfd_reloc->addend / 4, p + 1);
2913                       p = try_prev_fixup (abfd, &subspace_reloc_size,
2914                                           p, 2, reloc_queue);
2915                     }
2916                   else
2917                     {
2918                       bfd_put_8 (abfd, bfd_reloc->howto->type + 2, p);
2919                       bfd_put_8 (abfd, (bfd_reloc->addend / 4) >> 16, p + 1);
2920                       bfd_put_16 (abfd, bfd_reloc->addend / 4, p + 2);
2921                       p = try_prev_fixup (abfd, &subspace_reloc_size,
2922                                           p, 4, reloc_queue);
2923                     }
2924                   break;
2925
2926                 case R_COMP1:
2927                   /* The only time we generate R_COMP1, R_COMP2 and
2928                      R_CODE_EXPR relocs is for the difference of two
2929                      symbols.  Hence we can cheat here.  */
2930                   bfd_put_8 (abfd, bfd_reloc->howto->type, p);
2931                   bfd_put_8 (abfd, 0x44, p + 1);
2932                   p = try_prev_fixup (abfd, &subspace_reloc_size,
2933                                       p, 2, reloc_queue);
2934                   break;
2935
2936                 case R_COMP2:
2937                   /* The only time we generate R_COMP1, R_COMP2 and
2938                      R_CODE_EXPR relocs is for the difference of two
2939                      symbols.  Hence we can cheat here.  */
2940                   bfd_put_8 (abfd, bfd_reloc->howto->type, p);
2941                   bfd_put_8 (abfd, 0x80, p + 1);
2942                   bfd_put_8 (abfd, sym_num >> 16, p + 2);
2943                   bfd_put_16 (abfd, (bfd_vma) sym_num, p + 3);
2944                   p = try_prev_fixup (abfd, &subspace_reloc_size,
2945                                       p, 5, reloc_queue);
2946                   break;
2947
2948                 case R_CODE_EXPR:
2949                 case R_DATA_EXPR:
2950                   /* The only time we generate R_COMP1, R_COMP2 and
2951                      R_CODE_EXPR relocs is for the difference of two
2952                      symbols.  Hence we can cheat here.  */
2953                   bfd_put_8 (abfd, bfd_reloc->howto->type, p);
2954                   subspace_reloc_size += 1;
2955                   p += 1;
2956                   break;
2957
2958                 /* Put a "R_RESERVED" relocation in the stream if
2959                    we hit something we do not understand.  The linker
2960                    will complain loudly if this ever happens.  */
2961                 default:
2962                   bfd_put_8 (abfd, 0xff, p);
2963                   subspace_reloc_size += 1;
2964                   p += 1;
2965                   break;
2966                 }
2967             }
2968
2969           /* Last BFD relocation for a subspace has been processed.
2970              Map the rest of the subspace with R_NO_RELOCATION fixups.  */
2971           p = som_reloc_skip (abfd, subsection->size - reloc_offset,
2972                               p, &subspace_reloc_size, reloc_queue);
2973
2974           /* Scribble out the relocations.  */
2975           amt = p - tmp_space;
2976           if (bfd_bwrite ((void *) tmp_space, amt, abfd) != amt)
2977             return FALSE;
2978           p = tmp_space;
2979
2980           total_reloc_size += subspace_reloc_size;
2981           som_section_data (subsection)->subspace_dict->fixup_request_quantity
2982             = subspace_reloc_size;
2983         }
2984       section = section->next;
2985     }
2986   *total_reloc_sizep = total_reloc_size;
2987   return TRUE;
2988 }
2989
2990 /* Write out the space/subspace string table.  */
2991
2992 static bfd_boolean
2993 som_write_space_strings (bfd *abfd,
2994                          unsigned long current_offset,
2995                          unsigned int *string_sizep)
2996 {
2997   /* Chunk of memory that we can use as buffer space, then throw
2998      away.  */
2999   size_t tmp_space_size = SOM_TMP_BUFSIZE;
3000   char *tmp_space = alloca (tmp_space_size);
3001   char *p = tmp_space;
3002   unsigned int strings_size = 0;
3003   asection *section;
3004   bfd_size_type amt;
3005
3006   /* Seek to the start of the space strings in preparation for writing
3007      them out.  */
3008   if (bfd_seek (abfd, (file_ptr) current_offset, SEEK_SET) != 0)
3009     return FALSE;
3010
3011   /* Walk through all the spaces and subspaces (order is not important)
3012      building up and writing string table entries for their names.  */
3013   for (section = abfd->sections; section != NULL; section = section->next)
3014     {
3015       size_t length;
3016
3017       /* Only work with space/subspaces; avoid any other sections
3018          which might have been made (.text for example).  */
3019       if (!som_is_space (section) && !som_is_subspace (section))
3020         continue;
3021
3022       /* Get the length of the space/subspace name.  */
3023       length = strlen (section->name);
3024
3025       /* If there is not enough room for the next entry, then dump the
3026          current buffer contents now and maybe allocate a larger
3027          buffer.  Each entry will take 4 bytes to hold the string
3028          length + the string itself + null terminator.  */
3029       if (p - tmp_space + 5 + length > tmp_space_size)
3030         {
3031           /* Flush buffer before refilling or reallocating.  */
3032           amt = p - tmp_space;
3033           if (bfd_bwrite ((void *) &tmp_space[0], amt, abfd) != amt)
3034             return FALSE;
3035
3036           /* Reallocate if now empty buffer still too small.  */
3037           if (5 + length > tmp_space_size)
3038             {
3039               /* Ensure a minimum growth factor to avoid O(n**2) space
3040                  consumption for n strings.  The optimal minimum
3041                  factor seems to be 2, as no other value can guarantee
3042                  wasting less than 50% space.  (Note that we cannot
3043                  deallocate space allocated by `alloca' without
3044                  returning from this function.)  The same technique is
3045                  used a few more times below when a buffer is
3046                  reallocated.  */
3047               tmp_space_size = MAX (2 * tmp_space_size, 5 + length);
3048               tmp_space = alloca (tmp_space_size);
3049             }
3050
3051           /* Reset to beginning of the (possibly new) buffer space.  */
3052           p = tmp_space;
3053         }
3054
3055       /* First element in a string table entry is the length of the
3056          string.  Alignment issues are already handled.  */
3057       bfd_put_32 (abfd, (bfd_vma) length, p);
3058       p += 4;
3059       strings_size += 4;
3060
3061       /* Record the index in the space/subspace records.  */
3062       if (som_is_space (section))
3063         som_section_data (section)->space_dict->name.n_strx = strings_size;
3064       else
3065         som_section_data (section)->subspace_dict->name.n_strx = strings_size;
3066
3067       /* Next comes the string itself + a null terminator.  */
3068       strcpy (p, section->name);
3069       p += length + 1;
3070       strings_size += length + 1;
3071
3072       /* Always align up to the next word boundary.  */
3073       while (strings_size % 4)
3074         {
3075           bfd_put_8 (abfd, 0, p);
3076           p++;
3077           strings_size++;
3078         }
3079     }
3080
3081   /* Done with the space/subspace strings.  Write out any information
3082      contained in a partial block.  */
3083   amt = p - tmp_space;
3084   if (bfd_bwrite ((void *) &tmp_space[0], amt, abfd) != amt)
3085     return FALSE;
3086   *string_sizep = strings_size;
3087   return TRUE;
3088 }
3089
3090 /* Write out the symbol string table.  */
3091
3092 static bfd_boolean
3093 som_write_symbol_strings (bfd *abfd,
3094                           unsigned long current_offset,
3095                           asymbol **syms,
3096                           unsigned int num_syms,
3097                           unsigned int *string_sizep,
3098                           COMPUNIT *compilation_unit)
3099 {
3100   unsigned int i;
3101
3102   /* Chunk of memory that we can use as buffer space, then throw
3103      away.  */
3104   size_t tmp_space_size = SOM_TMP_BUFSIZE;
3105   char *tmp_space = alloca (tmp_space_size);
3106   char *p = tmp_space;
3107
3108   unsigned int strings_size = 0;
3109   char *comp[4];
3110   bfd_size_type amt;
3111
3112   /* This gets a bit gruesome because of the compilation unit.  The
3113      strings within the compilation unit are part of the symbol
3114      strings, but don't have symbol_dictionary entries.  So, manually
3115      write them and update the compilation unit header.  On input, the
3116      compilation unit header contains local copies of the strings.
3117      Move them aside.  */
3118   if (compilation_unit)
3119     {
3120       comp[0] = compilation_unit->name.n_name;
3121       comp[1] = compilation_unit->language_name.n_name;
3122       comp[2] = compilation_unit->product_id.n_name;
3123       comp[3] = compilation_unit->version_id.n_name;
3124     }
3125
3126   /* Seek to the start of the space strings in preparation for writing
3127      them out.  */
3128   if (bfd_seek (abfd, (file_ptr) current_offset, SEEK_SET) != 0)
3129     return FALSE;
3130
3131   if (compilation_unit)
3132     {
3133       for (i = 0; i < 4; i++)
3134         {
3135           size_t length = strlen (comp[i]);
3136
3137           /* If there is not enough room for the next entry, then dump
3138              the current buffer contents now and maybe allocate a
3139              larger buffer.  */
3140           if (p - tmp_space + 5 + length > tmp_space_size)
3141             {
3142               /* Flush buffer before refilling or reallocating.  */
3143               amt = p - tmp_space;
3144               if (bfd_bwrite ((void *) &tmp_space[0], amt, abfd) != amt)
3145                 return FALSE;
3146
3147               /* Reallocate if now empty buffer still too small.  */
3148               if (5 + length > tmp_space_size)
3149                 {
3150                   /* See alloca above for discussion of new size.  */
3151                   tmp_space_size = MAX (2 * tmp_space_size, 5 + length);
3152                   tmp_space = alloca (tmp_space_size);
3153                 }
3154
3155               /* Reset to beginning of the (possibly new) buffer
3156                  space.  */
3157               p = tmp_space;
3158             }
3159
3160           /* First element in a string table entry is the length of
3161              the string.  This must always be 4 byte aligned.  This is
3162              also an appropriate time to fill in the string index
3163              field in the symbol table entry.  */
3164           bfd_put_32 (abfd, (bfd_vma) length, p);
3165           strings_size += 4;
3166           p += 4;
3167
3168           /* Next comes the string itself + a null terminator.  */
3169           strcpy (p, comp[i]);
3170
3171           switch (i)
3172             {
3173             case 0:
3174               obj_som_compilation_unit (abfd)->name.n_strx = strings_size;
3175               break;
3176             case 1:
3177               obj_som_compilation_unit (abfd)->language_name.n_strx =
3178                 strings_size;
3179               break;
3180             case 2:
3181               obj_som_compilation_unit (abfd)->product_id.n_strx =
3182                 strings_size;
3183               break;
3184             case 3:
3185               obj_som_compilation_unit (abfd)->version_id.n_strx =
3186                 strings_size;
3187               break;
3188             }
3189
3190           p += length + 1;
3191           strings_size += length + 1;
3192
3193           /* Always align up to the next word boundary.  */
3194           while (strings_size % 4)
3195             {
3196               bfd_put_8 (abfd, 0, p);
3197               strings_size++;
3198               p++;
3199             }
3200         }
3201     }
3202
3203   for (i = 0; i < num_syms; i++)
3204     {
3205       size_t length = strlen (syms[i]->name);
3206
3207       /* If there is not enough room for the next entry, then dump the
3208          current buffer contents now and maybe allocate a larger buffer.  */
3209      if (p - tmp_space + 5 + length > tmp_space_size)
3210         {
3211           /* Flush buffer before refilling or reallocating.  */
3212           amt = p - tmp_space;
3213           if (bfd_bwrite ((void *) &tmp_space[0], amt, abfd) != amt)
3214             return FALSE;
3215
3216           /* Reallocate if now empty buffer still too small.  */
3217           if (5 + length > tmp_space_size)
3218             {
3219               /* See alloca above for discussion of new size.  */
3220               tmp_space_size = MAX (2 * tmp_space_size, 5 + length);
3221               tmp_space = alloca (tmp_space_size);
3222             }
3223
3224           /* Reset to beginning of the (possibly new) buffer space.  */
3225           p = tmp_space;
3226         }
3227
3228       /* First element in a string table entry is the length of the
3229          string.  This must always be 4 byte aligned.  This is also
3230          an appropriate time to fill in the string index field in the
3231          symbol table entry.  */
3232       bfd_put_32 (abfd, (bfd_vma) length, p);
3233       strings_size += 4;
3234       p += 4;
3235
3236       /* Next comes the string itself + a null terminator.  */
3237       strcpy (p, syms[i]->name);
3238
3239       som_symbol_data (syms[i])->stringtab_offset = strings_size;
3240       p += length + 1;
3241       strings_size += length + 1;
3242
3243       /* Always align up to the next word boundary.  */
3244       while (strings_size % 4)
3245         {
3246           bfd_put_8 (abfd, 0, p);
3247           strings_size++;
3248           p++;
3249         }
3250     }
3251
3252   /* Scribble out any partial block.  */
3253   amt = p - tmp_space;
3254   if (bfd_bwrite ((void *) &tmp_space[0], amt, abfd) != amt)
3255     return FALSE;
3256
3257   *string_sizep = strings_size;
3258   return TRUE;
3259 }
3260
3261 /* Compute variable information to be placed in the SOM headers,
3262    space/subspace dictionaries, relocation streams, etc.  Begin
3263    writing parts of the object file.  */
3264
3265 static bfd_boolean
3266 som_begin_writing (bfd *abfd)
3267 {
3268   unsigned long current_offset = 0;
3269   unsigned int strings_size = 0;
3270   unsigned long num_spaces, num_subspaces, i;
3271   asection *section;
3272   unsigned int total_subspaces = 0;
3273   struct som_exec_auxhdr *exec_header = NULL;
3274
3275   /* The file header will always be first in an object file,
3276      everything else can be in random locations.  To keep things
3277      "simple" BFD will lay out the object file in the manner suggested
3278      by the PRO ABI for PA-RISC Systems.  */
3279
3280   /* Before any output can really begin offsets for all the major
3281      portions of the object file must be computed.  So, starting
3282      with the initial file header compute (and sometimes write)
3283      each portion of the object file.  */
3284
3285   /* Make room for the file header, it's contents are not complete
3286      yet, so it can not be written at this time.  */
3287   current_offset += sizeof (struct header);
3288
3289   /* Any auxiliary headers will follow the file header.  Right now
3290      we support only the copyright and version headers.  */
3291   obj_som_file_hdr (abfd)->aux_header_location = current_offset;
3292   obj_som_file_hdr (abfd)->aux_header_size = 0;
3293   if (abfd->flags & (EXEC_P | DYNAMIC))
3294     {
3295       /* Parts of the exec header will be filled in later, so
3296          delay writing the header itself.  Fill in the defaults,
3297          and write it later.  */
3298       current_offset += sizeof (struct som_exec_auxhdr);
3299       obj_som_file_hdr (abfd)->aux_header_size
3300         += sizeof (struct som_exec_auxhdr);
3301       exec_header = obj_som_exec_hdr (abfd);
3302       exec_header->som_auxhdr.type = EXEC_AUX_ID;
3303       exec_header->som_auxhdr.length = 40;
3304     }
3305   if (obj_som_version_hdr (abfd) != NULL)
3306     {
3307       bfd_size_type len;
3308
3309       if (bfd_seek (abfd, (file_ptr) current_offset, SEEK_SET) != 0)
3310         return FALSE;
3311
3312       /* Write the aux_id structure and the string length.  */
3313       len = sizeof (struct aux_id) + sizeof (unsigned int);
3314       obj_som_file_hdr (abfd)->aux_header_size += len;
3315       current_offset += len;
3316       if (bfd_bwrite ((void *) obj_som_version_hdr (abfd), len, abfd) != len)
3317         return FALSE;
3318
3319       /* Write the version string.  */
3320       len = obj_som_version_hdr (abfd)->header_id.length - sizeof (int);
3321       obj_som_file_hdr (abfd)->aux_header_size += len;
3322       current_offset += len;
3323       if (bfd_bwrite ((void *) obj_som_version_hdr (abfd)->user_string, len, abfd)
3324           != len)
3325         return FALSE;
3326     }
3327
3328   if (obj_som_copyright_hdr (abfd) != NULL)
3329     {
3330       bfd_size_type len;
3331
3332       if (bfd_seek (abfd, (file_ptr) current_offset, SEEK_SET) != 0)
3333         return FALSE;
3334
3335       /* Write the aux_id structure and the string length.  */
3336       len = sizeof (struct aux_id) + sizeof (unsigned int);
3337       obj_som_file_hdr (abfd)->aux_header_size += len;
3338       current_offset += len;
3339       if (bfd_bwrite ((void *) obj_som_copyright_hdr (abfd), len, abfd) != len)
3340         return FALSE;
3341
3342       /* Write the copyright string.  */
3343       len = obj_som_copyright_hdr (abfd)->header_id.length - sizeof (int);
3344       obj_som_file_hdr (abfd)->aux_header_size += len;
3345       current_offset += len;
3346       if (bfd_bwrite ((void *) obj_som_copyright_hdr (abfd)->copyright, len, abfd)
3347           != len)
3348         return FALSE;
3349     }
3350
3351   /* Next comes the initialization pointers; we have no initialization
3352      pointers, so current offset does not change.  */
3353   obj_som_file_hdr (abfd)->init_array_location = current_offset;
3354   obj_som_file_hdr (abfd)->init_array_total = 0;
3355
3356   /* Next are the space records.  These are fixed length records.
3357
3358      Count the number of spaces to determine how much room is needed
3359      in the object file for the space records.
3360
3361      The names of the spaces are stored in a separate string table,
3362      and the index for each space into the string table is computed
3363      below.  Therefore, it is not possible to write the space headers
3364      at this time.  */
3365   num_spaces = som_count_spaces (abfd);
3366   obj_som_file_hdr (abfd)->space_location = current_offset;
3367   obj_som_file_hdr (abfd)->space_total = num_spaces;
3368   current_offset += num_spaces * sizeof (struct space_dictionary_record);
3369
3370   /* Next are the subspace records.  These are fixed length records.
3371
3372      Count the number of subspaes to determine how much room is needed
3373      in the object file for the subspace records.
3374
3375      A variety if fields in the subspace record are still unknown at
3376      this time (index into string table, fixup stream location/size, etc).  */
3377   num_subspaces = som_count_subspaces (abfd);
3378   obj_som_file_hdr (abfd)->subspace_location = current_offset;
3379   obj_som_file_hdr (abfd)->subspace_total = num_subspaces;
3380   current_offset
3381     += num_subspaces * sizeof (struct som_subspace_dictionary_record);
3382
3383   /* Next is the string table for the space/subspace names.  We will
3384      build and write the string table on the fly.  At the same time
3385      we will fill in the space/subspace name index fields.  */
3386
3387   /* The string table needs to be aligned on a word boundary.  */
3388   if (current_offset % 4)
3389     current_offset += (4 - (current_offset % 4));
3390
3391   /* Mark the offset of the space/subspace string table in the
3392      file header.  */
3393   obj_som_file_hdr (abfd)->space_strings_location = current_offset;
3394
3395   /* Scribble out the space strings.  */
3396   if (! som_write_space_strings (abfd, current_offset, &strings_size))
3397     return FALSE;
3398
3399   /* Record total string table size in the header and update the
3400      current offset.  */
3401   obj_som_file_hdr (abfd)->space_strings_size = strings_size;
3402   current_offset += strings_size;
3403
3404   /* Next is the compilation unit.  */
3405   obj_som_file_hdr (abfd)->compiler_location = current_offset;
3406   obj_som_file_hdr (abfd)->compiler_total = 0;
3407   if (obj_som_compilation_unit (abfd))
3408     {
3409       obj_som_file_hdr (abfd)->compiler_total = 1;
3410       current_offset += COMPUNITSZ;
3411     }
3412
3413   /* Now compute the file positions for the loadable subspaces, taking
3414      care to make sure everything stays properly aligned.  */
3415
3416   section = abfd->sections;
3417   for (i = 0; i < num_spaces; i++)
3418     {
3419       asection *subsection;
3420       int first_subspace;
3421       unsigned int subspace_offset = 0;
3422
3423       /* Find a space.  */
3424       while (!som_is_space (section))
3425         section = section->next;
3426
3427       first_subspace = 1;
3428       /* Now look for all its subspaces.  */
3429       for (subsection = abfd->sections;
3430            subsection != NULL;
3431            subsection = subsection->next)
3432         {
3433
3434           if (!som_is_subspace (subsection)
3435               || !som_is_container (section, subsection)
3436               || (subsection->flags & SEC_ALLOC) == 0)
3437             continue;
3438
3439           /* If this is the first subspace in the space, and we are
3440              building an executable, then take care to make sure all
3441              the alignments are correct and update the exec header.  */
3442           if (first_subspace
3443               && (abfd->flags & (EXEC_P | DYNAMIC)))
3444             {
3445               /* Demand paged executables have each space aligned to a
3446                  page boundary.  Sharable executables (write-protected
3447                  text) have just the private (aka data & bss) space aligned
3448                  to a page boundary.  Ugh.  Not true for HPUX.
3449
3450                  The HPUX kernel requires the text to always be page aligned
3451                  within the file regardless of the executable's type.  */
3452               if (abfd->flags & (D_PAGED | DYNAMIC)
3453                   || (subsection->flags & SEC_CODE)
3454                   || ((abfd->flags & WP_TEXT)
3455                       && (subsection->flags & SEC_DATA)))
3456                 current_offset = SOM_ALIGN (current_offset, PA_PAGESIZE);
3457
3458               /* Update the exec header.  */
3459               if (subsection->flags & SEC_CODE && exec_header->exec_tfile == 0)
3460                 {
3461                   exec_header->exec_tmem = section->vma;
3462                   exec_header->exec_tfile = current_offset;
3463                 }
3464               if (subsection->flags & SEC_DATA && exec_header->exec_dfile == 0)
3465                 {
3466                   exec_header->exec_dmem = section->vma;
3467                   exec_header->exec_dfile = current_offset;
3468                 }
3469
3470               /* Keep track of exactly where we are within a particular
3471                  space.  This is necessary as the braindamaged HPUX
3472                  loader will create holes between subspaces *and*
3473                  subspace alignments are *NOT* preserved.  What a crock.  */
3474               subspace_offset = subsection->vma;
3475
3476               /* Only do this for the first subspace within each space.  */
3477               first_subspace = 0;
3478             }
3479           else if (abfd->flags & (EXEC_P | DYNAMIC))
3480             {
3481               /* The braindamaged HPUX loader may have created a hole
3482                  between two subspaces.  It is *not* sufficient to use
3483                  the alignment specifications within the subspaces to
3484                  account for these holes -- I've run into at least one
3485                  case where the loader left one code subspace unaligned
3486                  in a final executable.
3487
3488                  To combat this we keep a current offset within each space,
3489                  and use the subspace vma fields to detect and preserve
3490                  holes.  What a crock!
3491
3492                  ps.  This is not necessary for unloadable space/subspaces.  */
3493               current_offset += subsection->vma - subspace_offset;
3494               if (subsection->flags & SEC_CODE)
3495                 exec_header->exec_tsize += subsection->vma - subspace_offset;
3496               else
3497                 exec_header->exec_dsize += subsection->vma - subspace_offset;
3498               subspace_offset += subsection->vma - subspace_offset;
3499             }
3500
3501           subsection->target_index = total_subspaces++;
3502           /* This is real data to be loaded from the file.  */
3503           if (subsection->flags & SEC_LOAD)
3504             {
3505               /* Update the size of the code & data.  */
3506               if (abfd->flags & (EXEC_P | DYNAMIC)
3507                   && subsection->flags & SEC_CODE)
3508                 exec_header->exec_tsize += subsection->size;
3509               else if (abfd->flags & (EXEC_P | DYNAMIC)
3510                        && subsection->flags & SEC_DATA)
3511                 exec_header->exec_dsize += subsection->size;
3512               som_section_data (subsection)->subspace_dict->file_loc_init_value
3513                 = current_offset;
3514               subsection->filepos = current_offset;
3515               current_offset += subsection->size;
3516               subspace_offset += subsection->size;
3517             }
3518           /* Looks like uninitialized data.  */
3519           else
3520             {
3521               /* Update the size of the bss section.  */
3522               if (abfd->flags & (EXEC_P | DYNAMIC))
3523                 exec_header->exec_bsize += subsection->size;
3524
3525               som_section_data (subsection)->subspace_dict->file_loc_init_value
3526                 = 0;
3527               som_section_data (subsection)->subspace_dict->
3528                 initialization_length = 0;
3529             }
3530         }
3531       /* Goto the next section.  */
3532       section = section->next;
3533     }
3534
3535   /* Finally compute the file positions for unloadable subspaces.
3536      If building an executable, start the unloadable stuff on its
3537      own page.  */
3538
3539   if (abfd->flags & (EXEC_P | DYNAMIC))
3540     current_offset = SOM_ALIGN (current_offset, PA_PAGESIZE);
3541
3542   obj_som_file_hdr (abfd)->unloadable_sp_location = current_offset;
3543   section = abfd->sections;
3544   for (i = 0; i < num_spaces; i++)
3545     {
3546       asection *subsection;
3547
3548       /* Find a space.  */
3549       while (!som_is_space (section))
3550         section = section->next;
3551
3552       if (abfd->flags & (EXEC_P | DYNAMIC))
3553         current_offset = SOM_ALIGN (current_offset, PA_PAGESIZE);
3554
3555       /* Now look for all its subspaces.  */
3556       for (subsection = abfd->sections;
3557            subsection != NULL;
3558            subsection = subsection->next)
3559         {
3560
3561           if (!som_is_subspace (subsection)
3562               || !som_is_container (section, subsection)
3563               || (subsection->flags & SEC_ALLOC) != 0)
3564             continue;
3565
3566           subsection->target_index = total_subspaces++;
3567           /* This is real data to be loaded from the file.  */
3568           if ((subsection->flags & SEC_LOAD) == 0)
3569             {
3570               som_section_data (subsection)->subspace_dict->file_loc_init_value
3571                 = current_offset;
3572               subsection->filepos = current_offset;
3573               current_offset += subsection->size;
3574             }
3575           /* Looks like uninitialized data.  */
3576           else
3577             {
3578               som_section_data (subsection)->subspace_dict->file_loc_init_value
3579                 = 0;
3580               som_section_data (subsection)->subspace_dict->
3581                 initialization_length = subsection->size;
3582             }
3583         }
3584       /* Goto the next section.  */
3585       section = section->next;
3586     }
3587
3588   /* If building an executable, then make sure to seek to and write
3589      one byte at the end of the file to make sure any necessary
3590      zeros are filled in.  Ugh.  */
3591   if (abfd->flags & (EXEC_P | DYNAMIC))
3592     current_offset = SOM_ALIGN (current_offset, PA_PAGESIZE);
3593   if (bfd_seek (abfd, (file_ptr) current_offset - 1, SEEK_SET) != 0)
3594     return FALSE;
3595   if (bfd_bwrite ((void *) "", (bfd_size_type) 1, abfd) != 1)
3596     return FALSE;
3597
3598   obj_som_file_hdr (abfd)->unloadable_sp_size
3599     = current_offset - obj_som_file_hdr (abfd)->unloadable_sp_location;
3600
3601   /* Loader fixups are not supported in any way shape or form.  */
3602   obj_som_file_hdr (abfd)->loader_fixup_location = 0;
3603   obj_som_file_hdr (abfd)->loader_fixup_total = 0;
3604
3605   /* Done.  Store the total size of the SOM so far.  */
3606   obj_som_file_hdr (abfd)->som_length = current_offset;
3607
3608   return TRUE;
3609 }
3610
3611 /* Finally, scribble out the various headers to the disk.  */
3612
3613 static bfd_boolean
3614 som_finish_writing (bfd *abfd)
3615 {
3616   int num_spaces = som_count_spaces (abfd);
3617   asymbol **syms = bfd_get_outsymbols (abfd);
3618   int i, num_syms;
3619   int subspace_index = 0;
3620   file_ptr location;
3621   asection *section;
3622   unsigned long current_offset;
3623   unsigned int strings_size, total_reloc_size;
3624   bfd_size_type amt;
3625
3626   /* We must set up the version identifier here as objcopy/strip copy
3627      private BFD data too late for us to handle this in som_begin_writing.  */
3628   if (obj_som_exec_data (abfd)
3629       && obj_som_exec_data (abfd)->version_id)
3630     obj_som_file_hdr (abfd)->version_id = obj_som_exec_data (abfd)->version_id;
3631   else
3632     obj_som_file_hdr (abfd)->version_id = NEW_VERSION_ID;
3633
3634   /* Next is the symbol table.  These are fixed length records.
3635
3636      Count the number of symbols to determine how much room is needed
3637      in the object file for the symbol table.
3638
3639      The names of the symbols are stored in a separate string table,
3640      and the index for each symbol name into the string table is computed
3641      below.  Therefore, it is not possible to write the symbol table
3642      at this time.
3643
3644      These used to be output before the subspace contents, but they
3645      were moved here to work around a stupid bug in the hpux linker
3646      (fixed in hpux10).  */
3647   current_offset = obj_som_file_hdr (abfd)->som_length;
3648
3649   /* Make sure we're on a word boundary.  */
3650   if (current_offset % 4)
3651     current_offset += (4 - (current_offset % 4));
3652
3653   num_syms = bfd_get_symcount (abfd);
3654   obj_som_file_hdr (abfd)->symbol_location = current_offset;
3655   obj_som_file_hdr (abfd)->symbol_total = num_syms;
3656   current_offset += num_syms * sizeof (struct symbol_dictionary_record);
3657
3658   /* Next are the symbol strings.
3659      Align them to a word boundary.  */
3660   if (current_offset % 4)
3661     current_offset += (4 - (current_offset % 4));
3662   obj_som_file_hdr (abfd)->symbol_strings_location = current_offset;
3663
3664   /* Scribble out the symbol strings.  */
3665   if (! som_write_symbol_strings (abfd, current_offset, syms,
3666                                   num_syms, &strings_size,
3667                                   obj_som_compilation_unit (abfd)))
3668     return FALSE;
3669
3670   /* Record total string table size in header and update the
3671      current offset.  */
3672   obj_som_file_hdr (abfd)->symbol_strings_size = strings_size;
3673   current_offset += strings_size;
3674
3675   /* Do prep work before handling fixups.  */
3676   som_prep_for_fixups (abfd,
3677                        bfd_get_outsymbols (abfd),
3678                        bfd_get_symcount (abfd));
3679
3680   /* At the end of the file is the fixup stream which starts on a
3681      word boundary.  */
3682   if (current_offset % 4)
3683     current_offset += (4 - (current_offset % 4));
3684   obj_som_file_hdr (abfd)->fixup_request_location = current_offset;
3685
3686   /* Write the fixups and update fields in subspace headers which
3687      relate to the fixup stream.  */
3688   if (! som_write_fixups (abfd, current_offset, &total_reloc_size))
3689     return FALSE;
3690
3691   /* Record the total size of the fixup stream in the file header.  */
3692   obj_som_file_hdr (abfd)->fixup_request_total = total_reloc_size;
3693
3694   /* Done.  Store the total size of the SOM.  */
3695   obj_som_file_hdr (abfd)->som_length = current_offset + total_reloc_size;
3696
3697   /* Now that the symbol table information is complete, build and
3698      write the symbol table.  */
3699   if (! som_build_and_write_symbol_table (abfd))
3700     return FALSE;
3701
3702   /* Subspaces are written first so that we can set up information
3703      about them in their containing spaces as the subspace is written.  */
3704
3705   /* Seek to the start of the subspace dictionary records.  */
3706   location = obj_som_file_hdr (abfd)->subspace_location;
3707   if (bfd_seek (abfd, location, SEEK_SET) != 0)
3708     return FALSE;
3709
3710   section = abfd->sections;
3711   /* Now for each loadable space write out records for its subspaces.  */
3712   for (i = 0; i < num_spaces; i++)
3713     {
3714       asection *subsection;
3715
3716       /* Find a space.  */
3717       while (!som_is_space (section))
3718         section = section->next;
3719
3720       /* Now look for all its subspaces.  */
3721       for (subsection = abfd->sections;
3722            subsection != NULL;
3723            subsection = subsection->next)
3724         {
3725
3726           /* Skip any section which does not correspond to a space
3727              or subspace.  Or does not have SEC_ALLOC set (and therefore
3728              has no real bits on the disk).  */
3729           if (!som_is_subspace (subsection)
3730               || !som_is_container (section, subsection)
3731               || (subsection->flags & SEC_ALLOC) == 0)
3732             continue;
3733
3734           /* If this is the first subspace for this space, then save
3735              the index of the subspace in its containing space.  Also
3736              set "is_loadable" in the containing space.  */
3737
3738           if (som_section_data (section)->space_dict->subspace_quantity == 0)
3739             {
3740               som_section_data (section)->space_dict->is_loadable = 1;
3741               som_section_data (section)->space_dict->subspace_index
3742                 = subspace_index;
3743             }
3744
3745           /* Increment the number of subspaces seen and the number of
3746              subspaces contained within the current space.  */
3747           subspace_index++;
3748           som_section_data (section)->space_dict->subspace_quantity++;
3749
3750           /* Mark the index of the current space within the subspace's
3751              dictionary record.  */
3752           som_section_data (subsection)->subspace_dict->space_index = i;
3753
3754           /* Dump the current subspace header.  */
3755           amt = sizeof (struct som_subspace_dictionary_record);
3756           if (bfd_bwrite ((void *) som_section_data (subsection)->subspace_dict,
3757                          amt, abfd) != amt)
3758             return FALSE;
3759         }
3760       /* Goto the next section.  */
3761       section = section->next;
3762     }
3763
3764   /* Now repeat the process for unloadable subspaces.  */
3765   section = abfd->sections;
3766   /* Now for each space write out records for its subspaces.  */
3767   for (i = 0; i < num_spaces; i++)
3768     {
3769       asection *subsection;
3770
3771       /* Find a space.  */
3772       while (!som_is_space (section))
3773         section = section->next;
3774
3775       /* Now look for all its subspaces.  */
3776       for (subsection = abfd->sections;
3777            subsection != NULL;
3778            subsection = subsection->next)
3779         {
3780
3781           /* Skip any section which does not correspond to a space or
3782              subspace, or which SEC_ALLOC set (and therefore handled
3783              in the loadable spaces/subspaces code above).  */
3784
3785           if (!som_is_subspace (subsection)
3786               || !som_is_container (section, subsection)
3787               || (subsection->flags & SEC_ALLOC) != 0)
3788             continue;
3789
3790           /* If this is the first subspace for this space, then save
3791              the index of the subspace in its containing space.  Clear
3792              "is_loadable".  */
3793
3794           if (som_section_data (section)->space_dict->subspace_quantity == 0)
3795             {
3796               som_section_data (section)->space_dict->is_loadable = 0;
3797               som_section_data (section)->space_dict->subspace_index
3798                 = subspace_index;
3799             }
3800
3801           /* Increment the number of subspaces seen and the number of
3802              subspaces contained within the current space.  */
3803           som_section_data (section)->space_dict->subspace_quantity++;
3804           subspace_index++;
3805
3806           /* Mark the index of the current space within the subspace's
3807              dictionary record.  */
3808           som_section_data (subsection)->subspace_dict->space_index = i;
3809
3810           /* Dump this subspace header.  */
3811           amt = sizeof (struct som_subspace_dictionary_record);
3812           if (bfd_bwrite ((void *) som_section_data (subsection)->subspace_dict,
3813                          amt, abfd) != amt)
3814             return FALSE;
3815         }
3816       /* Goto the next section.  */
3817       section = section->next;
3818     }
3819
3820   /* All the subspace dictionary records are written, and all the
3821      fields are set up in the space dictionary records.
3822
3823      Seek to the right location and start writing the space
3824      dictionary records.  */
3825   location = obj_som_file_hdr (abfd)->space_location;
3826   if (bfd_seek (abfd, location, SEEK_SET) != 0)
3827     return FALSE;
3828
3829   section = abfd->sections;
3830   for (i = 0; i < num_spaces; i++)
3831     {
3832       /* Find a space.  */
3833       while (!som_is_space (section))
3834         section = section->next;
3835
3836       /* Dump its header.  */
3837       amt = sizeof (struct space_dictionary_record);
3838       if (bfd_bwrite ((void *) som_section_data (section)->space_dict,
3839                      amt, abfd) != amt)
3840         return FALSE;
3841
3842       /* Goto the next section.  */
3843       section = section->next;
3844     }
3845
3846   /* Write the compilation unit record if there is one.  */
3847   if (obj_som_compilation_unit (abfd))
3848     {
3849       location = obj_som_file_hdr (abfd)->compiler_location;
3850       if (bfd_seek (abfd, location, SEEK_SET) != 0)
3851         return FALSE;
3852
3853       amt = COMPUNITSZ;
3854       if (bfd_bwrite ((void *) obj_som_compilation_unit (abfd), amt, abfd) != amt)
3855         return FALSE;
3856     }
3857
3858   /* Setting of the system_id has to happen very late now that copying of
3859      BFD private data happens *after* section contents are set.  */
3860   if (abfd->flags & (EXEC_P | DYNAMIC))
3861     obj_som_file_hdr (abfd)->system_id = obj_som_exec_data (abfd)->system_id;
3862   else if (bfd_get_mach (abfd) == pa20)
3863     obj_som_file_hdr (abfd)->system_id = CPU_PA_RISC2_0;
3864   else if (bfd_get_mach (abfd) == pa11)
3865     obj_som_file_hdr (abfd)->system_id = CPU_PA_RISC1_1;
3866   else
3867     obj_som_file_hdr (abfd)->system_id = CPU_PA_RISC1_0;
3868
3869   /* Compute the checksum for the file header just before writing
3870      the header to disk.  */
3871   obj_som_file_hdr (abfd)->checksum = som_compute_checksum (abfd);
3872
3873   /* Only thing left to do is write out the file header.  It is always
3874      at location zero.  Seek there and write it.  */
3875   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
3876     return FALSE;
3877   amt = sizeof (struct header);
3878   if (bfd_bwrite ((void *) obj_som_file_hdr (abfd), amt, abfd) != amt)
3879     return FALSE;
3880
3881   /* Now write the exec header.  */
3882   if (abfd->flags & (EXEC_P | DYNAMIC))
3883     {
3884       long tmp, som_length;
3885       struct som_exec_auxhdr *exec_header;
3886
3887       exec_header = obj_som_exec_hdr (abfd);
3888       exec_header->exec_entry = bfd_get_start_address (abfd);
3889       exec_header->exec_flags = obj_som_exec_data (abfd)->exec_flags;
3890
3891       /* Oh joys.  Ram some of the BSS data into the DATA section
3892          to be compatible with how the hp linker makes objects
3893          (saves memory space).  */
3894       tmp = exec_header->exec_dsize;
3895       tmp = SOM_ALIGN (tmp, PA_PAGESIZE);
3896       exec_header->exec_bsize -= (tmp - exec_header->exec_dsize);
3897       if (exec_header->exec_bsize < 0)
3898         exec_header->exec_bsize = 0;
3899       exec_header->exec_dsize = tmp;
3900
3901       /* Now perform some sanity checks.  The idea is to catch bogons now and
3902          inform the user, instead of silently generating a bogus file.  */
3903       som_length = obj_som_file_hdr (abfd)->som_length;
3904       if (exec_header->exec_tfile + exec_header->exec_tsize > som_length
3905           || exec_header->exec_dfile + exec_header->exec_dsize > som_length)
3906         {
3907           bfd_set_error (bfd_error_bad_value);
3908           return FALSE;
3909         }
3910
3911       if (bfd_seek (abfd, obj_som_file_hdr (abfd)->aux_header_location,
3912                     SEEK_SET) != 0)
3913         return FALSE;
3914
3915       amt = AUX_HDR_SIZE;
3916       if (bfd_bwrite ((void *) exec_header, amt, abfd) != amt)
3917         return FALSE;
3918     }
3919   return TRUE;
3920 }
3921
3922 /* Compute and return the checksum for a SOM file header.  */
3923
3924 static unsigned long
3925 som_compute_checksum (bfd *abfd)
3926 {
3927   unsigned long checksum, count, i;
3928   unsigned long *buffer = (unsigned long *) obj_som_file_hdr (abfd);
3929
3930   checksum = 0;
3931   count = sizeof (struct header) / sizeof (unsigned long);
3932   for (i = 0; i < count; i++)
3933     checksum ^= *(buffer + i);
3934
3935   return checksum;
3936 }
3937
3938 static void
3939 som_bfd_derive_misc_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
3940                                  asymbol *sym,
3941                                  struct som_misc_symbol_info *info)
3942 {
3943   /* Initialize.  */
3944   memset (info, 0, sizeof (struct som_misc_symbol_info));
3945
3946   /* The HP SOM linker requires detailed type information about
3947      all symbols (including undefined symbols!).  Unfortunately,
3948      the type specified in an import/export statement does not
3949      always match what the linker wants.  Severe braindamage.  */
3950
3951   /* Section symbols will not have a SOM symbol type assigned to
3952      them yet.  Assign all section symbols type ST_DATA.  */
3953   if (sym->flags & BSF_SECTION_SYM)
3954     info->symbol_type = ST_DATA;
3955   else
3956     {
3957       /* For BFD style common, the linker will choke unless we set the
3958          type and scope to ST_STORAGE and SS_UNSAT, respectively.  */
3959       if (bfd_is_com_section (sym->section))
3960         {
3961           info->symbol_type = ST_STORAGE;
3962           info->symbol_scope = SS_UNSAT;
3963         }
3964
3965       /* It is possible to have a symbol without an associated
3966          type.  This happens if the user imported the symbol
3967          without a type and the symbol was never defined
3968          locally.  If BSF_FUNCTION is set for this symbol, then
3969          assign it type ST_CODE (the HP linker requires undefined
3970          external functions to have type ST_CODE rather than ST_ENTRY).  */
3971       else if ((som_symbol_data (sym)->som_type == SYMBOL_TYPE_UNKNOWN
3972                 || som_symbol_data (sym)->som_type == SYMBOL_TYPE_CODE)
3973                && bfd_is_und_section (sym->section)
3974                && sym->flags & BSF_FUNCTION)
3975         info->symbol_type = ST_CODE;
3976
3977       /* Handle function symbols which were defined in this file.
3978          They should have type ST_ENTRY.  Also retrieve the argument
3979          relocation bits from the SOM backend information.  */
3980       else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_ENTRY
3981                || (som_symbol_data (sym)->som_type == SYMBOL_TYPE_CODE
3982                    && (sym->flags & BSF_FUNCTION))
3983                || (som_symbol_data (sym)->som_type == SYMBOL_TYPE_UNKNOWN
3984                    && (sym->flags & BSF_FUNCTION)))
3985         {
3986           info->symbol_type = ST_ENTRY;
3987           info->arg_reloc = som_symbol_data (sym)->tc_data.ap.hppa_arg_reloc;
3988           info->priv_level= som_symbol_data (sym)->tc_data.ap.hppa_priv_level;
3989         }
3990
3991       /* For unknown symbols set the symbol's type based on the symbol's
3992          section (ST_DATA for DATA sections, ST_CODE for CODE sections).  */
3993       else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_UNKNOWN)
3994         {
3995           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 = bfd_zalloc (abfd, amt);
4476
4477   if (new == NULL)
4478     return NULL;
4479   new->symbol.the_bfd = abfd;
4480
4481   return &new->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_final_link                      _bfd_generic_final_link
6347 #define som_bfd_gc_sections                     bfd_generic_gc_sections
6348 #define som_bfd_merge_sections                  bfd_generic_merge_sections
6349 #define som_bfd_is_group_section                bfd_generic_is_group_section
6350 #define som_bfd_discard_group                   bfd_generic_discard_group
6351 #define som_section_already_linked              _bfd_generic_section_already_linked
6352 #define som_bfd_merge_private_bfd_data          _bfd_generic_bfd_merge_private_bfd_data
6353 #define som_bfd_copy_private_header_data        _bfd_generic_bfd_copy_private_header_data
6354 #define som_bfd_set_private_flags               _bfd_generic_bfd_set_private_flags
6355 #define som_find_inliner_info                   _bfd_nosymbols_find_inliner_info
6356
6357 const bfd_target som_vec =
6358 {
6359   "som",                        /* Name.  */
6360   bfd_target_som_flavour,
6361   BFD_ENDIAN_BIG,               /* Target byte order.  */
6362   BFD_ENDIAN_BIG,               /* Target headers byte order.  */
6363   (HAS_RELOC | EXEC_P |         /* Object flags.  */
6364    HAS_LINENO | HAS_DEBUG |
6365    HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED | DYNAMIC),
6366   (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS | SEC_LINK_ONCE
6367    | SEC_ALLOC | SEC_LOAD | SEC_RELOC),         /* Section flags.  */
6368
6369   /* Leading_symbol_char: is the first char of a user symbol
6370      predictable, and if so what is it.  */
6371   0,
6372   '/',                          /* AR_pad_char.  */
6373   14,                           /* AR_max_namelen.  */
6374   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
6375   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
6376   bfd_getb16, bfd_getb_signed_16, bfd_putb16,   /* Data.  */
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,   /* Headers.  */
6380   {_bfd_dummy_target,
6381    som_object_p,                /* bfd_check_format.  */
6382    bfd_generic_archive_p,
6383    _bfd_dummy_target
6384   },
6385   {
6386     bfd_false,
6387     som_mkobject,
6388     _bfd_generic_mkarchive,
6389     bfd_false
6390   },
6391   {
6392     bfd_false,
6393     som_write_object_contents,
6394     _bfd_write_archive_contents,
6395     bfd_false,
6396   },
6397 #undef som
6398
6399   BFD_JUMP_TABLE_GENERIC (som),
6400   BFD_JUMP_TABLE_COPY (som),
6401   BFD_JUMP_TABLE_CORE (_bfd_nocore),
6402   BFD_JUMP_TABLE_ARCHIVE (som),
6403   BFD_JUMP_TABLE_SYMBOLS (som),
6404   BFD_JUMP_TABLE_RELOCS (som),
6405   BFD_JUMP_TABLE_WRITE (som),
6406   BFD_JUMP_TABLE_LINK (som),
6407   BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
6408
6409   NULL,
6410
6411   NULL
6412 };
6413
6414 #endif /* HOST_HPPAHPUX || HOST_HPPABSD || HOST_HPPAOSF */