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