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