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