Make all callers of malloc or realloc (including via obstacks)
[binutils-gdb.git] / bfd / som.c
1 /* bfd back-end for HP PA-RISC SOM objects.
2 Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
3
4 Contributed by the Center for Software Science at the
5 University of Utah (pa-gdb-bugs@cs.utah.edu).
6
7 This file is part of BFD, the Binary File Descriptor library.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
22
23 #include "bfd.h"
24 #include "sysdep.h"
25
26 #if defined (HOST_HPPAHPUX) || defined (HOST_HPPABSD) || defined (HOST_HPPAOSF)
27
28 #include "libbfd.h"
29 #include "som.h"
30 #include "libhppa.h"
31
32 #include <stdio.h>
33 #include <sys/types.h>
34 #include <sys/param.h>
35 #include <sys/dir.h>
36 #include <signal.h>
37 #include <machine/reg.h>
38 #include <sys/user.h> /* After a.out.h */
39 #include <sys/file.h>
40 #include <errno.h>
41
42 /* Magic not defined in standard HP-UX header files until 8.0 */
43
44 #ifndef CPU_PA_RISC1_0
45 #define CPU_PA_RISC1_0 0x20B
46 #endif /* CPU_PA_RISC1_0 */
47
48 #ifndef CPU_PA_RISC1_1
49 #define CPU_PA_RISC1_1 0x210
50 #endif /* CPU_PA_RISC1_1 */
51
52 #ifndef _PA_RISC1_0_ID
53 #define _PA_RISC1_0_ID CPU_PA_RISC1_0
54 #endif /* _PA_RISC1_0_ID */
55
56 #ifndef _PA_RISC1_1_ID
57 #define _PA_RISC1_1_ID CPU_PA_RISC1_1
58 #endif /* _PA_RISC1_1_ID */
59
60 #ifndef _PA_RISC_MAXID
61 #define _PA_RISC_MAXID 0x2FF
62 #endif /* _PA_RISC_MAXID */
63
64 #ifndef _PA_RISC_ID
65 #define _PA_RISC_ID(__m_num) \
66 (((__m_num) == _PA_RISC1_0_ID) || \
67 ((__m_num) >= _PA_RISC1_1_ID && (__m_num) <= _PA_RISC_MAXID))
68 #endif /* _PA_RISC_ID */
69
70 /* Size (in chars) of the temporary buffers used during fixup and string
71 table writes. */
72
73 #define SOM_TMP_BUFSIZE 8192
74
75
76 /* SOM allows any one of the four previous relocations to be reused
77 with a "R_PREV_FIXUP" relocation entry. Since R_PREV_FIXUP
78 relocations are always a single byte, using a R_PREV_FIXUP instead
79 of some multi-byte relocation makes object files smaller.
80
81 Note one side effect of using a R_PREV_FIXUP is the relocation that
82 is being repeated moves to the front of the queue. */
83 struct reloc_queue
84 {
85 unsigned char *reloc;
86 unsigned int size;
87 } reloc_queue[4];
88
89 /* This fully describes the symbol types which may be attached to
90 an EXPORT or IMPORT directive. Only SOM uses this formation
91 (ELF has no need for it). */
92 typedef enum
93 {
94 SYMBOL_TYPE_UNKNOWN,
95 SYMBOL_TYPE_ABSOLUTE,
96 SYMBOL_TYPE_CODE,
97 SYMBOL_TYPE_DATA,
98 SYMBOL_TYPE_ENTRY,
99 SYMBOL_TYPE_MILLICODE,
100 SYMBOL_TYPE_PLABEL,
101 SYMBOL_TYPE_PRI_PROG,
102 SYMBOL_TYPE_SEC_PROG,
103 } pa_symbol_type;
104
105 struct section_to_type
106 {
107 char *section;
108 char type;
109 };
110
111 /* Forward declarations */
112
113 static boolean som_mkobject PARAMS ((bfd *));
114 static bfd_target * som_object_setup PARAMS ((bfd *,
115 struct header *,
116 struct som_exec_auxhdr *));
117 static asection * make_unique_section PARAMS ((bfd *, CONST char *, int));
118 static boolean setup_sections PARAMS ((bfd *, struct header *));
119 static bfd_target * som_object_p PARAMS ((bfd *));
120 static boolean som_write_object_contents PARAMS ((bfd *));
121 static boolean som_slurp_string_table PARAMS ((bfd *));
122 static unsigned int som_slurp_symbol_table PARAMS ((bfd *));
123 static unsigned int som_get_symtab_upper_bound PARAMS ((bfd *));
124 static unsigned int som_canonicalize_reloc PARAMS ((bfd *, sec_ptr,
125 arelent **, asymbol **));
126 static unsigned int som_get_reloc_upper_bound PARAMS ((bfd *, sec_ptr));
127 static unsigned int som_set_reloc_info PARAMS ((unsigned char *, unsigned int,
128 arelent *, asection *,
129 asymbol **, boolean));
130 static boolean som_slurp_reloc_table PARAMS ((bfd *, asection *,
131 asymbol **, boolean));
132 static unsigned int som_get_symtab PARAMS ((bfd *, asymbol **));
133 static asymbol * som_make_empty_symbol PARAMS ((bfd *));
134 static void som_print_symbol PARAMS ((bfd *, PTR,
135 asymbol *, bfd_print_symbol_type));
136 static boolean som_new_section_hook PARAMS ((bfd *, asection *));
137 static boolean som_set_section_contents PARAMS ((bfd *, sec_ptr, PTR,
138 file_ptr, bfd_size_type));
139 static boolean som_set_arch_mach PARAMS ((bfd *, enum bfd_architecture,
140 unsigned long));
141 static boolean som_find_nearest_line PARAMS ((bfd *, asection *,
142 asymbol **, bfd_vma,
143 CONST char **,
144 CONST char **,
145 unsigned int *));
146 static void som_get_symbol_info PARAMS ((bfd *, asymbol *, symbol_info *));
147 static asection * som_section_from_subspace_index PARAMS ((bfd *,
148 unsigned int));
149 static int log2 PARAMS ((unsigned int));
150 static bfd_reloc_status_type hppa_som_reloc PARAMS ((bfd *, arelent *,
151 asymbol *, PTR,
152 asection *, bfd *,
153 char **));
154 static void som_initialize_reloc_queue PARAMS ((struct reloc_queue *));
155 static void som_reloc_queue_insert PARAMS ((unsigned char *, unsigned int,
156 struct reloc_queue *));
157 static void som_reloc_queue_fix PARAMS ((struct reloc_queue *, unsigned int));
158 static int som_reloc_queue_find PARAMS ((unsigned char *, unsigned int,
159 struct reloc_queue *));
160 static unsigned char * try_prev_fixup PARAMS ((bfd *, int *, unsigned char *,
161 unsigned int,
162 struct reloc_queue *));
163
164 static unsigned char * som_reloc_skip PARAMS ((bfd *, unsigned int,
165 unsigned char *, unsigned int *,
166 struct reloc_queue *));
167 static unsigned char * som_reloc_addend PARAMS ((bfd *, int, unsigned char *,
168 unsigned int *,
169 struct reloc_queue *));
170 static unsigned char * som_reloc_call PARAMS ((bfd *, unsigned char *,
171 unsigned int *,
172 arelent *, int,
173 struct reloc_queue *));
174 static unsigned long som_count_spaces PARAMS ((bfd *));
175 static unsigned long som_count_subspaces PARAMS ((bfd *));
176 static int compare_syms PARAMS ((asymbol **, asymbol **));
177 static unsigned long som_compute_checksum PARAMS ((bfd *));
178 static boolean som_prep_headers PARAMS ((bfd *));
179 static int som_sizeof_headers PARAMS ((bfd *, boolean));
180 static boolean som_write_headers PARAMS ((bfd *));
181 static boolean som_build_and_write_symbol_table PARAMS ((bfd *));
182 static void som_prep_for_fixups PARAMS ((bfd *, asymbol **, unsigned long));
183 static boolean som_write_fixups PARAMS ((bfd *, unsigned long, unsigned int *));
184 static boolean som_write_space_strings PARAMS ((bfd *, unsigned long,
185 unsigned int *));
186 static boolean som_write_symbol_strings PARAMS ((bfd *, unsigned long,
187 asymbol **, unsigned int,
188 unsigned *));
189 static boolean som_begin_writing PARAMS ((bfd *));
190 static const reloc_howto_type * som_bfd_reloc_type_lookup
191 PARAMS ((bfd_arch_info_type *, bfd_reloc_code_real_type));
192 static char som_section_type PARAMS ((const char *));
193 static int som_decode_symclass PARAMS ((asymbol *));
194
195
196 /* Map SOM section names to POSIX/BSD single-character symbol types.
197
198 This table includes all the standard subspaces as defined in the
199 current "PRO ABI for PA-RISC Systems", $UNWIND$ which for
200 some reason was left out, and sections specific to embedded stabs. */
201
202 static const struct section_to_type stt[] = {
203 {"$TEXT$", 't'},
204 {"$SHLIB_INFO$", 't'},
205 {"$MILLICODE$", 't'},
206 {"$LIT$", 't'},
207 {"$CODE$", 't'},
208 {"$UNWIND_START$", 't'},
209 {"$UNWIND$", 't'},
210 {"$PRIVATE$", 'd'},
211 {"$PLT$", 'd'},
212 {"$SHLIB_DATA$", 'd'},
213 {"$DATA$", 'd'},
214 {"$SHORTDATA$", 'g'},
215 {"$DLT$", 'd'},
216 {"$GLOBAL$", 'g'},
217 {"$SHORTBSS$", 's'},
218 {"$BSS$", 'b'},
219 {"$GDB_STRINGS$", 'N'},
220 {"$GDB_SYMBOLS$", 'N'},
221 {0, 0}
222 };
223
224 /* About the relocation formatting table...
225
226 There are 256 entries in the table, one for each possible
227 relocation opcode available in SOM. We index the table by
228 the relocation opcode. The names and operations are those
229 defined by a.out_800 (4).
230
231 Right now this table is only used to count and perform minimal
232 processing on relocation streams so that they can be internalized
233 into BFD and symbolically printed by utilities. To make actual use
234 of them would be much more difficult, BFD's concept of relocations
235 is far too simple to handle SOM relocations. The basic assumption
236 that a relocation can be completely processed independent of other
237 relocations before an object file is written is invalid for SOM.
238
239 The SOM relocations are meant to be processed as a stream, they
240 specify copying of data from the input section to the output section
241 while possibly modifying the data in some manner. They also can
242 specify that a variable number of zeros or uninitialized data be
243 inserted on in the output segment at the current offset. Some
244 relocations specify that some previous relocation be re-applied at
245 the current location in the input/output sections. And finally a number
246 of relocations have effects on other sections (R_ENTRY, R_EXIT,
247 R_UNWIND_AUX and a variety of others). There isn't even enough room
248 in the BFD relocation data structure to store enough information to
249 perform all the relocations.
250
251 Each entry in the table has three fields.
252
253 The first entry is an index into this "class" of relocations. This
254 index can then be used as a variable within the relocation itself.
255
256 The second field is a format string which actually controls processing
257 of the relocation. It uses a simple postfix machine to do calculations
258 based on variables/constants found in the string and the relocation
259 stream.
260
261 The third field specifys whether or not this relocation may use
262 a constant (V) from the previous R_DATA_OVERRIDE rather than a constant
263 stored in the instruction.
264
265 Variables:
266
267 L = input space byte count
268 D = index into class of relocations
269 M = output space byte count
270 N = statement number (unused?)
271 O = stack operation
272 R = parameter relocation bits
273 S = symbol index
274 U = 64 bits of stack unwind and frame size info (we only keep 32 bits)
275 V = a literal constant (usually used in the next relocation)
276 P = a previous relocation
277
278 Lower case letters (starting with 'b') refer to following
279 bytes in the relocation stream. 'b' is the next 1 byte,
280 c is the next 2 bytes, d is the next 3 bytes, etc...
281 This is the variable part of the relocation entries that
282 makes our life a living hell.
283
284 numerical constants are also used in the format string. Note
285 the constants are represented in decimal.
286
287 '+', "*" and "=" represents the obvious postfix operators.
288 '<' represents a left shift.
289
290 Stack Operations:
291
292 Parameter Relocation Bits:
293
294 Unwind Entries:
295
296 Previous Relocations: The index field represents which in the queue
297 of 4 previous fixups should be re-applied.
298
299 Literal Constants: These are generally used to represent addend
300 parts of relocations when these constants are not stored in the
301 fields of the instructions themselves. For example the instruction
302 addil foo-$global$-0x1234 would use an override for "0x1234" rather
303 than storing it into the addil itself. */
304
305 struct fixup_format
306 {
307 int D;
308 char *format;
309 };
310
311 static const struct fixup_format som_fixup_formats[256] =
312 {
313 /* R_NO_RELOCATION */
314 0, "LD1+4*=", /* 0x00 */
315 1, "LD1+4*=", /* 0x01 */
316 2, "LD1+4*=", /* 0x02 */
317 3, "LD1+4*=", /* 0x03 */
318 4, "LD1+4*=", /* 0x04 */
319 5, "LD1+4*=", /* 0x05 */
320 6, "LD1+4*=", /* 0x06 */
321 7, "LD1+4*=", /* 0x07 */
322 8, "LD1+4*=", /* 0x08 */
323 9, "LD1+4*=", /* 0x09 */
324 10, "LD1+4*=", /* 0x0a */
325 11, "LD1+4*=", /* 0x0b */
326 12, "LD1+4*=", /* 0x0c */
327 13, "LD1+4*=", /* 0x0d */
328 14, "LD1+4*=", /* 0x0e */
329 15, "LD1+4*=", /* 0x0f */
330 16, "LD1+4*=", /* 0x10 */
331 17, "LD1+4*=", /* 0x11 */
332 18, "LD1+4*=", /* 0x12 */
333 19, "LD1+4*=", /* 0x13 */
334 20, "LD1+4*=", /* 0x14 */
335 21, "LD1+4*=", /* 0x15 */
336 22, "LD1+4*=", /* 0x16 */
337 23, "LD1+4*=", /* 0x17 */
338 0, "LD8<b+1+4*=", /* 0x18 */
339 1, "LD8<b+1+4*=", /* 0x19 */
340 2, "LD8<b+1+4*=", /* 0x1a */
341 3, "LD8<b+1+4*=", /* 0x1b */
342 0, "LD16<c+1+4*=", /* 0x1c */
343 1, "LD16<c+1+4*=", /* 0x1d */
344 2, "LD16<c+1+4*=", /* 0x1e */
345 0, "Ld1+=", /* 0x1f */
346 /* R_ZEROES */
347 0, "Lb1+4*=", /* 0x20 */
348 1, "Ld1+=", /* 0x21 */
349 /* R_UNINIT */
350 0, "Lb1+4*=", /* 0x22 */
351 1, "Ld1+=", /* 0x23 */
352 /* R_RELOCATION */
353 0, "L4=", /* 0x24 */
354 /* R_DATA_ONE_SYMBOL */
355 0, "L4=Sb=", /* 0x25 */
356 1, "L4=Sd=", /* 0x26 */
357 /* R_DATA_PLEBEL */
358 0, "L4=Sb=", /* 0x27 */
359 1, "L4=Sd=", /* 0x28 */
360 /* R_SPACE_REF */
361 0, "L4=", /* 0x29 */
362 /* R_REPEATED_INIT */
363 0, "L4=Mb1+4*=", /* 0x2a */
364 1, "Lb4*=Mb1+L*=", /* 0x2b */
365 2, "Lb4*=Md1+4*=", /* 0x2c */
366 3, "Ld1+=Me1+=", /* 0x2d */
367 /* R_RESERVED */
368 0, "", /* 0x2e */
369 0, "", /* 0x2f */
370 /* R_PCREL_CALL */
371 0, "L4=RD=Sb=", /* 0x30 */
372 1, "L4=RD=Sb=", /* 0x31 */
373 2, "L4=RD=Sb=", /* 0x32 */
374 3, "L4=RD=Sb=", /* 0x33 */
375 4, "L4=RD=Sb=", /* 0x34 */
376 5, "L4=RD=Sb=", /* 0x35 */
377 6, "L4=RD=Sb=", /* 0x36 */
378 7, "L4=RD=Sb=", /* 0x37 */
379 8, "L4=RD=Sb=", /* 0x38 */
380 9, "L4=RD=Sb=", /* 0x39 */
381 0, "L4=RD8<b+=Sb=",/* 0x3a */
382 1, "L4=RD8<b+=Sb=",/* 0x3b */
383 0, "L4=RD8<b+=Sd=",/* 0x3c */
384 1, "L4=RD8<b+=Sd=",/* 0x3d */
385 /* R_RESERVED */
386 0, "", /* 0x3e */
387 0, "", /* 0x3f */
388 /* R_ABS_CALL */
389 0, "L4=RD=Sb=", /* 0x40 */
390 1, "L4=RD=Sb=", /* 0x41 */
391 2, "L4=RD=Sb=", /* 0x42 */
392 3, "L4=RD=Sb=", /* 0x43 */
393 4, "L4=RD=Sb=", /* 0x44 */
394 5, "L4=RD=Sb=", /* 0x45 */
395 6, "L4=RD=Sb=", /* 0x46 */
396 7, "L4=RD=Sb=", /* 0x47 */
397 8, "L4=RD=Sb=", /* 0x48 */
398 9, "L4=RD=Sb=", /* 0x49 */
399 0, "L4=RD8<b+=Sb=",/* 0x4a */
400 1, "L4=RD8<b+=Sb=",/* 0x4b */
401 0, "L4=RD8<b+=Sd=",/* 0x4c */
402 1, "L4=RD8<b+=Sd=",/* 0x4d */
403 /* R_RESERVED */
404 0, "", /* 0x4e */
405 0, "", /* 0x4f */
406 /* R_DP_RELATIVE */
407 0, "L4=SD=", /* 0x50 */
408 1, "L4=SD=", /* 0x51 */
409 2, "L4=SD=", /* 0x52 */
410 3, "L4=SD=", /* 0x53 */
411 4, "L4=SD=", /* 0x54 */
412 5, "L4=SD=", /* 0x55 */
413 6, "L4=SD=", /* 0x56 */
414 7, "L4=SD=", /* 0x57 */
415 8, "L4=SD=", /* 0x58 */
416 9, "L4=SD=", /* 0x59 */
417 10, "L4=SD=", /* 0x5a */
418 11, "L4=SD=", /* 0x5b */
419 12, "L4=SD=", /* 0x5c */
420 13, "L4=SD=", /* 0x5d */
421 14, "L4=SD=", /* 0x5e */
422 15, "L4=SD=", /* 0x5f */
423 16, "L4=SD=", /* 0x60 */
424 17, "L4=SD=", /* 0x61 */
425 18, "L4=SD=", /* 0x62 */
426 19, "L4=SD=", /* 0x63 */
427 20, "L4=SD=", /* 0x64 */
428 21, "L4=SD=", /* 0x65 */
429 22, "L4=SD=", /* 0x66 */
430 23, "L4=SD=", /* 0x67 */
431 24, "L4=SD=", /* 0x68 */
432 25, "L4=SD=", /* 0x69 */
433 26, "L4=SD=", /* 0x6a */
434 27, "L4=SD=", /* 0x6b */
435 28, "L4=SD=", /* 0x6c */
436 29, "L4=SD=", /* 0x6d */
437 30, "L4=SD=", /* 0x6e */
438 31, "L4=SD=", /* 0x6f */
439 32, "L4=Sb=", /* 0x70 */
440 33, "L4=Sd=", /* 0x71 */
441 /* R_RESERVED */
442 0, "", /* 0x72 */
443 0, "", /* 0x73 */
444 0, "", /* 0x74 */
445 0, "", /* 0x75 */
446 0, "", /* 0x76 */
447 0, "", /* 0x77 */
448 /* R_DLT_REL */
449 0, "L4=Sb=", /* 0x78 */
450 1, "L4=Sd=", /* 0x79 */
451 /* R_RESERVED */
452 0, "", /* 0x7a */
453 0, "", /* 0x7b */
454 0, "", /* 0x7c */
455 0, "", /* 0x7d */
456 0, "", /* 0x7e */
457 0, "", /* 0x7f */
458 /* R_CODE_ONE_SYMBOL */
459 0, "L4=SD=", /* 0x80 */
460 1, "L4=SD=", /* 0x81 */
461 2, "L4=SD=", /* 0x82 */
462 3, "L4=SD=", /* 0x83 */
463 4, "L4=SD=", /* 0x84 */
464 5, "L4=SD=", /* 0x85 */
465 6, "L4=SD=", /* 0x86 */
466 7, "L4=SD=", /* 0x87 */
467 8, "L4=SD=", /* 0x88 */
468 9, "L4=SD=", /* 0x89 */
469 10, "L4=SD=", /* 0x8q */
470 11, "L4=SD=", /* 0x8b */
471 12, "L4=SD=", /* 0x8c */
472 13, "L4=SD=", /* 0x8d */
473 14, "L4=SD=", /* 0x8e */
474 15, "L4=SD=", /* 0x8f */
475 16, "L4=SD=", /* 0x90 */
476 17, "L4=SD=", /* 0x91 */
477 18, "L4=SD=", /* 0x92 */
478 19, "L4=SD=", /* 0x93 */
479 20, "L4=SD=", /* 0x94 */
480 21, "L4=SD=", /* 0x95 */
481 22, "L4=SD=", /* 0x96 */
482 23, "L4=SD=", /* 0x97 */
483 24, "L4=SD=", /* 0x98 */
484 25, "L4=SD=", /* 0x99 */
485 26, "L4=SD=", /* 0x9a */
486 27, "L4=SD=", /* 0x9b */
487 28, "L4=SD=", /* 0x9c */
488 29, "L4=SD=", /* 0x9d */
489 30, "L4=SD=", /* 0x9e */
490 31, "L4=SD=", /* 0x9f */
491 32, "L4=Sb=", /* 0xa0 */
492 33, "L4=Sd=", /* 0xa1 */
493 /* R_RESERVED */
494 0, "", /* 0xa2 */
495 0, "", /* 0xa3 */
496 0, "", /* 0xa4 */
497 0, "", /* 0xa5 */
498 0, "", /* 0xa6 */
499 0, "", /* 0xa7 */
500 0, "", /* 0xa8 */
501 0, "", /* 0xa9 */
502 0, "", /* 0xaa */
503 0, "", /* 0xab */
504 0, "", /* 0xac */
505 0, "", /* 0xad */
506 /* R_MILLI_REL */
507 0, "L4=Sb=", /* 0xae */
508 1, "L4=Sd=", /* 0xaf */
509 /* R_CODE_PLABEL */
510 0, "L4=Sb=", /* 0xb0 */
511 1, "L4=Sd=", /* 0xb1 */
512 /* R_BREAKPOINT */
513 0, "L4=", /* 0xb2 */
514 /* R_ENTRY */
515 0, "Ui=", /* 0xb3 */
516 1, "Uf=", /* 0xb4 */
517 /* R_ALT_ENTRY */
518 0, "", /* 0xb5 */
519 /* R_EXIT */
520 0, "", /* 0xb6 */
521 /* R_BEGIN_TRY */
522 0, "", /* 0xb7 */
523 /* R_END_TRY */
524 0, "R0=", /* 0xb8 */
525 1, "Rb4*=", /* 0xb9 */
526 2, "Rd4*=", /* 0xba */
527 /* R_BEGIN_BRTAB */
528 0, "", /* 0xbb */
529 /* R_END_BRTAB */
530 0, "", /* 0xbc */
531 /* R_STATEMENT */
532 0, "Nb=", /* 0xbd */
533 1, "Nc=", /* 0xbe */
534 2, "Nd=", /* 0xbf */
535 /* R_DATA_EXPR */
536 0, "L4=", /* 0xc0 */
537 /* R_CODE_EXPR */
538 0, "L4=", /* 0xc1 */
539 /* R_FSEL */
540 0, "", /* 0xc2 */
541 /* R_LSEL */
542 0, "", /* 0xc3 */
543 /* R_RSEL */
544 0, "", /* 0xc4 */
545 /* R_N_MODE */
546 0, "", /* 0xc5 */
547 /* R_S_MODE */
548 0, "", /* 0xc6 */
549 /* R_D_MODE */
550 0, "", /* 0xc7 */
551 /* R_R_MODE */
552 0, "", /* 0xc8 */
553 /* R_DATA_OVERRIDE */
554 0, "V0=", /* 0xc9 */
555 1, "Vb=", /* 0xca */
556 2, "Vc=", /* 0xcb */
557 3, "Vd=", /* 0xcc */
558 4, "Ve=", /* 0xcd */
559 /* R_TRANSLATED */
560 0, "", /* 0xce */
561 /* R_RESERVED */
562 0, "", /* 0xcf */
563 /* R_COMP1 */
564 0, "Ob=", /* 0xd0 */
565 /* R_COMP2 */
566 0, "Ob=Sd=", /* 0xd1 */
567 /* R_COMP3 */
568 0, "Ob=Ve=", /* 0xd2 */
569 /* R_PREV_FIXUP */
570 0, "P", /* 0xd3 */
571 1, "P", /* 0xd4 */
572 2, "P", /* 0xd5 */
573 3, "P", /* 0xd6 */
574 /* R_RESERVED */
575 0, "", /* 0xd7 */
576 0, "", /* 0xd8 */
577 0, "", /* 0xd9 */
578 0, "", /* 0xda */
579 0, "", /* 0xdb */
580 0, "", /* 0xdc */
581 0, "", /* 0xdd */
582 0, "", /* 0xde */
583 0, "", /* 0xdf */
584 0, "", /* 0xe0 */
585 0, "", /* 0xe1 */
586 0, "", /* 0xe2 */
587 0, "", /* 0xe3 */
588 0, "", /* 0xe4 */
589 0, "", /* 0xe5 */
590 0, "", /* 0xe6 */
591 0, "", /* 0xe7 */
592 0, "", /* 0xe8 */
593 0, "", /* 0xe9 */
594 0, "", /* 0xea */
595 0, "", /* 0xeb */
596 0, "", /* 0xec */
597 0, "", /* 0xed */
598 0, "", /* 0xee */
599 0, "", /* 0xef */
600 0, "", /* 0xf0 */
601 0, "", /* 0xf1 */
602 0, "", /* 0xf2 */
603 0, "", /* 0xf3 */
604 0, "", /* 0xf4 */
605 0, "", /* 0xf5 */
606 0, "", /* 0xf6 */
607 0, "", /* 0xf7 */
608 0, "", /* 0xf8 */
609 0, "", /* 0xf9 */
610 0, "", /* 0xfa */
611 0, "", /* 0xfb */
612 0, "", /* 0xfc */
613 0, "", /* 0xfd */
614 0, "", /* 0xfe */
615 0, "", /* 0xff */
616 };
617
618 static const int comp1_opcodes[] =
619 {
620 0x00,
621 0x40,
622 0x41,
623 0x42,
624 0x43,
625 0x44,
626 0x45,
627 0x46,
628 0x47,
629 0x48,
630 0x49,
631 0x4a,
632 0x4b,
633 0x60,
634 0x80,
635 0xa0,
636 0xc0,
637 -1
638 };
639
640 static const int comp2_opcodes[] =
641 {
642 0x00,
643 0x80,
644 0x82,
645 0xc0,
646 -1
647 };
648
649 static const int comp3_opcodes[] =
650 {
651 0x00,
652 0x02,
653 -1
654 };
655
656 /* These apparently are not in older versions of hpux reloc.h. */
657 #ifndef R_DLT_REL
658 #define R_DLT_REL 0x78
659 #endif
660
661 #ifndef R_AUX_UNWIND
662 #define R_AUX_UNWIND 0xcf
663 #endif
664
665 #ifndef R_SEC_STMT
666 #define R_SEC_STMT 0xd7
667 #endif
668
669 static reloc_howto_type som_hppa_howto_table[] =
670 {
671 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
672 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
673 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
674 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
675 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
676 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
677 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
678 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
679 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
680 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
681 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
682 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
683 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
684 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
685 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
686 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
687 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
688 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
689 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
690 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
691 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
692 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
693 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
694 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
695 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
696 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
697 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
698 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
699 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
700 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
701 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
702 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
703 {R_ZEROES, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ZEROES"},
704 {R_ZEROES, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ZEROES"},
705 {R_UNINIT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_UNINIT"},
706 {R_UNINIT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_UNINIT"},
707 {R_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RELOCATION"},
708 {R_DATA_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DATA_ONE_SYMBOL"},
709 {R_DATA_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DATA_ONE_SYMBOL"},
710 {R_DATA_PLABEL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DATA_PLABEL"},
711 {R_DATA_PLABEL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DATA_PLABEL"},
712 {R_SPACE_REF, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_SPACE_REF"},
713 {R_REPEATED_INIT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "REPEATED_INIT"},
714 {R_REPEATED_INIT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "REPEATED_INIT"},
715 {R_REPEATED_INIT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "REPEATED_INIT"},
716 {R_REPEATED_INIT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "REPEATED_INIT"},
717 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
718 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
719 {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"},
720 {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"},
721 {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"},
722 {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"},
723 {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"},
724 {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"},
725 {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"},
726 {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"},
727 {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"},
728 {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"},
729 {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"},
730 {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"},
731 {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"},
732 {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"},
733 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
734 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
735 {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"},
736 {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"},
737 {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"},
738 {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"},
739 {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"},
740 {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"},
741 {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"},
742 {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"},
743 {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"},
744 {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"},
745 {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"},
746 {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"},
747 {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"},
748 {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"},
749 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
750 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
751 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
752 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
753 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
754 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
755 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
756 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
757 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
758 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
759 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
760 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
761 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
762 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
763 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
764 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
765 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
766 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
767 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
768 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
769 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
770 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
771 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
772 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
773 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
774 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
775 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
776 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
777 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
778 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
779 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
780 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
781 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
782 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
783 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
784 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
785 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
786 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
787 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
788 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
789 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
790 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
791 {R_DLT_REL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DLT_REL"},
792 {R_DLT_REL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DLT_REL"},
793 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
794 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
795 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
796 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
797 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
798 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
799 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
800 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
801 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
802 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
803 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
804 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
805 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
806 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
807 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
808 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
809 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
810 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
811 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
812 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
813 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
814 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
815 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
816 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
817 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
818 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
819 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
820 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
821 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
822 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
823 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
824 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
825 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
826 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
827 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
828 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
829 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
830 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
831 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
832 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
833 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
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_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
837 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
838 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
839 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
840 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
841 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
842 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
843 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
844 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
845 {R_MILLI_REL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_MILLI_REL"},
846 {R_MILLI_REL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_MILLI_REL"},
847 {R_CODE_PLABEL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_PLABEL"},
848 {R_CODE_PLABEL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_PLABEL"},
849 {R_BREAKPOINT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_BREAKPOINT"},
850 {R_ENTRY, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ENTRY"},
851 {R_ENTRY, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ENTRY"},
852 {R_ALT_ENTRY, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ALT_ENTRY"},
853 {R_EXIT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_EXIT"},
854 {R_BEGIN_TRY, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_BEGIN_TRY"},
855 {R_END_TRY, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_END_TRY"},
856 {R_END_TRY, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_END_TRY"},
857 {R_END_TRY, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_END_TRY"},
858 {R_BEGIN_BRTAB, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_BEGIN_BRTAB"},
859 {R_END_BRTAB, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_END_BRTAB"},
860 {R_STATEMENT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_STATEMENT"},
861 {R_STATEMENT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_STATEMENT"},
862 {R_STATEMENT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_STATEMENT"},
863 {R_DATA_EXPR, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DATA_EXPR"},
864 {R_CODE_EXPR, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_EXPR"},
865 {R_FSEL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_FSEL"},
866 {R_LSEL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_LSEL"},
867 {R_RSEL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RSEL"},
868 {R_N_MODE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_N_MODE"},
869 {R_S_MODE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_S_MODE"},
870 {R_D_MODE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_D_MODE"},
871 {R_R_MODE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_R_MODE"},
872 {R_DATA_OVERRIDE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DATA_OVERRIDE"},
873 {R_DATA_OVERRIDE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DATA_OVERRIDE"},
874 {R_DATA_OVERRIDE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DATA_OVERRIDE"},
875 {R_DATA_OVERRIDE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DATA_OVERRIDE"},
876 {R_DATA_OVERRIDE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DATA_OVERRIDE"},
877 {R_TRANSLATED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_TRANSLATED"},
878 {R_AUX_UNWIND, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_AUX_UNWIND"},
879 {R_COMP1, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_COMP1"},
880 {R_COMP2, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_COMP2"},
881 {R_COMP3, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_COMP3"},
882 {R_PREV_FIXUP, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PREV_FIXUP"},
883 {R_PREV_FIXUP, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PREV_FIXUP"},
884 {R_PREV_FIXUP, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PREV_FIXUP"},
885 {R_PREV_FIXUP, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PREV_FIXUP"},
886 {R_SEC_STMT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_SEC_STMT"},
887 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
888 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
889 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
890 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
891 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
892 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
893 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
894 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
895 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
896 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
897 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
898 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
899 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
900 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
901 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
902 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
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_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
909 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
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_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
917 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
918 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
919 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
920 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
921 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
922 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
923 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
924 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
925 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
926 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}};
927
928
929 /* Initialize the SOM relocation queue. By definition the queue holds
930 the last four multibyte fixups. */
931
932 static void
933 som_initialize_reloc_queue (queue)
934 struct reloc_queue *queue;
935 {
936 queue[0].reloc = NULL;
937 queue[0].size = 0;
938 queue[1].reloc = NULL;
939 queue[1].size = 0;
940 queue[2].reloc = NULL;
941 queue[2].size = 0;
942 queue[3].reloc = NULL;
943 queue[3].size = 0;
944 }
945
946 /* Insert a new relocation into the relocation queue. */
947
948 static void
949 som_reloc_queue_insert (p, size, queue)
950 unsigned char *p;
951 unsigned int size;
952 struct reloc_queue *queue;
953 {
954 queue[3].reloc = queue[2].reloc;
955 queue[3].size = queue[2].size;
956 queue[2].reloc = queue[1].reloc;
957 queue[2].size = queue[1].size;
958 queue[1].reloc = queue[0].reloc;
959 queue[1].size = queue[0].size;
960 queue[0].reloc = p;
961 queue[0].size = size;
962 }
963
964 /* When an entry in the relocation queue is reused, the entry moves
965 to the front of the queue. */
966
967 static void
968 som_reloc_queue_fix (queue, index)
969 struct reloc_queue *queue;
970 unsigned int index;
971 {
972 if (index == 0)
973 return;
974
975 if (index == 1)
976 {
977 unsigned char *tmp1 = queue[0].reloc;
978 unsigned int tmp2 = queue[0].size;
979 queue[0].reloc = queue[1].reloc;
980 queue[0].size = queue[1].size;
981 queue[1].reloc = tmp1;
982 queue[1].size = tmp2;
983 return;
984 }
985
986 if (index == 2)
987 {
988 unsigned char *tmp1 = queue[0].reloc;
989 unsigned int tmp2 = queue[0].size;
990 queue[0].reloc = queue[2].reloc;
991 queue[0].size = queue[2].size;
992 queue[2].reloc = queue[1].reloc;
993 queue[2].size = queue[1].size;
994 queue[1].reloc = tmp1;
995 queue[1].size = tmp2;
996 return;
997 }
998
999 if (index == 3)
1000 {
1001 unsigned char *tmp1 = queue[0].reloc;
1002 unsigned int tmp2 = queue[0].size;
1003 queue[0].reloc = queue[3].reloc;
1004 queue[0].size = queue[3].size;
1005 queue[3].reloc = queue[2].reloc;
1006 queue[3].size = queue[2].size;
1007 queue[2].reloc = queue[1].reloc;
1008 queue[2].size = queue[1].size;
1009 queue[1].reloc = tmp1;
1010 queue[1].size = tmp2;
1011 return;
1012 }
1013 abort();
1014 }
1015
1016 /* Search for a particular relocation in the relocation queue. */
1017
1018 static int
1019 som_reloc_queue_find (p, size, queue)
1020 unsigned char *p;
1021 unsigned int size;
1022 struct reloc_queue *queue;
1023 {
1024 if (queue[0].reloc && !bcmp (p, queue[0].reloc, size)
1025 && size == queue[0].size)
1026 return 0;
1027 if (queue[1].reloc && !bcmp (p, queue[1].reloc, size)
1028 && size == queue[1].size)
1029 return 1;
1030 if (queue[2].reloc && !bcmp (p, queue[2].reloc, size)
1031 && size == queue[2].size)
1032 return 2;
1033 if (queue[3].reloc && !bcmp (p, queue[3].reloc, size)
1034 && size == queue[3].size)
1035 return 3;
1036 return -1;
1037 }
1038
1039 static unsigned char *
1040 try_prev_fixup (abfd, subspace_reloc_sizep, p, size, queue)
1041 bfd *abfd;
1042 int *subspace_reloc_sizep;
1043 unsigned char *p;
1044 unsigned int size;
1045 struct reloc_queue *queue;
1046 {
1047 int queue_index = som_reloc_queue_find (p, size, queue);
1048
1049 if (queue_index != -1)
1050 {
1051 /* Found this in a previous fixup. Undo the fixup we
1052 just built and use R_PREV_FIXUP instead. We saved
1053 a total of size - 1 bytes in the fixup stream. */
1054 bfd_put_8 (abfd, R_PREV_FIXUP + queue_index, p);
1055 p += 1;
1056 *subspace_reloc_sizep += 1;
1057 som_reloc_queue_fix (queue, queue_index);
1058 }
1059 else
1060 {
1061 som_reloc_queue_insert (p, size, queue);
1062 *subspace_reloc_sizep += size;
1063 p += size;
1064 }
1065 return p;
1066 }
1067
1068 /* Emit the proper R_NO_RELOCATION fixups to map the next SKIP
1069 bytes without any relocation. Update the size of the subspace
1070 relocation stream via SUBSPACE_RELOC_SIZE_P; also return the
1071 current pointer into the relocation stream. */
1072
1073 static unsigned char *
1074 som_reloc_skip (abfd, skip, p, subspace_reloc_sizep, queue)
1075 bfd *abfd;
1076 unsigned int skip;
1077 unsigned char *p;
1078 unsigned int *subspace_reloc_sizep;
1079 struct reloc_queue *queue;
1080 {
1081 /* Use a 4 byte R_NO_RELOCATION entry with a maximal value
1082 then R_PREV_FIXUPs to get the difference down to a
1083 reasonable size. */
1084 if (skip >= 0x1000000)
1085 {
1086 skip -= 0x1000000;
1087 bfd_put_8 (abfd, R_NO_RELOCATION + 31, p);
1088 bfd_put_8 (abfd, 0xff, p + 1);
1089 bfd_put_16 (abfd, 0xffff, p + 2);
1090 p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 4, queue);
1091 while (skip >= 0x1000000)
1092 {
1093 skip -= 0x1000000;
1094 bfd_put_8 (abfd, R_PREV_FIXUP, p);
1095 p++;
1096 *subspace_reloc_sizep += 1;
1097 /* No need to adjust queue here since we are repeating the
1098 most recent fixup. */
1099 }
1100 }
1101
1102 /* The difference must be less than 0x1000000. Use one
1103 more R_NO_RELOCATION entry to get to the right difference. */
1104 if ((skip & 3) == 0 && skip <= 0xc0000 && skip > 0)
1105 {
1106 /* Difference can be handled in a simple single-byte
1107 R_NO_RELOCATION entry. */
1108 if (skip <= 0x60)
1109 {
1110 bfd_put_8 (abfd, R_NO_RELOCATION + (skip >> 2) - 1, p);
1111 *subspace_reloc_sizep += 1;
1112 p++;
1113 }
1114 /* Handle it with a two byte R_NO_RELOCATION entry. */
1115 else if (skip <= 0x1000)
1116 {
1117 bfd_put_8 (abfd, R_NO_RELOCATION + 24 + (((skip >> 2) - 1) >> 8), p);
1118 bfd_put_8 (abfd, (skip >> 2) - 1, p + 1);
1119 p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 2, queue);
1120 }
1121 /* Handle it with a three byte R_NO_RELOCATION entry. */
1122 else
1123 {
1124 bfd_put_8 (abfd, R_NO_RELOCATION + 28 + (((skip >> 2) - 1) >> 16), p);
1125 bfd_put_16 (abfd, (skip >> 2) - 1, p + 1);
1126 p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 3, queue);
1127 }
1128 }
1129 /* Ugh. Punt and use a 4 byte entry. */
1130 else if (skip > 0)
1131 {
1132 bfd_put_8 (abfd, R_NO_RELOCATION + 31, p);
1133 bfd_put_8 (abfd, skip >> 16, p + 1);
1134 bfd_put_16 (abfd, skip, p + 2);
1135 p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 4, queue);
1136 }
1137 return p;
1138 }
1139
1140 /* Emit the proper R_DATA_OVERRIDE fixups to handle a nonzero addend
1141 from a BFD relocation. Update the size of the subspace relocation
1142 stream via SUBSPACE_RELOC_SIZE_P; also return the current pointer
1143 into the relocation stream. */
1144
1145 static unsigned char *
1146 som_reloc_addend (abfd, addend, p, subspace_reloc_sizep, queue)
1147 bfd *abfd;
1148 int addend;
1149 unsigned char *p;
1150 unsigned int *subspace_reloc_sizep;
1151 struct reloc_queue *queue;
1152 {
1153 if ((unsigned)(addend) + 0x80 < 0x100)
1154 {
1155 bfd_put_8 (abfd, R_DATA_OVERRIDE + 1, p);
1156 bfd_put_8 (abfd, addend, p + 1);
1157 p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 2, queue);
1158 }
1159 else if ((unsigned) (addend) + 0x8000 < 0x10000)
1160 {
1161 bfd_put_8 (abfd, R_DATA_OVERRIDE + 2, p);
1162 bfd_put_16 (abfd, addend, p + 1);
1163 p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 3, queue);
1164 }
1165 else if ((unsigned) (addend) + 0x800000 < 0x1000000)
1166 {
1167 bfd_put_8 (abfd, R_DATA_OVERRIDE + 3, p);
1168 bfd_put_8 (abfd, addend >> 16, p + 1);
1169 bfd_put_16 (abfd, addend, p + 2);
1170 p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 4, queue);
1171 }
1172 else
1173 {
1174 bfd_put_8 (abfd, R_DATA_OVERRIDE + 4, p);
1175 bfd_put_32 (abfd, addend, p + 1);
1176 p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 5, queue);
1177 }
1178 return p;
1179 }
1180
1181 /* Handle a single function call relocation. */
1182
1183 static unsigned char *
1184 som_reloc_call (abfd, p, subspace_reloc_sizep, bfd_reloc, sym_num, queue)
1185 bfd *abfd;
1186 unsigned char *p;
1187 unsigned int *subspace_reloc_sizep;
1188 arelent *bfd_reloc;
1189 int sym_num;
1190 struct reloc_queue *queue;
1191 {
1192 int arg_bits = HPPA_R_ARG_RELOC (bfd_reloc->addend);
1193 int rtn_bits = arg_bits & 0x3;
1194 int type, done = 0;
1195
1196 /* You'll never believe all this is necessary to handle relocations
1197 for function calls. Having to compute and pack the argument
1198 relocation bits is the real nightmare.
1199
1200 If you're interested in how this works, just forget it. You really
1201 do not want to know about this braindamage. */
1202
1203 /* First see if this can be done with a "simple" relocation. Simple
1204 relocations have a symbol number < 0x100 and have simple encodings
1205 of argument relocations. */
1206
1207 if (sym_num < 0x100)
1208 {
1209 switch (arg_bits)
1210 {
1211 case 0:
1212 case 1:
1213 type = 0;
1214 break;
1215 case 1 << 8:
1216 case 1 << 8 | 1:
1217 type = 1;
1218 break;
1219 case 1 << 8 | 1 << 6:
1220 case 1 << 8 | 1 << 6 | 1:
1221 type = 2;
1222 break;
1223 case 1 << 8 | 1 << 6 | 1 << 4:
1224 case 1 << 8 | 1 << 6 | 1 << 4 | 1:
1225 type = 3;
1226 break;
1227 case 1 << 8 | 1 << 6 | 1 << 4 | 1 << 2:
1228 case 1 << 8 | 1 << 6 | 1 << 4 | 1 << 2 | 1:
1229 type = 4;
1230 break;
1231 default:
1232 /* Not one of the easy encodings. This will have to be
1233 handled by the more complex code below. */
1234 type = -1;
1235 break;
1236 }
1237 if (type != -1)
1238 {
1239 /* Account for the return value too. */
1240 if (rtn_bits)
1241 type += 5;
1242
1243 /* Emit a 2 byte relocation. Then see if it can be handled
1244 with a relocation which is already in the relocation queue. */
1245 bfd_put_8 (abfd, bfd_reloc->howto->type + type, p);
1246 bfd_put_8 (abfd, sym_num, p + 1);
1247 p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 2, queue);
1248 done = 1;
1249 }
1250 }
1251
1252 /* If this could not be handled with a simple relocation, then do a hard
1253 one. Hard relocations occur if the symbol number was too high or if
1254 the encoding of argument relocation bits is too complex. */
1255 if (! done)
1256 {
1257 /* Don't ask about these magic sequences. I took them straight
1258 from gas-1.36 which took them from the a.out man page. */
1259 type = rtn_bits;
1260 if ((arg_bits >> 6 & 0xf) == 0xe)
1261 type += 9 * 40;
1262 else
1263 type += (3 * (arg_bits >> 8 & 3) + (arg_bits >> 6 & 3)) * 40;
1264 if ((arg_bits >> 2 & 0xf) == 0xe)
1265 type += 9 * 4;
1266 else
1267 type += (3 * (arg_bits >> 4 & 3) + (arg_bits >> 2 & 3)) * 4;
1268
1269 /* Output the first two bytes of the relocation. These describe
1270 the length of the relocation and encoding style. */
1271 bfd_put_8 (abfd, bfd_reloc->howto->type + 10
1272 + 2 * (sym_num >= 0x100) + (type >= 0x100),
1273 p);
1274 bfd_put_8 (abfd, type, p + 1);
1275
1276 /* Now output the symbol index and see if this bizarre relocation
1277 just happened to be in the relocation queue. */
1278 if (sym_num < 0x100)
1279 {
1280 bfd_put_8 (abfd, sym_num, p + 2);
1281 p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 3, queue);
1282 }
1283 else
1284 {
1285 bfd_put_8 (abfd, sym_num >> 16, p + 2);
1286 bfd_put_16 (abfd, sym_num, p + 3);
1287 p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 5, queue);
1288 }
1289 }
1290 return p;
1291 }
1292
1293
1294 /* Return the logarithm of X, base 2, considering X unsigned.
1295 Abort if X is not a power of two -- this should never happen (FIXME:
1296 It will happen on corrupt executables. GDB should give an error, not
1297 a coredump, in that case). */
1298
1299 static int
1300 log2 (x)
1301 unsigned int x;
1302 {
1303 int log = 0;
1304
1305 /* Test for 0 or a power of 2. */
1306 if (x == 0 || x != (x & -x))
1307 abort();
1308
1309 while ((x >>= 1) != 0)
1310 log++;
1311 return log;
1312 }
1313
1314 static bfd_reloc_status_type
1315 hppa_som_reloc (abfd, reloc_entry, symbol_in, data,
1316 input_section, output_bfd, error_message)
1317 bfd *abfd;
1318 arelent *reloc_entry;
1319 asymbol *symbol_in;
1320 PTR data;
1321 asection *input_section;
1322 bfd *output_bfd;
1323 char **error_message;
1324 {
1325 if (output_bfd)
1326 {
1327 reloc_entry->address += input_section->output_offset;
1328 return bfd_reloc_ok;
1329 }
1330 return bfd_reloc_ok;
1331 }
1332
1333 /* Given a generic HPPA relocation type, the instruction format,
1334 and a field selector, return an appropriate SOM reloation.
1335
1336 FIXME. Need to handle %RR, %LR and the like as field selectors.
1337 These will need to generate multiple SOM relocations. */
1338
1339 int **
1340 hppa_som_gen_reloc_type (abfd, base_type, format, field)
1341 bfd *abfd;
1342 int base_type;
1343 int format;
1344 enum hppa_reloc_field_selector_type field;
1345 {
1346 int *final_type, **final_types;
1347
1348 final_types = (int **) bfd_alloc_by_size_t (abfd, sizeof (int *) * 3);
1349 final_type = (int *) bfd_alloc_by_size_t (abfd, sizeof (int));
1350 if (!final_types || !final_type)
1351 {
1352 bfd_error = no_memory;
1353 return NULL;
1354 }
1355
1356 /* The field selector may require additional relocations to be
1357 generated. It's impossible to know at this moment if additional
1358 relocations will be needed, so we make them. The code to actually
1359 write the relocation/fixup stream is responsible for removing
1360 any redundant relocations. */
1361 switch (field)
1362 {
1363 case e_fsel:
1364 case e_psel:
1365 case e_lpsel:
1366 case e_rpsel:
1367 final_types[0] = final_type;
1368 final_types[1] = NULL;
1369 final_types[2] = NULL;
1370 *final_type = base_type;
1371 break;
1372
1373 case e_tsel:
1374 case e_ltsel:
1375 case e_rtsel:
1376 final_types[0] = (int *) bfd_alloc_by_size_t (abfd, sizeof (int));
1377 if (!final_types[0])
1378 {
1379 bfd_error = no_memory;
1380 return NULL;
1381 }
1382 if (field == e_tsel)
1383 *final_types[0] = R_FSEL;
1384 else if (field == e_ltsel)
1385 *final_types[0] = R_LSEL;
1386 else
1387 *final_types[0] = R_RSEL;
1388 final_types[1] = final_type;
1389 final_types[2] = NULL;
1390 *final_type = base_type;
1391 break;
1392
1393 case e_lssel:
1394 case e_rssel:
1395 final_types[0] = (int *) bfd_alloc_by_size_t (abfd, sizeof (int));
1396 if (!final_types[0])
1397 {
1398 bfd_error = no_memory;
1399 return NULL;
1400 }
1401 *final_types[0] = R_S_MODE;
1402 final_types[1] = final_type;
1403 final_types[2] = NULL;
1404 *final_type = base_type;
1405 break;
1406
1407 case e_lsel:
1408 case e_rsel:
1409 final_types[0] = (int *) bfd_alloc_by_size_t (abfd, sizeof (int));
1410 if (!final_types[0])
1411 {
1412 bfd_error = no_memory;
1413 return NULL;
1414 }
1415 *final_types[0] = R_N_MODE;
1416 final_types[1] = final_type;
1417 final_types[2] = NULL;
1418 *final_type = base_type;
1419 break;
1420
1421 case e_ldsel:
1422 case e_rdsel:
1423 final_types[0] = (int *) bfd_alloc_by_size_t (abfd, sizeof (int));
1424 if (!final_types[0])
1425 {
1426 bfd_error = no_memory;
1427 return NULL;
1428 }
1429 *final_types[0] = R_D_MODE;
1430 final_types[1] = final_type;
1431 final_types[2] = NULL;
1432 *final_type = base_type;
1433 break;
1434
1435 case e_lrsel:
1436 case e_rrsel:
1437 final_types[0] = (int *) bfd_alloc_by_size_t (abfd, sizeof (int));
1438 if (!final_types[0])
1439 {
1440 bfd_error = no_memory;
1441 return NULL;
1442 }
1443 *final_types[0] = R_R_MODE;
1444 final_types[1] = final_type;
1445 final_types[2] = NULL;
1446 *final_type = base_type;
1447 break;
1448 }
1449
1450 switch (base_type)
1451 {
1452 case R_HPPA:
1453 /* PLABELs get their own relocation type. */
1454 if (field == e_psel
1455 || field == e_lpsel
1456 || field == e_rpsel)
1457 {
1458 /* A PLABEL relocation that has a size of 32 bits must
1459 be a R_DATA_PLABEL. All others are R_CODE_PLABELs. */
1460 if (format == 32)
1461 *final_type = R_DATA_PLABEL;
1462 else
1463 *final_type = R_CODE_PLABEL;
1464 }
1465 /* PIC stuff. */
1466 else if (field == e_tsel
1467 || field == e_ltsel
1468 || field == e_rtsel)
1469 *final_type = R_DLT_REL;
1470 /* A relocation in the data space is always a full 32bits. */
1471 else if (format == 32)
1472 *final_type = R_DATA_ONE_SYMBOL;
1473
1474 break;
1475
1476 case R_HPPA_GOTOFF:
1477 /* More PLABEL special cases. */
1478 if (field == e_psel
1479 || field == e_lpsel
1480 || field == e_rpsel)
1481 *final_type = R_DATA_PLABEL;
1482 break;
1483
1484 case R_HPPA_NONE:
1485 case R_HPPA_ABS_CALL:
1486 case R_HPPA_PCREL_CALL:
1487 case R_HPPA_COMPLEX:
1488 case R_HPPA_COMPLEX_PCREL_CALL:
1489 case R_HPPA_COMPLEX_ABS_CALL:
1490 /* Right now we can default all these. */
1491 break;
1492 }
1493 return final_types;
1494 }
1495
1496 /* Return the address of the correct entry in the PA SOM relocation
1497 howto table. */
1498
1499 static const reloc_howto_type *
1500 som_bfd_reloc_type_lookup (arch, code)
1501 bfd_arch_info_type *arch;
1502 bfd_reloc_code_real_type code;
1503 {
1504 if ((int) code < (int) R_NO_RELOCATION + 255)
1505 {
1506 BFD_ASSERT ((int) som_hppa_howto_table[(int) code].type == (int) code);
1507 return &som_hppa_howto_table[(int) code];
1508 }
1509
1510 return (reloc_howto_type *) 0;
1511 }
1512
1513 /* Perform some initialization for an object. Save results of this
1514 initialization in the BFD. */
1515
1516 static bfd_target *
1517 som_object_setup (abfd, file_hdrp, aux_hdrp)
1518 bfd *abfd;
1519 struct header *file_hdrp;
1520 struct som_exec_auxhdr *aux_hdrp;
1521 {
1522 /* som_mkobject will set bfd_error if som_mkobject fails. */
1523 if (som_mkobject (abfd) != true)
1524 return 0;
1525
1526 /* Set BFD flags based on what information is available in the SOM. */
1527 abfd->flags = NO_FLAGS;
1528 if (! file_hdrp->entry_offset)
1529 abfd->flags |= HAS_RELOC;
1530 else
1531 abfd->flags |= EXEC_P;
1532 if (file_hdrp->symbol_total)
1533 abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
1534
1535 bfd_get_start_address (abfd) = aux_hdrp->exec_entry;
1536 bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 0);
1537 bfd_get_symcount (abfd) = file_hdrp->symbol_total;
1538
1539 /* Initialize the saved symbol table and string table to NULL.
1540 Save important offsets and sizes from the SOM header into
1541 the BFD. */
1542 obj_som_stringtab (abfd) = (char *) NULL;
1543 obj_som_symtab (abfd) = (som_symbol_type *) NULL;
1544 obj_som_stringtab_size (abfd) = file_hdrp->symbol_strings_size;
1545 obj_som_sym_filepos (abfd) = file_hdrp->symbol_location;
1546 obj_som_str_filepos (abfd) = file_hdrp->symbol_strings_location;
1547 obj_som_reloc_filepos (abfd) = file_hdrp->fixup_request_location;
1548
1549 return abfd->xvec;
1550 }
1551
1552 /* Create a new BFD section for NAME. If NAME already exists, then create a
1553 new unique name, with NAME as the prefix. This exists because SOM .o files
1554 may have more than one $CODE$ subspace. */
1555
1556 static asection *
1557 make_unique_section (abfd, name, num)
1558 bfd *abfd;
1559 CONST char *name;
1560 int num;
1561 {
1562 asection *sect;
1563 char *newname;
1564 char altname[100];
1565
1566 sect = bfd_make_section (abfd, name);
1567 while (!sect)
1568 {
1569 sprintf (altname, "%s-%d", name, num++);
1570 sect = bfd_make_section (abfd, altname);
1571 }
1572
1573 newname = bfd_alloc (abfd, strlen (sect->name) + 1);
1574 if (!newname)
1575 {
1576 bfd_error = no_memory;
1577 return NULL;
1578 }
1579 strcpy (newname, sect->name);
1580
1581 sect->name = newname;
1582 return sect;
1583 }
1584
1585 /* Convert all of the space and subspace info into BFD sections. Each space
1586 contains a number of subspaces, which in turn describe the mapping between
1587 regions of the exec file, and the address space that the program runs in.
1588 BFD sections which correspond to spaces will overlap the sections for the
1589 associated subspaces. */
1590
1591 static boolean
1592 setup_sections (abfd, file_hdr)
1593 bfd *abfd;
1594 struct header *file_hdr;
1595 {
1596 char *space_strings;
1597 int space_index;
1598 unsigned int total_subspaces = 0;
1599
1600 /* First, read in space names */
1601
1602 space_strings = alloca (file_hdr->space_strings_size);
1603 if (!space_strings)
1604 return false;
1605
1606 if (bfd_seek (abfd, file_hdr->space_strings_location, SEEK_SET) < 0)
1607 return false;
1608 if (bfd_read (space_strings, 1, file_hdr->space_strings_size, abfd)
1609 != file_hdr->space_strings_size)
1610 return false;
1611
1612 /* Loop over all of the space dictionaries, building up sections */
1613 for (space_index = 0; space_index < file_hdr->space_total; space_index++)
1614 {
1615 struct space_dictionary_record space;
1616 struct subspace_dictionary_record subspace, save_subspace;
1617 int subspace_index;
1618 asection *space_asect;
1619
1620 /* Read the space dictionary element */
1621 if (bfd_seek (abfd, file_hdr->space_location
1622 + space_index * sizeof space, SEEK_SET) < 0)
1623 return false;
1624 if (bfd_read (&space, 1, sizeof space, abfd) != sizeof space)
1625 return false;
1626
1627 /* Setup the space name string */
1628 space.name.n_name = space.name.n_strx + space_strings;
1629
1630 /* Make a section out of it */
1631 space_asect = make_unique_section (abfd, space.name.n_name, space_index);
1632 if (!space_asect)
1633 return false;
1634
1635 /* Now, read in the first subspace for this space */
1636 if (bfd_seek (abfd, file_hdr->subspace_location
1637 + space.subspace_index * sizeof subspace,
1638 SEEK_SET) < 0)
1639 return false;
1640 if (bfd_read (&subspace, 1, sizeof subspace, abfd) != sizeof subspace)
1641 return false;
1642 /* Seek back to the start of the subspaces for loop below */
1643 if (bfd_seek (abfd, file_hdr->subspace_location
1644 + space.subspace_index * sizeof subspace,
1645 SEEK_SET) < 0)
1646 return false;
1647
1648 /* Setup the start address and file loc from the first subspace record */
1649 space_asect->vma = subspace.subspace_start;
1650 space_asect->filepos = subspace.file_loc_init_value;
1651 space_asect->alignment_power = log2 (subspace.alignment);
1652
1653 /* Initialize save_subspace so we can reliably determine if this
1654 loop placed any useful values into it. */
1655 bzero (&save_subspace, sizeof (struct subspace_dictionary_record));
1656
1657 /* Loop over the rest of the subspaces, building up more sections */
1658 for (subspace_index = 0; subspace_index < space.subspace_quantity;
1659 subspace_index++)
1660 {
1661 asection *subspace_asect;
1662
1663 /* Read in the next subspace */
1664 if (bfd_read (&subspace, 1, sizeof subspace, abfd)
1665 != sizeof subspace)
1666 return false;
1667
1668 /* Setup the subspace name string */
1669 subspace.name.n_name = subspace.name.n_strx + space_strings;
1670
1671 /* Make a section out of this subspace */
1672 subspace_asect = make_unique_section (abfd, subspace.name.n_name,
1673 space.subspace_index + subspace_index);
1674
1675 if (!subspace_asect)
1676 return false;
1677
1678 /* Keep an easy mapping between subspaces and sections. */
1679 som_section_data (subspace_asect)->subspace_index
1680 = total_subspaces++;
1681
1682 /* Set SEC_READONLY and SEC_CODE/SEC_DATA as specified
1683 by the access_control_bits in the subspace header. */
1684 switch (subspace.access_control_bits >> 4)
1685 {
1686 /* Readonly data. */
1687 case 0x0:
1688 subspace_asect->flags |= SEC_DATA | SEC_READONLY;
1689 break;
1690
1691 /* Normal data. */
1692 case 0x1:
1693 subspace_asect->flags |= SEC_DATA;
1694 break;
1695
1696 /* Readonly code and the gateways.
1697 Gateways have other attributes which do not map
1698 into anything BFD knows about. */
1699 case 0x2:
1700 case 0x4:
1701 case 0x5:
1702 case 0x6:
1703 case 0x7:
1704 subspace_asect->flags |= SEC_CODE | SEC_READONLY;
1705 break;
1706
1707 /* dynamic (writable) code. */
1708 case 0x3:
1709 subspace_asect->flags |= SEC_CODE;
1710 break;
1711 }
1712
1713 if (subspace.dup_common || subspace.is_common)
1714 subspace_asect->flags |= SEC_IS_COMMON;
1715 else if (subspace.subspace_length > 0)
1716 subspace_asect->flags |= SEC_HAS_CONTENTS;
1717 if (subspace.is_loadable)
1718 subspace_asect->flags |= SEC_ALLOC | SEC_LOAD;
1719 if (subspace.code_only)
1720 subspace_asect->flags |= SEC_CODE;
1721
1722 /* Both file_loc_init_value and initialization_length will
1723 be zero for a BSS like subspace. */
1724 if (subspace.file_loc_init_value == 0
1725 && subspace.initialization_length == 0)
1726 subspace_asect->flags &= ~(SEC_DATA | SEC_LOAD);
1727
1728 /* This subspace has relocations.
1729 The fixup_request_quantity is a byte count for the number of
1730 entries in the relocation stream; it is not the actual number
1731 of relocations in the subspace. */
1732 if (subspace.fixup_request_quantity != 0)
1733 {
1734 subspace_asect->flags |= SEC_RELOC;
1735 subspace_asect->rel_filepos = subspace.fixup_request_index;
1736 som_section_data (subspace_asect)->reloc_size
1737 = subspace.fixup_request_quantity;
1738 /* We can not determine this yet. When we read in the
1739 relocation table the correct value will be filled in. */
1740 subspace_asect->reloc_count = -1;
1741 }
1742
1743 /* Update save_subspace if appropriate. */
1744 if (subspace.file_loc_init_value > save_subspace.file_loc_init_value)
1745 save_subspace = subspace;
1746
1747 subspace_asect->vma = subspace.subspace_start;
1748 subspace_asect->_cooked_size = subspace.subspace_length;
1749 subspace_asect->_raw_size = subspace.subspace_length;
1750 subspace_asect->alignment_power = log2 (subspace.alignment);
1751 subspace_asect->filepos = subspace.file_loc_init_value;
1752 }
1753
1754 /* Yow! there is no subspace within the space which actually
1755 has initialized information in it; this should never happen
1756 as far as I know. */
1757 if (!save_subspace.file_loc_init_value)
1758 abort ();
1759
1760 /* Setup the sizes for the space section based upon the info in the
1761 last subspace of the space. */
1762 space_asect->_cooked_size = save_subspace.subspace_start
1763 - space_asect->vma + save_subspace.subspace_length;
1764 space_asect->_raw_size = save_subspace.file_loc_init_value
1765 - space_asect->filepos + save_subspace.initialization_length;
1766 }
1767 return true;
1768 }
1769
1770 /* Read in a SOM object and make it into a BFD. */
1771
1772 static bfd_target *
1773 som_object_p (abfd)
1774 bfd *abfd;
1775 {
1776 struct header file_hdr;
1777 struct som_exec_auxhdr aux_hdr;
1778
1779 if (bfd_read ((PTR) & file_hdr, 1, FILE_HDR_SIZE, abfd) != FILE_HDR_SIZE)
1780 {
1781 bfd_error = system_call_error;
1782 return 0;
1783 }
1784
1785 if (!_PA_RISC_ID (file_hdr.system_id))
1786 {
1787 bfd_error = wrong_format;
1788 return 0;
1789 }
1790
1791 switch (file_hdr.a_magic)
1792 {
1793 case RELOC_MAGIC:
1794 case EXEC_MAGIC:
1795 case SHARE_MAGIC:
1796 case DEMAND_MAGIC:
1797 #ifdef DL_MAGIC
1798 case DL_MAGIC:
1799 #endif
1800 #ifdef SHL_MAGIC
1801 case SHL_MAGIC:
1802 #endif
1803 #ifdef EXECLIBMAGIC
1804 case EXECLIBMAGIC:
1805 #endif
1806 #ifdef SHARED_MAGIC_CNX
1807 case SHARED_MAGIC_CNX:
1808 #endif
1809 break;
1810 default:
1811 bfd_error = wrong_format;
1812 return 0;
1813 }
1814
1815 if (file_hdr.version_id != VERSION_ID
1816 && file_hdr.version_id != NEW_VERSION_ID)
1817 {
1818 bfd_error = wrong_format;
1819 return 0;
1820 }
1821
1822 /* If the aux_header_size field in the file header is zero, then this
1823 object is an incomplete executable (a .o file). Do not try to read
1824 a non-existant auxiliary header. */
1825 bzero (&aux_hdr, sizeof (struct som_exec_auxhdr));
1826 if (file_hdr.aux_header_size != 0)
1827 {
1828 if (bfd_read ((PTR) & aux_hdr, 1, AUX_HDR_SIZE, abfd) != AUX_HDR_SIZE)
1829 {
1830 bfd_error = wrong_format;
1831 return 0;
1832 }
1833 }
1834
1835 if (!setup_sections (abfd, &file_hdr))
1836 {
1837 /* setup_sections does not bubble up a bfd error code. */
1838 bfd_error = bad_value;
1839 return 0;
1840 }
1841
1842 /* This appears to be a valid SOM object. Do some initialization. */
1843 return som_object_setup (abfd, &file_hdr, &aux_hdr);
1844 }
1845
1846 /* Create a SOM object. */
1847
1848 static boolean
1849 som_mkobject (abfd)
1850 bfd *abfd;
1851 {
1852 /* Allocate memory to hold backend information. */
1853 abfd->tdata.som_data = (struct som_data_struct *)
1854 bfd_zalloc (abfd, sizeof (struct som_data_struct));
1855 if (abfd->tdata.som_data == NULL)
1856 {
1857 bfd_error = no_memory;
1858 return false;
1859 }
1860 obj_som_file_hdr (abfd)
1861 = (struct header *) bfd_zalloc (abfd, sizeof (struct header));
1862 if (obj_som_file_hdr (abfd) == NULL)
1863
1864 {
1865 bfd_error = no_memory;
1866 return false;
1867 }
1868 return true;
1869 }
1870
1871 /* Initialize some information in the file header. This routine makes
1872 not attempt at doing the right thing for a full executable; it
1873 is only meant to handle relocatable objects. */
1874
1875 static boolean
1876 som_prep_headers (abfd)
1877 bfd *abfd;
1878 {
1879 struct header *file_hdr = obj_som_file_hdr (abfd);
1880 asection *section;
1881
1882 /* FIXME. This should really be conditional based on whether or not
1883 PA1.1 instructions/registers have been used. */
1884 file_hdr->system_id = HP9000S800_ID;
1885
1886 /* FIXME. Only correct for building relocatable objects. */
1887 if (abfd->flags & EXEC_P)
1888 abort ();
1889 else
1890 file_hdr->a_magic = RELOC_MAGIC;
1891
1892 /* Only new format SOM is supported. */
1893 file_hdr->version_id = NEW_VERSION_ID;
1894
1895 /* These fields are optional, and embedding timestamps is not always
1896 a wise thing to do, it makes comparing objects during a multi-stage
1897 bootstrap difficult. */
1898 file_hdr->file_time.secs = 0;
1899 file_hdr->file_time.nanosecs = 0;
1900
1901 if (abfd->flags & EXEC_P)
1902 abort ();
1903 else
1904 {
1905 file_hdr->entry_space = 0;
1906 file_hdr->entry_subspace = 0;
1907 file_hdr->entry_offset = 0;
1908 }
1909
1910 /* FIXME. I do not know if we ever need to put anything other
1911 than zero in this field. */
1912 file_hdr->presumed_dp = 0;
1913
1914 /* Now iterate over the sections translating information from
1915 BFD sections to SOM spaces/subspaces. */
1916
1917 for (section = abfd->sections; section != NULL; section = section->next)
1918 {
1919 /* Ignore anything which has not been marked as a space or
1920 subspace. */
1921 if (som_section_data (section)->is_space == 0
1922
1923 && som_section_data (section)->is_subspace == 0)
1924 continue;
1925
1926 if (som_section_data (section)->is_space)
1927 {
1928 /* Set space attributes. Note most attributes of SOM spaces
1929 are set based on the subspaces it contains. */
1930 som_section_data (section)->space_dict.loader_fix_index = -1;
1931 som_section_data (section)->space_dict.init_pointer_index = -1;
1932 }
1933 else
1934 {
1935 /* Set subspace attributes. Basic stuff is done here, additional
1936 attributes are filled in later as more information becomes
1937 available. */
1938 if (section->flags & SEC_IS_COMMON)
1939 {
1940 som_section_data (section)->subspace_dict.dup_common = 1;
1941 som_section_data (section)->subspace_dict.is_common = 1;
1942 }
1943
1944 if (section->flags & SEC_ALLOC)
1945 som_section_data (section)->subspace_dict.is_loadable = 1;
1946
1947 if (section->flags & SEC_CODE)
1948 som_section_data (section)->subspace_dict.code_only = 1;
1949
1950 som_section_data (section)->subspace_dict.subspace_start =
1951 section->vma;
1952 som_section_data (section)->subspace_dict.subspace_length =
1953 bfd_section_size (abfd, section);
1954 som_section_data (section)->subspace_dict.initialization_length =
1955 bfd_section_size (abfd, section);
1956 som_section_data (section)->subspace_dict.alignment =
1957 1 << section->alignment_power;
1958 }
1959 }
1960 return true;
1961 }
1962
1963 /* Count and return the number of spaces attached to the given BFD. */
1964
1965 static unsigned long
1966 som_count_spaces (abfd)
1967 bfd *abfd;
1968 {
1969 int count = 0;
1970 asection *section;
1971
1972 for (section = abfd->sections; section != NULL; section = section->next)
1973 count += som_section_data (section)->is_space;
1974
1975 return count;
1976 }
1977
1978 /* Count the number of subspaces attached to the given BFD. */
1979
1980 static unsigned long
1981 som_count_subspaces (abfd)
1982 bfd *abfd;
1983 {
1984 int count = 0;
1985 asection *section;
1986
1987 for (section = abfd->sections; section != NULL; section = section->next)
1988 count += som_section_data (section)->is_subspace;
1989
1990 return count;
1991 }
1992
1993 /* Return -1, 0, 1 indicating the relative ordering of sym1 and sym2.
1994
1995 We desire symbols to be ordered starting with the symbol with the
1996 highest relocation count down to the symbol with the lowest relocation
1997 count. Doing so compacts the relocation stream. */
1998
1999 static int
2000 compare_syms (sym1, sym2)
2001 asymbol **sym1;
2002 asymbol **sym2;
2003
2004 {
2005 unsigned int count1, count2;
2006
2007 /* Get relocation count for each symbol. Note that the count
2008 is stored in the udata pointer for section symbols! */
2009 if ((*sym1)->flags & BSF_SECTION_SYM)
2010 count1 = (int)(*sym1)->udata;
2011 else
2012 count1 = (*som_symbol_data ((*sym1)))->reloc_count;
2013
2014 if ((*sym2)->flags & BSF_SECTION_SYM)
2015 count2 = (int)(*sym2)->udata;
2016 else
2017 count2 = (*som_symbol_data ((*sym2)))->reloc_count;
2018
2019 /* Return the appropriate value. */
2020 if (count1 < count2)
2021 return 1;
2022 else if (count1 > count2)
2023 return -1;
2024 return 0;
2025 }
2026
2027 /* Perform various work in preparation for emitting the fixup stream. */
2028
2029 static void
2030 som_prep_for_fixups (abfd, syms, num_syms)
2031 bfd *abfd;
2032 asymbol **syms;
2033 unsigned long num_syms;
2034 {
2035 int i;
2036 asection *section;
2037
2038 /* Most SOM relocations involving a symbol have a length which is
2039 dependent on the index of the symbol. So symbols which are
2040 used often in relocations should have a small index. */
2041
2042 /* First initialize the counters for each symbol. */
2043 for (i = 0; i < num_syms; i++)
2044 {
2045 /* Handle a section symbol; these have no pointers back to the
2046 SOM symbol info. So we just use the pointer field (udata)
2047 to hold the relocation count.
2048
2049 FIXME. While we're here set the name of any section symbol
2050 to something which will not screw GDB. How do other formats
2051 deal with this?!? */
2052 if (som_symbol_data (syms[i]) == NULL)
2053 {
2054 syms[i]->flags |= BSF_SECTION_SYM;
2055 syms[i]->name = "L$0\002";
2056 syms[i]->udata = (PTR) 0;
2057 }
2058 else
2059 (*som_symbol_data (syms[i]))->reloc_count = 0;
2060 }
2061
2062 /* Now that the counters are initialized, make a weighted count
2063 of how often a given symbol is used in a relocation. */
2064 for (section = abfd->sections; section != NULL; section = section->next)
2065 {
2066 int i;
2067
2068 /* Does this section have any relocations? */
2069 if (section->reloc_count <= 0)
2070 continue;
2071
2072 /* Walk through each relocation for this section. */
2073 for (i = 1; i < section->reloc_count; i++)
2074 {
2075 arelent *reloc = section->orelocation[i];
2076 int scale;
2077
2078 /* If no symbol, then there is no counter to increase. */
2079 if (reloc->sym_ptr_ptr == NULL)
2080 continue;
2081
2082 /* Scaling to encourage symbols involved in R_DP_RELATIVE
2083 and R_CODE_ONE_SYMBOL relocations to come first. These
2084 two relocations have single byte versions if the symbol
2085 index is very small. */
2086 if (reloc->howto->type == R_DP_RELATIVE
2087 || reloc->howto->type == R_CODE_ONE_SYMBOL)
2088 scale = 2;
2089 else
2090 scale = 1;
2091
2092 /* Handle section symbols by ramming the count in the udata
2093 field. It will not be used and the count is very important
2094 for these symbols. */
2095 if ((*reloc->sym_ptr_ptr)->flags & BSF_SECTION_SYM)
2096 {
2097 (*reloc->sym_ptr_ptr)->udata =
2098 (PTR) ((int) (*reloc->sym_ptr_ptr)->udata + scale);
2099 continue;
2100 }
2101
2102 /* A normal symbol. Increment the count. */
2103 (*som_symbol_data ((*reloc->sym_ptr_ptr)))->reloc_count += scale;
2104 }
2105 }
2106
2107 /* Now sort the symbols. */
2108 qsort (syms, num_syms, sizeof (asymbol *), compare_syms);
2109
2110 /* Compute the symbol indexes, they will be needed by the relocation
2111 code. */
2112 for (i = 0; i < num_syms; i++)
2113 {
2114 /* A section symbol. Again, there is no pointer to backend symbol
2115 information, so we reuse (abuse) the udata field again. */
2116 if (syms[i]->flags & BSF_SECTION_SYM)
2117 syms[i]->udata = (PTR) i;
2118 else
2119 (*som_symbol_data (syms[i]))->index = i;
2120 }
2121 }
2122
2123 static boolean
2124 som_write_fixups (abfd, current_offset, total_reloc_sizep)
2125 bfd *abfd;
2126 unsigned long current_offset;
2127 unsigned int *total_reloc_sizep;
2128 {
2129 unsigned int i, j;
2130 unsigned char *tmp_space, *p;
2131 unsigned int total_reloc_size = 0;
2132 unsigned int subspace_reloc_size = 0;
2133 unsigned int num_spaces = obj_som_file_hdr (abfd)->space_total;
2134 asection *section = abfd->sections;
2135
2136 /* Get a chunk of memory that we can use as buffer space, then throw
2137 away. */
2138 tmp_space = alloca (SOM_TMP_BUFSIZE);
2139 bzero (tmp_space, SOM_TMP_BUFSIZE);
2140 p = tmp_space;
2141
2142 /* All the fixups for a particular subspace are emitted in a single
2143 stream. All the subspaces for a particular space are emitted
2144 as a single stream.
2145
2146 So, to get all the locations correct one must iterate through all the
2147 spaces, for each space iterate through its subspaces and output a
2148 fixups stream. */
2149 for (i = 0; i < num_spaces; i++)
2150 {
2151 asection *subsection;
2152
2153 /* Find a space. */
2154 while (som_section_data (section)->is_space == 0)
2155 section = section->next;
2156
2157 /* Now iterate through each of its subspaces. */
2158 for (subsection = abfd->sections;
2159 subsection != NULL;
2160 subsection = subsection->next)
2161 {
2162 int reloc_offset, current_rounding_mode;
2163
2164 /* Find a subspace of this space. */
2165 if (som_section_data (subsection)->is_subspace == 0
2166 || som_section_data (subsection)->containing_space != section)
2167 continue;
2168
2169 /* If this subspace had no relocations, then we're finished
2170 with it. */
2171 if (subsection->reloc_count <= 0)
2172 {
2173 som_section_data (subsection)->subspace_dict.fixup_request_index
2174 = -1;
2175 continue;
2176 }
2177
2178 /* This subspace has some relocations. Put the relocation stream
2179 index into the subspace record. */
2180 som_section_data (subsection)->subspace_dict.fixup_request_index
2181 = total_reloc_size;
2182
2183 /* To make life easier start over with a clean slate for
2184 each subspace. Seek to the start of the relocation stream
2185 for this subspace in preparation for writing out its fixup
2186 stream. */
2187 if (bfd_seek (abfd, current_offset + total_reloc_size, SEEK_SET) != 0)
2188 {
2189 bfd_error = system_call_error;
2190 return false;
2191 }
2192
2193 /* Buffer space has already been allocated. Just perform some
2194 initialization here. */
2195 p = tmp_space;
2196 subspace_reloc_size = 0;
2197 reloc_offset = 0;
2198 som_initialize_reloc_queue (reloc_queue);
2199 current_rounding_mode = R_N_MODE;
2200
2201 /* Translate each BFD relocation into one or more SOM
2202 relocations. */
2203 for (j = 0; j < subsection->reloc_count; j++)
2204 {
2205 arelent *bfd_reloc = subsection->orelocation[j];
2206 unsigned int skip;
2207 int sym_num;
2208
2209 /* Get the symbol number. Remember it's stored in a
2210 special place for section symbols. */
2211 if ((*bfd_reloc->sym_ptr_ptr)->flags & BSF_SECTION_SYM)
2212 sym_num = (int) (*bfd_reloc->sym_ptr_ptr)->udata;
2213 else
2214 sym_num = (*som_symbol_data ((*bfd_reloc->sym_ptr_ptr)))->index;
2215
2216 /* If there is not enough room for the next couple relocations,
2217 then dump the current buffer contents now. Also reinitialize
2218 the relocation queue.
2219
2220 FIXME. We assume here that no BFD relocation will expand
2221 to more than 100 bytes of SOM relocations. This should (?!?)
2222 be quite safe. */
2223 if (p - tmp_space + 100 > SOM_TMP_BUFSIZE)
2224 {
2225 if (bfd_write ((PTR) tmp_space, p - tmp_space, 1, abfd)
2226 != p - tmp_space)
2227 {
2228 bfd_error = system_call_error;
2229 return false;
2230 }
2231 p = tmp_space;
2232 som_initialize_reloc_queue (reloc_queue);
2233 }
2234
2235 /* Emit R_NO_RELOCATION fixups to map any bytes which were
2236 skipped. */
2237 skip = bfd_reloc->address - reloc_offset;
2238 p = som_reloc_skip (abfd, skip, p,
2239 &subspace_reloc_size, reloc_queue);
2240
2241 /* Update reloc_offset for the next iteration.
2242
2243 Many relocations do not consume input bytes. They
2244 are markers, or set state necessary to perform some
2245 later relocation. */
2246 switch (bfd_reloc->howto->type)
2247 {
2248 /* This only needs to handle relocations that may be
2249 made by hppa_som_gen_reloc. */
2250 case R_ENTRY:
2251 case R_EXIT:
2252 case R_N_MODE:
2253 case R_S_MODE:
2254 case R_D_MODE:
2255 case R_R_MODE:
2256 case R_FSEL:
2257 case R_LSEL:
2258 case R_RSEL:
2259 reloc_offset = bfd_reloc->address;
2260 break;
2261
2262 default:
2263 reloc_offset = bfd_reloc->address + 4;
2264 break;
2265 }
2266
2267 /* Now the actual relocation we care about. */
2268 switch (bfd_reloc->howto->type)
2269 {
2270 case R_PCREL_CALL:
2271 case R_ABS_CALL:
2272 p = som_reloc_call (abfd, p, &subspace_reloc_size,
2273 bfd_reloc, sym_num, reloc_queue);
2274 break;
2275
2276 case R_CODE_ONE_SYMBOL:
2277 case R_DP_RELATIVE:
2278 /* Account for any addend. */
2279 if (bfd_reloc->addend)
2280 p = som_reloc_addend (abfd, bfd_reloc->addend, p,
2281 &subspace_reloc_size, reloc_queue);
2282
2283 if (sym_num < 0x20)
2284 {
2285 bfd_put_8 (abfd, bfd_reloc->howto->type + sym_num, p);
2286 subspace_reloc_size += 1;
2287 p += 1;
2288 }
2289 else if (sym_num < 0x100)
2290 {
2291 bfd_put_8 (abfd, bfd_reloc->howto->type + 32, p);
2292 bfd_put_8 (abfd, sym_num, p + 1);
2293 p = try_prev_fixup (abfd, &subspace_reloc_size, p,
2294 2, reloc_queue);
2295 }
2296 else if (sym_num < 0x10000000)
2297 {
2298 bfd_put_8 (abfd, bfd_reloc->howto->type + 33, p);
2299 bfd_put_8 (abfd, sym_num >> 16, p + 1);
2300 bfd_put_16 (abfd, sym_num, p + 2);
2301 p = try_prev_fixup (abfd, &subspace_reloc_size,
2302 p, 4, reloc_queue);
2303 }
2304 else
2305 abort ();
2306 break;
2307
2308 case R_DATA_ONE_SYMBOL:
2309 case R_DATA_PLABEL:
2310 case R_CODE_PLABEL:
2311 case R_DLT_REL:
2312 /* Account for any addend. */
2313 if (bfd_reloc->addend)
2314 p = som_reloc_addend (abfd, bfd_reloc->addend, p,
2315 &subspace_reloc_size, reloc_queue);
2316
2317 if (sym_num < 0x100)
2318 {
2319 bfd_put_8 (abfd, bfd_reloc->howto->type, p);
2320 bfd_put_8 (abfd, sym_num, p + 1);
2321 p = try_prev_fixup (abfd, &subspace_reloc_size, p,
2322 2, reloc_queue);
2323 }
2324 else if (sym_num < 0x10000000)
2325 {
2326 bfd_put_8 (abfd, bfd_reloc->howto->type + 1, p);
2327 bfd_put_8 (abfd, sym_num >> 16, p + 1);
2328 bfd_put_16 (abfd, sym_num, p + 2);
2329 p = try_prev_fixup (abfd, &subspace_reloc_size,
2330 p, 4, reloc_queue);
2331 }
2332 else
2333 abort ();
2334 break;
2335
2336 case R_ENTRY:
2337 {
2338 int *descp
2339 = (int *) (*som_symbol_data ((*bfd_reloc->sym_ptr_ptr)))->unwind;
2340 bfd_put_8 (abfd, R_ENTRY, p);
2341 bfd_put_32 (abfd, descp[0], p + 1);
2342 bfd_put_32 (abfd, descp[1], p + 5);
2343 p = try_prev_fixup (abfd, &subspace_reloc_size,
2344 p, 9, reloc_queue);
2345 break;
2346 }
2347
2348 case R_EXIT:
2349 bfd_put_8 (abfd, R_EXIT, p);
2350 subspace_reloc_size += 1;
2351 p += 1;
2352 break;
2353
2354 case R_N_MODE:
2355 case R_S_MODE:
2356 case R_D_MODE:
2357 case R_R_MODE:
2358 /* If this relocation requests the current rounding
2359 mode, then it is redundant. */
2360 if (bfd_reloc->howto->type != current_rounding_mode)
2361 {
2362 bfd_put_8 (abfd, bfd_reloc->howto->type, p);
2363 subspace_reloc_size += 1;
2364 p += 1;
2365 current_rounding_mode = bfd_reloc->howto->type;
2366 }
2367 break;
2368
2369 case R_FSEL:
2370 case R_LSEL:
2371 case R_RSEL:
2372 bfd_put_8 (abfd, bfd_reloc->howto->type, p);
2373 subspace_reloc_size += 1;
2374 p += 1;
2375 break;
2376
2377 /* Put a "R_RESERVED" relocation in the stream if
2378 we hit something we do not understand. The linker
2379 will complain loudly if this ever happens. */
2380 default:
2381 bfd_put_8 (abfd, 0xff, p);
2382 subspace_reloc_size += 1;
2383 p += 1;
2384 break;
2385 }
2386 }
2387
2388 /* Last BFD relocation for a subspace has been processed.
2389 Map the rest of the subspace with R_NO_RELOCATION fixups. */
2390 p = som_reloc_skip (abfd, bfd_section_size (abfd, subsection)
2391 - reloc_offset,
2392 p, &subspace_reloc_size, reloc_queue);
2393
2394 /* Scribble out the relocations. */
2395 if (bfd_write ((PTR) tmp_space, p - tmp_space, 1, abfd)
2396 != p - tmp_space)
2397 {
2398 bfd_error = system_call_error;
2399 return false;
2400 }
2401 p = tmp_space;
2402
2403 total_reloc_size += subspace_reloc_size;
2404 som_section_data (subsection)->subspace_dict.fixup_request_quantity
2405 = subspace_reloc_size;
2406 }
2407 section = section->next;
2408 }
2409 *total_reloc_sizep = total_reloc_size;
2410 return true;
2411 }
2412
2413 /* Write out the space/subspace string table. */
2414
2415 static boolean
2416 som_write_space_strings (abfd, current_offset, string_sizep)
2417 bfd *abfd;
2418 unsigned long current_offset;
2419 unsigned int *string_sizep;
2420 {
2421 unsigned char *tmp_space, *p;
2422 unsigned int strings_size = 0;
2423 asection *section;
2424
2425 /* Get a chunk of memory that we can use as buffer space, then throw
2426 away. */
2427 tmp_space = alloca (SOM_TMP_BUFSIZE);
2428 bzero (tmp_space, SOM_TMP_BUFSIZE);
2429 p = tmp_space;
2430
2431 /* Seek to the start of the space strings in preparation for writing
2432 them out. */
2433 if (bfd_seek (abfd, current_offset, SEEK_SET) != 0)
2434 {
2435 bfd_error = system_call_error;
2436 return false;
2437 }
2438
2439 /* Walk through all the spaces and subspaces (order is not important)
2440 building up and writing string table entries for their names. */
2441 for (section = abfd->sections; section != NULL; section = section->next)
2442 {
2443 int length;
2444
2445 /* Only work with space/subspaces; avoid any other sections
2446 which might have been made (.text for example). */
2447 if (som_section_data (section)->is_space == 0
2448 && som_section_data (section)->is_subspace == 0)
2449 continue;
2450
2451 /* Get the length of the space/subspace name. */
2452 length = strlen (section->name);
2453
2454 /* If there is not enough room for the next entry, then dump the
2455 current buffer contents now. Each entry will take 4 bytes to
2456 hold the string length + the string itself + null terminator. */
2457 if (p - tmp_space + 5 + length > SOM_TMP_BUFSIZE)
2458 {
2459 if (bfd_write ((PTR) tmp_space, p - tmp_space, 1, abfd)
2460 != p - tmp_space)
2461 {
2462 bfd_error = system_call_error;
2463 return false;
2464 }
2465 /* Reset to beginning of the buffer space. */
2466 p = tmp_space;
2467 }
2468
2469 /* First element in a string table entry is the length of the
2470 string. Alignment issues are already handled. */
2471 bfd_put_32 (abfd, length, p);
2472 p += 4;
2473 strings_size += 4;
2474
2475 /* Record the index in the space/subspace records. */
2476 if (som_section_data (section)->is_space)
2477 som_section_data (section)->space_dict.name.n_strx = strings_size;
2478 else
2479 som_section_data (section)->subspace_dict.name.n_strx = strings_size;
2480
2481 /* Next comes the string itself + a null terminator. */
2482 strcpy (p, section->name);
2483 p += length + 1;
2484 strings_size += length + 1;
2485
2486 /* Always align up to the next word boundary. */
2487 while (strings_size % 4)
2488 {
2489 bfd_put_8 (abfd, 0, p);
2490 p++;
2491 strings_size++;
2492 }
2493 }
2494
2495 /* Done with the space/subspace strings. Write out any information
2496 contained in a partial block. */
2497 if (bfd_write ((PTR) tmp_space, p - tmp_space, 1, abfd) != p - tmp_space)
2498 {
2499 bfd_error = system_call_error;
2500 return false;
2501 }
2502 *string_sizep = strings_size;
2503 return true;
2504 }
2505
2506 /* Write out the symbol string table. */
2507
2508 static boolean
2509 som_write_symbol_strings (abfd, current_offset, syms, num_syms, string_sizep)
2510 bfd *abfd;
2511 unsigned long current_offset;
2512 asymbol **syms;
2513 unsigned int num_syms;
2514 unsigned int *string_sizep;
2515 {
2516 unsigned int i;
2517 unsigned char *tmp_space, *p;
2518 unsigned int strings_size = 0;
2519
2520 /* Get a chunk of memory that we can use as buffer space, then throw
2521 away. */
2522 tmp_space = alloca (SOM_TMP_BUFSIZE);
2523 bzero (tmp_space, SOM_TMP_BUFSIZE);
2524 p = tmp_space;
2525
2526 /* Seek to the start of the space strings in preparation for writing
2527 them out. */
2528 if (bfd_seek (abfd, current_offset, SEEK_SET) != 0)
2529 {
2530 bfd_error = system_call_error;
2531 return false;
2532 }
2533
2534 for (i = 0; i < num_syms; i++)
2535 {
2536 int length = strlen (syms[i]->name);
2537
2538 /* If there is not enough room for the next entry, then dump the
2539 current buffer contents now. */
2540 if (p - tmp_space + 5 + length > SOM_TMP_BUFSIZE)
2541 {
2542 if (bfd_write ((PTR) tmp_space, p - tmp_space, 1, abfd)
2543 != p - tmp_space)
2544 {
2545 bfd_error = system_call_error;
2546 return false;
2547 }
2548 /* Reset to beginning of the buffer space. */
2549 p = tmp_space;
2550 }
2551
2552 /* First element in a string table entry is the length of the
2553 string. This must always be 4 byte aligned. This is also
2554 an appropriate time to fill in the string index field in the
2555 symbol table entry. */
2556 bfd_put_32 (abfd, length, p);
2557 strings_size += 4;
2558 p += 4;
2559
2560 /* Next comes the string itself + a null terminator. */
2561 strcpy (p, syms[i]->name);
2562
2563 /* ACK. FIXME. */
2564 syms[i]->name = (char *)strings_size;
2565 p += length + 1;
2566 strings_size += length + 1;
2567
2568 /* Always align up to the next word boundary. */
2569 while (strings_size % 4)
2570 {
2571 bfd_put_8 (abfd, 0, p);
2572 strings_size++;
2573 p++;
2574 }
2575 }
2576
2577 /* Scribble out any partial block. */
2578 if (bfd_write ((PTR) tmp_space, p - tmp_space, 1, abfd) != p - tmp_space)
2579 {
2580 bfd_error = system_call_error;
2581 return false;
2582 }
2583
2584 *string_sizep = strings_size;
2585 return true;
2586 }
2587
2588 /* Compute variable information to be placed in the SOM headers,
2589 space/subspace dictionaries, relocation streams, etc. Begin
2590 writing parts of the object file. */
2591
2592 static boolean
2593 som_begin_writing (abfd)
2594 bfd *abfd;
2595 {
2596 unsigned long current_offset = 0;
2597 int strings_size = 0;
2598 unsigned int total_reloc_size = 0;
2599 unsigned long num_spaces, num_subspaces, num_syms, i;
2600 asection *section;
2601 asymbol **syms = bfd_get_outsymbols (abfd);
2602 unsigned int total_subspaces = 0;
2603
2604 /* The file header will always be first in an object file,
2605 everything else can be in random locations. To keep things
2606 "simple" BFD will lay out the object file in the manner suggested
2607 by the PRO ABI for PA-RISC Systems. */
2608
2609 /* Before any output can really begin offsets for all the major
2610 portions of the object file must be computed. So, starting
2611 with the initial file header compute (and sometimes write)
2612 each portion of the object file. */
2613
2614 /* Make room for the file header, it's contents are not complete
2615 yet, so it can not be written at this time. */
2616 current_offset += sizeof (struct header);
2617
2618 /* Any auxiliary headers will follow the file header. Right now
2619 we support only the copyright and version headers. */
2620 obj_som_file_hdr (abfd)->aux_header_location = current_offset;
2621 obj_som_file_hdr (abfd)->aux_header_size = 0;
2622 if (obj_som_version_hdr (abfd) != NULL)
2623 {
2624 unsigned int len;
2625
2626 bfd_seek (abfd, current_offset, SEEK_SET);
2627
2628 /* Write the aux_id structure and the string length. */
2629 len = sizeof (struct aux_id) + sizeof (unsigned int);
2630 obj_som_file_hdr (abfd)->aux_header_size += len;
2631 current_offset += len;
2632 if (bfd_write ((PTR) obj_som_version_hdr (abfd), len, 1, abfd) != len)
2633 {
2634 bfd_error = system_call_error;
2635 return false;
2636 }
2637
2638 /* Write the version string. */
2639 len = obj_som_version_hdr (abfd)->header_id.length - sizeof (int);
2640 obj_som_file_hdr (abfd)->aux_header_size += len;
2641 current_offset += len;
2642 if (bfd_write ((PTR) obj_som_version_hdr (abfd)->user_string,
2643 len, 1, abfd) != len)
2644 {
2645 bfd_error = system_call_error;
2646 return false;
2647 }
2648 }
2649
2650 if (obj_som_copyright_hdr (abfd) != NULL)
2651 {
2652 unsigned int len;
2653
2654 bfd_seek (abfd, current_offset, SEEK_SET);
2655
2656 /* Write the aux_id structure and the string length. */
2657 len = sizeof (struct aux_id) + sizeof (unsigned int);
2658 obj_som_file_hdr (abfd)->aux_header_size += len;
2659 current_offset += len;
2660 if (bfd_write ((PTR) obj_som_copyright_hdr (abfd), len, 1, abfd) != len)
2661 {
2662 bfd_error = system_call_error;
2663 return false;
2664 }
2665
2666 /* Write the copyright string. */
2667 len = obj_som_copyright_hdr (abfd)->header_id.length - sizeof (int);
2668 obj_som_file_hdr (abfd)->aux_header_size += len;
2669 current_offset += len;
2670 if (bfd_write ((PTR) obj_som_copyright_hdr (abfd)->copyright,
2671 len, 1, abfd) != len)
2672 {
2673 bfd_error = system_call_error;
2674 return false;
2675 }
2676 }
2677
2678 /* Next comes the initialization pointers; we have no initialization
2679 pointers, so current offset does not change. */
2680 obj_som_file_hdr (abfd)->init_array_location = current_offset;
2681 obj_som_file_hdr (abfd)->init_array_total = 0;
2682
2683 /* Next are the space records. These are fixed length records.
2684
2685 Count the number of spaces to determine how much room is needed
2686 in the object file for the space records.
2687
2688 The names of the spaces are stored in a separate string table,
2689 and the index for each space into the string table is computed
2690 below. Therefore, it is not possible to write the space headers
2691 at this time. */
2692 num_spaces = som_count_spaces (abfd);
2693 obj_som_file_hdr (abfd)->space_location = current_offset;
2694 obj_som_file_hdr (abfd)->space_total = num_spaces;
2695 current_offset += num_spaces * sizeof (struct space_dictionary_record);
2696
2697 /* Next are the subspace records. These are fixed length records.
2698
2699 Count the number of subspaes to determine how much room is needed
2700 in the object file for the subspace records.
2701
2702 A variety if fields in the subspace record are still unknown at
2703 this time (index into string table, fixup stream location/size, etc). */
2704 num_subspaces = som_count_subspaces (abfd);
2705 obj_som_file_hdr (abfd)->subspace_location = current_offset;
2706 obj_som_file_hdr (abfd)->subspace_total = num_subspaces;
2707 current_offset += num_subspaces * sizeof (struct subspace_dictionary_record);
2708
2709 /* Next is the string table for the space/subspace names. We will
2710 build and write the string table on the fly. At the same time
2711 we will fill in the space/subspace name index fields. */
2712
2713 /* The string table needs to be aligned on a word boundary. */
2714 if (current_offset % 4)
2715 current_offset += (4 - (current_offset % 4));
2716
2717 /* Mark the offset of the space/subspace string table in the
2718 file header. */
2719 obj_som_file_hdr (abfd)->space_strings_location = current_offset;
2720
2721 /* Scribble out the space strings. */
2722 if (som_write_space_strings (abfd, current_offset, &strings_size) == false)
2723 return false;
2724
2725 /* Record total string table size in the header and update the
2726 current offset. */
2727 obj_som_file_hdr (abfd)->space_strings_size = strings_size;
2728 current_offset += strings_size;
2729
2730 /* Next is the symbol table. These are fixed length records.
2731
2732 Count the number of symbols to determine how much room is needed
2733 in the object file for the symbol table.
2734
2735 The names of the symbols are stored in a separate string table,
2736 and the index for each symbol name into the string table is computed
2737 below. Therefore, it is not possible to write the symobl table
2738 at this time. */
2739 num_syms = bfd_get_symcount (abfd);
2740 obj_som_file_hdr (abfd)->symbol_location = current_offset;
2741 obj_som_file_hdr (abfd)->symbol_total = num_syms;
2742 current_offset += num_syms * sizeof (struct symbol_dictionary_record);
2743
2744 /* Do prep work before handling fixups. */
2745 som_prep_for_fixups (abfd, syms, num_syms);
2746
2747 /* Next comes the fixup stream which starts on a word boundary. */
2748 if (current_offset % 4)
2749 current_offset += (4 - (current_offset % 4));
2750 obj_som_file_hdr (abfd)->fixup_request_location = current_offset;
2751
2752 /* Write the fixups and update fields in subspace headers which
2753 relate to the fixup stream. */
2754 if (som_write_fixups (abfd, current_offset, &total_reloc_size) == false)
2755 return false;
2756
2757 /* Record the total size of the fixup stream in the file header. */
2758 obj_som_file_hdr (abfd)->fixup_request_total = total_reloc_size;
2759 current_offset += total_reloc_size;
2760
2761 /* Next are the symbol strings.
2762 Align them to a word boundary. */
2763 if (current_offset % 4)
2764 current_offset += (4 - (current_offset % 4));
2765 obj_som_file_hdr (abfd)->symbol_strings_location = current_offset;
2766
2767 /* Scribble out the symbol strings. */
2768 if (som_write_symbol_strings (abfd, current_offset, syms,
2769 num_syms, &strings_size)
2770 == false)
2771 return false;
2772
2773 /* Record total string table size in header and update the
2774 current offset. */
2775 obj_som_file_hdr (abfd)->symbol_strings_size = strings_size;
2776 current_offset += strings_size;
2777
2778 /* Next is the compiler records. We do not use these. */
2779 obj_som_file_hdr (abfd)->compiler_location = current_offset;
2780 obj_som_file_hdr (abfd)->compiler_total = 0;
2781
2782 /* Now compute the file positions for the loadable subspaces. */
2783
2784 section = abfd->sections;
2785 for (i = 0; i < num_spaces; i++)
2786 {
2787 asection *subsection;
2788
2789 /* Find a space. */
2790 while (som_section_data (section)->is_space == 0)
2791 section = section->next;
2792
2793 /* Now look for all its subspaces. */
2794 for (subsection = abfd->sections;
2795 subsection != NULL;
2796 subsection = subsection->next)
2797 {
2798
2799 if (som_section_data (subsection)->is_subspace == 0
2800 || som_section_data (subsection)->containing_space != section
2801 || (subsection->flags & SEC_ALLOC) == 0)
2802 continue;
2803
2804 som_section_data (subsection)->subspace_index = total_subspaces++;
2805 /* This is real data to be loaded from the file. */
2806 if (subsection->flags & SEC_LOAD)
2807 {
2808 som_section_data (subsection)->subspace_dict.file_loc_init_value
2809 = current_offset;
2810 section->filepos = current_offset;
2811 current_offset += bfd_section_size (abfd, subsection);
2812 }
2813 /* Looks like uninitialized data. */
2814 else
2815 {
2816 som_section_data (subsection)->subspace_dict.file_loc_init_value
2817 = 0;
2818 som_section_data (subsection)->subspace_dict.
2819 initialization_length = 0;
2820 }
2821 }
2822 /* Goto the next section. */
2823 section = section->next;
2824 }
2825
2826 /* Finally compute the file positions for unloadable subspaces. */
2827
2828 obj_som_file_hdr (abfd)->unloadable_sp_location = current_offset;
2829 section = abfd->sections;
2830 for (i = 0; i < num_spaces; i++)
2831 {
2832 asection *subsection;
2833
2834 /* Find a space. */
2835 while (som_section_data (section)->is_space == 0)
2836 section = section->next;
2837
2838 /* Now look for all its subspaces. */
2839 for (subsection = abfd->sections;
2840 subsection != NULL;
2841 subsection = subsection->next)
2842 {
2843
2844 if (som_section_data (subsection)->is_subspace == 0
2845 || som_section_data (subsection)->containing_space != section
2846 || (subsection->flags & SEC_ALLOC) != 0)
2847 continue;
2848
2849 som_section_data (subsection)->subspace_index = total_subspaces++;
2850 /* This is real data to be loaded from the file. */
2851 if ((subsection->flags & SEC_LOAD) == 0)
2852 {
2853 som_section_data (subsection)->subspace_dict.file_loc_init_value
2854 = current_offset;
2855 section->filepos = current_offset;
2856 current_offset += bfd_section_size (abfd, subsection);
2857 }
2858 /* Looks like uninitialized data. */
2859 else
2860 {
2861 som_section_data (subsection)->subspace_dict.file_loc_init_value
2862 = 0;
2863 som_section_data (subsection)->subspace_dict.
2864 initialization_length = bfd_section_size (abfd, subsection);
2865 }
2866 }
2867 /* Goto the next section. */
2868 section = section->next;
2869 }
2870
2871 obj_som_file_hdr (abfd)->unloadable_sp_size
2872 = current_offset - obj_som_file_hdr (abfd)->unloadable_sp_location;
2873
2874 /* Loader fixups are not supported in any way shape or form. */
2875 obj_som_file_hdr (abfd)->loader_fixup_location = 0;
2876 obj_som_file_hdr (abfd)->loader_fixup_total = 0;
2877
2878 /* Done. Store the total size of the SOM. */
2879 obj_som_file_hdr (abfd)->som_length = current_offset;
2880 return true;
2881 }
2882
2883 /* Finally, scribble out the various headers to the disk. */
2884
2885 static boolean
2886 som_write_headers (abfd)
2887 bfd *abfd;
2888 {
2889 int num_spaces = som_count_spaces (abfd);
2890 int i;
2891 int subspace_index = 0;
2892 file_ptr location;
2893 asection *section;
2894
2895 /* Subspaces are written first so that we can set up information
2896 about them in their containing spaces as the subspace is written. */
2897
2898 /* Seek to the start of the subspace dictionary records. */
2899 location = obj_som_file_hdr (abfd)->subspace_location;
2900 bfd_seek (abfd, location, SEEK_SET);
2901 section = abfd->sections;
2902 /* Now for each loadable space write out records for its subspaces. */
2903 for (i = 0; i < num_spaces; i++)
2904 {
2905 asection *subsection;
2906
2907 /* Find a space. */
2908 while (som_section_data (section)->is_space == 0)
2909 section = section->next;
2910
2911 /* Now look for all its subspaces. */
2912 for (subsection = abfd->sections;
2913 subsection != NULL;
2914 subsection = subsection->next)
2915 {
2916
2917 /* Skip any section which does not correspond to a space
2918 or subspace. Or does not have SEC_ALLOC set (and therefore
2919 has no real bits on the disk). */
2920 if (som_section_data (subsection)->is_subspace == 0
2921 || som_section_data (subsection)->containing_space != section
2922 || (subsection->flags & SEC_ALLOC) == 0)
2923 continue;
2924
2925 /* If this is the first subspace for this space, then save
2926 the index of the subspace in its containing space. Also
2927 set "is_loadable" in the containing space. */
2928
2929 if (som_section_data (section)->space_dict.subspace_quantity == 0)
2930 {
2931 som_section_data (section)->space_dict.is_loadable = 1;
2932 som_section_data (section)->space_dict.subspace_index
2933 = subspace_index;
2934 }
2935
2936 /* Increment the number of subspaces seen and the number of
2937 subspaces contained within the current space. */
2938 subspace_index++;
2939 som_section_data (section)->space_dict.subspace_quantity++;
2940
2941 /* Mark the index of the current space within the subspace's
2942 dictionary record. */
2943 som_section_data (subsection)->subspace_dict.space_index = i;
2944
2945 /* Dump the current subspace header. */
2946 if (bfd_write ((PTR) &som_section_data (subsection)->subspace_dict,
2947 sizeof (struct subspace_dictionary_record), 1, abfd)
2948 != sizeof (struct subspace_dictionary_record))
2949 {
2950 bfd_error = system_call_error;
2951 return false;
2952 }
2953 }
2954 /* Goto the next section. */
2955 section = section->next;
2956 }
2957
2958 /* Now repeat the process for unloadable subspaces. */
2959 section = abfd->sections;
2960 /* Now for each space write out records for its subspaces. */
2961 for (i = 0; i < num_spaces; i++)
2962 {
2963 asection *subsection;
2964
2965 /* Find a space. */
2966 while (som_section_data (section)->is_space == 0)
2967 section = section->next;
2968
2969 /* Now look for all its subspaces. */
2970 for (subsection = abfd->sections;
2971 subsection != NULL;
2972 subsection = subsection->next)
2973 {
2974
2975 /* Skip any section which does not correspond to a space or
2976 subspace, or which SEC_ALLOC set (and therefore handled
2977 in the loadable spaces/subspaces code above. */
2978
2979 if (som_section_data (subsection)->is_subspace == 0
2980 || som_section_data (subsection)->containing_space != section
2981 || (subsection->flags & SEC_ALLOC) != 0)
2982 continue;
2983
2984 /* If this is the first subspace for this space, then save
2985 the index of the subspace in its containing space. Clear
2986 "is_loadable". */
2987
2988 if (som_section_data (section)->space_dict.subspace_quantity == 0)
2989 {
2990 som_section_data (section)->space_dict.is_loadable = 0;
2991 som_section_data (section)->space_dict.subspace_index
2992 = subspace_index;
2993 }
2994
2995 /* Increment the number of subspaces seen and the number of
2996 subspaces contained within the current space. */
2997 som_section_data (section)->space_dict.subspace_quantity++;
2998 subspace_index++;
2999
3000 /* Mark the index of the current space within the subspace's
3001 dictionary record. */
3002 som_section_data (subsection)->subspace_dict.space_index = i;
3003
3004 /* Dump this subspace header. */
3005 if (bfd_write ((PTR) &som_section_data (subsection)->subspace_dict,
3006 sizeof (struct subspace_dictionary_record), 1, abfd)
3007 != sizeof (struct subspace_dictionary_record))
3008 {
3009 bfd_error = system_call_error;
3010 return false;
3011 }
3012 }
3013 /* Goto the next section. */
3014 section = section->next;
3015 }
3016
3017 /* All the subspace dictiondary records are written, and all the
3018 fields are set up in the space dictionary records.
3019
3020 Seek to the right location and start writing the space
3021 dictionary records. */
3022 location = obj_som_file_hdr (abfd)->space_location;
3023 bfd_seek (abfd, location, SEEK_SET);
3024
3025 section = abfd->sections;
3026 for (i = 0; i < num_spaces; i++)
3027 {
3028
3029 /* Find a space. */
3030 while (som_section_data (section)->is_space == 0)
3031 section = section->next;
3032
3033 /* Dump its header */
3034 if (bfd_write ((PTR) &som_section_data (section)->space_dict,
3035 sizeof (struct space_dictionary_record), 1, abfd)
3036 != sizeof (struct space_dictionary_record))
3037 {
3038 bfd_error = system_call_error;
3039 return false;
3040 }
3041
3042 /* Goto the next section. */
3043 section = section->next;
3044 }
3045
3046 /* Only thing left to do is write out the file header. It is always
3047 at location zero. Seek there and write it. */
3048 bfd_seek (abfd, (file_ptr) 0, SEEK_SET);
3049 if (bfd_write ((PTR) obj_som_file_hdr (abfd),
3050 sizeof (struct header), 1, abfd)
3051 != sizeof (struct header))
3052 {
3053 bfd_error = system_call_error;
3054 return false;
3055 }
3056 return true;
3057 }
3058
3059 /* Compute and return the checksum for a SOM file header. */
3060
3061 static unsigned long
3062 som_compute_checksum (abfd)
3063 bfd *abfd;
3064 {
3065 unsigned long checksum, count, i;
3066 unsigned long *buffer = (unsigned long *) obj_som_file_hdr (abfd);
3067
3068 checksum = 0;
3069 count = sizeof (struct header) / sizeof (unsigned long);
3070 for (i = 0; i < count; i++)
3071 checksum ^= *(buffer + i);
3072
3073 return checksum;
3074 }
3075
3076 /* Build and write, in one big chunk, the entire symbol table for
3077 this BFD. */
3078
3079 static boolean
3080 som_build_and_write_symbol_table (abfd)
3081 bfd *abfd;
3082 {
3083 unsigned int num_syms = bfd_get_symcount (abfd);
3084 file_ptr symtab_location = obj_som_file_hdr (abfd)->symbol_location;
3085 asymbol **bfd_syms = bfd_get_outsymbols (abfd);
3086 struct symbol_dictionary_record *som_symtab;
3087 int i, symtab_size;
3088
3089 /* Compute total symbol table size and allocate a chunk of memory
3090 to hold the symbol table as we build it. */
3091 symtab_size = num_syms * sizeof (struct symbol_dictionary_record);
3092 som_symtab = (struct symbol_dictionary_record *) alloca (symtab_size);
3093 bzero (som_symtab, symtab_size);
3094
3095 /* Walk over each symbol. */
3096 for (i = 0; i < num_syms; i++)
3097 {
3098 /* This is really an index into the symbol strings table.
3099 By the time we get here, the index has already been
3100 computed and stored into the name field in the BFD symbol. */
3101 som_symtab[i].name.n_strx = (int) bfd_syms[i]->name;
3102
3103 /* The HP SOM linker requires detailed type information about
3104 all symbols (including undefined symbols!). Unfortunately,
3105 the type specified in an import/export statement does not
3106 always match what the linker wants. Severe braindamage. */
3107
3108 /* Section symbols will not have a SOM symbol type assigned to
3109 them yet. Assign all section symbols type ST_DATA. */
3110 if (bfd_syms[i]->flags & BSF_SECTION_SYM)
3111 som_symtab[i].symbol_type = ST_DATA;
3112 else
3113 {
3114 /* Common symbols must have scope SS_UNSAT and type
3115 ST_STORAGE or the linker will choke. */
3116 if (bfd_syms[i]->section == &bfd_com_section)
3117 {
3118 som_symtab[i].symbol_scope = SS_UNSAT;
3119 som_symtab[i].symbol_type = ST_STORAGE;
3120 }
3121
3122 /* It is possible to have a symbol without an associated
3123 type. This happens if the user imported the symbol
3124 without a type and the symbol was never defined
3125 locally. If BSF_FUNCTION is set for this symbol, then
3126 assign it type ST_CODE (the HP linker requires undefined
3127 external functions to have type ST_CODE rather than ST_ENTRY. */
3128 else if (((*som_symbol_data (bfd_syms[i]))->som_type
3129 == SYMBOL_TYPE_UNKNOWN)
3130 && (bfd_syms[i]->section == &bfd_und_section)
3131 && (bfd_syms[i]->flags & BSF_FUNCTION))
3132 som_symtab[i].symbol_type = ST_CODE;
3133
3134 /* Handle function symbols which were defined in this file.
3135 They should have type ST_ENTRY. Also retrieve the argument
3136 relocation bits from the SOM backend information. */
3137 else if (((*som_symbol_data (bfd_syms[i]))->som_type
3138 == SYMBOL_TYPE_ENTRY)
3139 || (((*som_symbol_data (bfd_syms[i]))->som_type
3140 == SYMBOL_TYPE_CODE)
3141 && (bfd_syms[i]->flags & BSF_FUNCTION))
3142 || (((*som_symbol_data (bfd_syms[i]))->som_type
3143 == SYMBOL_TYPE_UNKNOWN)
3144 && (bfd_syms[i]->flags & BSF_FUNCTION)))
3145 {
3146 som_symtab[i].symbol_type = ST_ENTRY;
3147 som_symtab[i].arg_reloc
3148 = (*som_symbol_data (bfd_syms[i]))->tc_data.hppa_arg_reloc;
3149 }
3150
3151 /* If the type is unknown at this point, it should be
3152 ST_DATA (functions were handled as special cases above). */
3153 else if ((*som_symbol_data (bfd_syms[i]))->som_type
3154 == SYMBOL_TYPE_UNKNOWN)
3155 som_symtab[i].symbol_type = ST_DATA;
3156
3157 /* From now on it's a very simple mapping. */
3158 else if ((*som_symbol_data (bfd_syms[i]))->som_type
3159 == SYMBOL_TYPE_ABSOLUTE)
3160 som_symtab[i].symbol_type = ST_ABSOLUTE;
3161 else if ((*som_symbol_data (bfd_syms[i]))->som_type
3162 == SYMBOL_TYPE_CODE)
3163 som_symtab[i].symbol_type = ST_CODE;
3164 else if ((*som_symbol_data (bfd_syms[i]))->som_type
3165 == SYMBOL_TYPE_DATA)
3166 som_symtab[i].symbol_type = ST_DATA;
3167 else if ((*som_symbol_data (bfd_syms[i]))->som_type
3168 == SYMBOL_TYPE_MILLICODE)
3169 som_symtab[i].symbol_type = ST_MILLICODE;
3170 else if ((*som_symbol_data (bfd_syms[i]))->som_type
3171 == SYMBOL_TYPE_PLABEL)
3172 som_symtab[i].symbol_type = ST_PLABEL;
3173 else if ((*som_symbol_data (bfd_syms[i]))->som_type
3174 == SYMBOL_TYPE_PRI_PROG)
3175 som_symtab[i].symbol_type = ST_PRI_PROG;
3176 else if ((*som_symbol_data (bfd_syms[i]))->som_type
3177 == SYMBOL_TYPE_SEC_PROG)
3178 som_symtab[i].symbol_type = ST_SEC_PROG;
3179 }
3180
3181 /* Now handle the symbol's scope. Exported data which is not
3182 in the common section has scope SS_UNIVERSAL. Note scope
3183 of common symbols was handled earlier! */
3184 if (bfd_syms[i]->flags & BSF_EXPORT
3185 && bfd_syms[i]->section != &bfd_com_section)
3186 som_symtab[i].symbol_scope = SS_UNIVERSAL;
3187 /* Any undefined symbol at this point has a scope SS_UNSAT. */
3188 else if (bfd_syms[i]->section == &bfd_und_section)
3189 som_symtab[i].symbol_scope = SS_UNSAT;
3190 /* Anything else which is not in the common section has scope
3191 SS_LOCAL. */
3192 else if (bfd_syms[i]->section != &bfd_com_section)
3193 som_symtab[i].symbol_scope = SS_LOCAL;
3194
3195 /* Now set the symbol_info field. It has no real meaning
3196 for undefined or common symbols, but the HP linker will
3197 choke if it's not set to some "reasonable" value. We
3198 use zero as a reasonable value. */
3199 if (bfd_syms[i]->section == &bfd_com_section
3200 || bfd_syms[i]->section == &bfd_und_section)
3201 som_symtab[i].symbol_info = 0;
3202 /* For all other symbols, the symbol_info field contains the
3203 subspace index of the space this symbol is contained in. */
3204 else
3205 som_symtab[i].symbol_info
3206 = som_section_data (bfd_syms[i]->section)->subspace_index;
3207
3208 /* Set the symbol's value. */
3209 som_symtab[i].symbol_value
3210 = bfd_syms[i]->value + bfd_syms[i]->section->vma;
3211 }
3212
3213 /* Egad. Everything is ready, seek to the right location and
3214 scribble out the symbol table. */
3215 if (bfd_seek (abfd, symtab_location, SEEK_SET) != 0)
3216 {
3217 bfd_error = system_call_error;
3218 return false;
3219 }
3220
3221 if (bfd_write ((PTR) som_symtab, symtab_size, 1, abfd) != symtab_size)
3222 {
3223 bfd_error = system_call_error;
3224 return false;
3225 }
3226 return true;
3227 }
3228
3229 /* Write an object in SOM format. */
3230
3231 static boolean
3232 som_write_object_contents (abfd)
3233 bfd *abfd;
3234 {
3235 if (abfd->output_has_begun == false)
3236 {
3237 /* Set up fixed parts of the file, space, and subspace headers.
3238 Notify the world that output has begun. */
3239 som_prep_headers (abfd);
3240 abfd->output_has_begun = true;
3241 /* Start writing the object file. This include all the string
3242 tables, fixup streams, and other portions of the object file. */
3243 som_begin_writing (abfd);
3244 }
3245
3246 /* Now that the symbol table information is complete, build and
3247 write the symbol table. */
3248 if (som_build_and_write_symbol_table (abfd) == false)
3249 return false;
3250
3251 /* Compute the checksum for the file header just before writing
3252 the header to disk. */
3253 obj_som_file_hdr (abfd)->checksum = som_compute_checksum (abfd);
3254 return (som_write_headers (abfd));
3255 }
3256
3257 \f
3258 /* Read and save the string table associated with the given BFD. */
3259
3260 static boolean
3261 som_slurp_string_table (abfd)
3262 bfd *abfd;
3263 {
3264 char *stringtab;
3265
3266 /* Use the saved version if its available. */
3267 if (obj_som_stringtab (abfd) != NULL)
3268 return true;
3269
3270 /* Allocate and read in the string table. */
3271 stringtab = bfd_zalloc (abfd, obj_som_stringtab_size (abfd));
3272 if (stringtab == NULL)
3273 {
3274 bfd_error = no_memory;
3275 return false;
3276 }
3277
3278 if (bfd_seek (abfd, obj_som_str_filepos (abfd), SEEK_SET) < 0)
3279 {
3280 bfd_error = system_call_error;
3281 return false;
3282 }
3283
3284 if (bfd_read (stringtab, obj_som_stringtab_size (abfd), 1, abfd)
3285 != obj_som_stringtab_size (abfd))
3286 {
3287 bfd_error = system_call_error;
3288 return false;
3289 }
3290
3291 /* Save our results and return success. */
3292 obj_som_stringtab (abfd) = stringtab;
3293 return true;
3294 }
3295
3296 /* Return the amount of data (in bytes) required to hold the symbol
3297 table for this object. */
3298
3299 static unsigned int
3300 som_get_symtab_upper_bound (abfd)
3301 bfd *abfd;
3302 {
3303 if (!som_slurp_symbol_table (abfd))
3304 return 0;
3305
3306 return (bfd_get_symcount (abfd) + 1) * (sizeof (som_symbol_type *));
3307 }
3308
3309 /* Convert from a SOM subspace index to a BFD section. */
3310
3311 static asection *
3312 som_section_from_subspace_index (abfd, index)
3313 bfd *abfd;
3314 unsigned int index;
3315 {
3316 asection *section;
3317
3318 for (section = abfd->sections; section != NULL; section = section->next)
3319 if (som_section_data (section)->subspace_index == index)
3320 return section;
3321
3322 /* Should never happen. */
3323 abort();
3324 }
3325
3326 /* Read and save the symbol table associated with the given BFD. */
3327
3328 static unsigned int
3329 som_slurp_symbol_table (abfd)
3330 bfd *abfd;
3331 {
3332 int symbol_count = bfd_get_symcount (abfd);
3333 int symsize = sizeof (struct symbol_dictionary_record);
3334 char *stringtab;
3335 struct symbol_dictionary_record *buf, *bufp, *endbufp;
3336 som_symbol_type *sym, *symbase;
3337
3338 /* Return saved value if it exists. */
3339 if (obj_som_symtab (abfd) != NULL)
3340 return true;
3341
3342 /* Sanity checking. Make sure there are some symbols and that
3343 we can read the string table too. */
3344 if (symbol_count == 0)
3345 {
3346 bfd_error = no_symbols;
3347 return false;
3348 }
3349
3350 if (!som_slurp_string_table (abfd))
3351 return false;
3352
3353 stringtab = obj_som_stringtab (abfd);
3354
3355 symbase = (som_symbol_type *)
3356 bfd_zalloc (abfd, symbol_count * sizeof (som_symbol_type));
3357 if (symbase == NULL)
3358 {
3359 bfd_error = no_memory;
3360 return false;
3361 }
3362
3363 /* Read in the external SOM representation. */
3364 buf = alloca (symbol_count * symsize);
3365 if (buf == NULL)
3366 {
3367 bfd_error = no_memory;
3368 return false;
3369 }
3370 if (bfd_seek (abfd, obj_som_sym_filepos (abfd), SEEK_SET) < 0)
3371 {
3372 bfd_error = system_call_error;
3373 return false;
3374 }
3375 if (bfd_read (buf, symbol_count * symsize, 1, abfd)
3376 != symbol_count * symsize)
3377 {
3378 bfd_error = no_symbols;
3379 return (false);
3380 }
3381
3382 /* Iterate over all the symbols and internalize them. */
3383 endbufp = buf + symbol_count;
3384 for (bufp = buf, sym = symbase; bufp < endbufp; ++bufp)
3385 {
3386
3387 /* I don't think we care about these. */
3388 if (bufp->symbol_type == ST_SYM_EXT
3389 || bufp->symbol_type == ST_ARG_EXT)
3390 continue;
3391
3392 /* Some reasonable defaults. */
3393 sym->symbol.the_bfd = abfd;
3394 sym->symbol.name = bufp->name.n_strx + stringtab;
3395 sym->symbol.value = bufp->symbol_value;
3396 sym->symbol.section = 0;
3397 sym->symbol.flags = 0;
3398
3399 switch (bufp->symbol_type)
3400 {
3401 case ST_ENTRY:
3402 case ST_PRI_PROG:
3403 case ST_SEC_PROG:
3404 case ST_MILLICODE:
3405 sym->symbol.flags |= BSF_FUNCTION;
3406 sym->symbol.value &= ~0x3;
3407 break;
3408
3409 case ST_STUB:
3410 case ST_CODE:
3411 sym->symbol.value &= ~0x3;
3412
3413 default:
3414 break;
3415 }
3416
3417 /* Handle scoping and section information. */
3418 switch (bufp->symbol_scope)
3419 {
3420 /* symbol_info field is undefined for SS_EXTERNAL and SS_UNSAT symbols,
3421 so the section associated with this symbol can't be known. */
3422 case SS_EXTERNAL:
3423 case SS_UNSAT:
3424 if (bufp->symbol_type != ST_STORAGE)
3425 sym->symbol.section = &bfd_und_section;
3426 else
3427 sym->symbol.section = &bfd_com_section;
3428 sym->symbol.flags |= (BSF_EXPORT | BSF_GLOBAL);
3429 break;
3430
3431 case SS_UNIVERSAL:
3432 sym->symbol.flags |= (BSF_EXPORT | BSF_GLOBAL);
3433 sym->symbol.section
3434 = som_section_from_subspace_index (abfd, bufp->symbol_info);
3435 sym->symbol.value -= sym->symbol.section->vma;
3436 break;
3437
3438 #if 0
3439 /* SS_GLOBAL and SS_LOCAL are two names for the same thing.
3440 Sound dumb? It is. */
3441 case SS_GLOBAL:
3442 #endif
3443 case SS_LOCAL:
3444 sym->symbol.flags |= BSF_LOCAL;
3445 sym->symbol.section
3446 = som_section_from_subspace_index (abfd, bufp->symbol_info);
3447 sym->symbol.value -= sym->symbol.section->vma;
3448 break;
3449 }
3450
3451 /* Mark symbols left around by the debugger. */
3452 if (strlen (sym->symbol.name) >= 2
3453 && sym->symbol.name[0] == 'L'
3454 && (sym->symbol.name[1] == '$' || sym->symbol.name[2] == '$'
3455 || sym->symbol.name[3] == '$'))
3456 sym->symbol.flags |= BSF_DEBUGGING;
3457
3458 /* Note increment at bottom of loop, since we skip some symbols
3459 we can not include it as part of the for statement. */
3460 sym++;
3461 }
3462
3463 /* Save our results and return success. */
3464 obj_som_symtab (abfd) = symbase;
3465 return (true);
3466 }
3467
3468 /* Canonicalize a SOM symbol table. Return the number of entries
3469 in the symbol table. */
3470
3471 static unsigned int
3472 som_get_symtab (abfd, location)
3473 bfd *abfd;
3474 asymbol **location;
3475 {
3476 int i;
3477 som_symbol_type *symbase;
3478
3479 if (!som_slurp_symbol_table (abfd))
3480 return 0;
3481
3482 i = bfd_get_symcount (abfd);
3483 symbase = obj_som_symtab (abfd);
3484
3485 for (; i > 0; i--, location++, symbase++)
3486 *location = &symbase->symbol;
3487
3488 /* Final null pointer. */
3489 *location = 0;
3490 return (bfd_get_symcount (abfd));
3491 }
3492
3493 /* Make a SOM symbol. There is nothing special to do here. */
3494
3495 static asymbol *
3496 som_make_empty_symbol (abfd)
3497 bfd *abfd;
3498 {
3499 som_symbol_type *new =
3500 (som_symbol_type *) bfd_zalloc (abfd, sizeof (som_symbol_type));
3501 if (new == NULL)
3502 {
3503 bfd_error = no_memory;
3504 return 0;
3505 }
3506 new->symbol.the_bfd = abfd;
3507
3508 return &new->symbol;
3509 }
3510
3511 /* Print symbol information. */
3512
3513 static void
3514 som_print_symbol (ignore_abfd, afile, symbol, how)
3515 bfd *ignore_abfd;
3516 PTR afile;
3517 asymbol *symbol;
3518 bfd_print_symbol_type how;
3519 {
3520 FILE *file = (FILE *) afile;
3521 switch (how)
3522 {
3523 case bfd_print_symbol_name:
3524 fprintf (file, "%s", symbol->name);
3525 break;
3526 case bfd_print_symbol_more:
3527 fprintf (file, "som ");
3528 fprintf_vma (file, symbol->value);
3529 fprintf (file, " %lx", (long) symbol->flags);
3530 break;
3531 case bfd_print_symbol_all:
3532 {
3533 CONST char *section_name;
3534 section_name = symbol->section ? symbol->section->name : "(*none*)";
3535 bfd_print_symbol_vandf ((PTR) file, symbol);
3536 fprintf (file, " %s\t%s", section_name, symbol->name);
3537 break;
3538 }
3539 }
3540 }
3541
3542 /* Count or process variable-length SOM fixup records.
3543
3544 To avoid code duplication we use this code both to compute the number
3545 of relocations requested by a stream, and to internalize the stream.
3546
3547 When computing the number of relocations requested by a stream the
3548 variables rptr, section, and symbols have no meaning.
3549
3550 Return the number of relocations requested by the fixup stream. When
3551 not just counting
3552
3553 This needs at least two or three more passes to get it cleaned up. */
3554
3555 static unsigned int
3556 som_set_reloc_info (fixup, end, internal_relocs, section, symbols, just_count)
3557 unsigned char *fixup;
3558 unsigned int end;
3559 arelent *internal_relocs;
3560 asection *section;
3561 asymbol **symbols;
3562 boolean just_count;
3563 {
3564 unsigned int op, varname;
3565 unsigned char *end_fixups = &fixup[end];
3566 const struct fixup_format *fp;
3567 char *cp;
3568 unsigned char *save_fixup;
3569 int variables[26], stack[20], c, v, count, prev_fixup, *sp;
3570 const int *subop;
3571 arelent *rptr= internal_relocs;
3572 unsigned int offset = just_count ? 0 : section->vma;
3573
3574 #define var(c) variables[(c) - 'A']
3575 #define push(v) (*sp++ = (v))
3576 #define pop() (*--sp)
3577 #define emptystack() (sp == stack)
3578
3579 som_initialize_reloc_queue (reloc_queue);
3580 bzero (variables, sizeof (variables));
3581 bzero (stack, sizeof (stack));
3582 count = 0;
3583 prev_fixup = 0;
3584 sp = stack;
3585
3586 while (fixup < end_fixups)
3587 {
3588
3589 /* Save pointer to the start of this fixup. We'll use
3590 it later to determine if it is necessary to put this fixup
3591 on the queue. */
3592 save_fixup = fixup;
3593
3594 /* Get the fixup code and its associated format. */
3595 op = *fixup++;
3596 fp = &som_fixup_formats[op];
3597
3598 /* Handle a request for a previous fixup. */
3599 if (*fp->format == 'P')
3600 {
3601 /* Get pointer to the beginning of the prev fixup, move
3602 the repeated fixup to the head of the queue. */
3603 fixup = reloc_queue[fp->D].reloc;
3604 som_reloc_queue_fix (reloc_queue, fp->D);
3605 prev_fixup = 1;
3606
3607 /* Get the fixup code and its associated format. */
3608 op = *fixup++;
3609 fp = &som_fixup_formats[op];
3610 }
3611
3612 /* If we are not just counting, set some reasonable defaults. */
3613 if (! just_count)
3614 {
3615 rptr->address = offset;
3616 rptr->howto = &som_hppa_howto_table[op];
3617 rptr->addend = 0;
3618 rptr->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;
3619 }
3620
3621 /* Set default input length to 0. Get the opcode class index
3622 into D. */
3623 var ('L') = 0;
3624 var ('D') = fp->D;
3625
3626 /* Get the opcode format. */
3627 cp = fp->format;
3628
3629 /* Process the format string. Parsing happens in two phases,
3630 parse RHS, then assign to LHS. Repeat until no more
3631 characters in the format string. */
3632 while (*cp)
3633 {
3634 /* The variable this pass is going to compute a value for. */
3635 varname = *cp++;
3636
3637 /* Start processing RHS. Continue until a NULL or '=' is found. */
3638 do
3639 {
3640 c = *cp++;
3641
3642 /* If this is a variable, push it on the stack. */
3643 if (isupper (c))
3644 push (var (c));
3645
3646 /* If this is a lower case letter, then it represents
3647 additional data from the fixup stream to be pushed onto
3648 the stack. */
3649 else if (islower (c))
3650 {
3651 for (v = 0; c > 'a'; --c)
3652 v = (v << 8) | *fixup++;
3653 push (v);
3654 }
3655
3656 /* A decimal constant. Push it on the stack. */
3657 else if (isdigit (c))
3658 {
3659 v = c - '0';
3660 while (isdigit (*cp))
3661 v = (v * 10) + (*cp++ - '0');
3662 push (v);
3663 }
3664 else
3665
3666 /* An operator. Pop two two values from the stack and
3667 use them as operands to the given operation. Push
3668 the result of the operation back on the stack. */
3669 switch (c)
3670 {
3671 case '+':
3672 v = pop ();
3673 v += pop ();
3674 push (v);
3675 break;
3676 case '*':
3677 v = pop ();
3678 v *= pop ();
3679 push (v);
3680 break;
3681 case '<':
3682 v = pop ();
3683 v = pop () << v;
3684 push (v);
3685 break;
3686 default:
3687 abort ();
3688 }
3689 }
3690 while (*cp && *cp != '=');
3691
3692 /* Move over the equal operator. */
3693 cp++;
3694
3695 /* Pop the RHS off the stack. */
3696 c = pop ();
3697
3698 /* Perform the assignment. */
3699 var (varname) = c;
3700
3701 /* Handle side effects. and special 'O' stack cases. */
3702 switch (varname)
3703 {
3704 /* Consume some bytes from the input space. */
3705 case 'L':
3706 offset += c;
3707 break;
3708 /* A symbol to use in the relocation. Make a note
3709 of this if we are not just counting. */
3710 case 'S':
3711 if (! just_count)
3712 rptr->sym_ptr_ptr = &symbols[c];
3713 break;
3714 /* Handle the linker expression stack. */
3715 case 'O':
3716 switch (op)
3717 {
3718 case R_COMP1:
3719 subop = comp1_opcodes;
3720 break;
3721 case R_COMP2:
3722 subop = comp2_opcodes;
3723 break;
3724 case R_COMP3:
3725 subop = comp3_opcodes;
3726 break;
3727 default:
3728 abort ();
3729 }
3730 while (*subop <= (unsigned char) c)
3731 ++subop;
3732 --subop;
3733 break;
3734 default:
3735 break;
3736 }
3737 }
3738
3739 /* If we used a previous fixup, clean up after it. */
3740 if (prev_fixup)
3741 {
3742 fixup = save_fixup + 1;
3743 prev_fixup = 0;
3744 }
3745 /* Queue it. */
3746 else if (fixup > save_fixup + 1)
3747 som_reloc_queue_insert (save_fixup, fixup - save_fixup, reloc_queue);
3748
3749 /* We do not pass R_DATA_OVERRIDE or R_NO_RELOCATION
3750 fixups to BFD. */
3751 if (som_hppa_howto_table[op].type != R_DATA_OVERRIDE
3752 && som_hppa_howto_table[op].type != R_NO_RELOCATION)
3753 {
3754 /* Done with a single reloction. Loop back to the top. */
3755 if (! just_count)
3756 {
3757 rptr->addend = var ('V');
3758 rptr++;
3759 }
3760 count++;
3761 /* Now that we've handled a "full" relocation, reset
3762 some state. */
3763 bzero (variables, sizeof (variables));
3764 bzero (stack, sizeof (stack));
3765 }
3766 }
3767 return count;
3768
3769 #undef var
3770 #undef push
3771 #undef pop
3772 #undef emptystack
3773 }
3774
3775 /* Read in the relocs (aka fixups in SOM terms) for a section.
3776
3777 som_get_reloc_upper_bound calls this routine with JUST_COUNT
3778 set to true to indicate it only needs a count of the number
3779 of actual relocations. */
3780
3781 static boolean
3782 som_slurp_reloc_table (abfd, section, symbols, just_count)
3783 bfd *abfd;
3784 asection *section;
3785 asymbol **symbols;
3786 boolean just_count;
3787 {
3788 char *external_relocs;
3789 unsigned int fixup_stream_size;
3790 arelent *internal_relocs;
3791 unsigned int num_relocs;
3792
3793 fixup_stream_size = som_section_data (section)->reloc_size;
3794 /* If there were no relocations, then there is nothing to do. */
3795 if (section->reloc_count == 0)
3796 return true;
3797
3798 /* If reloc_count is -1, then the relocation stream has not been
3799 parsed. We must do so now to know how many relocations exist. */
3800 if (section->reloc_count == -1)
3801 {
3802 external_relocs = (char *) bfd_zalloc (abfd, fixup_stream_size);
3803 if (external_relocs == (char *) NULL)
3804 {
3805 bfd_error = no_memory;
3806 return false;
3807 }
3808 /* Read in the external forms. */
3809 if (bfd_seek (abfd,
3810 obj_som_reloc_filepos (abfd) + section->rel_filepos,
3811 SEEK_SET)
3812 != 0)
3813 {
3814 bfd_error = system_call_error;
3815 return false;
3816 }
3817 if (bfd_read (external_relocs, 1, fixup_stream_size, abfd)
3818 != fixup_stream_size)
3819 {
3820 bfd_error = system_call_error;
3821 return false;
3822 }
3823 /* Let callers know how many relocations found.
3824 also save the relocation stream as we will
3825 need it again. */
3826 section->reloc_count = som_set_reloc_info (external_relocs,
3827 fixup_stream_size,
3828 NULL, NULL, NULL, true);
3829
3830 som_section_data (section)->reloc_stream = external_relocs;
3831 }
3832
3833 /* If the caller only wanted a count, then return now. */
3834 if (just_count)
3835 return true;
3836
3837 num_relocs = section->reloc_count;
3838 external_relocs = som_section_data (section)->reloc_stream;
3839 /* Return saved information about the relocations if it is available. */
3840 if (section->relocation != (arelent *) NULL)
3841 return true;
3842
3843 internal_relocs = (arelent *) bfd_zalloc (abfd,
3844 num_relocs * sizeof (arelent));
3845 if (internal_relocs == (arelent *) NULL)
3846 {
3847 bfd_error = no_memory;
3848 return false;
3849 }
3850
3851 /* Process and internalize the relocations. */
3852 som_set_reloc_info (external_relocs, fixup_stream_size,
3853 internal_relocs, section, symbols, false);
3854
3855 /* Save our results and return success. */
3856 section->relocation = internal_relocs;
3857 return (true);
3858 }
3859
3860 /* Return the number of bytes required to store the relocation
3861 information associated with the given section. */
3862
3863 static unsigned int
3864 som_get_reloc_upper_bound (abfd, asect)
3865 bfd *abfd;
3866 sec_ptr asect;
3867 {
3868 /* If section has relocations, then read in the relocation stream
3869 and parse it to determine how many relocations exist. */
3870 if (asect->flags & SEC_RELOC)
3871 {
3872 if (som_slurp_reloc_table (abfd, asect, NULL, true))
3873 return (asect->reloc_count + 1) * sizeof (arelent);
3874 }
3875 /* Either there are no relocations or an error occurred while
3876 reading and parsing the relocation stream. */
3877 return 0;
3878 }
3879
3880 /* Convert relocations from SOM (external) form into BFD internal
3881 form. Return the number of relocations. */
3882
3883 static unsigned int
3884 som_canonicalize_reloc (abfd, section, relptr, symbols)
3885 bfd *abfd;
3886 sec_ptr section;
3887 arelent **relptr;
3888 asymbol **symbols;
3889 {
3890 arelent *tblptr;
3891 int count;
3892
3893 if (som_slurp_reloc_table (abfd, section, symbols, false) == false)
3894 return 0;
3895
3896 count = section->reloc_count;
3897 tblptr = section->relocation;
3898 if (tblptr == (arelent *) NULL)
3899 return 0;
3900
3901 while (count--)
3902 *relptr++ = tblptr++;
3903
3904 *relptr = (arelent *) NULL;
3905 return section->reloc_count;
3906 }
3907
3908 extern bfd_target som_vec;
3909
3910 /* A hook to set up object file dependent section information. */
3911
3912 static boolean
3913 som_new_section_hook (abfd, newsect)
3914 bfd *abfd;
3915 asection *newsect;
3916 {
3917 newsect->used_by_bfd =
3918 (PTR) bfd_zalloc (abfd, sizeof (struct som_section_data_struct));
3919 if (!newsect->used_by_bfd)
3920 {
3921 bfd_error = no_memory;
3922 return false;
3923 }
3924 newsect->alignment_power = 3;
3925
3926 /* Initialize the subspace_index field to -1 so that it does
3927 not match a subspace with an index of 0. */
3928 som_section_data (newsect)->subspace_index = -1;
3929
3930 /* We allow more than three sections internally */
3931 return true;
3932 }
3933
3934 /* Set backend info for sections which can not be described
3935 in the BFD data structures. */
3936
3937 void
3938 bfd_som_set_section_attributes (section, defined, private, sort_key, spnum)
3939 asection *section;
3940 int defined;
3941 int private;
3942 unsigned char sort_key;
3943 int spnum;
3944 {
3945 struct space_dictionary_record *space_dict;
3946
3947 som_section_data (section)->is_space = 1;
3948 space_dict = &som_section_data (section)->space_dict;
3949 space_dict->is_defined = defined;
3950 space_dict->is_private = private;
3951 space_dict->sort_key = sort_key;
3952 space_dict->space_number = spnum;
3953 }
3954
3955 /* Set backend info for subsections which can not be described
3956 in the BFD data structures. */
3957
3958 void
3959 bfd_som_set_subsection_attributes (section, container, access,
3960 sort_key, quadrant)
3961 asection *section;
3962 asection *container;
3963 int access;
3964 unsigned int sort_key;
3965 int quadrant;
3966 {
3967 struct subspace_dictionary_record *subspace_dict;
3968 som_section_data (section)->is_subspace = 1;
3969 subspace_dict = &som_section_data (section)->subspace_dict;
3970 subspace_dict->access_control_bits = access;
3971 subspace_dict->sort_key = sort_key;
3972 subspace_dict->quadrant = quadrant;
3973 som_section_data (section)->containing_space = container;
3974 }
3975
3976 /* Set the full SOM symbol type. SOM needs far more symbol information
3977 than any other object file format I'm aware of. It is mandatory
3978 to be able to know if a symbol is an entry point, millicode, data,
3979 code, absolute, storage request, or procedure label. If you get
3980 the symbol type wrong your program will not link. */
3981
3982 void
3983 bfd_som_set_symbol_type (symbol, type)
3984 asymbol *symbol;
3985 unsigned int type;
3986 {
3987 (*som_symbol_data (symbol))->som_type = type;
3988 }
3989
3990 /* Attach 64bits of unwind information to a symbol (which hopefully
3991 is a function of some kind!). It would be better to keep this
3992 in the R_ENTRY relocation, but there is not enough space. */
3993
3994 void
3995 bfd_som_attach_unwind_info (symbol, unwind_desc)
3996 asymbol *symbol;
3997 char *unwind_desc;
3998 {
3999 (*som_symbol_data (symbol))->unwind = unwind_desc;
4000 }
4001
4002 /* Attach an auxiliary header to the BFD backend so that it may be
4003 written into the object file. */
4004 void
4005 bfd_som_attach_aux_hdr (abfd, type, string)
4006 bfd *abfd;
4007 int type;
4008 char *string;
4009 {
4010 if (type == VERSION_AUX_ID)
4011 {
4012 int len = strlen (string);
4013 int pad = 0;
4014
4015 if (len % 4)
4016 pad = (4 - (len % 4));
4017 obj_som_version_hdr (abfd) = (struct user_string_aux_hdr *)
4018 bfd_zalloc (abfd, sizeof (struct aux_id)
4019 + sizeof (unsigned int) + len + pad);
4020 if (!obj_som_version_hdr (abfd))
4021 {
4022 bfd_error = no_memory;
4023 abort(); /* FIXME */
4024 }
4025 obj_som_version_hdr (abfd)->header_id.type = VERSION_AUX_ID;
4026 obj_som_version_hdr (abfd)->header_id.length = len + pad;
4027 obj_som_version_hdr (abfd)->header_id.length += sizeof (int);
4028 obj_som_version_hdr (abfd)->string_length = len;
4029 strncpy (obj_som_version_hdr (abfd)->user_string, string, len);
4030 }
4031 else if (type == COPYRIGHT_AUX_ID)
4032 {
4033 int len = strlen (string);
4034 int pad = 0;
4035
4036 if (len % 4)
4037 pad = (4 - (len % 4));
4038 obj_som_copyright_hdr (abfd) = (struct copyright_aux_hdr *)
4039 bfd_zalloc (abfd, sizeof (struct aux_id)
4040 + sizeof (unsigned int) + len + pad);
4041 if (!obj_som_copyright_hdr (abfd))
4042 {
4043 bfd_error = no_error;
4044 abort(); /* FIXME */
4045 }
4046 obj_som_copyright_hdr (abfd)->header_id.type = COPYRIGHT_AUX_ID;
4047 obj_som_copyright_hdr (abfd)->header_id.length = len + pad;
4048 obj_som_copyright_hdr (abfd)->header_id.length += sizeof (int);
4049 obj_som_copyright_hdr (abfd)->string_length = len;
4050 strcpy (obj_som_copyright_hdr (abfd)->copyright, string);
4051 }
4052 else
4053 abort ();
4054 }
4055
4056 static boolean
4057 som_set_section_contents (abfd, section, location, offset, count)
4058 bfd *abfd;
4059 sec_ptr section;
4060 PTR location;
4061 file_ptr offset;
4062 bfd_size_type count;
4063 {
4064 if (abfd->output_has_begun == false)
4065 {
4066 /* Set up fixed parts of the file, space, and subspace headers.
4067 Notify the world that output has begun. */
4068 som_prep_headers (abfd);
4069 abfd->output_has_begun = true;
4070 /* Start writing the object file. This include all the string
4071 tables, fixup streams, and other portions of the object file. */
4072 som_begin_writing (abfd);
4073 }
4074
4075 /* Only write subspaces which have "real" contents (eg. the contents
4076 are not generated at run time by the OS). */
4077 if (som_section_data (section)->is_subspace != 1
4078 || ((section->flags & (SEC_LOAD | SEC_DEBUGGING)) == 0))
4079 return true;
4080
4081 /* Seek to the proper offset within the object file and write the
4082 data. */
4083 offset += som_section_data (section)->subspace_dict.file_loc_init_value;
4084 if (bfd_seek (abfd, offset, SEEK_SET) == -1)
4085 {
4086 bfd_error = system_call_error;
4087 return false;
4088 }
4089
4090 if (bfd_write ((PTR) location, 1, count, abfd) != count)
4091 {
4092 bfd_error = system_call_error;
4093 return false;
4094 }
4095 return true;
4096 }
4097
4098 static boolean
4099 som_set_arch_mach (abfd, arch, machine)
4100 bfd *abfd;
4101 enum bfd_architecture arch;
4102 unsigned long machine;
4103 {
4104 /* Allow any architecture to be supported by the SOM backend */
4105 return bfd_default_set_arch_mach (abfd, arch, machine);
4106 }
4107
4108 static boolean
4109 som_find_nearest_line (abfd, section, symbols, offset, filename_ptr,
4110 functionname_ptr, line_ptr)
4111 bfd *abfd;
4112 asection *section;
4113 asymbol **symbols;
4114 bfd_vma offset;
4115 CONST char **filename_ptr;
4116 CONST char **functionname_ptr;
4117 unsigned int *line_ptr;
4118 {
4119 fprintf (stderr, "som_find_nearest_line unimplemented\n");
4120 fflush (stderr);
4121 abort ();
4122 return (false);
4123 }
4124
4125 static int
4126 som_sizeof_headers (abfd, reloc)
4127 bfd *abfd;
4128 boolean reloc;
4129 {
4130 fprintf (stderr, "som_sizeof_headers unimplemented\n");
4131 fflush (stderr);
4132 abort ();
4133 return (0);
4134 }
4135
4136 /* Return the single-character symbol type corresponding to
4137 SOM section S, or '?' for an unknown SOM section. */
4138
4139 static char
4140 som_section_type (s)
4141 const char *s;
4142 {
4143 const struct section_to_type *t;
4144
4145 for (t = &stt[0]; t->section; t++)
4146 if (!strcmp (s, t->section))
4147 return t->type;
4148 return '?';
4149 }
4150
4151 static int
4152 som_decode_symclass (symbol)
4153 asymbol *symbol;
4154 {
4155 char c;
4156
4157 if (bfd_is_com_section (symbol->section))
4158 return 'C';
4159 if (symbol->section == &bfd_und_section)
4160 return 'U';
4161 if (symbol->section == &bfd_ind_section)
4162 return 'I';
4163 if (!(symbol->flags & (BSF_GLOBAL|BSF_LOCAL)))
4164 return '?';
4165
4166 if (symbol->section == &bfd_abs_section)
4167 c = 'a';
4168 else if (symbol->section)
4169 c = som_section_type (symbol->section->name);
4170 else
4171 return '?';
4172 if (symbol->flags & BSF_GLOBAL)
4173 c = toupper (c);
4174 return c;
4175 }
4176
4177 /* Return information about SOM symbol SYMBOL in RET. */
4178
4179 static void
4180 som_get_symbol_info (ignore_abfd, symbol, ret)
4181 bfd *ignore_abfd;
4182 asymbol *symbol;
4183 symbol_info *ret;
4184 {
4185 ret->type = som_decode_symclass (symbol);
4186 if (ret->type != 'U')
4187 ret->value = symbol->value+symbol->section->vma;
4188 else
4189 ret->value = 0;
4190 ret->name = symbol->name;
4191 }
4192
4193 /* End of miscellaneous support functions. */
4194
4195 #define som_bfd_debug_info_start bfd_void
4196 #define som_bfd_debug_info_end bfd_void
4197 #define som_bfd_debug_info_accumulate (PROTO(void,(*),(bfd*, struct sec *))) bfd_void
4198
4199 #define som_openr_next_archived_file bfd_generic_openr_next_archived_file
4200 #define som_generic_stat_arch_elt bfd_generic_stat_arch_elt
4201 #define som_slurp_armap bfd_false
4202 #define som_slurp_extended_name_table _bfd_slurp_extended_name_table
4203 #define som_truncate_arname (void (*)())bfd_nullvoidptr
4204 #define som_write_armap 0
4205
4206 #define som_get_lineno (struct lineno_cache_entry *(*)())bfd_nullvoidptr
4207 #define som_close_and_cleanup bfd_generic_close_and_cleanup
4208 #define som_get_section_contents bfd_generic_get_section_contents
4209
4210 #define som_bfd_get_relocated_section_contents \
4211 bfd_generic_get_relocated_section_contents
4212 #define som_bfd_relax_section bfd_generic_relax_section
4213 #define som_bfd_make_debug_symbol \
4214 ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
4215 #define som_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
4216 #define som_bfd_link_add_symbols _bfd_generic_link_add_symbols
4217 #define som_bfd_final_link _bfd_generic_final_link
4218
4219 /* Core file support is in the hpux-core backend. */
4220 #define som_core_file_failing_command _bfd_dummy_core_file_failing_command
4221 #define som_core_file_failing_signal _bfd_dummy_core_file_failing_signal
4222 #define som_core_file_matches_executable_p _bfd_dummy_core_file_matches_executable_p
4223
4224 bfd_target som_vec =
4225 {
4226 "som", /* name */
4227 bfd_target_som_flavour,
4228 true, /* target byte order */
4229 true, /* target headers byte order */
4230 (HAS_RELOC | EXEC_P | /* object flags */
4231 HAS_LINENO | HAS_DEBUG |
4232 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
4233 (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
4234 | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
4235
4236 /* leading_symbol_char: is the first char of a user symbol
4237 predictable, and if so what is it */
4238 0,
4239 ' ', /* ar_pad_char */
4240 16, /* ar_max_namelen */
4241 3, /* minimum alignment */
4242 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
4243 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
4244 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
4245 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
4246 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
4247 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
4248 {_bfd_dummy_target,
4249 som_object_p, /* bfd_check_format */
4250 bfd_generic_archive_p,
4251 _bfd_dummy_target
4252 },
4253 {
4254 bfd_false,
4255 som_mkobject,
4256 _bfd_generic_mkarchive,
4257 bfd_false
4258 },
4259 {
4260 bfd_false,
4261 som_write_object_contents,
4262 _bfd_write_archive_contents,
4263 bfd_false,
4264 },
4265 #undef som
4266 JUMP_TABLE (som),
4267 (PTR) 0
4268 };
4269
4270 #endif /* HOST_HPPAHPUX || HOST_HPPABSD || HOST_HPPAOSF */