source: trunk/src/binutils/bfd/coff-alpha.c@ 610

Last change on this file since 610 was 610, checked in by bird, 22 years ago

This commit was generated by cvs2svn to compensate for changes in r609,
which included commits to RCS files with non-trunk default branches.

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