OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [bfd/] [som.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.