PR 11225
[binutils.git] / bfd / coff-alpha.c
blob8a8f6203abb4cdf2f9916d97cbeca40a81d5e398
1 /* BFD back-end for ALPHA Extended-Coff files.
2 Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3 2003, 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
4 Modified from coff-mips.c by Steve Chamberlain <sac@cygnus.com> and
5 Ian Lance Taylor <ian@cygnus.com>.
7 This file is part of BFD, the Binary File Descriptor library.
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 3 of the License, or
12 (at your option) any later version.
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.
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., 51 Franklin Street - Fifth Floor, Boston,
22 MA 02110-1301, USA. */
24 #include "sysdep.h"
25 #include "bfd.h"
26 #include "bfdlink.h"
27 #include "libbfd.h"
28 #include "coff/internal.h"
29 #include "coff/sym.h"
30 #include "coff/symconst.h"
31 #include "coff/ecoff.h"
32 #include "coff/alpha.h"
33 #include "aout/ar.h"
34 #include "libcoff.h"
35 #include "libecoff.h"
37 /* Prototypes for static functions. */
39 static const bfd_target *alpha_ecoff_object_p
40 PARAMS ((bfd *));
41 static bfd_boolean alpha_ecoff_bad_format_hook
42 PARAMS ((bfd *abfd, PTR filehdr));
43 static PTR alpha_ecoff_mkobject_hook
44 PARAMS ((bfd *, PTR filehdr, PTR aouthdr));
45 static void alpha_ecoff_swap_reloc_in
46 PARAMS ((bfd *, PTR, struct internal_reloc *));
47 static void alpha_ecoff_swap_reloc_out
48 PARAMS ((bfd *, const struct internal_reloc *, PTR));
49 static void alpha_adjust_reloc_in
50 PARAMS ((bfd *, const struct internal_reloc *, arelent *));
51 static void alpha_adjust_reloc_out
52 PARAMS ((bfd *, const arelent *, struct internal_reloc *));
53 static reloc_howto_type *alpha_bfd_reloc_type_lookup
54 PARAMS ((bfd *, bfd_reloc_code_real_type));
55 static bfd_byte *alpha_ecoff_get_relocated_section_contents
56 PARAMS ((bfd *abfd, struct bfd_link_info *, struct bfd_link_order *,
57 bfd_byte *data, bfd_boolean relocatable, asymbol **symbols));
58 static bfd_vma alpha_convert_external_reloc
59 PARAMS ((bfd *, struct bfd_link_info *, bfd *, struct external_reloc *,
60 struct ecoff_link_hash_entry *));
61 static bfd_boolean alpha_relocate_section
62 PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, PTR));
63 static bfd_boolean alpha_adjust_headers
64 PARAMS ((bfd *, struct internal_filehdr *, struct internal_aouthdr *));
65 static PTR alpha_ecoff_read_ar_hdr
66 PARAMS ((bfd *));
67 static bfd *alpha_ecoff_get_elt_at_filepos
68 PARAMS ((bfd *, file_ptr));
69 static bfd *alpha_ecoff_openr_next_archived_file
70 PARAMS ((bfd *, bfd *));
71 static bfd *alpha_ecoff_get_elt_at_index
72 PARAMS ((bfd *, symindex));
74 /* ECOFF has COFF sections, but the debugging information is stored in
75 a completely different format. ECOFF targets use some of the
76 swapping routines from coffswap.h, and some of the generic COFF
77 routines in coffgen.c, but, unlike the real COFF targets, do not
78 use coffcode.h itself.
80 Get the generic COFF swapping routines, except for the reloc,
81 symbol, and lineno ones. Give them ecoff names. Define some
82 accessor macros for the large sizes used for Alpha ECOFF. */
84 #define GET_FILEHDR_SYMPTR H_GET_64
85 #define PUT_FILEHDR_SYMPTR H_PUT_64
86 #define GET_AOUTHDR_TSIZE H_GET_64
87 #define PUT_AOUTHDR_TSIZE H_PUT_64
88 #define GET_AOUTHDR_DSIZE H_GET_64
89 #define PUT_AOUTHDR_DSIZE H_PUT_64
90 #define GET_AOUTHDR_BSIZE H_GET_64
91 #define PUT_AOUTHDR_BSIZE H_PUT_64
92 #define GET_AOUTHDR_ENTRY H_GET_64
93 #define PUT_AOUTHDR_ENTRY H_PUT_64
94 #define GET_AOUTHDR_TEXT_START H_GET_64
95 #define PUT_AOUTHDR_TEXT_START H_PUT_64
96 #define GET_AOUTHDR_DATA_START H_GET_64
97 #define PUT_AOUTHDR_DATA_START H_PUT_64
98 #define GET_SCNHDR_PADDR H_GET_64
99 #define PUT_SCNHDR_PADDR H_PUT_64
100 #define GET_SCNHDR_VADDR H_GET_64
101 #define PUT_SCNHDR_VADDR H_PUT_64
102 #define GET_SCNHDR_SIZE H_GET_64
103 #define PUT_SCNHDR_SIZE H_PUT_64
104 #define GET_SCNHDR_SCNPTR H_GET_64
105 #define PUT_SCNHDR_SCNPTR H_PUT_64
106 #define GET_SCNHDR_RELPTR H_GET_64
107 #define PUT_SCNHDR_RELPTR H_PUT_64
108 #define GET_SCNHDR_LNNOPTR H_GET_64
109 #define PUT_SCNHDR_LNNOPTR H_PUT_64
111 #define ALPHAECOFF
113 #define NO_COFF_RELOCS
114 #define NO_COFF_SYMBOLS
115 #define NO_COFF_LINENOS
116 #define coff_swap_filehdr_in alpha_ecoff_swap_filehdr_in
117 #define coff_swap_filehdr_out alpha_ecoff_swap_filehdr_out
118 #define coff_swap_aouthdr_in alpha_ecoff_swap_aouthdr_in
119 #define coff_swap_aouthdr_out alpha_ecoff_swap_aouthdr_out
120 #define coff_swap_scnhdr_in alpha_ecoff_swap_scnhdr_in
121 #define coff_swap_scnhdr_out alpha_ecoff_swap_scnhdr_out
122 #include "coffswap.h"
124 /* Get the ECOFF swapping routines. */
125 #define ECOFF_64
126 #include "ecoffswap.h"
128 /* How to process the various reloc types. */
130 static bfd_reloc_status_type reloc_nil
131 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
133 static bfd_reloc_status_type
134 reloc_nil (abfd, reloc, sym, data, sec, output_bfd, error_message)
135 bfd *abfd ATTRIBUTE_UNUSED;
136 arelent *reloc ATTRIBUTE_UNUSED;
137 asymbol *sym ATTRIBUTE_UNUSED;
138 PTR data ATTRIBUTE_UNUSED;
139 asection *sec ATTRIBUTE_UNUSED;
140 bfd *output_bfd ATTRIBUTE_UNUSED;
141 char **error_message ATTRIBUTE_UNUSED;
143 return bfd_reloc_ok;
146 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
147 from smaller values. Start with zero, widen, *then* decrement. */
148 #define MINUS_ONE (((bfd_vma)0) - 1)
150 static reloc_howto_type alpha_howto_table[] =
152 /* Reloc type 0 is ignored by itself. However, it appears after a
153 GPDISP reloc to identify the location where the low order 16 bits
154 of the gp register are loaded. */
155 HOWTO (ALPHA_R_IGNORE, /* type */
156 0, /* rightshift */
157 0, /* size (0 = byte, 1 = short, 2 = long) */
158 8, /* bitsize */
159 TRUE, /* pc_relative */
160 0, /* bitpos */
161 complain_overflow_dont, /* complain_on_overflow */
162 reloc_nil, /* special_function */
163 "IGNORE", /* name */
164 TRUE, /* partial_inplace */
165 0, /* src_mask */
166 0, /* dst_mask */
167 TRUE), /* pcrel_offset */
169 /* A 32 bit reference to a symbol. */
170 HOWTO (ALPHA_R_REFLONG, /* type */
171 0, /* rightshift */
172 2, /* size (0 = byte, 1 = short, 2 = long) */
173 32, /* bitsize */
174 FALSE, /* pc_relative */
175 0, /* bitpos */
176 complain_overflow_bitfield, /* complain_on_overflow */
177 0, /* special_function */
178 "REFLONG", /* name */
179 TRUE, /* partial_inplace */
180 0xffffffff, /* src_mask */
181 0xffffffff, /* dst_mask */
182 FALSE), /* pcrel_offset */
184 /* A 64 bit reference to a symbol. */
185 HOWTO (ALPHA_R_REFQUAD, /* type */
186 0, /* rightshift */
187 4, /* size (0 = byte, 1 = short, 2 = long) */
188 64, /* bitsize */
189 FALSE, /* pc_relative */
190 0, /* bitpos */
191 complain_overflow_bitfield, /* complain_on_overflow */
192 0, /* special_function */
193 "REFQUAD", /* name */
194 TRUE, /* partial_inplace */
195 MINUS_ONE, /* src_mask */
196 MINUS_ONE, /* dst_mask */
197 FALSE), /* pcrel_offset */
199 /* A 32 bit GP relative offset. This is just like REFLONG except
200 that when the value is used the value of the gp register will be
201 added in. */
202 HOWTO (ALPHA_R_GPREL32, /* type */
203 0, /* rightshift */
204 2, /* size (0 = byte, 1 = short, 2 = long) */
205 32, /* bitsize */
206 FALSE, /* pc_relative */
207 0, /* bitpos */
208 complain_overflow_bitfield, /* complain_on_overflow */
209 0, /* special_function */
210 "GPREL32", /* name */
211 TRUE, /* partial_inplace */
212 0xffffffff, /* src_mask */
213 0xffffffff, /* dst_mask */
214 FALSE), /* pcrel_offset */
216 /* Used for an instruction that refers to memory off the GP
217 register. The offset is 16 bits of the 32 bit instruction. This
218 reloc always seems to be against the .lita section. */
219 HOWTO (ALPHA_R_LITERAL, /* type */
220 0, /* rightshift */
221 2, /* size (0 = byte, 1 = short, 2 = long) */
222 16, /* bitsize */
223 FALSE, /* pc_relative */
224 0, /* bitpos */
225 complain_overflow_signed, /* complain_on_overflow */
226 0, /* special_function */
227 "LITERAL", /* name */
228 TRUE, /* partial_inplace */
229 0xffff, /* src_mask */
230 0xffff, /* dst_mask */
231 FALSE), /* pcrel_offset */
233 /* This reloc only appears immediately following a LITERAL reloc.
234 It identifies a use of the literal. It seems that the linker can
235 use this to eliminate a portion of the .lita section. The symbol
236 index is special: 1 means the literal address is in the base
237 register of a memory format instruction; 2 means the literal
238 address is in the byte offset register of a byte-manipulation
239 instruction; 3 means the literal address is in the target
240 register of a jsr instruction. This does not actually do any
241 relocation. */
242 HOWTO (ALPHA_R_LITUSE, /* type */
243 0, /* rightshift */
244 2, /* size (0 = byte, 1 = short, 2 = long) */
245 32, /* bitsize */
246 FALSE, /* pc_relative */
247 0, /* bitpos */
248 complain_overflow_dont, /* complain_on_overflow */
249 reloc_nil, /* special_function */
250 "LITUSE", /* name */
251 FALSE, /* partial_inplace */
252 0, /* src_mask */
253 0, /* dst_mask */
254 FALSE), /* pcrel_offset */
256 /* Load the gp register. This is always used for a ldah instruction
257 which loads the upper 16 bits of the gp register. The next reloc
258 will be an IGNORE reloc which identifies the location of the lda
259 instruction which loads the lower 16 bits. The symbol index of
260 the GPDISP instruction appears to actually be the number of bytes
261 between the ldah and lda instructions. This gives two different
262 ways to determine where the lda instruction is; I don't know why
263 both are used. The value to use for the relocation is the
264 difference between the GP value and the current location; the
265 load will always be done against a register holding the current
266 address. */
267 HOWTO (ALPHA_R_GPDISP, /* type */
268 16, /* rightshift */
269 2, /* size (0 = byte, 1 = short, 2 = long) */
270 16, /* bitsize */
271 TRUE, /* pc_relative */
272 0, /* bitpos */
273 complain_overflow_dont, /* complain_on_overflow */
274 reloc_nil, /* special_function */
275 "GPDISP", /* name */
276 TRUE, /* partial_inplace */
277 0xffff, /* src_mask */
278 0xffff, /* dst_mask */
279 TRUE), /* pcrel_offset */
281 /* A 21 bit branch. The native assembler generates these for
282 branches within the text segment, and also fills in the PC
283 relative offset in the instruction. */
284 HOWTO (ALPHA_R_BRADDR, /* type */
285 2, /* rightshift */
286 2, /* size (0 = byte, 1 = short, 2 = long) */
287 21, /* bitsize */
288 TRUE, /* pc_relative */
289 0, /* bitpos */
290 complain_overflow_signed, /* complain_on_overflow */
291 0, /* special_function */
292 "BRADDR", /* name */
293 TRUE, /* partial_inplace */
294 0x1fffff, /* src_mask */
295 0x1fffff, /* dst_mask */
296 FALSE), /* pcrel_offset */
298 /* A hint for a jump to a register. */
299 HOWTO (ALPHA_R_HINT, /* type */
300 2, /* rightshift */
301 2, /* size (0 = byte, 1 = short, 2 = long) */
302 14, /* bitsize */
303 TRUE, /* pc_relative */
304 0, /* bitpos */
305 complain_overflow_dont, /* complain_on_overflow */
306 0, /* special_function */
307 "HINT", /* name */
308 TRUE, /* partial_inplace */
309 0x3fff, /* src_mask */
310 0x3fff, /* dst_mask */
311 FALSE), /* pcrel_offset */
313 /* 16 bit PC relative offset. */
314 HOWTO (ALPHA_R_SREL16, /* type */
315 0, /* rightshift */
316 1, /* size (0 = byte, 1 = short, 2 = long) */
317 16, /* bitsize */
318 TRUE, /* pc_relative */
319 0, /* bitpos */
320 complain_overflow_signed, /* complain_on_overflow */
321 0, /* special_function */
322 "SREL16", /* name */
323 TRUE, /* partial_inplace */
324 0xffff, /* src_mask */
325 0xffff, /* dst_mask */
326 FALSE), /* pcrel_offset */
328 /* 32 bit PC relative offset. */
329 HOWTO (ALPHA_R_SREL32, /* type */
330 0, /* rightshift */
331 2, /* size (0 = byte, 1 = short, 2 = long) */
332 32, /* bitsize */
333 TRUE, /* pc_relative */
334 0, /* bitpos */
335 complain_overflow_signed, /* complain_on_overflow */
336 0, /* special_function */
337 "SREL32", /* name */
338 TRUE, /* partial_inplace */
339 0xffffffff, /* src_mask */
340 0xffffffff, /* dst_mask */
341 FALSE), /* pcrel_offset */
343 /* A 64 bit PC relative offset. */
344 HOWTO (ALPHA_R_SREL64, /* type */
345 0, /* rightshift */
346 4, /* size (0 = byte, 1 = short, 2 = long) */
347 64, /* bitsize */
348 TRUE, /* pc_relative */
349 0, /* bitpos */
350 complain_overflow_signed, /* complain_on_overflow */
351 0, /* special_function */
352 "SREL64", /* name */
353 TRUE, /* partial_inplace */
354 MINUS_ONE, /* src_mask */
355 MINUS_ONE, /* dst_mask */
356 FALSE), /* pcrel_offset */
358 /* Push a value on the reloc evaluation stack. */
359 HOWTO (ALPHA_R_OP_PUSH, /* type */
360 0, /* rightshift */
361 0, /* size (0 = byte, 1 = short, 2 = long) */
362 0, /* bitsize */
363 FALSE, /* pc_relative */
364 0, /* bitpos */
365 complain_overflow_dont, /* complain_on_overflow */
366 0, /* special_function */
367 "OP_PUSH", /* name */
368 FALSE, /* partial_inplace */
369 0, /* src_mask */
370 0, /* dst_mask */
371 FALSE), /* pcrel_offset */
373 /* Store the value from the stack at the given address. Store it in
374 a bitfield of size r_size starting at bit position r_offset. */
375 HOWTO (ALPHA_R_OP_STORE, /* type */
376 0, /* rightshift */
377 4, /* size (0 = byte, 1 = short, 2 = long) */
378 64, /* bitsize */
379 FALSE, /* pc_relative */
380 0, /* bitpos */
381 complain_overflow_dont, /* complain_on_overflow */
382 0, /* special_function */
383 "OP_STORE", /* name */
384 FALSE, /* partial_inplace */
385 0, /* src_mask */
386 MINUS_ONE, /* dst_mask */
387 FALSE), /* pcrel_offset */
389 /* Subtract the reloc address from the value on the top of the
390 relocation stack. */
391 HOWTO (ALPHA_R_OP_PSUB, /* type */
392 0, /* rightshift */
393 0, /* size (0 = byte, 1 = short, 2 = long) */
394 0, /* bitsize */
395 FALSE, /* pc_relative */
396 0, /* bitpos */
397 complain_overflow_dont, /* complain_on_overflow */
398 0, /* special_function */
399 "OP_PSUB", /* name */
400 FALSE, /* partial_inplace */
401 0, /* src_mask */
402 0, /* dst_mask */
403 FALSE), /* pcrel_offset */
405 /* Shift the value on the top of the relocation stack right by the
406 given value. */
407 HOWTO (ALPHA_R_OP_PRSHIFT, /* type */
408 0, /* rightshift */
409 0, /* size (0 = byte, 1 = short, 2 = long) */
410 0, /* bitsize */
411 FALSE, /* pc_relative */
412 0, /* bitpos */
413 complain_overflow_dont, /* complain_on_overflow */
414 0, /* special_function */
415 "OP_PRSHIFT", /* name */
416 FALSE, /* partial_inplace */
417 0, /* src_mask */
418 0, /* dst_mask */
419 FALSE), /* pcrel_offset */
421 /* Adjust the GP value for a new range in the object file. */
422 HOWTO (ALPHA_R_GPVALUE, /* type */
423 0, /* rightshift */
424 0, /* size (0 = byte, 1 = short, 2 = long) */
425 0, /* bitsize */
426 FALSE, /* pc_relative */
427 0, /* bitpos */
428 complain_overflow_dont, /* complain_on_overflow */
429 0, /* special_function */
430 "GPVALUE", /* name */
431 FALSE, /* partial_inplace */
432 0, /* src_mask */
433 0, /* dst_mask */
434 FALSE) /* pcrel_offset */
437 /* Recognize an Alpha ECOFF file. */
439 static const bfd_target *
440 alpha_ecoff_object_p (abfd)
441 bfd *abfd;
443 static const bfd_target *ret;
445 ret = coff_object_p (abfd);
447 if (ret != NULL)
449 asection *sec;
451 /* Alpha ECOFF has a .pdata section. The lnnoptr field of the
452 .pdata section is the number of entries it contains. Each
453 entry takes up 8 bytes. The number of entries is required
454 since the section is aligned to a 16 byte boundary. When we
455 link .pdata sections together, we do not want to include the
456 alignment bytes. We handle this on input by faking the size
457 of the .pdata section to remove the unwanted alignment bytes.
458 On output we will set the lnnoptr field and force the
459 alignment. */
460 sec = bfd_get_section_by_name (abfd, _PDATA);
461 if (sec != (asection *) NULL)
463 bfd_size_type size;
465 size = sec->line_filepos * 8;
466 BFD_ASSERT (size == sec->size
467 || size + 8 == sec->size);
468 if (! bfd_set_section_size (abfd, sec, size))
469 return NULL;
473 return ret;
476 /* See whether the magic number matches. */
478 static bfd_boolean
479 alpha_ecoff_bad_format_hook (abfd, filehdr)
480 bfd *abfd ATTRIBUTE_UNUSED;
481 PTR filehdr;
483 struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
485 if (! ALPHA_ECOFF_BADMAG (*internal_f))
486 return TRUE;
488 if (ALPHA_ECOFF_COMPRESSEDMAG (*internal_f))
489 (*_bfd_error_handler)
490 (_("%B: Cannot handle compressed Alpha binaries.\n"
491 " Use compiler flags, or objZ, to generate uncompressed binaries."),
492 abfd);
494 return FALSE;
497 /* This is a hook called by coff_real_object_p to create any backend
498 specific information. */
500 static PTR
501 alpha_ecoff_mkobject_hook (abfd, filehdr, aouthdr)
502 bfd *abfd;
503 PTR filehdr;
504 PTR aouthdr;
506 PTR ecoff;
508 ecoff = _bfd_ecoff_mkobject_hook (abfd, filehdr, aouthdr);
510 if (ecoff != NULL)
512 struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
514 /* Set additional BFD flags according to the object type from the
515 machine specific file header flags. */
516 switch (internal_f->f_flags & F_ALPHA_OBJECT_TYPE_MASK)
518 case F_ALPHA_SHARABLE:
519 abfd->flags |= DYNAMIC;
520 break;
521 case F_ALPHA_CALL_SHARED:
522 /* Always executable if using shared libraries as the run time
523 loader might resolve undefined references. */
524 abfd->flags |= (DYNAMIC | EXEC_P);
525 break;
528 return ecoff;
531 /* Reloc handling. */
533 /* Swap a reloc in. */
535 static void
536 alpha_ecoff_swap_reloc_in (abfd, ext_ptr, intern)
537 bfd *abfd;
538 PTR ext_ptr;
539 struct internal_reloc *intern;
541 const RELOC *ext = (RELOC *) ext_ptr;
543 intern->r_vaddr = H_GET_64 (abfd, ext->r_vaddr);
544 intern->r_symndx = H_GET_32 (abfd, ext->r_symndx);
546 BFD_ASSERT (bfd_header_little_endian (abfd));
548 intern->r_type = ((ext->r_bits[0] & RELOC_BITS0_TYPE_LITTLE)
549 >> RELOC_BITS0_TYPE_SH_LITTLE);
550 intern->r_extern = (ext->r_bits[1] & RELOC_BITS1_EXTERN_LITTLE) != 0;
551 intern->r_offset = ((ext->r_bits[1] & RELOC_BITS1_OFFSET_LITTLE)
552 >> RELOC_BITS1_OFFSET_SH_LITTLE);
553 /* Ignored the reserved bits. */
554 intern->r_size = ((ext->r_bits[3] & RELOC_BITS3_SIZE_LITTLE)
555 >> RELOC_BITS3_SIZE_SH_LITTLE);
557 if (intern->r_type == ALPHA_R_LITUSE
558 || intern->r_type == ALPHA_R_GPDISP)
560 /* Handle the LITUSE and GPDISP relocs specially. Its symndx
561 value is not actually a symbol index, but is instead a
562 special code. We put the code in the r_size field, and
563 clobber the symndx. */
564 if (intern->r_size != 0)
565 abort ();
566 intern->r_size = intern->r_symndx;
567 intern->r_symndx = RELOC_SECTION_NONE;
569 else if (intern->r_type == ALPHA_R_IGNORE)
571 /* The IGNORE reloc generally follows a GPDISP reloc, and is
572 against the .lita section. The section is irrelevant. */
573 if (! intern->r_extern &&
574 intern->r_symndx == RELOC_SECTION_ABS)
575 abort ();
576 if (! intern->r_extern && intern->r_symndx == RELOC_SECTION_LITA)
577 intern->r_symndx = RELOC_SECTION_ABS;
581 /* Swap a reloc out. */
583 static void
584 alpha_ecoff_swap_reloc_out (abfd, intern, dst)
585 bfd *abfd;
586 const struct internal_reloc *intern;
587 PTR dst;
589 RELOC *ext = (RELOC *) dst;
590 long symndx;
591 unsigned char size;
593 /* Undo the hackery done in swap_reloc_in. */
594 if (intern->r_type == ALPHA_R_LITUSE
595 || intern->r_type == ALPHA_R_GPDISP)
597 symndx = intern->r_size;
598 size = 0;
600 else if (intern->r_type == ALPHA_R_IGNORE
601 && ! intern->r_extern
602 && intern->r_symndx == RELOC_SECTION_ABS)
604 symndx = RELOC_SECTION_LITA;
605 size = intern->r_size;
607 else
609 symndx = intern->r_symndx;
610 size = intern->r_size;
613 /* XXX FIXME: The maximum symndx value used to be 14 but this
614 fails with object files produced by DEC's C++ compiler.
615 Where does the value 14 (or 15) come from anyway ? */
616 BFD_ASSERT (intern->r_extern
617 || (intern->r_symndx >= 0 && intern->r_symndx <= 15));
619 H_PUT_64 (abfd, intern->r_vaddr, ext->r_vaddr);
620 H_PUT_32 (abfd, symndx, ext->r_symndx);
622 BFD_ASSERT (bfd_header_little_endian (abfd));
624 ext->r_bits[0] = ((intern->r_type << RELOC_BITS0_TYPE_SH_LITTLE)
625 & RELOC_BITS0_TYPE_LITTLE);
626 ext->r_bits[1] = ((intern->r_extern ? RELOC_BITS1_EXTERN_LITTLE : 0)
627 | ((intern->r_offset << RELOC_BITS1_OFFSET_SH_LITTLE)
628 & RELOC_BITS1_OFFSET_LITTLE));
629 ext->r_bits[2] = 0;
630 ext->r_bits[3] = ((size << RELOC_BITS3_SIZE_SH_LITTLE)
631 & RELOC_BITS3_SIZE_LITTLE);
634 /* Finish canonicalizing a reloc. Part of this is generic to all
635 ECOFF targets, and that part is in ecoff.c. The rest is done in
636 this backend routine. It must fill in the howto field. */
638 static void
639 alpha_adjust_reloc_in (abfd, intern, rptr)
640 bfd *abfd;
641 const struct internal_reloc *intern;
642 arelent *rptr;
644 if (intern->r_type > ALPHA_R_GPVALUE)
646 (*_bfd_error_handler)
647 (_("%B: unknown/unsupported relocation type %d"),
648 abfd, intern->r_type);
649 bfd_set_error (bfd_error_bad_value);
650 rptr->addend = 0;
651 rptr->howto = NULL;
652 return;
655 switch (intern->r_type)
657 case ALPHA_R_BRADDR:
658 case ALPHA_R_SREL16:
659 case ALPHA_R_SREL32:
660 case ALPHA_R_SREL64:
661 /* This relocs appear to be fully resolved when they are against
662 internal symbols. Against external symbols, BRADDR at least
663 appears to be resolved against the next instruction. */
664 if (! intern->r_extern)
665 rptr->addend = 0;
666 else
667 rptr->addend = - (intern->r_vaddr + 4);
668 break;
670 case ALPHA_R_GPREL32:
671 case ALPHA_R_LITERAL:
672 /* Copy the gp value for this object file into the addend, to
673 ensure that we are not confused by the linker. */
674 if (! intern->r_extern)
675 rptr->addend += ecoff_data (abfd)->gp;
676 break;
678 case ALPHA_R_LITUSE:
679 case ALPHA_R_GPDISP:
680 /* The LITUSE and GPDISP relocs do not use a symbol, or an
681 addend, but they do use a special code. Put this code in the
682 addend field. */
683 rptr->addend = intern->r_size;
684 break;
686 case ALPHA_R_OP_STORE:
687 /* The STORE reloc needs the size and offset fields. We store
688 them in the addend. */
689 BFD_ASSERT (intern->r_offset <= 256);
690 rptr->addend = (intern->r_offset << 8) + intern->r_size;
691 break;
693 case ALPHA_R_OP_PUSH:
694 case ALPHA_R_OP_PSUB:
695 case ALPHA_R_OP_PRSHIFT:
696 /* The PUSH, PSUB and PRSHIFT relocs do not actually use an
697 address. I believe that the address supplied is really an
698 addend. */
699 rptr->addend = intern->r_vaddr;
700 break;
702 case ALPHA_R_GPVALUE:
703 /* Set the addend field to the new GP value. */
704 rptr->addend = intern->r_symndx + ecoff_data (abfd)->gp;
705 break;
707 case ALPHA_R_IGNORE:
708 /* If the type is ALPHA_R_IGNORE, make sure this is a reference
709 to the absolute section so that the reloc is ignored. For
710 some reason the address of this reloc type is not adjusted by
711 the section vma. We record the gp value for this object file
712 here, for convenience when doing the GPDISP relocation. */
713 rptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
714 rptr->address = intern->r_vaddr;
715 rptr->addend = ecoff_data (abfd)->gp;
716 break;
718 default:
719 break;
722 rptr->howto = &alpha_howto_table[intern->r_type];
725 /* When writing out a reloc we need to pull some values back out of
726 the addend field into the reloc. This is roughly the reverse of
727 alpha_adjust_reloc_in, except that there are several changes we do
728 not need to undo. */
730 static void
731 alpha_adjust_reloc_out (abfd, rel, intern)
732 bfd *abfd ATTRIBUTE_UNUSED;
733 const arelent *rel;
734 struct internal_reloc *intern;
736 switch (intern->r_type)
738 case ALPHA_R_LITUSE:
739 case ALPHA_R_GPDISP:
740 intern->r_size = rel->addend;
741 break;
743 case ALPHA_R_OP_STORE:
744 intern->r_size = rel->addend & 0xff;
745 intern->r_offset = (rel->addend >> 8) & 0xff;
746 break;
748 case ALPHA_R_OP_PUSH:
749 case ALPHA_R_OP_PSUB:
750 case ALPHA_R_OP_PRSHIFT:
751 intern->r_vaddr = rel->addend;
752 break;
754 case ALPHA_R_IGNORE:
755 intern->r_vaddr = rel->address;
756 break;
758 default:
759 break;
763 /* The size of the stack for the relocation evaluator. */
764 #define RELOC_STACKSIZE (10)
766 /* Alpha ECOFF relocs have a built in expression evaluator as well as
767 other interdependencies. Rather than use a bunch of special
768 functions and global variables, we use a single routine to do all
769 the relocation for a section. I haven't yet worked out how the
770 assembler is going to handle this. */
772 static bfd_byte *
773 alpha_ecoff_get_relocated_section_contents (abfd, link_info, link_order,
774 data, relocatable, symbols)
775 bfd *abfd;
776 struct bfd_link_info *link_info;
777 struct bfd_link_order *link_order;
778 bfd_byte *data;
779 bfd_boolean relocatable;
780 asymbol **symbols;
782 bfd *input_bfd = link_order->u.indirect.section->owner;
783 asection *input_section = link_order->u.indirect.section;
784 long reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section);
785 arelent **reloc_vector = NULL;
786 long reloc_count;
787 bfd *output_bfd = relocatable ? abfd : (bfd *) NULL;
788 bfd_vma gp;
789 bfd_size_type sz;
790 bfd_boolean gp_undefined;
791 bfd_vma stack[RELOC_STACKSIZE];
792 int tos = 0;
794 if (reloc_size < 0)
795 goto error_return;
796 reloc_vector = (arelent **) bfd_malloc ((bfd_size_type) reloc_size);
797 if (reloc_vector == NULL && reloc_size != 0)
798 goto error_return;
800 sz = input_section->rawsize ? input_section->rawsize : input_section->size;
801 if (! bfd_get_section_contents (input_bfd, input_section, data, 0, sz))
802 goto error_return;
804 reloc_count = bfd_canonicalize_reloc (input_bfd, input_section,
805 reloc_vector, symbols);
806 if (reloc_count < 0)
807 goto error_return;
808 if (reloc_count == 0)
809 goto successful_return;
811 /* Get the GP value for the output BFD. */
812 gp_undefined = FALSE;
813 gp = _bfd_get_gp_value (abfd);
814 if (gp == 0)
816 if (relocatable)
818 asection *sec;
819 bfd_vma lo;
821 /* Make up a value. */
822 lo = (bfd_vma) -1;
823 for (sec = abfd->sections; sec != NULL; sec = sec->next)
825 if (sec->vma < lo
826 && (strcmp (sec->name, ".sbss") == 0
827 || strcmp (sec->name, ".sdata") == 0
828 || strcmp (sec->name, ".lit4") == 0
829 || strcmp (sec->name, ".lit8") == 0
830 || strcmp (sec->name, ".lita") == 0))
831 lo = sec->vma;
833 gp = lo + 0x8000;
834 _bfd_set_gp_value (abfd, gp);
836 else
838 struct bfd_link_hash_entry *h;
840 h = bfd_link_hash_lookup (link_info->hash, "_gp", FALSE, FALSE,
841 TRUE);
842 if (h == (struct bfd_link_hash_entry *) NULL
843 || h->type != bfd_link_hash_defined)
844 gp_undefined = TRUE;
845 else
847 gp = (h->u.def.value
848 + h->u.def.section->output_section->vma
849 + h->u.def.section->output_offset);
850 _bfd_set_gp_value (abfd, gp);
855 for (; *reloc_vector != (arelent *) NULL; reloc_vector++)
857 arelent *rel;
858 bfd_reloc_status_type r;
859 char *err;
861 rel = *reloc_vector;
862 r = bfd_reloc_ok;
863 switch (rel->howto->type)
865 case ALPHA_R_IGNORE:
866 rel->address += input_section->output_offset;
867 break;
869 case ALPHA_R_REFLONG:
870 case ALPHA_R_REFQUAD:
871 case ALPHA_R_BRADDR:
872 case ALPHA_R_HINT:
873 case ALPHA_R_SREL16:
874 case ALPHA_R_SREL32:
875 case ALPHA_R_SREL64:
876 if (relocatable
877 && ((*rel->sym_ptr_ptr)->flags & BSF_SECTION_SYM) == 0)
879 rel->address += input_section->output_offset;
880 break;
882 r = bfd_perform_relocation (input_bfd, rel, data, input_section,
883 output_bfd, &err);
884 break;
886 case ALPHA_R_GPREL32:
887 /* This relocation is used in a switch table. It is a 32
888 bit offset from the current GP value. We must adjust it
889 by the different between the original GP value and the
890 current GP value. The original GP value is stored in the
891 addend. We adjust the addend and let
892 bfd_perform_relocation finish the job. */
893 rel->addend -= gp;
894 r = bfd_perform_relocation (input_bfd, rel, data, input_section,
895 output_bfd, &err);
896 if (r == bfd_reloc_ok && gp_undefined)
898 r = bfd_reloc_dangerous;
899 err = (char *) _("GP relative relocation used when GP not defined");
901 break;
903 case ALPHA_R_LITERAL:
904 /* This is a reference to a literal value, generally
905 (always?) in the .lita section. This is a 16 bit GP
906 relative relocation. Sometimes the subsequent reloc is a
907 LITUSE reloc, which indicates how this reloc is used.
908 This sometimes permits rewriting the two instructions
909 referred to by the LITERAL and the LITUSE into different
910 instructions which do not refer to .lita. This can save
911 a memory reference, and permits removing a value from
912 .lita thus saving GP relative space.
914 We do not these optimizations. To do them we would need
915 to arrange to link the .lita section first, so that by
916 the time we got here we would know the final values to
917 use. This would not be particularly difficult, but it is
918 not currently implemented. */
921 unsigned long insn;
923 /* I believe that the LITERAL reloc will only apply to a
924 ldq or ldl instruction, so check my assumption. */
925 insn = bfd_get_32 (input_bfd, data + rel->address);
926 BFD_ASSERT (((insn >> 26) & 0x3f) == 0x29
927 || ((insn >> 26) & 0x3f) == 0x28);
929 rel->addend -= gp;
930 r = bfd_perform_relocation (input_bfd, rel, data, input_section,
931 output_bfd, &err);
932 if (r == bfd_reloc_ok && gp_undefined)
934 r = bfd_reloc_dangerous;
935 err =
936 (char *) _("GP relative relocation used when GP not defined");
939 break;
941 case ALPHA_R_LITUSE:
942 /* See ALPHA_R_LITERAL above for the uses of this reloc. It
943 does not cause anything to happen, itself. */
944 rel->address += input_section->output_offset;
945 break;
947 case ALPHA_R_GPDISP:
948 /* This marks the ldah of an ldah/lda pair which loads the
949 gp register with the difference of the gp value and the
950 current location. The second of the pair is r_size bytes
951 ahead; it used to be marked with an ALPHA_R_IGNORE reloc,
952 but that no longer happens in OSF/1 3.2. */
954 unsigned long insn1, insn2;
955 bfd_vma addend;
957 /* Get the two instructions. */
958 insn1 = bfd_get_32 (input_bfd, data + rel->address);
959 insn2 = bfd_get_32 (input_bfd, data + rel->address + rel->addend);
961 BFD_ASSERT (((insn1 >> 26) & 0x3f) == 0x09); /* ldah */
962 BFD_ASSERT (((insn2 >> 26) & 0x3f) == 0x08); /* lda */
964 /* Get the existing addend. We must account for the sign
965 extension done by lda and ldah. */
966 addend = ((insn1 & 0xffff) << 16) + (insn2 & 0xffff);
967 if (insn1 & 0x8000)
969 addend -= 0x80000000;
970 addend -= 0x80000000;
972 if (insn2 & 0x8000)
973 addend -= 0x10000;
975 /* The existing addend includes the different between the
976 gp of the input BFD and the address in the input BFD.
977 Subtract this out. */
978 addend -= (ecoff_data (input_bfd)->gp
979 - (input_section->vma + rel->address));
981 /* Now add in the final gp value, and subtract out the
982 final address. */
983 addend += (gp
984 - (input_section->output_section->vma
985 + input_section->output_offset
986 + rel->address));
988 /* Change the instructions, accounting for the sign
989 extension, and write them out. */
990 if (addend & 0x8000)
991 addend += 0x10000;
992 insn1 = (insn1 & 0xffff0000) | ((addend >> 16) & 0xffff);
993 insn2 = (insn2 & 0xffff0000) | (addend & 0xffff);
995 bfd_put_32 (input_bfd, (bfd_vma) insn1, data + rel->address);
996 bfd_put_32 (input_bfd, (bfd_vma) insn2,
997 data + rel->address + rel->addend);
999 rel->address += input_section->output_offset;
1001 break;
1003 case ALPHA_R_OP_PUSH:
1004 /* Push a value on the reloc evaluation stack. */
1006 asymbol *symbol;
1007 bfd_vma relocation;
1009 if (relocatable)
1011 rel->address += input_section->output_offset;
1012 break;
1015 /* Figure out the relocation of this symbol. */
1016 symbol = *rel->sym_ptr_ptr;
1018 if (bfd_is_und_section (symbol->section))
1019 r = bfd_reloc_undefined;
1021 if (bfd_is_com_section (symbol->section))
1022 relocation = 0;
1023 else
1024 relocation = symbol->value;
1025 relocation += symbol->section->output_section->vma;
1026 relocation += symbol->section->output_offset;
1027 relocation += rel->addend;
1029 if (tos >= RELOC_STACKSIZE)
1030 abort ();
1032 stack[tos++] = relocation;
1034 break;
1036 case ALPHA_R_OP_STORE:
1037 /* Store a value from the reloc stack into a bitfield. */
1039 bfd_vma val;
1040 int offset, size;
1042 if (relocatable)
1044 rel->address += input_section->output_offset;
1045 break;
1048 if (tos == 0)
1049 abort ();
1051 /* The offset and size for this reloc are encoded into the
1052 addend field by alpha_adjust_reloc_in. */
1053 offset = (rel->addend >> 8) & 0xff;
1054 size = rel->addend & 0xff;
1056 val = bfd_get_64 (abfd, data + rel->address);
1057 val &=~ (((1 << size) - 1) << offset);
1058 val |= (stack[--tos] & ((1 << size) - 1)) << offset;
1059 bfd_put_64 (abfd, val, data + rel->address);
1061 break;
1063 case ALPHA_R_OP_PSUB:
1064 /* Subtract a value from the top of the stack. */
1066 asymbol *symbol;
1067 bfd_vma relocation;
1069 if (relocatable)
1071 rel->address += input_section->output_offset;
1072 break;
1075 /* Figure out the relocation of this symbol. */
1076 symbol = *rel->sym_ptr_ptr;
1078 if (bfd_is_und_section (symbol->section))
1079 r = bfd_reloc_undefined;
1081 if (bfd_is_com_section (symbol->section))
1082 relocation = 0;
1083 else
1084 relocation = symbol->value;
1085 relocation += symbol->section->output_section->vma;
1086 relocation += symbol->section->output_offset;
1087 relocation += rel->addend;
1089 if (tos == 0)
1090 abort ();
1092 stack[tos - 1] -= relocation;
1094 break;
1096 case ALPHA_R_OP_PRSHIFT:
1097 /* Shift the value on the top of the stack. */
1099 asymbol *symbol;
1100 bfd_vma relocation;
1102 if (relocatable)
1104 rel->address += input_section->output_offset;
1105 break;
1108 /* Figure out the relocation of this symbol. */
1109 symbol = *rel->sym_ptr_ptr;
1111 if (bfd_is_und_section (symbol->section))
1112 r = bfd_reloc_undefined;
1114 if (bfd_is_com_section (symbol->section))
1115 relocation = 0;
1116 else
1117 relocation = symbol->value;
1118 relocation += symbol->section->output_section->vma;
1119 relocation += symbol->section->output_offset;
1120 relocation += rel->addend;
1122 if (tos == 0)
1123 abort ();
1125 stack[tos - 1] >>= relocation;
1127 break;
1129 case ALPHA_R_GPVALUE:
1130 /* I really don't know if this does the right thing. */
1131 gp = rel->addend;
1132 gp_undefined = FALSE;
1133 break;
1135 default:
1136 abort ();
1139 if (relocatable)
1141 asection *os = input_section->output_section;
1143 /* A partial link, so keep the relocs. */
1144 os->orelocation[os->reloc_count] = rel;
1145 os->reloc_count++;
1148 if (r != bfd_reloc_ok)
1150 switch (r)
1152 case bfd_reloc_undefined:
1153 if (! ((*link_info->callbacks->undefined_symbol)
1154 (link_info, bfd_asymbol_name (*rel->sym_ptr_ptr),
1155 input_bfd, input_section, rel->address, TRUE)))
1156 goto error_return;
1157 break;
1158 case bfd_reloc_dangerous:
1159 if (! ((*link_info->callbacks->reloc_dangerous)
1160 (link_info, err, input_bfd, input_section,
1161 rel->address)))
1162 goto error_return;
1163 break;
1164 case bfd_reloc_overflow:
1165 if (! ((*link_info->callbacks->reloc_overflow)
1166 (link_info, NULL,
1167 bfd_asymbol_name (*rel->sym_ptr_ptr),
1168 rel->howto->name, rel->addend, input_bfd,
1169 input_section, rel->address)))
1170 goto error_return;
1171 break;
1172 case bfd_reloc_outofrange:
1173 default:
1174 abort ();
1175 break;
1180 if (tos != 0)
1181 abort ();
1183 successful_return:
1184 if (reloc_vector != NULL)
1185 free (reloc_vector);
1186 return data;
1188 error_return:
1189 if (reloc_vector != NULL)
1190 free (reloc_vector);
1191 return NULL;
1194 /* Get the howto structure for a generic reloc type. */
1196 static reloc_howto_type *
1197 alpha_bfd_reloc_type_lookup (abfd, code)
1198 bfd *abfd ATTRIBUTE_UNUSED;
1199 bfd_reloc_code_real_type code;
1201 int alpha_type;
1203 switch (code)
1205 case BFD_RELOC_32:
1206 alpha_type = ALPHA_R_REFLONG;
1207 break;
1208 case BFD_RELOC_64:
1209 case BFD_RELOC_CTOR:
1210 alpha_type = ALPHA_R_REFQUAD;
1211 break;
1212 case BFD_RELOC_GPREL32:
1213 alpha_type = ALPHA_R_GPREL32;
1214 break;
1215 case BFD_RELOC_ALPHA_LITERAL:
1216 alpha_type = ALPHA_R_LITERAL;
1217 break;
1218 case BFD_RELOC_ALPHA_LITUSE:
1219 alpha_type = ALPHA_R_LITUSE;
1220 break;
1221 case BFD_RELOC_ALPHA_GPDISP_HI16:
1222 alpha_type = ALPHA_R_GPDISP;
1223 break;
1224 case BFD_RELOC_ALPHA_GPDISP_LO16:
1225 alpha_type = ALPHA_R_IGNORE;
1226 break;
1227 case BFD_RELOC_23_PCREL_S2:
1228 alpha_type = ALPHA_R_BRADDR;
1229 break;
1230 case BFD_RELOC_ALPHA_HINT:
1231 alpha_type = ALPHA_R_HINT;
1232 break;
1233 case BFD_RELOC_16_PCREL:
1234 alpha_type = ALPHA_R_SREL16;
1235 break;
1236 case BFD_RELOC_32_PCREL:
1237 alpha_type = ALPHA_R_SREL32;
1238 break;
1239 case BFD_RELOC_64_PCREL:
1240 alpha_type = ALPHA_R_SREL64;
1241 break;
1242 default:
1243 return (reloc_howto_type *) NULL;
1246 return &alpha_howto_table[alpha_type];
1249 static reloc_howto_type *
1250 alpha_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1251 const char *r_name)
1253 unsigned int i;
1255 for (i = 0;
1256 i < sizeof (alpha_howto_table) / sizeof (alpha_howto_table[0]);
1257 i++)
1258 if (alpha_howto_table[i].name != NULL
1259 && strcasecmp (alpha_howto_table[i].name, r_name) == 0)
1260 return &alpha_howto_table[i];
1262 return NULL;
1265 /* A helper routine for alpha_relocate_section which converts an
1266 external reloc when generating relocatable output. Returns the
1267 relocation amount. */
1269 static bfd_vma
1270 alpha_convert_external_reloc (output_bfd, info, input_bfd, ext_rel, h)
1271 bfd *output_bfd ATTRIBUTE_UNUSED;
1272 struct bfd_link_info *info;
1273 bfd *input_bfd;
1274 struct external_reloc *ext_rel;
1275 struct ecoff_link_hash_entry *h;
1277 unsigned long r_symndx;
1278 bfd_vma relocation;
1280 BFD_ASSERT (info->relocatable);
1282 if (h->root.type == bfd_link_hash_defined
1283 || h->root.type == bfd_link_hash_defweak)
1285 asection *hsec;
1286 const char *name;
1288 /* This symbol is defined in the output. Convert the reloc from
1289 being against the symbol to being against the section. */
1291 /* Clear the r_extern bit. */
1292 ext_rel->r_bits[1] &=~ RELOC_BITS1_EXTERN_LITTLE;
1294 /* Compute a new r_symndx value. */
1295 hsec = h->root.u.def.section;
1296 name = bfd_get_section_name (output_bfd, hsec->output_section);
1298 r_symndx = (unsigned long) -1;
1299 switch (name[1])
1301 case 'A':
1302 if (strcmp (name, "*ABS*") == 0)
1303 r_symndx = RELOC_SECTION_ABS;
1304 break;
1305 case 'b':
1306 if (strcmp (name, ".bss") == 0)
1307 r_symndx = RELOC_SECTION_BSS;
1308 break;
1309 case 'd':
1310 if (strcmp (name, ".data") == 0)
1311 r_symndx = RELOC_SECTION_DATA;
1312 break;
1313 case 'f':
1314 if (strcmp (name, ".fini") == 0)
1315 r_symndx = RELOC_SECTION_FINI;
1316 break;
1317 case 'i':
1318 if (strcmp (name, ".init") == 0)
1319 r_symndx = RELOC_SECTION_INIT;
1320 break;
1321 case 'l':
1322 if (strcmp (name, ".lita") == 0)
1323 r_symndx = RELOC_SECTION_LITA;
1324 else if (strcmp (name, ".lit8") == 0)
1325 r_symndx = RELOC_SECTION_LIT8;
1326 else if (strcmp (name, ".lit4") == 0)
1327 r_symndx = RELOC_SECTION_LIT4;
1328 break;
1329 case 'p':
1330 if (strcmp (name, ".pdata") == 0)
1331 r_symndx = RELOC_SECTION_PDATA;
1332 break;
1333 case 'r':
1334 if (strcmp (name, ".rdata") == 0)
1335 r_symndx = RELOC_SECTION_RDATA;
1336 else if (strcmp (name, ".rconst") == 0)
1337 r_symndx = RELOC_SECTION_RCONST;
1338 break;
1339 case 's':
1340 if (strcmp (name, ".sdata") == 0)
1341 r_symndx = RELOC_SECTION_SDATA;
1342 else if (strcmp (name, ".sbss") == 0)
1343 r_symndx = RELOC_SECTION_SBSS;
1344 break;
1345 case 't':
1346 if (strcmp (name, ".text") == 0)
1347 r_symndx = RELOC_SECTION_TEXT;
1348 break;
1349 case 'x':
1350 if (strcmp (name, ".xdata") == 0)
1351 r_symndx = RELOC_SECTION_XDATA;
1352 break;
1355 if (r_symndx == (unsigned long) -1)
1356 abort ();
1358 /* Add the section VMA and the symbol value. */
1359 relocation = (h->root.u.def.value
1360 + hsec->output_section->vma
1361 + hsec->output_offset);
1363 else
1365 /* Change the symndx value to the right one for
1366 the output BFD. */
1367 r_symndx = h->indx;
1368 if (r_symndx == (unsigned long) -1)
1370 /* Caller must give an error. */
1371 r_symndx = 0;
1373 relocation = 0;
1376 /* Write out the new r_symndx value. */
1377 H_PUT_32 (input_bfd, r_symndx, ext_rel->r_symndx);
1379 return relocation;
1382 /* Relocate a section while linking an Alpha ECOFF file. This is
1383 quite similar to get_relocated_section_contents. Perhaps they
1384 could be combined somehow. */
1386 static bfd_boolean
1387 alpha_relocate_section (output_bfd, info, input_bfd, input_section,
1388 contents, external_relocs)
1389 bfd *output_bfd;
1390 struct bfd_link_info *info;
1391 bfd *input_bfd;
1392 asection *input_section;
1393 bfd_byte *contents;
1394 PTR external_relocs;
1396 asection **symndx_to_section, *lita_sec;
1397 struct ecoff_link_hash_entry **sym_hashes;
1398 bfd_vma gp;
1399 bfd_boolean gp_undefined;
1400 bfd_vma stack[RELOC_STACKSIZE];
1401 int tos = 0;
1402 struct external_reloc *ext_rel;
1403 struct external_reloc *ext_rel_end;
1404 bfd_size_type amt;
1406 /* We keep a table mapping the symndx found in an internal reloc to
1407 the appropriate section. This is faster than looking up the
1408 section by name each time. */
1409 symndx_to_section = ecoff_data (input_bfd)->symndx_to_section;
1410 if (symndx_to_section == (asection **) NULL)
1412 amt = NUM_RELOC_SECTIONS * sizeof (asection *);
1413 symndx_to_section = (asection **) bfd_alloc (input_bfd, amt);
1414 if (!symndx_to_section)
1415 return FALSE;
1417 symndx_to_section[RELOC_SECTION_NONE] = NULL;
1418 symndx_to_section[RELOC_SECTION_TEXT] =
1419 bfd_get_section_by_name (input_bfd, ".text");
1420 symndx_to_section[RELOC_SECTION_RDATA] =
1421 bfd_get_section_by_name (input_bfd, ".rdata");
1422 symndx_to_section[RELOC_SECTION_DATA] =
1423 bfd_get_section_by_name (input_bfd, ".data");
1424 symndx_to_section[RELOC_SECTION_SDATA] =
1425 bfd_get_section_by_name (input_bfd, ".sdata");
1426 symndx_to_section[RELOC_SECTION_SBSS] =
1427 bfd_get_section_by_name (input_bfd, ".sbss");
1428 symndx_to_section[RELOC_SECTION_BSS] =
1429 bfd_get_section_by_name (input_bfd, ".bss");
1430 symndx_to_section[RELOC_SECTION_INIT] =
1431 bfd_get_section_by_name (input_bfd, ".init");
1432 symndx_to_section[RELOC_SECTION_LIT8] =
1433 bfd_get_section_by_name (input_bfd, ".lit8");
1434 symndx_to_section[RELOC_SECTION_LIT4] =
1435 bfd_get_section_by_name (input_bfd, ".lit4");
1436 symndx_to_section[RELOC_SECTION_XDATA] =
1437 bfd_get_section_by_name (input_bfd, ".xdata");
1438 symndx_to_section[RELOC_SECTION_PDATA] =
1439 bfd_get_section_by_name (input_bfd, ".pdata");
1440 symndx_to_section[RELOC_SECTION_FINI] =
1441 bfd_get_section_by_name (input_bfd, ".fini");
1442 symndx_to_section[RELOC_SECTION_LITA] =
1443 bfd_get_section_by_name (input_bfd, ".lita");
1444 symndx_to_section[RELOC_SECTION_ABS] = bfd_abs_section_ptr;
1445 symndx_to_section[RELOC_SECTION_RCONST] =
1446 bfd_get_section_by_name (input_bfd, ".rconst");
1448 ecoff_data (input_bfd)->symndx_to_section = symndx_to_section;
1451 sym_hashes = ecoff_data (input_bfd)->sym_hashes;
1453 /* On the Alpha, the .lita section must be addressable by the global
1454 pointer. To support large programs, we need to allow multiple
1455 global pointers. This works as long as each input .lita section
1456 is <64KB big. This implies that when producing relocatable
1457 output, the .lita section is limited to 64KB. . */
1459 lita_sec = symndx_to_section[RELOC_SECTION_LITA];
1460 gp = _bfd_get_gp_value (output_bfd);
1461 if (! info->relocatable && lita_sec != NULL)
1463 struct ecoff_section_tdata *lita_sec_data;
1465 /* Make sure we have a section data structure to which we can
1466 hang on to the gp value we pick for the section. */
1467 lita_sec_data = ecoff_section_data (input_bfd, lita_sec);
1468 if (lita_sec_data == NULL)
1470 amt = sizeof (struct ecoff_section_tdata);
1471 lita_sec_data = ((struct ecoff_section_tdata *)
1472 bfd_zalloc (input_bfd, amt));
1473 lita_sec->used_by_bfd = lita_sec_data;
1476 if (lita_sec_data->gp != 0)
1478 /* If we already assigned a gp to this section, we better
1479 stick with that value. */
1480 gp = lita_sec_data->gp;
1482 else
1484 bfd_vma lita_vma;
1485 bfd_size_type lita_size;
1487 lita_vma = lita_sec->output_offset + lita_sec->output_section->vma;
1488 lita_size = lita_sec->size;
1490 if (gp == 0
1491 || lita_vma < gp - 0x8000
1492 || lita_vma + lita_size >= gp + 0x8000)
1494 /* Either gp hasn't been set at all or the current gp
1495 cannot address this .lita section. In both cases we
1496 reset the gp to point into the "middle" of the
1497 current input .lita section. */
1498 if (gp && !ecoff_data (output_bfd)->issued_multiple_gp_warning)
1500 (*info->callbacks->warning) (info,
1501 _("using multiple gp values"),
1502 (char *) NULL, output_bfd,
1503 (asection *) NULL, (bfd_vma) 0);
1504 ecoff_data (output_bfd)->issued_multiple_gp_warning = TRUE;
1506 if (lita_vma < gp - 0x8000)
1507 gp = lita_vma + lita_size - 0x8000;
1508 else
1509 gp = lita_vma + 0x8000;
1513 lita_sec_data->gp = gp;
1516 _bfd_set_gp_value (output_bfd, gp);
1519 gp_undefined = (gp == 0);
1521 BFD_ASSERT (bfd_header_little_endian (output_bfd));
1522 BFD_ASSERT (bfd_header_little_endian (input_bfd));
1524 ext_rel = (struct external_reloc *) external_relocs;
1525 ext_rel_end = ext_rel + input_section->reloc_count;
1526 for (; ext_rel < ext_rel_end; ext_rel++)
1528 bfd_vma r_vaddr;
1529 unsigned long r_symndx;
1530 int r_type;
1531 int r_extern;
1532 int r_offset;
1533 int r_size;
1534 bfd_boolean relocatep;
1535 bfd_boolean adjust_addrp;
1536 bfd_boolean gp_usedp;
1537 bfd_vma addend;
1539 r_vaddr = H_GET_64 (input_bfd, ext_rel->r_vaddr);
1540 r_symndx = H_GET_32 (input_bfd, ext_rel->r_symndx);
1542 r_type = ((ext_rel->r_bits[0] & RELOC_BITS0_TYPE_LITTLE)
1543 >> RELOC_BITS0_TYPE_SH_LITTLE);
1544 r_extern = (ext_rel->r_bits[1] & RELOC_BITS1_EXTERN_LITTLE) != 0;
1545 r_offset = ((ext_rel->r_bits[1] & RELOC_BITS1_OFFSET_LITTLE)
1546 >> RELOC_BITS1_OFFSET_SH_LITTLE);
1547 /* Ignored the reserved bits. */
1548 r_size = ((ext_rel->r_bits[3] & RELOC_BITS3_SIZE_LITTLE)
1549 >> RELOC_BITS3_SIZE_SH_LITTLE);
1551 relocatep = FALSE;
1552 adjust_addrp = TRUE;
1553 gp_usedp = FALSE;
1554 addend = 0;
1556 switch (r_type)
1558 case ALPHA_R_GPRELHIGH:
1559 (*_bfd_error_handler)
1560 (_("%B: unsupported relocation: ALPHA_R_GPRELHIGH"),
1561 input_bfd);
1562 bfd_set_error (bfd_error_bad_value);
1563 continue;
1565 case ALPHA_R_GPRELLOW:
1566 (*_bfd_error_handler)
1567 (_("%B: unsupported relocation: ALPHA_R_GPRELLOW"),
1568 input_bfd);
1569 bfd_set_error (bfd_error_bad_value);
1570 continue;
1572 default:
1573 (*_bfd_error_handler)
1574 (_("%B: unknown relocation type %d"),
1575 input_bfd, (int) r_type);
1576 bfd_set_error (bfd_error_bad_value);
1577 continue;
1579 case ALPHA_R_IGNORE:
1580 /* This reloc appears after a GPDISP reloc. On earlier
1581 versions of OSF/1, It marked the position of the second
1582 instruction to be altered by the GPDISP reloc, but it is
1583 not otherwise used for anything. For some reason, the
1584 address of the relocation does not appear to include the
1585 section VMA, unlike the other relocation types. */
1586 if (info->relocatable)
1587 H_PUT_64 (input_bfd, input_section->output_offset + r_vaddr,
1588 ext_rel->r_vaddr);
1589 adjust_addrp = FALSE;
1590 break;
1592 case ALPHA_R_REFLONG:
1593 case ALPHA_R_REFQUAD:
1594 case ALPHA_R_HINT:
1595 relocatep = TRUE;
1596 break;
1598 case ALPHA_R_BRADDR:
1599 case ALPHA_R_SREL16:
1600 case ALPHA_R_SREL32:
1601 case ALPHA_R_SREL64:
1602 if (r_extern)
1603 addend += - (r_vaddr + 4);
1604 relocatep = TRUE;
1605 break;
1607 case ALPHA_R_GPREL32:
1608 /* This relocation is used in a switch table. It is a 32
1609 bit offset from the current GP value. We must adjust it
1610 by the different between the original GP value and the
1611 current GP value. */
1612 relocatep = TRUE;
1613 addend = ecoff_data (input_bfd)->gp - gp;
1614 gp_usedp = TRUE;
1615 break;
1617 case ALPHA_R_LITERAL:
1618 /* This is a reference to a literal value, generally
1619 (always?) in the .lita section. This is a 16 bit GP
1620 relative relocation. Sometimes the subsequent reloc is a
1621 LITUSE reloc, which indicates how this reloc is used.
1622 This sometimes permits rewriting the two instructions
1623 referred to by the LITERAL and the LITUSE into different
1624 instructions which do not refer to .lita. This can save
1625 a memory reference, and permits removing a value from
1626 .lita thus saving GP relative space.
1628 We do not these optimizations. To do them we would need
1629 to arrange to link the .lita section first, so that by
1630 the time we got here we would know the final values to
1631 use. This would not be particularly difficult, but it is
1632 not currently implemented. */
1634 /* I believe that the LITERAL reloc will only apply to a ldq
1635 or ldl instruction, so check my assumption. */
1637 unsigned long insn;
1639 insn = bfd_get_32 (input_bfd,
1640 contents + r_vaddr - input_section->vma);
1641 BFD_ASSERT (((insn >> 26) & 0x3f) == 0x29
1642 || ((insn >> 26) & 0x3f) == 0x28);
1645 relocatep = TRUE;
1646 addend = ecoff_data (input_bfd)->gp - gp;
1647 gp_usedp = TRUE;
1648 break;
1650 case ALPHA_R_LITUSE:
1651 /* See ALPHA_R_LITERAL above for the uses of this reloc. It
1652 does not cause anything to happen, itself. */
1653 break;
1655 case ALPHA_R_GPDISP:
1656 /* This marks the ldah of an ldah/lda pair which loads the
1657 gp register with the difference of the gp value and the
1658 current location. The second of the pair is r_symndx
1659 bytes ahead. It used to be marked with an ALPHA_R_IGNORE
1660 reloc, but OSF/1 3.2 no longer does that. */
1662 unsigned long insn1, insn2;
1664 /* Get the two instructions. */
1665 insn1 = bfd_get_32 (input_bfd,
1666 contents + r_vaddr - input_section->vma);
1667 insn2 = bfd_get_32 (input_bfd,
1668 (contents
1669 + r_vaddr
1670 - input_section->vma
1671 + r_symndx));
1673 BFD_ASSERT (((insn1 >> 26) & 0x3f) == 0x09); /* ldah */
1674 BFD_ASSERT (((insn2 >> 26) & 0x3f) == 0x08); /* lda */
1676 /* Get the existing addend. We must account for the sign
1677 extension done by lda and ldah. */
1678 addend = ((insn1 & 0xffff) << 16) + (insn2 & 0xffff);
1679 if (insn1 & 0x8000)
1681 /* This is addend -= 0x100000000 without causing an
1682 integer overflow on a 32 bit host. */
1683 addend -= 0x80000000;
1684 addend -= 0x80000000;
1686 if (insn2 & 0x8000)
1687 addend -= 0x10000;
1689 /* The existing addend includes the difference between the
1690 gp of the input BFD and the address in the input BFD.
1691 We want to change this to the difference between the
1692 final GP and the final address. */
1693 addend += (gp
1694 - ecoff_data (input_bfd)->gp
1695 + input_section->vma
1696 - (input_section->output_section->vma
1697 + input_section->output_offset));
1699 /* Change the instructions, accounting for the sign
1700 extension, and write them out. */
1701 if (addend & 0x8000)
1702 addend += 0x10000;
1703 insn1 = (insn1 & 0xffff0000) | ((addend >> 16) & 0xffff);
1704 insn2 = (insn2 & 0xffff0000) | (addend & 0xffff);
1706 bfd_put_32 (input_bfd, (bfd_vma) insn1,
1707 contents + r_vaddr - input_section->vma);
1708 bfd_put_32 (input_bfd, (bfd_vma) insn2,
1709 contents + r_vaddr - input_section->vma + r_symndx);
1711 gp_usedp = TRUE;
1713 break;
1715 case ALPHA_R_OP_PUSH:
1716 case ALPHA_R_OP_PSUB:
1717 case ALPHA_R_OP_PRSHIFT:
1718 /* Manipulate values on the reloc evaluation stack. The
1719 r_vaddr field is not an address in input_section, it is
1720 the current value (including any addend) of the object
1721 being used. */
1722 if (! r_extern)
1724 asection *s;
1726 s = symndx_to_section[r_symndx];
1727 if (s == (asection *) NULL)
1728 abort ();
1729 addend = s->output_section->vma + s->output_offset - s->vma;
1731 else
1733 struct ecoff_link_hash_entry *h;
1735 h = sym_hashes[r_symndx];
1736 if (h == (struct ecoff_link_hash_entry *) NULL)
1737 abort ();
1739 if (! info->relocatable)
1741 if (h->root.type == bfd_link_hash_defined
1742 || h->root.type == bfd_link_hash_defweak)
1743 addend = (h->root.u.def.value
1744 + h->root.u.def.section->output_section->vma
1745 + h->root.u.def.section->output_offset);
1746 else
1748 /* Note that we pass the address as 0, since we
1749 do not have a meaningful number for the
1750 location within the section that is being
1751 relocated. */
1752 if (! ((*info->callbacks->undefined_symbol)
1753 (info, h->root.root.string, input_bfd,
1754 input_section, (bfd_vma) 0, TRUE)))
1755 return FALSE;
1756 addend = 0;
1759 else
1761 if (h->root.type != bfd_link_hash_defined
1762 && h->root.type != bfd_link_hash_defweak
1763 && h->indx == -1)
1765 /* This symbol is not being written out. Pass
1766 the address as 0, as with undefined_symbol,
1767 above. */
1768 if (! ((*info->callbacks->unattached_reloc)
1769 (info, h->root.root.string, input_bfd,
1770 input_section, (bfd_vma) 0)))
1771 return FALSE;
1774 addend = alpha_convert_external_reloc (output_bfd, info,
1775 input_bfd,
1776 ext_rel, h);
1780 addend += r_vaddr;
1782 if (info->relocatable)
1784 /* Adjust r_vaddr by the addend. */
1785 H_PUT_64 (input_bfd, addend, ext_rel->r_vaddr);
1787 else
1789 switch (r_type)
1791 case ALPHA_R_OP_PUSH:
1792 if (tos >= RELOC_STACKSIZE)
1793 abort ();
1794 stack[tos++] = addend;
1795 break;
1797 case ALPHA_R_OP_PSUB:
1798 if (tos == 0)
1799 abort ();
1800 stack[tos - 1] -= addend;
1801 break;
1803 case ALPHA_R_OP_PRSHIFT:
1804 if (tos == 0)
1805 abort ();
1806 stack[tos - 1] >>= addend;
1807 break;
1811 adjust_addrp = FALSE;
1812 break;
1814 case ALPHA_R_OP_STORE:
1815 /* Store a value from the reloc stack into a bitfield. If
1816 we are generating relocatable output, all we do is
1817 adjust the address of the reloc. */
1818 if (! info->relocatable)
1820 bfd_vma mask;
1821 bfd_vma val;
1823 if (tos == 0)
1824 abort ();
1826 /* Get the relocation mask. The separate steps and the
1827 casts to bfd_vma are attempts to avoid a bug in the
1828 Alpha OSF 1.3 C compiler. See reloc.c for more
1829 details. */
1830 mask = 1;
1831 mask <<= (bfd_vma) r_size;
1832 mask -= 1;
1834 /* FIXME: I don't know what kind of overflow checking,
1835 if any, should be done here. */
1836 val = bfd_get_64 (input_bfd,
1837 contents + r_vaddr - input_section->vma);
1838 val &=~ mask << (bfd_vma) r_offset;
1839 val |= (stack[--tos] & mask) << (bfd_vma) r_offset;
1840 bfd_put_64 (input_bfd, val,
1841 contents + r_vaddr - input_section->vma);
1843 break;
1845 case ALPHA_R_GPVALUE:
1846 /* I really don't know if this does the right thing. */
1847 gp = ecoff_data (input_bfd)->gp + r_symndx;
1848 gp_undefined = FALSE;
1849 break;
1852 if (relocatep)
1854 reloc_howto_type *howto;
1855 struct ecoff_link_hash_entry *h = NULL;
1856 asection *s = NULL;
1857 bfd_vma relocation;
1858 bfd_reloc_status_type r;
1860 /* Perform a relocation. */
1862 howto = &alpha_howto_table[r_type];
1864 if (r_extern)
1866 h = sym_hashes[r_symndx];
1867 /* If h is NULL, that means that there is a reloc
1868 against an external symbol which we thought was just
1869 a debugging symbol. This should not happen. */
1870 if (h == (struct ecoff_link_hash_entry *) NULL)
1871 abort ();
1873 else
1875 if (r_symndx >= NUM_RELOC_SECTIONS)
1876 s = NULL;
1877 else
1878 s = symndx_to_section[r_symndx];
1880 if (s == (asection *) NULL)
1881 abort ();
1884 if (info->relocatable)
1886 /* We are generating relocatable output, and must
1887 convert the existing reloc. */
1888 if (r_extern)
1890 if (h->root.type != bfd_link_hash_defined
1891 && h->root.type != bfd_link_hash_defweak
1892 && h->indx == -1)
1894 /* This symbol is not being written out. */
1895 if (! ((*info->callbacks->unattached_reloc)
1896 (info, h->root.root.string, input_bfd,
1897 input_section, r_vaddr - input_section->vma)))
1898 return FALSE;
1901 relocation = alpha_convert_external_reloc (output_bfd,
1902 info,
1903 input_bfd,
1904 ext_rel,
1907 else
1909 /* This is a relocation against a section. Adjust
1910 the value by the amount the section moved. */
1911 relocation = (s->output_section->vma
1912 + s->output_offset
1913 - s->vma);
1916 /* If this is PC relative, the existing object file
1917 appears to already have the reloc worked out. We
1918 must subtract out the old value and add in the new
1919 one. */
1920 if (howto->pc_relative)
1921 relocation -= (input_section->output_section->vma
1922 + input_section->output_offset
1923 - input_section->vma);
1925 /* Put in any addend. */
1926 relocation += addend;
1928 /* Adjust the contents. */
1929 r = _bfd_relocate_contents (howto, input_bfd, relocation,
1930 (contents
1931 + r_vaddr
1932 - input_section->vma));
1934 else
1936 /* We are producing a final executable. */
1937 if (r_extern)
1939 /* This is a reloc against a symbol. */
1940 if (h->root.type == bfd_link_hash_defined
1941 || h->root.type == bfd_link_hash_defweak)
1943 asection *hsec;
1945 hsec = h->root.u.def.section;
1946 relocation = (h->root.u.def.value
1947 + hsec->output_section->vma
1948 + hsec->output_offset);
1950 else
1952 if (! ((*info->callbacks->undefined_symbol)
1953 (info, h->root.root.string, input_bfd,
1954 input_section,
1955 r_vaddr - input_section->vma, TRUE)))
1956 return FALSE;
1957 relocation = 0;
1960 else
1962 /* This is a reloc against a section. */
1963 relocation = (s->output_section->vma
1964 + s->output_offset
1965 - s->vma);
1967 /* Adjust a PC relative relocation by removing the
1968 reference to the original source section. */
1969 if (howto->pc_relative)
1970 relocation += input_section->vma;
1973 r = _bfd_final_link_relocate (howto,
1974 input_bfd,
1975 input_section,
1976 contents,
1977 r_vaddr - input_section->vma,
1978 relocation,
1979 addend);
1982 if (r != bfd_reloc_ok)
1984 switch (r)
1986 default:
1987 case bfd_reloc_outofrange:
1988 abort ();
1989 case bfd_reloc_overflow:
1991 const char *name;
1993 if (r_extern)
1994 name = sym_hashes[r_symndx]->root.root.string;
1995 else
1996 name = bfd_section_name (input_bfd,
1997 symndx_to_section[r_symndx]);
1998 if (! ((*info->callbacks->reloc_overflow)
1999 (info, NULL, name,
2000 alpha_howto_table[r_type].name,
2001 (bfd_vma) 0, input_bfd, input_section,
2002 r_vaddr - input_section->vma)))
2003 return FALSE;
2005 break;
2010 if (info->relocatable && adjust_addrp)
2012 /* Change the address of the relocation. */
2013 H_PUT_64 (input_bfd,
2014 (input_section->output_section->vma
2015 + input_section->output_offset
2016 - input_section->vma
2017 + r_vaddr),
2018 ext_rel->r_vaddr);
2021 if (gp_usedp && gp_undefined)
2023 if (! ((*info->callbacks->reloc_dangerous)
2024 (info, _("GP relative relocation used when GP not defined"),
2025 input_bfd, input_section, r_vaddr - input_section->vma)))
2026 return FALSE;
2027 /* Only give the error once per link. */
2028 gp = 4;
2029 _bfd_set_gp_value (output_bfd, gp);
2030 gp_undefined = FALSE;
2034 if (tos != 0)
2035 abort ();
2037 return TRUE;
2040 /* Do final adjustments to the filehdr and the aouthdr. This routine
2041 sets the dynamic bits in the file header. */
2043 static bfd_boolean
2044 alpha_adjust_headers (abfd, fhdr, ahdr)
2045 bfd *abfd;
2046 struct internal_filehdr *fhdr;
2047 struct internal_aouthdr *ahdr ATTRIBUTE_UNUSED;
2049 if ((abfd->flags & (DYNAMIC | EXEC_P)) == (DYNAMIC | EXEC_P))
2050 fhdr->f_flags |= F_ALPHA_CALL_SHARED;
2051 else if ((abfd->flags & DYNAMIC) != 0)
2052 fhdr->f_flags |= F_ALPHA_SHARABLE;
2053 return TRUE;
2056 /* Archive handling. In OSF/1 (or Digital Unix) v3.2, Digital
2057 introduced archive packing, in which the elements in an archive are
2058 optionally compressed using a simple dictionary scheme. We know
2059 how to read such archives, but we don't write them. */
2061 #define alpha_ecoff_slurp_armap _bfd_ecoff_slurp_armap
2062 #define alpha_ecoff_slurp_extended_name_table \
2063 _bfd_ecoff_slurp_extended_name_table
2064 #define alpha_ecoff_construct_extended_name_table \
2065 _bfd_ecoff_construct_extended_name_table
2066 #define alpha_ecoff_truncate_arname _bfd_ecoff_truncate_arname
2067 #define alpha_ecoff_write_armap _bfd_ecoff_write_armap
2068 #define alpha_ecoff_write_ar_hdr _bfd_generic_write_ar_hdr
2069 #define alpha_ecoff_generic_stat_arch_elt _bfd_ecoff_generic_stat_arch_elt
2070 #define alpha_ecoff_update_armap_timestamp _bfd_ecoff_update_armap_timestamp
2072 /* A compressed file uses this instead of ARFMAG. */
2074 #define ARFZMAG "Z\012"
2076 /* Read an archive header. This is like the standard routine, but it
2077 also accepts ARFZMAG. */
2079 static PTR
2080 alpha_ecoff_read_ar_hdr (abfd)
2081 bfd *abfd;
2083 struct areltdata *ret;
2084 struct ar_hdr *h;
2086 ret = (struct areltdata *) _bfd_generic_read_ar_hdr_mag (abfd, ARFZMAG);
2087 if (ret == NULL)
2088 return NULL;
2090 h = (struct ar_hdr *) ret->arch_header;
2091 if (strncmp (h->ar_fmag, ARFZMAG, 2) == 0)
2093 bfd_byte ab[8];
2095 /* This is a compressed file. We must set the size correctly.
2096 The size is the eight bytes after the dummy file header. */
2097 if (bfd_seek (abfd, (file_ptr) FILHSZ, SEEK_CUR) != 0
2098 || bfd_bread (ab, (bfd_size_type) 8, abfd) != 8
2099 || bfd_seek (abfd, (file_ptr) (- (FILHSZ + 8)), SEEK_CUR) != 0)
2100 return NULL;
2102 ret->parsed_size = H_GET_64 (abfd, ab);
2105 return (PTR) ret;
2108 /* Get an archive element at a specified file position. This is where
2109 we uncompress the archive element if necessary. */
2111 static bfd *
2112 alpha_ecoff_get_elt_at_filepos (archive, filepos)
2113 bfd *archive;
2114 file_ptr filepos;
2116 bfd *nbfd = NULL;
2117 struct areltdata *tdata;
2118 struct ar_hdr *hdr;
2119 bfd_byte ab[8];
2120 bfd_size_type size;
2121 bfd_byte *buf, *p;
2122 struct bfd_in_memory *bim;
2124 buf = NULL;
2125 nbfd = _bfd_get_elt_at_filepos (archive, filepos);
2126 if (nbfd == NULL)
2127 goto error_return;
2129 if ((nbfd->flags & BFD_IN_MEMORY) != 0)
2131 /* We have already expanded this BFD. */
2132 return nbfd;
2135 tdata = (struct areltdata *) nbfd->arelt_data;
2136 hdr = (struct ar_hdr *) tdata->arch_header;
2137 if (strncmp (hdr->ar_fmag, ARFZMAG, 2) != 0)
2138 return nbfd;
2140 /* We must uncompress this element. We do this by copying it into a
2141 memory buffer, and making bfd_bread and bfd_seek use that buffer.
2142 This can use a lot of memory, but it's simpler than getting a
2143 temporary file, making that work with the file descriptor caching
2144 code, and making sure that it is deleted at all appropriate
2145 times. It can be changed if it ever becomes important. */
2147 /* The compressed file starts with a dummy ECOFF file header. */
2148 if (bfd_seek (nbfd, (file_ptr) FILHSZ, SEEK_SET) != 0)
2149 goto error_return;
2151 /* The next eight bytes are the real file size. */
2152 if (bfd_bread (ab, (bfd_size_type) 8, nbfd) != 8)
2153 goto error_return;
2154 size = H_GET_64 (nbfd, ab);
2156 if (size != 0)
2158 bfd_size_type left;
2159 bfd_byte dict[4096];
2160 unsigned int h;
2161 bfd_byte b;
2163 buf = (bfd_byte *) bfd_malloc (size);
2164 if (buf == NULL)
2165 goto error_return;
2166 p = buf;
2168 left = size;
2170 /* I don't know what the next eight bytes are for. */
2171 if (bfd_bread (ab, (bfd_size_type) 8, nbfd) != 8)
2172 goto error_return;
2174 /* This is the uncompression algorithm. It's a simple
2175 dictionary based scheme in which each character is predicted
2176 by a hash of the previous three characters. A control byte
2177 indicates whether the character is predicted or whether it
2178 appears in the input stream; each control byte manages the
2179 next eight bytes in the output stream. */
2180 memset (dict, 0, sizeof dict);
2181 h = 0;
2182 while (bfd_bread (&b, (bfd_size_type) 1, nbfd) == 1)
2184 unsigned int i;
2186 for (i = 0; i < 8; i++, b >>= 1)
2188 bfd_byte n;
2190 if ((b & 1) == 0)
2191 n = dict[h];
2192 else
2194 if (! bfd_bread (&n, (bfd_size_type) 1, nbfd))
2195 goto error_return;
2196 dict[h] = n;
2199 *p++ = n;
2201 --left;
2202 if (left == 0)
2203 break;
2205 h <<= 4;
2206 h ^= n;
2207 h &= sizeof dict - 1;
2210 if (left == 0)
2211 break;
2215 /* Now the uncompressed file contents are in buf. */
2216 bim = ((struct bfd_in_memory *)
2217 bfd_malloc ((bfd_size_type) sizeof (struct bfd_in_memory)));
2218 if (bim == NULL)
2219 goto error_return;
2220 bim->size = size;
2221 bim->buffer = buf;
2223 nbfd->mtime_set = TRUE;
2224 nbfd->mtime = strtol (hdr->ar_date, (char **) NULL, 10);
2226 nbfd->flags |= BFD_IN_MEMORY;
2227 nbfd->iostream = (PTR) bim;
2228 BFD_ASSERT (! nbfd->cacheable);
2230 return nbfd;
2232 error_return:
2233 if (buf != NULL)
2234 free (buf);
2235 if (nbfd != NULL)
2236 bfd_close (nbfd);
2237 return NULL;
2240 /* Open the next archived file. */
2242 static bfd *
2243 alpha_ecoff_openr_next_archived_file (archive, last_file)
2244 bfd *archive;
2245 bfd *last_file;
2247 file_ptr filestart;
2249 if (last_file == NULL)
2250 filestart = bfd_ardata (archive)->first_file_filepos;
2251 else
2253 struct areltdata *t;
2254 struct ar_hdr *h;
2255 bfd_size_type size;
2257 /* We can't use arelt_size here, because that uses parsed_size,
2258 which is the uncompressed size. We need the compressed size. */
2259 t = (struct areltdata *) last_file->arelt_data;
2260 h = (struct ar_hdr *) t->arch_header;
2261 size = strtol (h->ar_size, (char **) NULL, 10);
2263 /* Pad to an even boundary...
2264 Note that last_file->origin can be odd in the case of
2265 BSD-4.4-style element with a long odd size. */
2266 filestart = last_file->origin + size;
2267 filestart += filestart % 2;
2270 return alpha_ecoff_get_elt_at_filepos (archive, filestart);
2273 /* Open the archive file given an index into the armap. */
2275 static bfd *
2276 alpha_ecoff_get_elt_at_index (bfd *abfd, symindex sym_index)
2278 carsym *entry;
2280 entry = bfd_ardata (abfd)->symdefs + sym_index;
2281 return alpha_ecoff_get_elt_at_filepos (abfd, entry->file_offset);
2284 /* This is the ECOFF backend structure. The backend field of the
2285 target vector points to this. */
2287 static const struct ecoff_backend_data alpha_ecoff_backend_data =
2289 /* COFF backend structure. */
2291 (void (*) PARAMS ((bfd *,PTR,int,int,int,int,PTR))) bfd_void, /* aux_in */
2292 (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_in */
2293 (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_in */
2294 (unsigned (*) PARAMS ((bfd *,PTR,int,int,int,int,PTR)))bfd_void,/*aux_out*/
2295 (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_out */
2296 (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_out */
2297 (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* reloc_out */
2298 alpha_ecoff_swap_filehdr_out, alpha_ecoff_swap_aouthdr_out,
2299 alpha_ecoff_swap_scnhdr_out,
2300 FILHSZ, AOUTSZ, SCNHSZ, 0, 0, 0, 0, FILNMLEN, TRUE,
2301 ECOFF_NO_LONG_SECTION_NAMES, 4, FALSE, 2,
2302 alpha_ecoff_swap_filehdr_in, alpha_ecoff_swap_aouthdr_in,
2303 alpha_ecoff_swap_scnhdr_in, NULL,
2304 alpha_ecoff_bad_format_hook, _bfd_ecoff_set_arch_mach_hook,
2305 alpha_ecoff_mkobject_hook, _bfd_ecoff_styp_to_sec_flags,
2306 _bfd_ecoff_set_alignment_hook, _bfd_ecoff_slurp_symbol_table,
2307 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2308 NULL, NULL, NULL, NULL
2310 /* Supported architecture. */
2311 bfd_arch_alpha,
2312 /* Initial portion of armap string. */
2313 "________64",
2314 /* The page boundary used to align sections in a demand-paged
2315 executable file. E.g., 0x1000. */
2316 0x2000,
2317 /* TRUE if the .rdata section is part of the text segment, as on the
2318 Alpha. FALSE if .rdata is part of the data segment, as on the
2319 MIPS. */
2320 TRUE,
2321 /* Bitsize of constructor entries. */
2323 /* Reloc to use for constructor entries. */
2324 &alpha_howto_table[ALPHA_R_REFQUAD],
2326 /* Symbol table magic number. */
2327 magicSym2,
2328 /* Alignment of debugging information. E.g., 4. */
2330 /* Sizes of external symbolic information. */
2331 sizeof (struct hdr_ext),
2332 sizeof (struct dnr_ext),
2333 sizeof (struct pdr_ext),
2334 sizeof (struct sym_ext),
2335 sizeof (struct opt_ext),
2336 sizeof (struct fdr_ext),
2337 sizeof (struct rfd_ext),
2338 sizeof (struct ext_ext),
2339 /* Functions to swap in external symbolic data. */
2340 ecoff_swap_hdr_in,
2341 ecoff_swap_dnr_in,
2342 ecoff_swap_pdr_in,
2343 ecoff_swap_sym_in,
2344 ecoff_swap_opt_in,
2345 ecoff_swap_fdr_in,
2346 ecoff_swap_rfd_in,
2347 ecoff_swap_ext_in,
2348 _bfd_ecoff_swap_tir_in,
2349 _bfd_ecoff_swap_rndx_in,
2350 /* Functions to swap out external symbolic data. */
2351 ecoff_swap_hdr_out,
2352 ecoff_swap_dnr_out,
2353 ecoff_swap_pdr_out,
2354 ecoff_swap_sym_out,
2355 ecoff_swap_opt_out,
2356 ecoff_swap_fdr_out,
2357 ecoff_swap_rfd_out,
2358 ecoff_swap_ext_out,
2359 _bfd_ecoff_swap_tir_out,
2360 _bfd_ecoff_swap_rndx_out,
2361 /* Function to read in symbolic data. */
2362 _bfd_ecoff_slurp_symbolic_info
2364 /* External reloc size. */
2365 RELSZ,
2366 /* Reloc swapping functions. */
2367 alpha_ecoff_swap_reloc_in,
2368 alpha_ecoff_swap_reloc_out,
2369 /* Backend reloc tweaking. */
2370 alpha_adjust_reloc_in,
2371 alpha_adjust_reloc_out,
2372 /* Relocate section contents while linking. */
2373 alpha_relocate_section,
2374 /* Do final adjustments to filehdr and aouthdr. */
2375 alpha_adjust_headers,
2376 /* Read an element from an archive at a given file position. */
2377 alpha_ecoff_get_elt_at_filepos
2380 /* Looking up a reloc type is Alpha specific. */
2381 #define _bfd_ecoff_bfd_reloc_type_lookup alpha_bfd_reloc_type_lookup
2382 #define _bfd_ecoff_bfd_reloc_name_lookup \
2383 alpha_bfd_reloc_name_lookup
2385 /* So is getting relocated section contents. */
2386 #define _bfd_ecoff_bfd_get_relocated_section_contents \
2387 alpha_ecoff_get_relocated_section_contents
2389 /* Handling file windows is generic. */
2390 #define _bfd_ecoff_get_section_contents_in_window \
2391 _bfd_generic_get_section_contents_in_window
2393 /* Relaxing sections is generic. */
2394 #define _bfd_ecoff_bfd_relax_section bfd_generic_relax_section
2395 #define _bfd_ecoff_bfd_gc_sections bfd_generic_gc_sections
2396 #define _bfd_ecoff_bfd_merge_sections bfd_generic_merge_sections
2397 #define _bfd_ecoff_bfd_is_group_section bfd_generic_is_group_section
2398 #define _bfd_ecoff_bfd_discard_group bfd_generic_discard_group
2399 #define _bfd_ecoff_section_already_linked \
2400 _bfd_generic_section_already_linked
2401 #define _bfd_ecoff_bfd_define_common_symbol bfd_generic_define_common_symbol
2403 const bfd_target ecoffalpha_little_vec =
2405 "ecoff-littlealpha", /* name */
2406 bfd_target_ecoff_flavour,
2407 BFD_ENDIAN_LITTLE, /* data byte order is little */
2408 BFD_ENDIAN_LITTLE, /* header byte order is little */
2410 (HAS_RELOC | EXEC_P | /* object flags */
2411 HAS_LINENO | HAS_DEBUG |
2412 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
2414 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
2415 0, /* leading underscore */
2416 ' ', /* ar_pad_char */
2417 15, /* ar_max_namelen */
2418 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
2419 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
2420 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
2421 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
2422 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
2423 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
2425 {_bfd_dummy_target, alpha_ecoff_object_p, /* bfd_check_format */
2426 bfd_generic_archive_p, _bfd_dummy_target},
2427 {bfd_false, _bfd_ecoff_mkobject, /* bfd_set_format */
2428 _bfd_generic_mkarchive, bfd_false},
2429 {bfd_false, _bfd_ecoff_write_object_contents, /* bfd_write_contents */
2430 _bfd_write_archive_contents, bfd_false},
2432 BFD_JUMP_TABLE_GENERIC (_bfd_ecoff),
2433 BFD_JUMP_TABLE_COPY (_bfd_ecoff),
2434 BFD_JUMP_TABLE_CORE (_bfd_nocore),
2435 BFD_JUMP_TABLE_ARCHIVE (alpha_ecoff),
2436 BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff),
2437 BFD_JUMP_TABLE_RELOCS (_bfd_ecoff),
2438 BFD_JUMP_TABLE_WRITE (_bfd_ecoff),
2439 BFD_JUMP_TABLE_LINK (_bfd_ecoff),
2440 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
2442 NULL,
2444 (PTR) &alpha_ecoff_backend_data