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