* hosts/alphalinux.h (TRAD_CORE_EXTRA_SIZE_ALLOWED): Expand to 4096.
[binutils.git] / bfd / coff-alpha.c
blobd841663edd55fcf2c2211c12294b53073246accb
1 /* BFD back-end for ALPHA Extended-Coff files.
2 Copyright 1993, 94, 95, 96, 1997 Free Software Foundation, Inc.
3 Modified from coff-mips.c by Steve Chamberlain <sac@cygnus.com> and
4 Ian Lance Taylor <ian@cygnus.com>.
6 This file is part of BFD, the Binary File Descriptor library.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22 #include "bfd.h"
23 #include "sysdep.h"
24 #include "bfdlink.h"
25 #include "libbfd.h"
26 #include "coff/internal.h"
27 #include "coff/sym.h"
28 #include "coff/symconst.h"
29 #include "coff/ecoff.h"
30 #include "coff/alpha.h"
31 #include "aout/ar.h"
32 #include "libcoff.h"
33 #include "libecoff.h"
35 /* Prototypes for static functions. */
37 static const bfd_target *alpha_ecoff_object_p PARAMS ((bfd *));
38 static boolean alpha_ecoff_bad_format_hook PARAMS ((bfd *abfd, PTR filehdr));
39 static PTR alpha_ecoff_mkobject_hook PARAMS ((bfd *, PTR filehdr, PTR aouthdr));
40 static void alpha_ecoff_swap_reloc_in PARAMS ((bfd *, PTR,
41 struct internal_reloc *));
42 static void alpha_ecoff_swap_reloc_out PARAMS ((bfd *,
43 const struct internal_reloc *,
44 PTR));
45 static void alpha_adjust_reloc_in PARAMS ((bfd *,
46 const struct internal_reloc *,
47 arelent *));
48 static void alpha_adjust_reloc_out PARAMS ((bfd *, const arelent *,
49 struct internal_reloc *));
50 static reloc_howto_type *alpha_bfd_reloc_type_lookup
51 PARAMS ((bfd *, bfd_reloc_code_real_type));
52 static bfd_byte *alpha_ecoff_get_relocated_section_contents
53 PARAMS ((bfd *abfd, struct bfd_link_info *, struct bfd_link_order *,
54 bfd_byte *data, boolean relocateable, asymbol **symbols));
55 static bfd_vma alpha_convert_external_reloc
56 PARAMS ((bfd *, struct bfd_link_info *, bfd *, struct external_reloc *,
57 struct ecoff_link_hash_entry *));
58 static boolean alpha_relocate_section PARAMS ((bfd *, struct bfd_link_info *,
59 bfd *, asection *,
60 bfd_byte *, PTR));
61 static boolean alpha_adjust_headers
62 PARAMS ((bfd *, struct internal_filehdr *, struct internal_aouthdr *));
63 static PTR alpha_ecoff_read_ar_hdr PARAMS ((bfd *));
64 static bfd *alpha_ecoff_get_elt_at_filepos PARAMS ((bfd *, file_ptr));
65 static bfd *alpha_ecoff_openr_next_archived_file PARAMS ((bfd *, bfd *));
66 static bfd *alpha_ecoff_get_elt_at_index PARAMS ((bfd *, symindex));
68 /* ECOFF has COFF sections, but the debugging information is stored in
69 a completely different format. ECOFF targets use some of the
70 swapping routines from coffswap.h, and some of the generic COFF
71 routines in coffgen.c, but, unlike the real COFF targets, do not
72 use coffcode.h itself.
74 Get the generic COFF swapping routines, except for the reloc,
75 symbol, and lineno ones. Give them ecoff names. Define some
76 accessor macros for the large sizes used for Alpha ECOFF. */
78 #define GET_FILEHDR_SYMPTR bfd_h_get_64
79 #define PUT_FILEHDR_SYMPTR bfd_h_put_64
80 #define GET_AOUTHDR_TSIZE bfd_h_get_64
81 #define PUT_AOUTHDR_TSIZE bfd_h_put_64
82 #define GET_AOUTHDR_DSIZE bfd_h_get_64
83 #define PUT_AOUTHDR_DSIZE bfd_h_put_64
84 #define GET_AOUTHDR_BSIZE bfd_h_get_64
85 #define PUT_AOUTHDR_BSIZE bfd_h_put_64
86 #define GET_AOUTHDR_ENTRY bfd_h_get_64
87 #define PUT_AOUTHDR_ENTRY bfd_h_put_64
88 #define GET_AOUTHDR_TEXT_START bfd_h_get_64
89 #define PUT_AOUTHDR_TEXT_START bfd_h_put_64
90 #define GET_AOUTHDR_DATA_START bfd_h_get_64
91 #define PUT_AOUTHDR_DATA_START bfd_h_put_64
92 #define GET_SCNHDR_PADDR bfd_h_get_64
93 #define PUT_SCNHDR_PADDR bfd_h_put_64
94 #define GET_SCNHDR_VADDR bfd_h_get_64
95 #define PUT_SCNHDR_VADDR bfd_h_put_64
96 #define GET_SCNHDR_SIZE bfd_h_get_64
97 #define PUT_SCNHDR_SIZE bfd_h_put_64
98 #define GET_SCNHDR_SCNPTR bfd_h_get_64
99 #define PUT_SCNHDR_SCNPTR bfd_h_put_64
100 #define GET_SCNHDR_RELPTR bfd_h_get_64
101 #define PUT_SCNHDR_RELPTR bfd_h_put_64
102 #define GET_SCNHDR_LNNOPTR bfd_h_get_64
103 #define PUT_SCNHDR_LNNOPTR bfd_h_put_64
105 #define ALPHAECOFF
107 #define NO_COFF_RELOCS
108 #define NO_COFF_SYMBOLS
109 #define NO_COFF_LINENOS
110 #define coff_swap_filehdr_in alpha_ecoff_swap_filehdr_in
111 #define coff_swap_filehdr_out alpha_ecoff_swap_filehdr_out
112 #define coff_swap_aouthdr_in alpha_ecoff_swap_aouthdr_in
113 #define coff_swap_aouthdr_out alpha_ecoff_swap_aouthdr_out
114 #define coff_swap_scnhdr_in alpha_ecoff_swap_scnhdr_in
115 #define coff_swap_scnhdr_out alpha_ecoff_swap_scnhdr_out
116 #include "coffswap.h"
118 /* Get the ECOFF swapping routines. */
119 #define ECOFF_64
120 #include "ecoffswap.h"
122 /* How to process the various reloc types. */
124 static bfd_reloc_status_type
125 reloc_nil PARAMS ((bfd *, arelent *, asymbol *, PTR,
126 asection *, bfd *, char **));
128 static bfd_reloc_status_type
129 reloc_nil (abfd, reloc, sym, data, sec, output_bfd, error_message)
130 bfd *abfd;
131 arelent *reloc;
132 asymbol *sym;
133 PTR data;
134 asection *sec;
135 bfd *output_bfd;
136 char **error_message;
138 return bfd_reloc_ok;
141 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
142 from smaller values. Start with zero, widen, *then* decrement. */
143 #define MINUS_ONE (((bfd_vma)0) - 1)
145 static reloc_howto_type alpha_howto_table[] =
147 /* Reloc type 0 is ignored by itself. However, it appears after a
148 GPDISP reloc to identify the location where the low order 16 bits
149 of the gp register are loaded. */
150 HOWTO (ALPHA_R_IGNORE, /* type */
151 0, /* rightshift */
152 0, /* size (0 = byte, 1 = short, 2 = long) */
153 8, /* bitsize */
154 true, /* pc_relative */
155 0, /* bitpos */
156 complain_overflow_dont, /* complain_on_overflow */
157 reloc_nil, /* special_function */
158 "IGNORE", /* name */
159 true, /* partial_inplace */
160 0, /* src_mask */
161 0, /* dst_mask */
162 true), /* pcrel_offset */
164 /* A 32 bit reference to a symbol. */
165 HOWTO (ALPHA_R_REFLONG, /* type */
166 0, /* rightshift */
167 2, /* size (0 = byte, 1 = short, 2 = long) */
168 32, /* bitsize */
169 false, /* pc_relative */
170 0, /* bitpos */
171 complain_overflow_bitfield, /* complain_on_overflow */
172 0, /* special_function */
173 "REFLONG", /* name */
174 true, /* partial_inplace */
175 0xffffffff, /* src_mask */
176 0xffffffff, /* dst_mask */
177 false), /* pcrel_offset */
179 /* A 64 bit reference to a symbol. */
180 HOWTO (ALPHA_R_REFQUAD, /* type */
181 0, /* rightshift */
182 4, /* size (0 = byte, 1 = short, 2 = long) */
183 64, /* bitsize */
184 false, /* pc_relative */
185 0, /* bitpos */
186 complain_overflow_bitfield, /* complain_on_overflow */
187 0, /* special_function */
188 "REFQUAD", /* name */
189 true, /* partial_inplace */
190 MINUS_ONE, /* src_mask */
191 MINUS_ONE, /* dst_mask */
192 false), /* pcrel_offset */
194 /* A 32 bit GP relative offset. This is just like REFLONG except
195 that when the value is used the value of the gp register will be
196 added in. */
197 HOWTO (ALPHA_R_GPREL32, /* type */
198 0, /* rightshift */
199 2, /* size (0 = byte, 1 = short, 2 = long) */
200 32, /* bitsize */
201 false, /* pc_relative */
202 0, /* bitpos */
203 complain_overflow_bitfield, /* complain_on_overflow */
204 0, /* special_function */
205 "GPREL32", /* name */
206 true, /* partial_inplace */
207 0xffffffff, /* src_mask */
208 0xffffffff, /* dst_mask */
209 false), /* pcrel_offset */
211 /* Used for an instruction that refers to memory off the GP
212 register. The offset is 16 bits of the 32 bit instruction. This
213 reloc always seems to be against the .lita section. */
214 HOWTO (ALPHA_R_LITERAL, /* type */
215 0, /* rightshift */
216 2, /* size (0 = byte, 1 = short, 2 = long) */
217 16, /* bitsize */
218 false, /* pc_relative */
219 0, /* bitpos */
220 complain_overflow_signed, /* complain_on_overflow */
221 0, /* special_function */
222 "LITERAL", /* name */
223 true, /* partial_inplace */
224 0xffff, /* src_mask */
225 0xffff, /* dst_mask */
226 false), /* pcrel_offset */
228 /* This reloc only appears immediately following a LITERAL reloc.
229 It identifies a use of the literal. It seems that the linker can
230 use this to eliminate a portion of the .lita section. The symbol
231 index is special: 1 means the literal address is in the base
232 register of a memory format instruction; 2 means the literal
233 address is in the byte offset register of a byte-manipulation
234 instruction; 3 means the literal address is in the target
235 register of a jsr instruction. This does not actually do any
236 relocation. */
237 HOWTO (ALPHA_R_LITUSE, /* type */
238 0, /* rightshift */
239 2, /* size (0 = byte, 1 = short, 2 = long) */
240 32, /* bitsize */
241 false, /* pc_relative */
242 0, /* bitpos */
243 complain_overflow_dont, /* complain_on_overflow */
244 reloc_nil, /* special_function */
245 "LITUSE", /* name */
246 false, /* partial_inplace */
247 0, /* src_mask */
248 0, /* dst_mask */
249 false), /* pcrel_offset */
251 /* Load the gp register. This is always used for a ldah instruction
252 which loads the upper 16 bits of the gp register. The next reloc
253 will be an IGNORE reloc which identifies the location of the lda
254 instruction which loads the lower 16 bits. The symbol index of
255 the GPDISP instruction appears to actually be the number of bytes
256 between the ldah and lda instructions. This gives two different
257 ways to determine where the lda instruction is; I don't know why
258 both are used. The value to use for the relocation is the
259 difference between the GP value and the current location; the
260 load will always be done against a register holding the current
261 address. */
262 HOWTO (ALPHA_R_GPDISP, /* type */
263 16, /* rightshift */
264 2, /* size (0 = byte, 1 = short, 2 = long) */
265 16, /* bitsize */
266 true, /* pc_relative */
267 0, /* bitpos */
268 complain_overflow_dont, /* complain_on_overflow */
269 reloc_nil, /* special_function */
270 "GPDISP", /* name */
271 true, /* partial_inplace */
272 0xffff, /* src_mask */
273 0xffff, /* dst_mask */
274 true), /* pcrel_offset */
276 /* A 21 bit branch. The native assembler generates these for
277 branches within the text segment, and also fills in the PC
278 relative offset in the instruction. */
279 HOWTO (ALPHA_R_BRADDR, /* type */
280 2, /* rightshift */
281 2, /* size (0 = byte, 1 = short, 2 = long) */
282 21, /* bitsize */
283 true, /* pc_relative */
284 0, /* bitpos */
285 complain_overflow_signed, /* complain_on_overflow */
286 0, /* special_function */
287 "BRADDR", /* name */
288 true, /* partial_inplace */
289 0x1fffff, /* src_mask */
290 0x1fffff, /* dst_mask */
291 false), /* pcrel_offset */
293 /* A hint for a jump to a register. */
294 HOWTO (ALPHA_R_HINT, /* type */
295 2, /* rightshift */
296 2, /* size (0 = byte, 1 = short, 2 = long) */
297 14, /* bitsize */
298 true, /* pc_relative */
299 0, /* bitpos */
300 complain_overflow_dont, /* complain_on_overflow */
301 0, /* special_function */
302 "HINT", /* name */
303 true, /* partial_inplace */
304 0x3fff, /* src_mask */
305 0x3fff, /* dst_mask */
306 false), /* pcrel_offset */
308 /* 16 bit PC relative offset. */
309 HOWTO (ALPHA_R_SREL16, /* type */
310 0, /* rightshift */
311 1, /* size (0 = byte, 1 = short, 2 = long) */
312 16, /* bitsize */
313 true, /* pc_relative */
314 0, /* bitpos */
315 complain_overflow_signed, /* complain_on_overflow */
316 0, /* special_function */
317 "SREL16", /* name */
318 true, /* partial_inplace */
319 0xffff, /* src_mask */
320 0xffff, /* dst_mask */
321 false), /* pcrel_offset */
323 /* 32 bit PC relative offset. */
324 HOWTO (ALPHA_R_SREL32, /* type */
325 0, /* rightshift */
326 2, /* size (0 = byte, 1 = short, 2 = long) */
327 32, /* bitsize */
328 true, /* pc_relative */
329 0, /* bitpos */
330 complain_overflow_signed, /* complain_on_overflow */
331 0, /* special_function */
332 "SREL32", /* name */
333 true, /* partial_inplace */
334 0xffffffff, /* src_mask */
335 0xffffffff, /* dst_mask */
336 false), /* pcrel_offset */
338 /* A 64 bit PC relative offset. */
339 HOWTO (ALPHA_R_SREL64, /* type */
340 0, /* rightshift */
341 4, /* size (0 = byte, 1 = short, 2 = long) */
342 64, /* bitsize */
343 true, /* pc_relative */
344 0, /* bitpos */
345 complain_overflow_signed, /* complain_on_overflow */
346 0, /* special_function */
347 "SREL64", /* name */
348 true, /* partial_inplace */
349 MINUS_ONE, /* src_mask */
350 MINUS_ONE, /* dst_mask */
351 false), /* pcrel_offset */
353 /* Push a value on the reloc evaluation stack. */
354 HOWTO (ALPHA_R_OP_PUSH, /* type */
355 0, /* rightshift */
356 0, /* size (0 = byte, 1 = short, 2 = long) */
357 0, /* bitsize */
358 false, /* pc_relative */
359 0, /* bitpos */
360 complain_overflow_dont, /* complain_on_overflow */
361 0, /* special_function */
362 "OP_PUSH", /* name */
363 false, /* partial_inplace */
364 0, /* src_mask */
365 0, /* dst_mask */
366 false), /* pcrel_offset */
368 /* Store the value from the stack at the given address. Store it in
369 a bitfield of size r_size starting at bit position r_offset. */
370 HOWTO (ALPHA_R_OP_STORE, /* type */
371 0, /* rightshift */
372 4, /* size (0 = byte, 1 = short, 2 = long) */
373 64, /* bitsize */
374 false, /* pc_relative */
375 0, /* bitpos */
376 complain_overflow_dont, /* complain_on_overflow */
377 0, /* special_function */
378 "OP_STORE", /* name */
379 false, /* partial_inplace */
380 0, /* src_mask */
381 MINUS_ONE, /* dst_mask */
382 false), /* pcrel_offset */
384 /* Subtract the reloc address from the value on the top of the
385 relocation stack. */
386 HOWTO (ALPHA_R_OP_PSUB, /* type */
387 0, /* rightshift */
388 0, /* size (0 = byte, 1 = short, 2 = long) */
389 0, /* bitsize */
390 false, /* pc_relative */
391 0, /* bitpos */
392 complain_overflow_dont, /* complain_on_overflow */
393 0, /* special_function */
394 "OP_PSUB", /* name */
395 false, /* partial_inplace */
396 0, /* src_mask */
397 0, /* dst_mask */
398 false), /* pcrel_offset */
400 /* Shift the value on the top of the relocation stack right by the
401 given value. */
402 HOWTO (ALPHA_R_OP_PRSHIFT, /* type */
403 0, /* rightshift */
404 0, /* size (0 = byte, 1 = short, 2 = long) */
405 0, /* bitsize */
406 false, /* pc_relative */
407 0, /* bitpos */
408 complain_overflow_dont, /* complain_on_overflow */
409 0, /* special_function */
410 "OP_PRSHIFT", /* name */
411 false, /* partial_inplace */
412 0, /* src_mask */
413 0, /* dst_mask */
414 false), /* pcrel_offset */
416 /* Adjust the GP value for a new range in the object file. */
417 HOWTO (ALPHA_R_GPVALUE, /* type */
418 0, /* rightshift */
419 0, /* size (0 = byte, 1 = short, 2 = long) */
420 0, /* bitsize */
421 false, /* pc_relative */
422 0, /* bitpos */
423 complain_overflow_dont, /* complain_on_overflow */
424 0, /* special_function */
425 "GPVALUE", /* name */
426 false, /* partial_inplace */
427 0, /* src_mask */
428 0, /* dst_mask */
429 false) /* pcrel_offset */
432 /* Recognize an Alpha ECOFF file. */
434 static const bfd_target *
435 alpha_ecoff_object_p (abfd)
436 bfd *abfd;
438 static const bfd_target *ret;
440 ret = coff_object_p (abfd);
442 if (ret != NULL)
444 asection *sec;
446 /* Alpha ECOFF has a .pdata section. The lnnoptr field of the
447 .pdata section is the number of entries it contains. Each
448 entry takes up 8 bytes. The number of entries is required
449 since the section is aligned to a 16 byte boundary. When we
450 link .pdata sections together, we do not want to include the
451 alignment bytes. We handle this on input by faking the size
452 of the .pdata section to remove the unwanted alignment bytes.
453 On output we will set the lnnoptr field and force the
454 alignment. */
455 sec = bfd_get_section_by_name (abfd, _PDATA);
456 if (sec != (asection *) NULL)
458 bfd_size_type size;
460 size = sec->line_filepos * 8;
461 BFD_ASSERT (size == bfd_section_size (abfd, sec)
462 || size + 8 == bfd_section_size (abfd, sec));
463 if (! bfd_set_section_size (abfd, sec, size))
464 return NULL;
468 return ret;
471 /* See whether the magic number matches. */
473 static boolean
474 alpha_ecoff_bad_format_hook (abfd, filehdr)
475 bfd *abfd;
476 PTR filehdr;
478 struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
480 if (ALPHA_ECOFF_BADMAG (*internal_f))
481 return false;
483 return true;
486 /* This is a hook called by coff_real_object_p to create any backend
487 specific information. */
489 static PTR
490 alpha_ecoff_mkobject_hook (abfd, filehdr, aouthdr)
491 bfd *abfd;
492 PTR filehdr;
493 PTR aouthdr;
495 PTR ecoff;
497 ecoff = _bfd_ecoff_mkobject_hook (abfd, filehdr, aouthdr);
499 if (ecoff != NULL)
501 struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
503 /* Set additional BFD flags according to the object type from the
504 machine specific file header flags. */
505 switch (internal_f->f_flags & F_ALPHA_OBJECT_TYPE_MASK)
507 case F_ALPHA_SHARABLE:
508 abfd->flags |= DYNAMIC;
509 break;
510 case F_ALPHA_CALL_SHARED:
511 /* Always executable if using shared libraries as the run time
512 loader might resolve undefined references. */
513 abfd->flags |= (DYNAMIC | EXEC_P);
514 break;
517 return ecoff;
520 /* Reloc handling. */
522 /* Swap a reloc in. */
524 static void
525 alpha_ecoff_swap_reloc_in (abfd, ext_ptr, intern)
526 bfd *abfd;
527 PTR ext_ptr;
528 struct internal_reloc *intern;
530 const RELOC *ext = (RELOC *) ext_ptr;
532 intern->r_vaddr = bfd_h_get_64 (abfd, (bfd_byte *) ext->r_vaddr);
533 intern->r_symndx = bfd_h_get_32 (abfd, (bfd_byte *) ext->r_symndx);
535 BFD_ASSERT (bfd_header_little_endian (abfd));
537 intern->r_type = ((ext->r_bits[0] & RELOC_BITS0_TYPE_LITTLE)
538 >> RELOC_BITS0_TYPE_SH_LITTLE);
539 intern->r_extern = (ext->r_bits[1] & RELOC_BITS1_EXTERN_LITTLE) != 0;
540 intern->r_offset = ((ext->r_bits[1] & RELOC_BITS1_OFFSET_LITTLE)
541 >> RELOC_BITS1_OFFSET_SH_LITTLE);
542 /* Ignored the reserved bits. */
543 intern->r_size = ((ext->r_bits[3] & RELOC_BITS3_SIZE_LITTLE)
544 >> RELOC_BITS3_SIZE_SH_LITTLE);
546 if (intern->r_type == ALPHA_R_LITUSE
547 || intern->r_type == ALPHA_R_GPDISP)
549 /* Handle the LITUSE and GPDISP relocs specially. Its symndx
550 value is not actually a symbol index, but is instead a
551 special code. We put the code in the r_size field, and
552 clobber the symndx. */
553 if (intern->r_size != 0)
554 abort ();
555 intern->r_size = intern->r_symndx;
556 intern->r_symndx = RELOC_SECTION_NONE;
558 else if (intern->r_type == ALPHA_R_IGNORE)
560 /* The IGNORE reloc generally follows a GPDISP reloc, and is
561 against the .lita section. The section is irrelevant. */
562 if (! intern->r_extern &&
563 intern->r_symndx == RELOC_SECTION_ABS)
564 abort ();
565 if (! intern->r_extern && intern->r_symndx == RELOC_SECTION_LITA)
566 intern->r_symndx = RELOC_SECTION_ABS;
570 /* Swap a reloc out. */
572 static void
573 alpha_ecoff_swap_reloc_out (abfd, intern, dst)
574 bfd *abfd;
575 const struct internal_reloc *intern;
576 PTR dst;
578 RELOC *ext = (RELOC *) dst;
579 long symndx;
580 unsigned char size;
582 /* Undo the hackery done in swap_reloc_in. */
583 if (intern->r_type == ALPHA_R_LITUSE
584 || intern->r_type == ALPHA_R_GPDISP)
586 symndx = intern->r_size;
587 size = 0;
589 else if (intern->r_type == ALPHA_R_IGNORE
590 && ! intern->r_extern
591 && intern->r_symndx == RELOC_SECTION_ABS)
593 symndx = RELOC_SECTION_LITA;
594 size = intern->r_size;
596 else
598 symndx = intern->r_symndx;
599 size = intern->r_size;
602 BFD_ASSERT (intern->r_extern
603 || (intern->r_symndx >= 0 && intern->r_symndx <= 14));
605 bfd_h_put_64 (abfd, intern->r_vaddr, (bfd_byte *) ext->r_vaddr);
606 bfd_h_put_32 (abfd, symndx, (bfd_byte *) ext->r_symndx);
608 BFD_ASSERT (bfd_header_little_endian (abfd));
610 ext->r_bits[0] = ((intern->r_type << RELOC_BITS0_TYPE_SH_LITTLE)
611 & RELOC_BITS0_TYPE_LITTLE);
612 ext->r_bits[1] = ((intern->r_extern ? RELOC_BITS1_EXTERN_LITTLE : 0)
613 | ((intern->r_offset << RELOC_BITS1_OFFSET_SH_LITTLE)
614 & RELOC_BITS1_OFFSET_LITTLE));
615 ext->r_bits[2] = 0;
616 ext->r_bits[3] = ((size << RELOC_BITS3_SIZE_SH_LITTLE)
617 & RELOC_BITS3_SIZE_LITTLE);
620 /* Finish canonicalizing a reloc. Part of this is generic to all
621 ECOFF targets, and that part is in ecoff.c. The rest is done in
622 this backend routine. It must fill in the howto field. */
624 static void
625 alpha_adjust_reloc_in (abfd, intern, rptr)
626 bfd *abfd;
627 const struct internal_reloc *intern;
628 arelent *rptr;
630 if (intern->r_type > ALPHA_R_GPVALUE)
631 abort ();
633 switch (intern->r_type)
635 case ALPHA_R_BRADDR:
636 case ALPHA_R_SREL16:
637 case ALPHA_R_SREL32:
638 case ALPHA_R_SREL64:
639 /* This relocs appear to be fully resolved when they are against
640 internal symbols. Against external symbols, BRADDR at least
641 appears to be resolved against the next instruction. */
642 if (! intern->r_extern)
643 rptr->addend = 0;
644 else
645 rptr->addend = - (intern->r_vaddr + 4);
646 break;
648 case ALPHA_R_GPREL32:
649 case ALPHA_R_LITERAL:
650 /* Copy the gp value for this object file into the addend, to
651 ensure that we are not confused by the linker. */
652 if (! intern->r_extern)
653 rptr->addend += ecoff_data (abfd)->gp;
654 break;
656 case ALPHA_R_LITUSE:
657 case ALPHA_R_GPDISP:
658 /* The LITUSE and GPDISP relocs do not use a symbol, or an
659 addend, but they do use a special code. Put this code in the
660 addend field. */
661 rptr->addend = intern->r_size;
662 break;
664 case ALPHA_R_OP_STORE:
665 /* The STORE reloc needs the size and offset fields. We store
666 them in the addend. */
667 BFD_ASSERT (intern->r_offset <= 256 && intern->r_size <= 256);
668 rptr->addend = (intern->r_offset << 8) + intern->r_size;
669 break;
671 case ALPHA_R_OP_PUSH:
672 case ALPHA_R_OP_PSUB:
673 case ALPHA_R_OP_PRSHIFT:
674 /* The PUSH, PSUB and PRSHIFT relocs do not actually use an
675 address. I believe that the address supplied is really an
676 addend. */
677 rptr->addend = intern->r_vaddr;
678 break;
680 case ALPHA_R_GPVALUE:
681 /* Set the addend field to the new GP value. */
682 rptr->addend = intern->r_symndx + ecoff_data (abfd)->gp;
683 break;
685 case ALPHA_R_IGNORE:
686 /* If the type is ALPHA_R_IGNORE, make sure this is a reference
687 to the absolute section so that the reloc is ignored. For
688 some reason the address of this reloc type is not adjusted by
689 the section vma. We record the gp value for this object file
690 here, for convenience when doing the GPDISP relocation. */
691 rptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
692 rptr->address = intern->r_vaddr;
693 rptr->addend = ecoff_data (abfd)->gp;
694 break;
696 default:
697 break;
700 rptr->howto = &alpha_howto_table[intern->r_type];
703 /* When writing out a reloc we need to pull some values back out of
704 the addend field into the reloc. This is roughly the reverse of
705 alpha_adjust_reloc_in, except that there are several changes we do
706 not need to undo. */
708 static void
709 alpha_adjust_reloc_out (abfd, rel, intern)
710 bfd *abfd;
711 const arelent *rel;
712 struct internal_reloc *intern;
714 switch (intern->r_type)
716 case ALPHA_R_LITUSE:
717 case ALPHA_R_GPDISP:
718 intern->r_size = rel->addend;
719 break;
721 case ALPHA_R_OP_STORE:
722 intern->r_size = rel->addend & 0xff;
723 intern->r_offset = (rel->addend >> 8) & 0xff;
724 break;
726 case ALPHA_R_OP_PUSH:
727 case ALPHA_R_OP_PSUB:
728 case ALPHA_R_OP_PRSHIFT:
729 intern->r_vaddr = rel->addend;
730 break;
732 case ALPHA_R_IGNORE:
733 intern->r_vaddr = rel->address;
734 break;
736 default:
737 break;
741 /* The size of the stack for the relocation evaluator. */
742 #define RELOC_STACKSIZE (10)
744 /* Alpha ECOFF relocs have a built in expression evaluator as well as
745 other interdependencies. Rather than use a bunch of special
746 functions and global variables, we use a single routine to do all
747 the relocation for a section. I haven't yet worked out how the
748 assembler is going to handle this. */
750 static bfd_byte *
751 alpha_ecoff_get_relocated_section_contents (abfd, link_info, link_order,
752 data, relocateable, symbols)
753 bfd *abfd;
754 struct bfd_link_info *link_info;
755 struct bfd_link_order *link_order;
756 bfd_byte *data;
757 boolean relocateable;
758 asymbol **symbols;
760 bfd *input_bfd = link_order->u.indirect.section->owner;
761 asection *input_section = link_order->u.indirect.section;
762 long reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section);
763 arelent **reloc_vector = NULL;
764 long reloc_count;
765 bfd *output_bfd = relocateable ? abfd : (bfd *) NULL;
766 bfd_vma gp;
767 boolean gp_undefined;
768 bfd_vma stack[RELOC_STACKSIZE];
769 int tos = 0;
771 if (reloc_size < 0)
772 goto error_return;
773 reloc_vector = (arelent **) bfd_malloc (reloc_size);
774 if (reloc_vector == NULL && reloc_size != 0)
775 goto error_return;
777 if (! bfd_get_section_contents (input_bfd, input_section, data,
778 (file_ptr) 0, input_section->_raw_size))
779 goto error_return;
781 /* The section size is not going to change. */
782 input_section->_cooked_size = input_section->_raw_size;
783 input_section->reloc_done = true;
785 reloc_count = bfd_canonicalize_reloc (input_bfd, input_section,
786 reloc_vector, symbols);
787 if (reloc_count < 0)
788 goto error_return;
789 if (reloc_count == 0)
790 goto successful_return;
792 /* Get the GP value for the output BFD. */
793 gp_undefined = false;
794 gp = _bfd_get_gp_value (abfd);
795 if (gp == 0)
797 if (relocateable != false)
799 asection *sec;
800 bfd_vma lo;
802 /* Make up a value. */
803 lo = (bfd_vma) -1;
804 for (sec = abfd->sections; sec != NULL; sec = sec->next)
806 if (sec->vma < lo
807 && (strcmp (sec->name, ".sbss") == 0
808 || strcmp (sec->name, ".sdata") == 0
809 || strcmp (sec->name, ".lit4") == 0
810 || strcmp (sec->name, ".lit8") == 0
811 || strcmp (sec->name, ".lita") == 0))
812 lo = sec->vma;
814 gp = lo + 0x8000;
815 _bfd_set_gp_value (abfd, gp);
817 else
819 struct bfd_link_hash_entry *h;
821 h = bfd_link_hash_lookup (link_info->hash, "_gp", false, false,
822 true);
823 if (h == (struct bfd_link_hash_entry *) NULL
824 || h->type != bfd_link_hash_defined)
825 gp_undefined = true;
826 else
828 gp = (h->u.def.value
829 + h->u.def.section->output_section->vma
830 + h->u.def.section->output_offset);
831 _bfd_set_gp_value (abfd, gp);
836 for (; *reloc_vector != (arelent *) NULL; reloc_vector++)
838 arelent *rel;
839 bfd_reloc_status_type r;
840 char *err;
842 rel = *reloc_vector;
843 r = bfd_reloc_ok;
844 switch (rel->howto->type)
846 case ALPHA_R_IGNORE:
847 rel->address += input_section->output_offset;
848 break;
850 case ALPHA_R_REFLONG:
851 case ALPHA_R_REFQUAD:
852 case ALPHA_R_BRADDR:
853 case ALPHA_R_HINT:
854 case ALPHA_R_SREL16:
855 case ALPHA_R_SREL32:
856 case ALPHA_R_SREL64:
857 if (relocateable
858 && ((*rel->sym_ptr_ptr)->flags & BSF_SECTION_SYM) == 0)
860 rel->address += input_section->output_offset;
861 break;
863 r = bfd_perform_relocation (input_bfd, rel, data, input_section,
864 output_bfd, &err);
865 break;
867 case ALPHA_R_GPREL32:
868 /* This relocation is used in a switch table. It is a 32
869 bit offset from the current GP value. We must adjust it
870 by the different between the original GP value and the
871 current GP value. The original GP value is stored in the
872 addend. We adjust the addend and let
873 bfd_perform_relocation finish the job. */
874 rel->addend -= gp;
875 r = bfd_perform_relocation (input_bfd, rel, data, input_section,
876 output_bfd, &err);
877 if (r == bfd_reloc_ok && gp_undefined)
879 r = bfd_reloc_dangerous;
880 err = (char *) _("GP relative relocation used when GP not defined");
882 break;
884 case ALPHA_R_LITERAL:
885 /* This is a reference to a literal value, generally
886 (always?) in the .lita section. This is a 16 bit GP
887 relative relocation. Sometimes the subsequent reloc is a
888 LITUSE reloc, which indicates how this reloc is used.
889 This sometimes permits rewriting the two instructions
890 referred to by the LITERAL and the LITUSE into different
891 instructions which do not refer to .lita. This can save
892 a memory reference, and permits removing a value from
893 .lita thus saving GP relative space.
895 We do not these optimizations. To do them we would need
896 to arrange to link the .lita section first, so that by
897 the time we got here we would know the final values to
898 use. This would not be particularly difficult, but it is
899 not currently implemented. */
902 unsigned long insn;
904 /* I believe that the LITERAL reloc will only apply to a
905 ldq or ldl instruction, so check my assumption. */
906 insn = bfd_get_32 (input_bfd, data + rel->address);
907 BFD_ASSERT (((insn >> 26) & 0x3f) == 0x29
908 || ((insn >> 26) & 0x3f) == 0x28);
910 rel->addend -= gp;
911 r = bfd_perform_relocation (input_bfd, rel, data, input_section,
912 output_bfd, &err);
913 if (r == bfd_reloc_ok && gp_undefined)
915 r = bfd_reloc_dangerous;
916 err =
917 (char *) _("GP relative relocation used when GP not defined");
920 break;
922 case ALPHA_R_LITUSE:
923 /* See ALPHA_R_LITERAL above for the uses of this reloc. It
924 does not cause anything to happen, itself. */
925 rel->address += input_section->output_offset;
926 break;
928 case ALPHA_R_GPDISP:
929 /* This marks the ldah of an ldah/lda pair which loads the
930 gp register with the difference of the gp value and the
931 current location. The second of the pair is r_size bytes
932 ahead; it used to be marked with an ALPHA_R_IGNORE reloc,
933 but that no longer happens in OSF/1 3.2. */
935 unsigned long insn1, insn2;
936 bfd_vma addend;
938 /* Get the two instructions. */
939 insn1 = bfd_get_32 (input_bfd, data + rel->address);
940 insn2 = bfd_get_32 (input_bfd, data + rel->address + rel->addend);
942 BFD_ASSERT (((insn1 >> 26) & 0x3f) == 0x09); /* ldah */
943 BFD_ASSERT (((insn2 >> 26) & 0x3f) == 0x08); /* lda */
945 /* Get the existing addend. We must account for the sign
946 extension done by lda and ldah. */
947 addend = ((insn1 & 0xffff) << 16) + (insn2 & 0xffff);
948 if (insn1 & 0x8000)
950 addend -= 0x80000000;
951 addend -= 0x80000000;
953 if (insn2 & 0x8000)
954 addend -= 0x10000;
956 /* The existing addend includes the different between the
957 gp of the input BFD and the address in the input BFD.
958 Subtract this out. */
959 addend -= (ecoff_data (input_bfd)->gp
960 - (input_section->vma + rel->address));
962 /* Now add in the final gp value, and subtract out the
963 final address. */
964 addend += (gp
965 - (input_section->output_section->vma
966 + input_section->output_offset
967 + rel->address));
969 /* Change the instructions, accounting for the sign
970 extension, and write them out. */
971 if (addend & 0x8000)
972 addend += 0x10000;
973 insn1 = (insn1 & 0xffff0000) | ((addend >> 16) & 0xffff);
974 insn2 = (insn2 & 0xffff0000) | (addend & 0xffff);
976 bfd_put_32 (input_bfd, (bfd_vma) insn1, data + rel->address);
977 bfd_put_32 (input_bfd, (bfd_vma) insn2,
978 data + rel->address + rel->addend);
980 rel->address += input_section->output_offset;
982 break;
984 case ALPHA_R_OP_PUSH:
985 /* Push a value on the reloc evaluation stack. */
987 asymbol *symbol;
988 bfd_vma relocation;
990 if (relocateable)
992 rel->address += input_section->output_offset;
993 break;
996 /* Figure out the relocation of this symbol. */
997 symbol = *rel->sym_ptr_ptr;
999 if (bfd_is_und_section (symbol->section))
1000 r = bfd_reloc_undefined;
1002 if (bfd_is_com_section (symbol->section))
1003 relocation = 0;
1004 else
1005 relocation = symbol->value;
1006 relocation += symbol->section->output_section->vma;
1007 relocation += symbol->section->output_offset;
1008 relocation += rel->addend;
1010 if (tos >= RELOC_STACKSIZE)
1011 abort ();
1013 stack[tos++] = relocation;
1015 break;
1017 case ALPHA_R_OP_STORE:
1018 /* Store a value from the reloc stack into a bitfield. */
1020 bfd_vma val;
1021 int offset, size;
1023 if (relocateable)
1025 rel->address += input_section->output_offset;
1026 break;
1029 if (tos == 0)
1030 abort ();
1032 /* The offset and size for this reloc are encoded into the
1033 addend field by alpha_adjust_reloc_in. */
1034 offset = (rel->addend >> 8) & 0xff;
1035 size = rel->addend & 0xff;
1037 val = bfd_get_64 (abfd, data + rel->address);
1038 val &=~ (((1 << size) - 1) << offset);
1039 val |= (stack[--tos] & ((1 << size) - 1)) << offset;
1040 bfd_put_64 (abfd, val, data + rel->address);
1042 break;
1044 case ALPHA_R_OP_PSUB:
1045 /* Subtract a value from the top of the stack. */
1047 asymbol *symbol;
1048 bfd_vma relocation;
1050 if (relocateable)
1052 rel->address += input_section->output_offset;
1053 break;
1056 /* Figure out the relocation of this symbol. */
1057 symbol = *rel->sym_ptr_ptr;
1059 if (bfd_is_und_section (symbol->section))
1060 r = bfd_reloc_undefined;
1062 if (bfd_is_com_section (symbol->section))
1063 relocation = 0;
1064 else
1065 relocation = symbol->value;
1066 relocation += symbol->section->output_section->vma;
1067 relocation += symbol->section->output_offset;
1068 relocation += rel->addend;
1070 if (tos == 0)
1071 abort ();
1073 stack[tos - 1] -= relocation;
1075 break;
1077 case ALPHA_R_OP_PRSHIFT:
1078 /* Shift the value on the top of the stack. */
1080 asymbol *symbol;
1081 bfd_vma relocation;
1083 if (relocateable)
1085 rel->address += input_section->output_offset;
1086 break;
1089 /* Figure out the relocation of this symbol. */
1090 symbol = *rel->sym_ptr_ptr;
1092 if (bfd_is_und_section (symbol->section))
1093 r = bfd_reloc_undefined;
1095 if (bfd_is_com_section (symbol->section))
1096 relocation = 0;
1097 else
1098 relocation = symbol->value;
1099 relocation += symbol->section->output_section->vma;
1100 relocation += symbol->section->output_offset;
1101 relocation += rel->addend;
1103 if (tos == 0)
1104 abort ();
1106 stack[tos - 1] >>= relocation;
1108 break;
1110 case ALPHA_R_GPVALUE:
1111 /* I really don't know if this does the right thing. */
1112 gp = rel->addend;
1113 gp_undefined = false;
1114 break;
1116 default:
1117 abort ();
1120 if (relocateable)
1122 asection *os = input_section->output_section;
1124 /* A partial link, so keep the relocs. */
1125 os->orelocation[os->reloc_count] = rel;
1126 os->reloc_count++;
1129 if (r != bfd_reloc_ok)
1131 switch (r)
1133 case bfd_reloc_undefined:
1134 if (! ((*link_info->callbacks->undefined_symbol)
1135 (link_info, bfd_asymbol_name (*rel->sym_ptr_ptr),
1136 input_bfd, input_section, rel->address)))
1137 goto error_return;
1138 break;
1139 case bfd_reloc_dangerous:
1140 if (! ((*link_info->callbacks->reloc_dangerous)
1141 (link_info, err, input_bfd, input_section,
1142 rel->address)))
1143 goto error_return;
1144 break;
1145 case bfd_reloc_overflow:
1146 if (! ((*link_info->callbacks->reloc_overflow)
1147 (link_info, bfd_asymbol_name (*rel->sym_ptr_ptr),
1148 rel->howto->name, rel->addend, input_bfd,
1149 input_section, rel->address)))
1150 goto error_return;
1151 break;
1152 case bfd_reloc_outofrange:
1153 default:
1154 abort ();
1155 break;
1160 if (tos != 0)
1161 abort ();
1163 successful_return:
1164 if (reloc_vector != NULL)
1165 free (reloc_vector);
1166 return data;
1168 error_return:
1169 if (reloc_vector != NULL)
1170 free (reloc_vector);
1171 return NULL;
1174 /* Get the howto structure for a generic reloc type. */
1176 static reloc_howto_type *
1177 alpha_bfd_reloc_type_lookup (abfd, code)
1178 bfd *abfd;
1179 bfd_reloc_code_real_type code;
1181 int alpha_type;
1183 switch (code)
1185 case BFD_RELOC_32:
1186 alpha_type = ALPHA_R_REFLONG;
1187 break;
1188 case BFD_RELOC_64:
1189 case BFD_RELOC_CTOR:
1190 alpha_type = ALPHA_R_REFQUAD;
1191 break;
1192 case BFD_RELOC_GPREL32:
1193 alpha_type = ALPHA_R_GPREL32;
1194 break;
1195 case BFD_RELOC_ALPHA_LITERAL:
1196 alpha_type = ALPHA_R_LITERAL;
1197 break;
1198 case BFD_RELOC_ALPHA_LITUSE:
1199 alpha_type = ALPHA_R_LITUSE;
1200 break;
1201 case BFD_RELOC_ALPHA_GPDISP_HI16:
1202 alpha_type = ALPHA_R_GPDISP;
1203 break;
1204 case BFD_RELOC_ALPHA_GPDISP_LO16:
1205 alpha_type = ALPHA_R_IGNORE;
1206 break;
1207 case BFD_RELOC_23_PCREL_S2:
1208 alpha_type = ALPHA_R_BRADDR;
1209 break;
1210 case BFD_RELOC_ALPHA_HINT:
1211 alpha_type = ALPHA_R_HINT;
1212 break;
1213 case BFD_RELOC_16_PCREL:
1214 alpha_type = ALPHA_R_SREL16;
1215 break;
1216 case BFD_RELOC_32_PCREL:
1217 alpha_type = ALPHA_R_SREL32;
1218 break;
1219 case BFD_RELOC_64_PCREL:
1220 alpha_type = ALPHA_R_SREL64;
1221 break;
1222 #if 0
1223 case ???:
1224 alpha_type = ALPHA_R_OP_PUSH;
1225 break;
1226 case ???:
1227 alpha_type = ALPHA_R_OP_STORE;
1228 break;
1229 case ???:
1230 alpha_type = ALPHA_R_OP_PSUB;
1231 break;
1232 case ???:
1233 alpha_type = ALPHA_R_OP_PRSHIFT;
1234 break;
1235 case ???:
1236 alpha_type = ALPHA_R_GPVALUE;
1237 break;
1238 #endif
1239 default:
1240 return (reloc_howto_type *) NULL;
1243 return &alpha_howto_table[alpha_type];
1246 /* A helper routine for alpha_relocate_section which converts an
1247 external reloc when generating relocateable output. Returns the
1248 relocation amount. */
1250 static bfd_vma
1251 alpha_convert_external_reloc (output_bfd, info, input_bfd, ext_rel, h)
1252 bfd *output_bfd;
1253 struct bfd_link_info *info;
1254 bfd *input_bfd;
1255 struct external_reloc *ext_rel;
1256 struct ecoff_link_hash_entry *h;
1258 unsigned long r_symndx;
1259 bfd_vma relocation;
1261 BFD_ASSERT (info->relocateable);
1263 if (h->root.type == bfd_link_hash_defined
1264 || h->root.type == bfd_link_hash_defweak)
1266 asection *hsec;
1267 const char *name;
1269 /* This symbol is defined in the output. Convert the reloc from
1270 being against the symbol to being against the section. */
1272 /* Clear the r_extern bit. */
1273 ext_rel->r_bits[1] &=~ RELOC_BITS1_EXTERN_LITTLE;
1275 /* Compute a new r_symndx value. */
1276 hsec = h->root.u.def.section;
1277 name = bfd_get_section_name (output_bfd, hsec->output_section);
1279 r_symndx = -1;
1280 switch (name[1])
1282 case 'A':
1283 if (strcmp (name, "*ABS*") == 0)
1284 r_symndx = RELOC_SECTION_ABS;
1285 break;
1286 case 'b':
1287 if (strcmp (name, ".bss") == 0)
1288 r_symndx = RELOC_SECTION_BSS;
1289 break;
1290 case 'd':
1291 if (strcmp (name, ".data") == 0)
1292 r_symndx = RELOC_SECTION_DATA;
1293 break;
1294 case 'f':
1295 if (strcmp (name, ".fini") == 0)
1296 r_symndx = RELOC_SECTION_FINI;
1297 break;
1298 case 'i':
1299 if (strcmp (name, ".init") == 0)
1300 r_symndx = RELOC_SECTION_INIT;
1301 break;
1302 case 'l':
1303 if (strcmp (name, ".lita") == 0)
1304 r_symndx = RELOC_SECTION_LITA;
1305 else if (strcmp (name, ".lit8") == 0)
1306 r_symndx = RELOC_SECTION_LIT8;
1307 else if (strcmp (name, ".lit4") == 0)
1308 r_symndx = RELOC_SECTION_LIT4;
1309 break;
1310 case 'p':
1311 if (strcmp (name, ".pdata") == 0)
1312 r_symndx = RELOC_SECTION_PDATA;
1313 break;
1314 case 'r':
1315 if (strcmp (name, ".rdata") == 0)
1316 r_symndx = RELOC_SECTION_RDATA;
1317 else if (strcmp (name, ".rconst") == 0)
1318 r_symndx = RELOC_SECTION_RCONST;
1319 break;
1320 case 's':
1321 if (strcmp (name, ".sdata") == 0)
1322 r_symndx = RELOC_SECTION_SDATA;
1323 else if (strcmp (name, ".sbss") == 0)
1324 r_symndx = RELOC_SECTION_SBSS;
1325 break;
1326 case 't':
1327 if (strcmp (name, ".text") == 0)
1328 r_symndx = RELOC_SECTION_TEXT;
1329 break;
1330 case 'x':
1331 if (strcmp (name, ".xdata") == 0)
1332 r_symndx = RELOC_SECTION_XDATA;
1333 break;
1336 if (r_symndx == -1)
1337 abort ();
1339 /* Add the section VMA and the symbol value. */
1340 relocation = (h->root.u.def.value
1341 + hsec->output_section->vma
1342 + hsec->output_offset);
1344 else
1346 /* Change the symndx value to the right one for
1347 the output BFD. */
1348 r_symndx = h->indx;
1349 if (r_symndx == -1)
1351 /* Caller must give an error. */
1352 r_symndx = 0;
1354 relocation = 0;
1357 /* Write out the new r_symndx value. */
1358 bfd_h_put_32 (input_bfd, (bfd_vma) r_symndx,
1359 (bfd_byte *) ext_rel->r_symndx);
1361 return relocation;
1364 /* Relocate a section while linking an Alpha ECOFF file. This is
1365 quite similar to get_relocated_section_contents. Perhaps they
1366 could be combined somehow. */
1368 static boolean
1369 alpha_relocate_section (output_bfd, info, input_bfd, input_section,
1370 contents, external_relocs)
1371 bfd *output_bfd;
1372 struct bfd_link_info *info;
1373 bfd *input_bfd;
1374 asection *input_section;
1375 bfd_byte *contents;
1376 PTR external_relocs;
1378 asection **symndx_to_section, *lita_sec;
1379 struct ecoff_link_hash_entry **sym_hashes;
1380 bfd_vma gp;
1381 boolean gp_undefined;
1382 bfd_vma stack[RELOC_STACKSIZE];
1383 int tos = 0;
1384 struct external_reloc *ext_rel;
1385 struct external_reloc *ext_rel_end;
1387 /* We keep a table mapping the symndx found in an internal reloc to
1388 the appropriate section. This is faster than looking up the
1389 section by name each time. */
1390 symndx_to_section = ecoff_data (input_bfd)->symndx_to_section;
1391 if (symndx_to_section == (asection **) NULL)
1393 symndx_to_section = ((asection **)
1394 bfd_alloc (input_bfd,
1395 (NUM_RELOC_SECTIONS
1396 * sizeof (asection *))));
1397 if (!symndx_to_section)
1398 return false;
1400 symndx_to_section[RELOC_SECTION_NONE] = NULL;
1401 symndx_to_section[RELOC_SECTION_TEXT] =
1402 bfd_get_section_by_name (input_bfd, ".text");
1403 symndx_to_section[RELOC_SECTION_RDATA] =
1404 bfd_get_section_by_name (input_bfd, ".rdata");
1405 symndx_to_section[RELOC_SECTION_DATA] =
1406 bfd_get_section_by_name (input_bfd, ".data");
1407 symndx_to_section[RELOC_SECTION_SDATA] =
1408 bfd_get_section_by_name (input_bfd, ".sdata");
1409 symndx_to_section[RELOC_SECTION_SBSS] =
1410 bfd_get_section_by_name (input_bfd, ".sbss");
1411 symndx_to_section[RELOC_SECTION_BSS] =
1412 bfd_get_section_by_name (input_bfd, ".bss");
1413 symndx_to_section[RELOC_SECTION_INIT] =
1414 bfd_get_section_by_name (input_bfd, ".init");
1415 symndx_to_section[RELOC_SECTION_LIT8] =
1416 bfd_get_section_by_name (input_bfd, ".lit8");
1417 symndx_to_section[RELOC_SECTION_LIT4] =
1418 bfd_get_section_by_name (input_bfd, ".lit4");
1419 symndx_to_section[RELOC_SECTION_XDATA] =
1420 bfd_get_section_by_name (input_bfd, ".xdata");
1421 symndx_to_section[RELOC_SECTION_PDATA] =
1422 bfd_get_section_by_name (input_bfd, ".pdata");
1423 symndx_to_section[RELOC_SECTION_FINI] =
1424 bfd_get_section_by_name (input_bfd, ".fini");
1425 symndx_to_section[RELOC_SECTION_LITA] =
1426 bfd_get_section_by_name (input_bfd, ".lita");
1427 symndx_to_section[RELOC_SECTION_ABS] = bfd_abs_section_ptr;
1428 symndx_to_section[RELOC_SECTION_RCONST] =
1429 bfd_get_section_by_name (input_bfd, ".rconst");
1431 ecoff_data (input_bfd)->symndx_to_section = symndx_to_section;
1434 sym_hashes = ecoff_data (input_bfd)->sym_hashes;
1436 /* On the Alpha, the .lita section must be addressable by the global
1437 pointer. To support large programs, we need to allow multiple
1438 global pointers. This works as long as each input .lita section
1439 is <64KB big. This implies that when producing relocatable
1440 output, the .lita section is limited to 64KB. . */
1442 lita_sec = symndx_to_section[RELOC_SECTION_LITA];
1443 gp = _bfd_get_gp_value (output_bfd);
1444 if (! info->relocateable && lita_sec != NULL)
1446 struct ecoff_section_tdata *lita_sec_data;
1448 /* Make sure we have a section data structure to which we can
1449 hang on to the gp value we pick for the section. */
1450 lita_sec_data = ecoff_section_data (input_bfd, lita_sec);
1451 if (lita_sec_data == NULL)
1453 lita_sec_data = ((struct ecoff_section_tdata *)
1454 bfd_zalloc (input_bfd,
1455 sizeof (struct ecoff_section_tdata)));
1456 ecoff_section_data (input_bfd, lita_sec) = lita_sec_data;
1459 if (lita_sec_data->gp != 0)
1461 /* If we already assigned a gp to this section, we better
1462 stick with that value. */
1463 gp = lita_sec_data->gp;
1465 else
1467 bfd_vma lita_vma;
1468 bfd_size_type lita_size;
1470 lita_vma = lita_sec->output_offset + lita_sec->output_section->vma;
1471 lita_size = lita_sec->_cooked_size;
1472 if (lita_size == 0)
1473 lita_size = lita_sec->_raw_size;
1475 if (gp == 0
1476 || lita_vma < gp - 0x8000
1477 || lita_vma + lita_size >= gp + 0x8000)
1479 /* Either gp hasn't been set at all or the current gp
1480 cannot address this .lita section. In both cases we
1481 reset the gp to point into the "middle" of the
1482 current input .lita section. */
1483 if (gp && !ecoff_data (output_bfd)->issued_multiple_gp_warning)
1485 (*info->callbacks->warning) (info,
1486 _("using multiple gp values"),
1487 (char *) NULL, output_bfd,
1488 (asection *) NULL, (bfd_vma) 0);
1489 ecoff_data (output_bfd)->issued_multiple_gp_warning = true;
1491 if (lita_vma < gp - 0x8000)
1492 gp = lita_vma + lita_size - 0x8000;
1493 else
1494 gp = lita_vma + 0x8000;
1498 lita_sec_data->gp = gp;
1501 _bfd_set_gp_value (output_bfd, gp);
1504 gp_undefined = (gp == 0);
1506 BFD_ASSERT (bfd_header_little_endian (output_bfd));
1507 BFD_ASSERT (bfd_header_little_endian (input_bfd));
1509 ext_rel = (struct external_reloc *) external_relocs;
1510 ext_rel_end = ext_rel + input_section->reloc_count;
1511 for (; ext_rel < ext_rel_end; ext_rel++)
1513 bfd_vma r_vaddr;
1514 unsigned long r_symndx;
1515 int r_type;
1516 int r_extern;
1517 int r_offset;
1518 int r_size;
1519 boolean relocatep;
1520 boolean adjust_addrp;
1521 boolean gp_usedp;
1522 bfd_vma addend;
1524 r_vaddr = bfd_h_get_64 (input_bfd, (bfd_byte *) ext_rel->r_vaddr);
1525 r_symndx = bfd_h_get_32 (input_bfd, (bfd_byte *) ext_rel->r_symndx);
1527 r_type = ((ext_rel->r_bits[0] & RELOC_BITS0_TYPE_LITTLE)
1528 >> RELOC_BITS0_TYPE_SH_LITTLE);
1529 r_extern = (ext_rel->r_bits[1] & RELOC_BITS1_EXTERN_LITTLE) != 0;
1530 r_offset = ((ext_rel->r_bits[1] & RELOC_BITS1_OFFSET_LITTLE)
1531 >> RELOC_BITS1_OFFSET_SH_LITTLE);
1532 /* Ignored the reserved bits. */
1533 r_size = ((ext_rel->r_bits[3] & RELOC_BITS3_SIZE_LITTLE)
1534 >> RELOC_BITS3_SIZE_SH_LITTLE);
1536 relocatep = false;
1537 adjust_addrp = true;
1538 gp_usedp = false;
1539 addend = 0;
1541 switch (r_type)
1543 default:
1544 abort ();
1546 case ALPHA_R_IGNORE:
1547 /* This reloc appears after a GPDISP reloc. On earlier
1548 versions of OSF/1, It marked the position of the second
1549 instruction to be altered by the GPDISP reloc, but it is
1550 not otherwise used for anything. For some reason, the
1551 address of the relocation does not appear to include the
1552 section VMA, unlike the other relocation types. */
1553 if (info->relocateable)
1554 bfd_h_put_64 (input_bfd,
1555 input_section->output_offset + r_vaddr,
1556 (bfd_byte *) ext_rel->r_vaddr);
1557 adjust_addrp = false;
1558 break;
1560 case ALPHA_R_REFLONG:
1561 case ALPHA_R_REFQUAD:
1562 case ALPHA_R_HINT:
1563 relocatep = true;
1564 break;
1566 case ALPHA_R_BRADDR:
1567 case ALPHA_R_SREL16:
1568 case ALPHA_R_SREL32:
1569 case ALPHA_R_SREL64:
1570 if (r_extern)
1571 addend += - (r_vaddr + 4);
1572 relocatep = true;
1573 break;
1575 case ALPHA_R_GPREL32:
1576 /* This relocation is used in a switch table. It is a 32
1577 bit offset from the current GP value. We must adjust it
1578 by the different between the original GP value and the
1579 current GP value. */
1580 relocatep = true;
1581 addend = ecoff_data (input_bfd)->gp - gp;
1582 gp_usedp = true;
1583 break;
1585 case ALPHA_R_LITERAL:
1586 /* This is a reference to a literal value, generally
1587 (always?) in the .lita section. This is a 16 bit GP
1588 relative relocation. Sometimes the subsequent reloc is a
1589 LITUSE reloc, which indicates how this reloc is used.
1590 This sometimes permits rewriting the two instructions
1591 referred to by the LITERAL and the LITUSE into different
1592 instructions which do not refer to .lita. This can save
1593 a memory reference, and permits removing a value from
1594 .lita thus saving GP relative space.
1596 We do not these optimizations. To do them we would need
1597 to arrange to link the .lita section first, so that by
1598 the time we got here we would know the final values to
1599 use. This would not be particularly difficult, but it is
1600 not currently implemented. */
1602 /* I believe that the LITERAL reloc will only apply to a ldq
1603 or ldl instruction, so check my assumption. */
1605 unsigned long insn;
1607 insn = bfd_get_32 (input_bfd,
1608 contents + r_vaddr - input_section->vma);
1609 BFD_ASSERT (((insn >> 26) & 0x3f) == 0x29
1610 || ((insn >> 26) & 0x3f) == 0x28);
1613 relocatep = true;
1614 addend = ecoff_data (input_bfd)->gp - gp;
1615 gp_usedp = true;
1616 break;
1618 case ALPHA_R_LITUSE:
1619 /* See ALPHA_R_LITERAL above for the uses of this reloc. It
1620 does not cause anything to happen, itself. */
1621 break;
1623 case ALPHA_R_GPDISP:
1624 /* This marks the ldah of an ldah/lda pair which loads the
1625 gp register with the difference of the gp value and the
1626 current location. The second of the pair is r_symndx
1627 bytes ahead. It used to be marked with an ALPHA_R_IGNORE
1628 reloc, but OSF/1 3.2 no longer does that. */
1630 unsigned long insn1, insn2;
1632 /* Get the two instructions. */
1633 insn1 = bfd_get_32 (input_bfd,
1634 contents + r_vaddr - input_section->vma);
1635 insn2 = bfd_get_32 (input_bfd,
1636 (contents
1637 + r_vaddr
1638 - input_section->vma
1639 + r_symndx));
1641 BFD_ASSERT (((insn1 >> 26) & 0x3f) == 0x09); /* ldah */
1642 BFD_ASSERT (((insn2 >> 26) & 0x3f) == 0x08); /* lda */
1644 /* Get the existing addend. We must account for the sign
1645 extension done by lda and ldah. */
1646 addend = ((insn1 & 0xffff) << 16) + (insn2 & 0xffff);
1647 if (insn1 & 0x8000)
1649 /* This is addend -= 0x100000000 without causing an
1650 integer overflow on a 32 bit host. */
1651 addend -= 0x80000000;
1652 addend -= 0x80000000;
1654 if (insn2 & 0x8000)
1655 addend -= 0x10000;
1657 /* The existing addend includes the difference between the
1658 gp of the input BFD and the address in the input BFD.
1659 We want to change this to the difference between the
1660 final GP and the final address. */
1661 addend += (gp
1662 - ecoff_data (input_bfd)->gp
1663 + input_section->vma
1664 - (input_section->output_section->vma
1665 + input_section->output_offset));
1667 /* Change the instructions, accounting for the sign
1668 extension, and write them out. */
1669 if (addend & 0x8000)
1670 addend += 0x10000;
1671 insn1 = (insn1 & 0xffff0000) | ((addend >> 16) & 0xffff);
1672 insn2 = (insn2 & 0xffff0000) | (addend & 0xffff);
1674 bfd_put_32 (input_bfd, (bfd_vma) insn1,
1675 contents + r_vaddr - input_section->vma);
1676 bfd_put_32 (input_bfd, (bfd_vma) insn2,
1677 contents + r_vaddr - input_section->vma + r_symndx);
1679 gp_usedp = true;
1681 break;
1683 case ALPHA_R_OP_PUSH:
1684 case ALPHA_R_OP_PSUB:
1685 case ALPHA_R_OP_PRSHIFT:
1686 /* Manipulate values on the reloc evaluation stack. The
1687 r_vaddr field is not an address in input_section, it is
1688 the current value (including any addend) of the object
1689 being used. */
1690 if (! r_extern)
1692 asection *s;
1694 s = symndx_to_section[r_symndx];
1695 if (s == (asection *) NULL)
1696 abort ();
1697 addend = s->output_section->vma + s->output_offset - s->vma;
1699 else
1701 struct ecoff_link_hash_entry *h;
1703 h = sym_hashes[r_symndx];
1704 if (h == (struct ecoff_link_hash_entry *) NULL)
1705 abort ();
1707 if (! info->relocateable)
1709 if (h->root.type == bfd_link_hash_defined
1710 || h->root.type == bfd_link_hash_defweak)
1711 addend = (h->root.u.def.value
1712 + h->root.u.def.section->output_section->vma
1713 + h->root.u.def.section->output_offset);
1714 else
1716 /* Note that we pass the address as 0, since we
1717 do not have a meaningful number for the
1718 location within the section that is being
1719 relocated. */
1720 if (! ((*info->callbacks->undefined_symbol)
1721 (info, h->root.root.string, input_bfd,
1722 input_section, (bfd_vma) 0)))
1723 return false;
1724 addend = 0;
1727 else
1729 if (h->root.type != bfd_link_hash_defined
1730 && h->root.type != bfd_link_hash_defweak
1731 && h->indx == -1)
1733 /* This symbol is not being written out. Pass
1734 the address as 0, as with undefined_symbol,
1735 above. */
1736 if (! ((*info->callbacks->unattached_reloc)
1737 (info, h->root.root.string, input_bfd,
1738 input_section, (bfd_vma) 0)))
1739 return false;
1742 addend = alpha_convert_external_reloc (output_bfd, info,
1743 input_bfd,
1744 ext_rel, h);
1748 addend += r_vaddr;
1750 if (info->relocateable)
1752 /* Adjust r_vaddr by the addend. */
1753 bfd_h_put_64 (input_bfd, addend,
1754 (bfd_byte *) ext_rel->r_vaddr);
1756 else
1758 switch (r_type)
1760 case ALPHA_R_OP_PUSH:
1761 if (tos >= RELOC_STACKSIZE)
1762 abort ();
1763 stack[tos++] = addend;
1764 break;
1766 case ALPHA_R_OP_PSUB:
1767 if (tos == 0)
1768 abort ();
1769 stack[tos - 1] -= addend;
1770 break;
1772 case ALPHA_R_OP_PRSHIFT:
1773 if (tos == 0)
1774 abort ();
1775 stack[tos - 1] >>= addend;
1776 break;
1780 adjust_addrp = false;
1781 break;
1783 case ALPHA_R_OP_STORE:
1784 /* Store a value from the reloc stack into a bitfield. If
1785 we are generating relocateable output, all we do is
1786 adjust the address of the reloc. */
1787 if (! info->relocateable)
1789 bfd_vma mask;
1790 bfd_vma val;
1792 if (tos == 0)
1793 abort ();
1795 /* Get the relocation mask. The separate steps and the
1796 casts to bfd_vma are attempts to avoid a bug in the
1797 Alpha OSF 1.3 C compiler. See reloc.c for more
1798 details. */
1799 mask = 1;
1800 mask <<= (bfd_vma) r_size;
1801 mask -= 1;
1803 /* FIXME: I don't know what kind of overflow checking,
1804 if any, should be done here. */
1805 val = bfd_get_64 (input_bfd,
1806 contents + r_vaddr - input_section->vma);
1807 val &=~ mask << (bfd_vma) r_offset;
1808 val |= (stack[--tos] & mask) << (bfd_vma) r_offset;
1809 bfd_put_64 (input_bfd, val,
1810 contents + r_vaddr - input_section->vma);
1812 break;
1814 case ALPHA_R_GPVALUE:
1815 /* I really don't know if this does the right thing. */
1816 gp = ecoff_data (input_bfd)->gp + r_symndx;
1817 gp_undefined = false;
1818 break;
1821 if (relocatep)
1823 reloc_howto_type *howto;
1824 struct ecoff_link_hash_entry *h = NULL;
1825 asection *s = NULL;
1826 bfd_vma relocation;
1827 bfd_reloc_status_type r;
1829 /* Perform a relocation. */
1831 howto = &alpha_howto_table[r_type];
1833 if (r_extern)
1835 h = sym_hashes[r_symndx];
1836 /* If h is NULL, that means that there is a reloc
1837 against an external symbol which we thought was just
1838 a debugging symbol. This should not happen. */
1839 if (h == (struct ecoff_link_hash_entry *) NULL)
1840 abort ();
1842 else
1844 if (r_symndx >= NUM_RELOC_SECTIONS)
1845 s = NULL;
1846 else
1847 s = symndx_to_section[r_symndx];
1849 if (s == (asection *) NULL)
1850 abort ();
1853 if (info->relocateable)
1855 /* We are generating relocateable output, and must
1856 convert the existing reloc. */
1857 if (r_extern)
1859 if (h->root.type != bfd_link_hash_defined
1860 && h->root.type != bfd_link_hash_defweak
1861 && h->indx == -1)
1863 /* This symbol is not being written out. */
1864 if (! ((*info->callbacks->unattached_reloc)
1865 (info, h->root.root.string, input_bfd,
1866 input_section, r_vaddr - input_section->vma)))
1867 return false;
1870 relocation = alpha_convert_external_reloc (output_bfd,
1871 info,
1872 input_bfd,
1873 ext_rel,
1876 else
1878 /* This is a relocation against a section. Adjust
1879 the value by the amount the section moved. */
1880 relocation = (s->output_section->vma
1881 + s->output_offset
1882 - s->vma);
1885 /* If this is PC relative, the existing object file
1886 appears to already have the reloc worked out. We
1887 must subtract out the old value and add in the new
1888 one. */
1889 if (howto->pc_relative)
1890 relocation -= (input_section->output_section->vma
1891 + input_section->output_offset
1892 - input_section->vma);
1894 /* Put in any addend. */
1895 relocation += addend;
1897 /* Adjust the contents. */
1898 r = _bfd_relocate_contents (howto, input_bfd, relocation,
1899 (contents
1900 + r_vaddr
1901 - input_section->vma));
1903 else
1905 /* We are producing a final executable. */
1906 if (r_extern)
1908 /* This is a reloc against a symbol. */
1909 if (h->root.type == bfd_link_hash_defined
1910 || h->root.type == bfd_link_hash_defweak)
1912 asection *hsec;
1914 hsec = h->root.u.def.section;
1915 relocation = (h->root.u.def.value
1916 + hsec->output_section->vma
1917 + hsec->output_offset);
1919 else
1921 if (! ((*info->callbacks->undefined_symbol)
1922 (info, h->root.root.string, input_bfd,
1923 input_section,
1924 r_vaddr - input_section->vma)))
1925 return false;
1926 relocation = 0;
1929 else
1931 /* This is a reloc against a section. */
1932 relocation = (s->output_section->vma
1933 + s->output_offset
1934 - s->vma);
1936 /* Adjust a PC relative relocation by removing the
1937 reference to the original source section. */
1938 if (howto->pc_relative)
1939 relocation += input_section->vma;
1942 r = _bfd_final_link_relocate (howto,
1943 input_bfd,
1944 input_section,
1945 contents,
1946 r_vaddr - input_section->vma,
1947 relocation,
1948 addend);
1951 if (r != bfd_reloc_ok)
1953 switch (r)
1955 default:
1956 case bfd_reloc_outofrange:
1957 abort ();
1958 case bfd_reloc_overflow:
1960 const char *name;
1962 if (r_extern)
1963 name = sym_hashes[r_symndx]->root.root.string;
1964 else
1965 name = bfd_section_name (input_bfd,
1966 symndx_to_section[r_symndx]);
1967 if (! ((*info->callbacks->reloc_overflow)
1968 (info, name, alpha_howto_table[r_type].name,
1969 (bfd_vma) 0, input_bfd, input_section,
1970 r_vaddr - input_section->vma)))
1971 return false;
1973 break;
1978 if (info->relocateable && adjust_addrp)
1980 /* Change the address of the relocation. */
1981 bfd_h_put_64 (input_bfd,
1982 (input_section->output_section->vma
1983 + input_section->output_offset
1984 - input_section->vma
1985 + r_vaddr),
1986 (bfd_byte *) ext_rel->r_vaddr);
1989 if (gp_usedp && gp_undefined)
1991 if (! ((*info->callbacks->reloc_dangerous)
1992 (info, _("GP relative relocation when GP not defined"),
1993 input_bfd, input_section, r_vaddr - input_section->vma)))
1994 return false;
1995 /* Only give the error once per link. */
1996 gp = 4;
1997 _bfd_set_gp_value (output_bfd, gp);
1998 gp_undefined = false;
2002 if (tos != 0)
2003 abort ();
2005 return true;
2008 /* Do final adjustments to the filehdr and the aouthdr. This routine
2009 sets the dynamic bits in the file header. */
2011 /*ARGSUSED*/
2012 static boolean
2013 alpha_adjust_headers (abfd, fhdr, ahdr)
2014 bfd *abfd;
2015 struct internal_filehdr *fhdr;
2016 struct internal_aouthdr *ahdr;
2018 if ((abfd->flags & (DYNAMIC | EXEC_P)) == (DYNAMIC | EXEC_P))
2019 fhdr->f_flags |= F_ALPHA_CALL_SHARED;
2020 else if ((abfd->flags & DYNAMIC) != 0)
2021 fhdr->f_flags |= F_ALPHA_SHARABLE;
2022 return true;
2025 /* Archive handling. In OSF/1 (or Digital Unix) v3.2, Digital
2026 introduced archive packing, in which the elements in an archive are
2027 optionally compressed using a simple dictionary scheme. We know
2028 how to read such archives, but we don't write them. */
2030 #define alpha_ecoff_slurp_armap _bfd_ecoff_slurp_armap
2031 #define alpha_ecoff_slurp_extended_name_table \
2032 _bfd_ecoff_slurp_extended_name_table
2033 #define alpha_ecoff_construct_extended_name_table \
2034 _bfd_ecoff_construct_extended_name_table
2035 #define alpha_ecoff_truncate_arname _bfd_ecoff_truncate_arname
2036 #define alpha_ecoff_write_armap _bfd_ecoff_write_armap
2037 #define alpha_ecoff_generic_stat_arch_elt _bfd_ecoff_generic_stat_arch_elt
2038 #define alpha_ecoff_update_armap_timestamp _bfd_ecoff_update_armap_timestamp
2040 /* A compressed file uses this instead of ARFMAG. */
2042 #define ARFZMAG "Z\012"
2044 /* Read an archive header. This is like the standard routine, but it
2045 also accepts ARFZMAG. */
2047 static PTR
2048 alpha_ecoff_read_ar_hdr (abfd)
2049 bfd *abfd;
2051 struct areltdata *ret;
2052 struct ar_hdr *h;
2054 ret = (struct areltdata *) _bfd_generic_read_ar_hdr_mag (abfd, ARFZMAG);
2055 if (ret == NULL)
2056 return NULL;
2058 h = (struct ar_hdr *) ret->arch_header;
2059 if (strncmp (h->ar_fmag, ARFZMAG, 2) == 0)
2061 bfd_byte ab[8];
2063 /* This is a compressed file. We must set the size correctly.
2064 The size is the eight bytes after the dummy file header. */
2065 if (bfd_seek (abfd, FILHSZ, SEEK_CUR) != 0
2066 || bfd_read (ab, 1, 8, abfd) != 8
2067 || bfd_seek (abfd, - (FILHSZ + 8), SEEK_CUR) != 0)
2068 return NULL;
2070 ret->parsed_size = bfd_h_get_64 (abfd, ab);
2073 return (PTR) ret;
2076 /* Get an archive element at a specified file position. This is where
2077 we uncompress the archive element if necessary. */
2079 static bfd *
2080 alpha_ecoff_get_elt_at_filepos (archive, filepos)
2081 bfd *archive;
2082 file_ptr filepos;
2084 bfd *nbfd = NULL;
2085 struct areltdata *tdata;
2086 struct ar_hdr *hdr;
2087 bfd_byte ab[8];
2088 bfd_size_type size;
2089 bfd_byte *buf, *p;
2090 struct bfd_in_memory *bim;
2092 nbfd = _bfd_get_elt_at_filepos (archive, filepos);
2093 if (nbfd == NULL)
2094 goto error_return;
2096 if ((nbfd->flags & BFD_IN_MEMORY) != 0)
2098 /* We have already expanded this BFD. */
2099 return nbfd;
2102 tdata = (struct areltdata *) nbfd->arelt_data;
2103 hdr = (struct ar_hdr *) tdata->arch_header;
2104 if (strncmp (hdr->ar_fmag, ARFZMAG, 2) != 0)
2105 return nbfd;
2107 /* We must uncompress this element. We do this by copying it into a
2108 memory buffer, and making bfd_read and bfd_seek use that buffer.
2109 This can use a lot of memory, but it's simpler than getting a
2110 temporary file, making that work with the file descriptor caching
2111 code, and making sure that it is deleted at all appropriate
2112 times. It can be changed if it ever becomes important. */
2114 /* The compressed file starts with a dummy ECOFF file header. */
2115 if (bfd_seek (nbfd, FILHSZ, SEEK_SET) != 0)
2116 goto error_return;
2118 /* The next eight bytes are the real file size. */
2119 if (bfd_read (ab, 1, 8, nbfd) != 8)
2120 goto error_return;
2121 size = bfd_h_get_64 (nbfd, ab);
2123 if (size == 0)
2124 buf = NULL;
2125 else
2127 bfd_size_type left;
2128 bfd_byte dict[4096];
2129 unsigned int h;
2130 bfd_byte b;
2132 buf = (bfd_byte *) bfd_alloc (nbfd, size);
2133 if (buf == NULL)
2134 goto error_return;
2135 p = buf;
2137 left = size;
2139 /* I don't know what the next eight bytes are for. */
2140 if (bfd_read (ab, 1, 8, nbfd) != 8)
2141 goto error_return;
2143 /* This is the uncompression algorithm. It's a simple
2144 dictionary based scheme in which each character is predicted
2145 by a hash of the previous three characters. A control byte
2146 indicates whether the character is predicted or whether it
2147 appears in the input stream; each control byte manages the
2148 next eight bytes in the output stream. */
2149 memset (dict, 0, sizeof dict);
2150 h = 0;
2151 while (bfd_read (&b, 1, 1, nbfd) == 1)
2153 unsigned int i;
2155 for (i = 0; i < 8; i++, b >>= 1)
2157 bfd_byte n;
2159 if ((b & 1) == 0)
2160 n = dict[h];
2161 else
2163 if (! bfd_read (&n, 1, 1, nbfd))
2164 goto error_return;
2165 dict[h] = n;
2168 *p++ = n;
2170 --left;
2171 if (left == 0)
2172 break;
2174 h <<= 4;
2175 h ^= n;
2176 h &= sizeof dict - 1;
2179 if (left == 0)
2180 break;
2184 /* Now the uncompressed file contents are in buf. */
2185 bim = ((struct bfd_in_memory *)
2186 bfd_alloc (nbfd, sizeof (struct bfd_in_memory)));
2187 if (bim == NULL)
2188 goto error_return;
2189 bim->size = size;
2190 bim->buffer = buf;
2192 nbfd->mtime_set = true;
2193 nbfd->mtime = strtol (hdr->ar_date, (char **) NULL, 10);
2195 nbfd->flags |= BFD_IN_MEMORY;
2196 nbfd->iostream = (PTR) bim;
2197 BFD_ASSERT (! nbfd->cacheable);
2199 return nbfd;
2201 error_return:
2202 if (nbfd != NULL)
2203 bfd_close (nbfd);
2204 return NULL;
2207 /* Open the next archived file. */
2209 static bfd *
2210 alpha_ecoff_openr_next_archived_file (archive, last_file)
2211 bfd *archive;
2212 bfd *last_file;
2214 file_ptr filestart;
2216 if (last_file == NULL)
2217 filestart = bfd_ardata (archive)->first_file_filepos;
2218 else
2220 struct areltdata *t;
2221 struct ar_hdr *h;
2222 bfd_size_type size;
2224 /* We can't use arelt_size here, because that uses parsed_size,
2225 which is the uncompressed size. We need the compressed size. */
2226 t = (struct areltdata *) last_file->arelt_data;
2227 h = (struct ar_hdr *) t->arch_header;
2228 size = strtol (h->ar_size, (char **) NULL, 10);
2230 /* Pad to an even boundary...
2231 Note that last_file->origin can be odd in the case of
2232 BSD-4.4-style element with a long odd size. */
2233 filestart = last_file->origin + size;
2234 filestart += filestart % 2;
2237 return alpha_ecoff_get_elt_at_filepos (archive, filestart);
2240 /* Open the archive file given an index into the armap. */
2242 static bfd *
2243 alpha_ecoff_get_elt_at_index (abfd, index)
2244 bfd *abfd;
2245 symindex index;
2247 carsym *entry;
2249 entry = bfd_ardata (abfd)->symdefs + index;
2250 return alpha_ecoff_get_elt_at_filepos (abfd, entry->file_offset);
2253 /* This is the ECOFF backend structure. The backend field of the
2254 target vector points to this. */
2256 static const struct ecoff_backend_data alpha_ecoff_backend_data =
2258 /* COFF backend structure. */
2260 (void (*) PARAMS ((bfd *,PTR,int,int,int,int,PTR))) bfd_void, /* aux_in */
2261 (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_in */
2262 (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_in */
2263 (unsigned (*) PARAMS ((bfd *,PTR,int,int,int,int,PTR)))bfd_void,/*aux_out*/
2264 (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_out */
2265 (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_out */
2266 (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* reloc_out */
2267 alpha_ecoff_swap_filehdr_out, alpha_ecoff_swap_aouthdr_out,
2268 alpha_ecoff_swap_scnhdr_out,
2269 FILHSZ, AOUTSZ, SCNHSZ, 0, 0, 0, 0, true, false, 4,
2270 alpha_ecoff_swap_filehdr_in, alpha_ecoff_swap_aouthdr_in,
2271 alpha_ecoff_swap_scnhdr_in, NULL,
2272 alpha_ecoff_bad_format_hook, _bfd_ecoff_set_arch_mach_hook,
2273 alpha_ecoff_mkobject_hook, _bfd_ecoff_styp_to_sec_flags,
2274 _bfd_ecoff_set_alignment_hook, _bfd_ecoff_slurp_symbol_table,
2275 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
2277 /* Supported architecture. */
2278 bfd_arch_alpha,
2279 /* Initial portion of armap string. */
2280 "________64",
2281 /* The page boundary used to align sections in a demand-paged
2282 executable file. E.g., 0x1000. */
2283 0x2000,
2284 /* True if the .rdata section is part of the text segment, as on the
2285 Alpha. False if .rdata is part of the data segment, as on the
2286 MIPS. */
2287 true,
2288 /* Bitsize of constructor entries. */
2290 /* Reloc to use for constructor entries. */
2291 &alpha_howto_table[ALPHA_R_REFQUAD],
2293 /* Symbol table magic number. */
2294 magicSym2,
2295 /* Alignment of debugging information. E.g., 4. */
2297 /* Sizes of external symbolic information. */
2298 sizeof (struct hdr_ext),
2299 sizeof (struct dnr_ext),
2300 sizeof (struct pdr_ext),
2301 sizeof (struct sym_ext),
2302 sizeof (struct opt_ext),
2303 sizeof (struct fdr_ext),
2304 sizeof (struct rfd_ext),
2305 sizeof (struct ext_ext),
2306 /* Functions to swap in external symbolic data. */
2307 ecoff_swap_hdr_in,
2308 ecoff_swap_dnr_in,
2309 ecoff_swap_pdr_in,
2310 ecoff_swap_sym_in,
2311 ecoff_swap_opt_in,
2312 ecoff_swap_fdr_in,
2313 ecoff_swap_rfd_in,
2314 ecoff_swap_ext_in,
2315 _bfd_ecoff_swap_tir_in,
2316 _bfd_ecoff_swap_rndx_in,
2317 /* Functions to swap out external symbolic data. */
2318 ecoff_swap_hdr_out,
2319 ecoff_swap_dnr_out,
2320 ecoff_swap_pdr_out,
2321 ecoff_swap_sym_out,
2322 ecoff_swap_opt_out,
2323 ecoff_swap_fdr_out,
2324 ecoff_swap_rfd_out,
2325 ecoff_swap_ext_out,
2326 _bfd_ecoff_swap_tir_out,
2327 _bfd_ecoff_swap_rndx_out,
2328 /* Function to read in symbolic data. */
2329 _bfd_ecoff_slurp_symbolic_info
2331 /* External reloc size. */
2332 RELSZ,
2333 /* Reloc swapping functions. */
2334 alpha_ecoff_swap_reloc_in,
2335 alpha_ecoff_swap_reloc_out,
2336 /* Backend reloc tweaking. */
2337 alpha_adjust_reloc_in,
2338 alpha_adjust_reloc_out,
2339 /* Relocate section contents while linking. */
2340 alpha_relocate_section,
2341 /* Do final adjustments to filehdr and aouthdr. */
2342 alpha_adjust_headers,
2343 /* Read an element from an archive at a given file position. */
2344 alpha_ecoff_get_elt_at_filepos
2347 /* Looking up a reloc type is Alpha specific. */
2348 #define _bfd_ecoff_bfd_reloc_type_lookup alpha_bfd_reloc_type_lookup
2350 /* So is getting relocated section contents. */
2351 #define _bfd_ecoff_bfd_get_relocated_section_contents \
2352 alpha_ecoff_get_relocated_section_contents
2354 /* Handling file windows is generic. */
2355 #define _bfd_ecoff_get_section_contents_in_window \
2356 _bfd_generic_get_section_contents_in_window
2358 /* Relaxing sections is generic. */
2359 #define _bfd_ecoff_bfd_relax_section bfd_generic_relax_section
2360 #define _bfd_ecoff_bfd_gc_sections bfd_generic_gc_sections
2362 const bfd_target ecoffalpha_little_vec =
2364 "ecoff-littlealpha", /* name */
2365 bfd_target_ecoff_flavour,
2366 BFD_ENDIAN_LITTLE, /* data byte order is little */
2367 BFD_ENDIAN_LITTLE, /* header byte order is little */
2369 (HAS_RELOC | EXEC_P | /* object flags */
2370 HAS_LINENO | HAS_DEBUG |
2371 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
2373 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
2374 0, /* leading underscore */
2375 ' ', /* ar_pad_char */
2376 15, /* ar_max_namelen */
2377 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
2378 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
2379 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
2380 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
2381 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
2382 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
2384 {_bfd_dummy_target, alpha_ecoff_object_p, /* bfd_check_format */
2385 _bfd_ecoff_archive_p, _bfd_dummy_target},
2386 {bfd_false, _bfd_ecoff_mkobject, /* bfd_set_format */
2387 _bfd_generic_mkarchive, bfd_false},
2388 {bfd_false, _bfd_ecoff_write_object_contents, /* bfd_write_contents */
2389 _bfd_write_archive_contents, bfd_false},
2391 BFD_JUMP_TABLE_GENERIC (_bfd_ecoff),
2392 BFD_JUMP_TABLE_COPY (_bfd_ecoff),
2393 BFD_JUMP_TABLE_CORE (_bfd_nocore),
2394 BFD_JUMP_TABLE_ARCHIVE (alpha_ecoff),
2395 BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff),
2396 BFD_JUMP_TABLE_RELOCS (_bfd_ecoff),
2397 BFD_JUMP_TABLE_WRITE (_bfd_ecoff),
2398 BFD_JUMP_TABLE_LINK (_bfd_ecoff),
2399 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
2401 (PTR) &alpha_ecoff_backend_data