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