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