* configure.in: Don't configure libgloss if we are not configuring
[deliverable/binutils-gdb.git] / bfd / coff-ppc.c
CommitLineData
e7aa05bf 1/* BFD back-end for PowerPC Microsoft Portable Executable files.
d3e572fe 2 Copyright 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
e7aa05bf
KK
3
4 Original version pieced together by Kim Knuttila (krk@cygnus.com)
5
6 There is nothing new under the sun. This file draws a lot on other
7 coff files, in particular, those for the rs/6000, alpha, mips, and
8 intel backends, and the PE work for the arm.
9
10This file is part of BFD, the Binary File Descriptor library.
11
12This program is free software; you can redistribute it and/or modify
13it under the terms of the GNU General Public License as published by
14the Free Software Foundation; either version 2 of the License, or
15(at your option) any later version.
16
17This program is distributed in the hope that it will be useful,
18but WITHOUT ANY WARRANTY; without even the implied warranty of
19MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20GNU General Public License for more details.
21
22You should have received a copy of the GNU General Public License
23along with this program; if not, write to the Free Software
24Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
25
26/* Current State:
27 - objdump works
28 - relocs generated by gas
93b6a3f8
KK
29 - ld will link files, but they do not run.
30 - dlltool will not produce correct output in some .reloc cases, and will
31 not produce the right glue code for dll function calls.
e7aa05bf
KK
32*/
33
34
35#include "bfd.h"
36#include "sysdep.h"
13d1a4dd 37
e7aa05bf
KK
38#include "libbfd.h"
39#include "obstack.h"
40
41#include "coff/powerpc.h"
42#include "coff/internal.h"
43
44#include "coff/pe.h"
45
46#ifdef BADMAG
47#undef BADMAG
48#endif
49
50#define BADMAG(x) PPCBADMAG(x)
51
52#include "libcoff.h"
53
59066248
KK
54/* The toc is a set of bfd_vma fields. We use the fact that valid */
55/* addresses are even (i.e. the bit representing "1" is off) to allow */
56/* us to encode a little extra information in the field */
57/* - Unallocated addresses are intialized to 1. */
58/* - Allocated addresses are even numbers. */
59/* The first time we actually write a reference to the toc in the bfd, */
60/* we want to record that fact in a fixup file (if it is asked for), so */
61/* we keep track of whether or not an address has been written by marking */
62/* the low order bit with a "1" upon writing */
63
64#define SET_UNALLOCATED(x) ((x) = 1)
65#define IS_UNALLOCATED(x) ((x) == 1)
66
67#define IS_WRITTEN(x) ((x) & 1)
68#define MARK_AS_WRITTEN(x) ((x) |= 1)
69#define MAKE_ADDR_AGAIN(x) ((x) &= ~1)
70
93b6a3f8
KK
71/* In order not to add an int to every hash table item for every coff
72 linker, we define our own hash table, derived from the coff one */
73
74/* PE linker hash table entries. */
75
76struct ppc_coff_link_hash_entry
77{
78 struct coff_link_hash_entry root; /* First entry, as required */
79
80 /* As we wonder around the relocs, we'll keep the assigned toc_offset
81 here */
82 bfd_vma toc_offset; /* Our addition, as required */
83 int symbol_is_glue;
84 unsigned long int glue_insn;
85 char eye_catcher[8];
86};
87
88/* Need a 7 char string for an eye catcher */
89#define EYE "krkjunk"
90
91#define CHECK_EYE(addr) \
92 if (strcmp(addr, EYE) != 0) \
93 { \
94 fprintf(stderr,\
95 "File %s, line %d, Hash check failure, bad eye %8s\n", \
96 __FILE__, __LINE__, addr); \
97 abort(); \
98 }
99
100/* PE linker hash table. */
101
102struct ppc_coff_link_hash_table
103{
104 struct coff_link_hash_table root; /* First entry, as required */
105};
106
107static struct bfd_hash_entry *ppc_coff_link_hash_newfunc
108 PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *,
109 const char *));
110
111/* Routine to create an entry in the link hash table. */
112
113static struct bfd_hash_entry *
114ppc_coff_link_hash_newfunc (entry, table, string)
115 struct bfd_hash_entry *entry;
116 struct bfd_hash_table *table;
117 const char *string;
118{
119 struct ppc_coff_link_hash_entry *ret =
120 (struct ppc_coff_link_hash_entry *) entry;
121
122 /* Allocate the structure if it has not already been allocated by a
123 subclass. */
124 if (ret == (struct ppc_coff_link_hash_entry *) NULL)
125 ret = (struct ppc_coff_link_hash_entry *)
126 bfd_hash_allocate (table,
127 sizeof (struct ppc_coff_link_hash_entry));
128
129 if (ret == (struct ppc_coff_link_hash_entry *) NULL)
130 return NULL;
131
132 /* Call the allocation method of the superclass. */
133 ret = ((struct ppc_coff_link_hash_entry *)
134 _bfd_coff_link_hash_newfunc ((struct bfd_hash_entry *) ret,
135 table, string));
136
137 if (ret)
138 {
139 /* Initialize the local fields. */
59066248 140 SET_UNALLOCATED(ret->toc_offset);
93b6a3f8
KK
141 ret->symbol_is_glue = 0;
142 ret->glue_insn = 0;
143 strcpy(ret->eye_catcher, EYE);
144 }
145
146 return (struct bfd_hash_entry *) ret;
147}
148
149/* Initialize a PE linker hash table. */
150
151static boolean
152ppc_coff_link_hash_table_init (table, abfd, newfunc)
153 struct ppc_coff_link_hash_table *table;
154 bfd *abfd;
155 struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *,
156 struct bfd_hash_table *,
157 const char *));
158{
159 return _bfd_coff_link_hash_table_init (&table->root, abfd, newfunc);
160}
161
162/* Create a PE linker hash table. */
163
164static struct bfd_link_hash_table *
165ppc_coff_link_hash_table_create (abfd)
166 bfd *abfd;
167{
168 struct ppc_coff_link_hash_table *ret;
169
170 ret = ((struct ppc_coff_link_hash_table *)
171 bfd_alloc (abfd, sizeof (struct ppc_coff_link_hash_table)));
172 if (ret == NULL)
a9713b91 173 return NULL;
93b6a3f8
KK
174 if (! ppc_coff_link_hash_table_init (ret, abfd,
175 ppc_coff_link_hash_newfunc))
176 {
177 bfd_release (abfd, ret);
178 return (struct bfd_link_hash_table *) NULL;
179 }
180 return &ret->root.root;
181}
182
183/* Now, tailor coffcode.h to use our hash stuff */
184
185#define coff_bfd_link_hash_table_create ppc_coff_link_hash_table_create
186
187\f
d6f41a7d
KK
188/* The nt loader points the toc register to &toc + 32768, in order to */
189/* use the complete range of a 16-bit displacement (I guess). We have */
190/* to adjust for this when we fix up loads displaced off the toc reg. */
191#define TOC_LOAD_ADJUSTMENT (-32768)
192#define TOC_SECTION_NAME ".private.toc"
193
e7aa05bf
KK
194/* The main body of code is in coffcode.h. */
195
196#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
197
198/* In case we're on a 32-bit machine, construct a 64-bit "-1" value
199 from smaller values. Start with zero, widen, *then* decrement. */
200#define MINUS_ONE (((bfd_vma)0) - 1)
201
202/* these should definitely go in a header file somewhere... */
203
204/* NOP */
205#define IMAGE_REL_PPC_ABSOLUTE 0x0000
206
207/* 64-bit address */
208#define IMAGE_REL_PPC_ADDR64 0x0001
209
210/* 32-bit address */
211#define IMAGE_REL_PPC_ADDR32 0x0002
212
213/* 26-bit address, shifted left 2 (branch absolute) */
214#define IMAGE_REL_PPC_ADDR24 0x0003
215
216/* 16-bit address */
217#define IMAGE_REL_PPC_ADDR16 0x0004
218
219/* 16-bit address, shifted left 2 (load doubleword) */
220#define IMAGE_REL_PPC_ADDR14 0x0005
221
222/* 26-bit PC-relative offset, shifted left 2 (branch relative) */
223#define IMAGE_REL_PPC_REL24 0x0006
224
225/* 16-bit PC-relative offset, shifted left 2 (br cond relative) */
226#define IMAGE_REL_PPC_REL14 0x0007
227
228/* 16-bit offset from TOC base */
229#define IMAGE_REL_PPC_TOCREL16 0x0008
230
231/* 16-bit offset from TOC base, shifted left 2 (load doubleword) */
232#define IMAGE_REL_PPC_TOCREL14 0x0009
233
234/* 32-bit addr w/o image base */
235#define IMAGE_REL_PPC_ADDR32NB 0x000A
236
237/* va of containing section (as in an image sectionhdr) */
238#define IMAGE_REL_PPC_SECREL 0x000B
239
240/* sectionheader number */
241#define IMAGE_REL_PPC_SECTION 0x000C
242
243/* substitute TOC restore instruction iff symbol is glue code */
244#define IMAGE_REL_PPC_IFGLUE 0x000D
245
246/* symbol is glue code; virtual address is TOC restore instruction */
247#define IMAGE_REL_PPC_IMGLUE 0x000E
248
249/* va of containing section (limited to 16 bits) */
250#define IMAGE_REL_PPC_SECREL16 0x000F
251
252/* stuff to handle immediate data when the number of bits in the */
253/* data is greater than the number of bits in the immediate field */
254/* We need to do (usually) 32 bit arithmetic on 16 bit chunks */
255#define IMAGE_REL_PPC_REFHI 0x0010
256#define IMAGE_REL_PPC_REFLO 0x0011
257#define IMAGE_REL_PPC_PAIR 0x0012
258
59066248
KK
259/* This is essentially the same as tocrel16, with TOCDEFN assumed */
260#define IMAGE_REL_PPC_TOCREL16_DEFN 0x0013
e7aa05bf
KK
261
262/* Flag bits in IMAGE_RELOCATION.TYPE */
263
264/* subtract reloc value rather than adding it */
265#define IMAGE_REL_PPC_NEG 0x0100
266
267/* fix branch prediction bit to predict branch taken */
268#define IMAGE_REL_PPC_BRTAKEN 0x0200
269
270/* fix branch prediction bit to predict branch not taken */
271#define IMAGE_REL_PPC_BRNTAKEN 0x0400
272
273/* toc slot defined in file (or, data in toc) */
274#define IMAGE_REL_PPC_TOCDEFN 0x0800
275
276/* masks to isolate above values in IMAGE_RELOCATION.Type */
277#define IMAGE_REL_PPC_TYPEMASK 0x00FF
278#define IMAGE_REL_PPC_FLAGMASK 0x0F00
279
280#define EXTRACT_TYPE(x) ((x) & IMAGE_REL_PPC_TYPEMASK)
281#define EXTRACT_FLAGS(x) ((x) & IMAGE_REL_PPC_FLAGMASK)
282#define EXTRACT_JUNK(x) \
283 ((x) & ~(IMAGE_REL_PPC_TYPEMASK | IMAGE_REL_PPC_FLAGMASK))
284
285\f
286/* static helper functions to make relocation work */
287/* (Work In Progress) */
288
289static bfd_reloc_status_type ppc_refhi_reloc PARAMS ((bfd *abfd,
290 arelent *reloc,
291 asymbol *symbol,
292 PTR data,
293 asection *section,
294 bfd *output_bfd,
295 char **error));
9addd1d4 296#if 0
e7aa05bf
KK
297static bfd_reloc_status_type ppc_reflo_reloc PARAMS ((bfd *abfd,
298 arelent *reloc,
299 asymbol *symbol,
300 PTR data,
301 asection *section,
302 bfd *output_bfd,
303 char **error));
9addd1d4 304#endif
e7aa05bf
KK
305static bfd_reloc_status_type ppc_pair_reloc PARAMS ((bfd *abfd,
306 arelent *reloc,
307 asymbol *symbol,
308 PTR data,
309 asection *section,
310 bfd *output_bfd,
311 char **error));
312
313\f
314static bfd_reloc_status_type ppc_toc16_reloc PARAMS ((bfd *abfd,
315 arelent *reloc,
316 asymbol *symbol,
317 PTR data,
318 asection *section,
319 bfd *output_bfd,
320 char **error));
321
9addd1d4 322#if 0
e7aa05bf
KK
323static bfd_reloc_status_type ppc_addr32nb_reloc PARAMS ((bfd *abfd,
324 arelent *reloc,
325 asymbol *symbol,
326 PTR data,
327 asection *section,
328 bfd *output_bfd,
329 char **error));
9addd1d4 330#endif
e7aa05bf
KK
331static bfd_reloc_status_type ppc_section_reloc PARAMS ((bfd *abfd,
332 arelent *reloc,
333 asymbol *symbol,
334 PTR data,
335 asection *section,
336 bfd *output_bfd,
337 char **error));
338
339static bfd_reloc_status_type ppc_secrel_reloc PARAMS ((bfd *abfd,
340 arelent *reloc,
341 asymbol *symbol,
342 PTR data,
343 asection *section,
344 bfd *output_bfd,
345 char **error));
346
347static bfd_reloc_status_type ppc_imglue_reloc PARAMS ((bfd *abfd,
348 arelent *reloc,
349 asymbol *symbol,
350 PTR data,
351 asection *section,
352 bfd *output_bfd,
353 char **error));
354
355
356
d6f41a7d 357static boolean in_reloc_p PARAMS((bfd *abfd, reloc_howto_type *howto));
e7aa05bf
KK
358
359\f
360/* FIXME: It'll take a while to get through all of these. I only need a few to
361 get us started, so those I'll make sure work. Those marked FIXME are either
362 completely unverified or have a specific unknown marked in the comment */
363
364/*---------------------------------------------------------------------------*/
365/* */
366/* Relocation entries for Windows/NT on PowerPC. */
367/* */
368/* From the document "" we find the following listed as used relocs: */
369/* */
370/* ABSOLUTE : The noop */
371/* ADDR[64|32|16] : fields that hold addresses in data fields or the */
372/* 16 bit displacement field on a load/store. */
373/* ADDR[24|14] : fields that hold addresses in branch and cond */
374/* branches. These represent [26|16] bit addresses. */
375/* The low order 2 bits are preserved. */
376/* REL[24|14] : branches relative to the Instruction Address */
377/* register. These represent [26|16] bit addresses, */
378/* as before. The instruction field will be zero, and */
379/* the address of the SYM will be inserted at link time. */
380/* TOCREL16 : 16 bit displacement field referring to a slot in */
381/* toc. */
382/* TOCREL14 : 16 bit displacement field, similar to REL14 or ADDR14. */
383/* ADDR32NB : 32 bit address relative to the virtual origin. */
384/* (On the alpha, this is always a linker generated thunk)*/
385/* (i.e. 32bit addr relative to the image base) */
386/* SECREL : The value is relative to the start of the section */
387/* containing the symbol. */
388/* SECTION : access to the header containing the item. Supports the */
389/* codeview debugger. */
390/* */
391/* In particular, note that the document does not indicate that the */
392/* relocations listed in the header file are used. */
393/* */
394/* */
395/* */
396/*---------------------------------------------------------------------------*/
397
398static reloc_howto_type ppc_coff_howto_table[] =
399{
400 /* IMAGE_REL_PPC_ABSOLUTE 0x0000 NOP */
401 /* Unused: */
402 HOWTO (IMAGE_REL_PPC_ABSOLUTE, /* type */
403 0, /* rightshift */
404 0, /* size (0 = byte, 1 = short, 2 = long) */
405 0, /* bitsize */
406 false, /* pc_relative */
407 0, /* bitpos */
408 complain_overflow_dont, /* dont complain_on_overflow */
409 0, /* special_function */
410 "ABSOLUTE", /* name */
411 false, /* partial_inplace */
412 0x00, /* src_mask */
413 0x00, /* dst_mask */
414 false), /* pcrel_offset */
d6f41a7d 415
e7aa05bf
KK
416 /* IMAGE_REL_PPC_ADDR64 0x0001 64-bit address */
417 /* Unused: */
418 HOWTO(IMAGE_REL_PPC_ADDR64, /* type */
d6f41a7d
KK
419 0, /* rightshift */
420 3, /* size (0 = byte, 1 = short, 2 = long) */
421 64, /* bitsize */
422 false, /* pc_relative */
423 0, /* bitpos */
424 complain_overflow_bitfield, /* complain_on_overflow */
425 0, /* special_function */
426 "ADDR64", /* name */
427 true, /* partial_inplace */
428 MINUS_ONE, /* src_mask */
429 MINUS_ONE, /* dst_mask */
430 false), /* pcrel_offset */
e7aa05bf
KK
431
432 /* IMAGE_REL_PPC_ADDR32 0x0002 32-bit address */
433 /* Used: */
434 HOWTO (IMAGE_REL_PPC_ADDR32, /* type */
435 0, /* rightshift */
436 2, /* size (0 = byte, 1 = short, 2 = long) */
437 32, /* bitsize */
438 false, /* pc_relative */
439 0, /* bitpos */
440 complain_overflow_bitfield, /* complain_on_overflow */
441 0, /* special_function */
442 "ADDR32", /* name */
443 true, /* partial_inplace */
444 0xffffffff, /* src_mask */
445 0xffffffff, /* dst_mask */
446 false), /* pcrel_offset */
d6f41a7d 447
e7aa05bf
KK
448 /* IMAGE_REL_PPC_ADDR24 0x0003 26-bit address, shifted left 2 (branch absolute) */
449 /* the LI field is in bit 6 through bit 29 is 24 bits, + 2 for the shift */
d6f41a7d 450 /* Of course, That's the IBM approved bit numbering, which is not what */
e7aa05bf
KK
451 /* anyone else uses.... The li field is in bit 2 thru 25 */
452 /* Used: */
453 HOWTO (IMAGE_REL_PPC_ADDR24, /* type */
454 0, /* rightshift */
455 2, /* size (0 = byte, 1 = short, 2 = long) */
456 26, /* bitsize */
457 false, /* pc_relative */
458 0, /* bitpos */
459 complain_overflow_bitfield, /* complain_on_overflow */
460 0, /* special_function */
461 "ADDR24", /* name */
462 true, /* partial_inplace */
463 0x07fffffc, /* src_mask */
464 0x07fffffc, /* dst_mask */
465 false), /* pcrel_offset */
d6f41a7d 466
e7aa05bf
KK
467 /* IMAGE_REL_PPC_ADDR16 0x0004 16-bit address */
468 /* Used: */
469 HOWTO (IMAGE_REL_PPC_ADDR16, /* type */
470 0, /* rightshift */
471 1, /* size (0 = byte, 1 = short, 2 = long) */
472 16, /* bitsize */
473 false, /* pc_relative */
474 0, /* bitpos */
475 complain_overflow_signed, /* complain_on_overflow */
476 0, /* special_function */
477 "ADDR16", /* name */
478 true, /* partial_inplace */
479 0xffff, /* src_mask */
480 0xffff, /* dst_mask */
481 false), /* pcrel_offset */
d6f41a7d 482
e7aa05bf
KK
483 /* IMAGE_REL_PPC_ADDR14 0x0005 */
484 /* 16-bit address, shifted left 2 (load doubleword) */
485 /* FIXME: the mask is likely wrong, and the bit position may be as well */
486 /* Unused: */
487 HOWTO (IMAGE_REL_PPC_ADDR14, /* type */
488 1, /* rightshift */
489 1, /* size (0 = byte, 1 = short, 2 = long) */
490 16, /* bitsize */
491 false, /* pc_relative */
492 0, /* bitpos */
493 complain_overflow_signed, /* complain_on_overflow */
494 0, /* special_function */
495 "ADDR16", /* name */
496 true, /* partial_inplace */
497 0xffff, /* src_mask */
498 0xffff, /* dst_mask */
499 false), /* pcrel_offset */
d6f41a7d 500
e7aa05bf
KK
501 /* IMAGE_REL_PPC_REL24 0x0006 */
502 /* 26-bit PC-relative offset, shifted left 2 (branch relative) */
503 /* Used: */
504 HOWTO (IMAGE_REL_PPC_REL24, /* type */
505 0, /* rightshift */
506 2, /* size (0 = byte, 1 = short, 2 = long) */
507 26, /* bitsize */
508 true, /* pc_relative */
509 0, /* bitpos */
510 complain_overflow_signed, /* complain_on_overflow */
511 0, /* special_function */
512 "REL24", /* name */
513 true, /* partial_inplace */
514 0x3fffffc, /* src_mask */
515 0x3fffffc, /* dst_mask */
516 false), /* pcrel_offset */
d6f41a7d 517
e7aa05bf
KK
518 /* IMAGE_REL_PPC_REL14 0x0007 */
519 /* 16-bit PC-relative offset, shifted left 2 (br cond relative) */
520 /* FIXME: the mask is likely wrong, and the bit position may be as well */
521 /* FIXME: how does it know how far to shift? */
522 /* Unused: */
523 HOWTO (IMAGE_REL_PPC_ADDR14, /* type */
524 1, /* rightshift */
525 1, /* size (0 = byte, 1 = short, 2 = long) */
526 16, /* bitsize */
527 false, /* pc_relative */
528 0, /* bitpos */
529 complain_overflow_signed, /* complain_on_overflow */
530 0, /* special_function */
531 "ADDR16", /* name */
532 true, /* partial_inplace */
533 0xffff, /* src_mask */
534 0xffff, /* dst_mask */
535 true), /* pcrel_offset */
d6f41a7d 536
e7aa05bf
KK
537 /* IMAGE_REL_PPC_TOCREL16 0x0008 */
538 /* 16-bit offset from TOC base */
539 /* Used: */
540 HOWTO (IMAGE_REL_PPC_TOCREL16,/* type */
541 0, /* rightshift */
542 1, /* size (0 = byte, 1 = short, 2 = long) */
543 16, /* bitsize */
544 false, /* pc_relative */
545 0, /* bitpos */
546 complain_overflow_dont, /* complain_on_overflow */
547 ppc_toc16_reloc, /* special_function */
548 "TOCREL16", /* name */
549 false, /* partial_inplace */
550 0xffff, /* src_mask */
551 0xffff, /* dst_mask */
552 false), /* pcrel_offset */
d6f41a7d 553
e7aa05bf
KK
554 /* IMAGE_REL_PPC_TOCREL14 0x0009 */
555 /* 16-bit offset from TOC base, shifted left 2 (load doubleword) */
556 /* Unused: */
557 HOWTO (IMAGE_REL_PPC_TOCREL14,/* type */
558 1, /* rightshift */
559 1, /* size (0 = byte, 1 = short, 2 = long) */
560 16, /* bitsize */
561 false, /* pc_relative */
562 0, /* bitpos */
563 complain_overflow_signed, /* complain_on_overflow */
564 0, /* special_function */
565 "TOCREL14", /* name */
566 false, /* partial_inplace */
567 0xffff, /* src_mask */
568 0xffff, /* dst_mask */
d6f41a7d
KK
569 false), /* pcrel_offset */
570
e7aa05bf
KK
571 /* IMAGE_REL_PPC_ADDR32NB 0x000A */
572 /* 32-bit addr w/ image base */
573 /* Unused: */
574 HOWTO (IMAGE_REL_PPC_ADDR32NB,/* type */
575 0, /* rightshift */
576 2, /* size (0 = byte, 1 = short, 2 = long) */
577 32, /* bitsize */
578 false, /* pc_relative */
579 0, /* bitpos */
580 complain_overflow_signed, /* complain_on_overflow */
d6f41a7d 581 0, /* special_function */
e7aa05bf
KK
582 "ADDR32NB", /* name */
583 true, /* partial_inplace */
584 0xffffffff, /* src_mask */
585 0xffffffff, /* dst_mask */
d6f41a7d
KK
586 false), /* pcrel_offset */
587
e7aa05bf
KK
588 /* IMAGE_REL_PPC_SECREL 0x000B */
589 /* va of containing section (as in an image sectionhdr) */
590 /* Unused: */
591 HOWTO (IMAGE_REL_PPC_SECREL,/* type */
592 0, /* rightshift */
593 2, /* size (0 = byte, 1 = short, 2 = long) */
594 32, /* bitsize */
595 false, /* pc_relative */
596 0, /* bitpos */
597 complain_overflow_signed, /* complain_on_overflow */
598 ppc_secrel_reloc, /* special_function */
599 "SECREL", /* name */
600 true, /* partial_inplace */
601 0xffffffff, /* src_mask */
602 0xffffffff, /* dst_mask */
603 true), /* pcrel_offset */
604
605 /* IMAGE_REL_PPC_SECTION 0x000C */
606 /* sectionheader number */
607 /* Unused: */
608 HOWTO (IMAGE_REL_PPC_SECTION,/* type */
609 0, /* rightshift */
610 2, /* size (0 = byte, 1 = short, 2 = long) */
611 32, /* bitsize */
612 false, /* pc_relative */
613 0, /* bitpos */
614 complain_overflow_signed, /* complain_on_overflow */
615 ppc_section_reloc, /* special_function */
616 "SECTION", /* name */
617 true, /* partial_inplace */
618 0xffffffff, /* src_mask */
619 0xffffffff, /* dst_mask */
620 true), /* pcrel_offset */
621
622 /* IMAGE_REL_PPC_IFGLUE 0x000D */
623 /* substitute TOC restore instruction iff symbol is glue code */
624 /* Used: */
625 HOWTO (IMAGE_REL_PPC_IFGLUE,/* type */
626 0, /* rightshift */
627 2, /* size (0 = byte, 1 = short, 2 = long) */
628 32, /* bitsize */
629 false, /* pc_relative */
630 0, /* bitpos */
631 complain_overflow_signed, /* complain_on_overflow */
632 0, /* special_function */
633 "IFGLUE", /* name */
634 true, /* partial_inplace */
635 0xffffffff, /* src_mask */
636 0xffffffff, /* dst_mask */
d6f41a7d 637 false), /* pcrel_offset */
e7aa05bf
KK
638
639 /* IMAGE_REL_PPC_IMGLUE 0x000E */
640 /* symbol is glue code; virtual address is TOC restore instruction */
641 /* Unused: */
642 HOWTO (IMAGE_REL_PPC_IMGLUE,/* type */
643 0, /* rightshift */
644 2, /* size (0 = byte, 1 = short, 2 = long) */
645 32, /* bitsize */
646 false, /* pc_relative */
647 0, /* bitpos */
648 complain_overflow_dont, /* complain_on_overflow */
649 ppc_imglue_reloc, /* special_function */
650 "IMGLUE", /* name */
651 false, /* partial_inplace */
652 0xffffffff, /* src_mask */
653 0xffffffff, /* dst_mask */
654 false), /* pcrel_offset */
655
656 /* IMAGE_REL_PPC_SECREL16 0x000F */
657 /* va of containing section (limited to 16 bits) */
658 /* Unused: */
659 HOWTO (IMAGE_REL_PPC_SECREL16,/* type */
660 0, /* rightshift */
661 1, /* size (0 = byte, 1 = short, 2 = long) */
662 16, /* bitsize */
663 false, /* pc_relative */
664 0, /* bitpos */
665 complain_overflow_signed, /* complain_on_overflow */
666 0, /* special_function */
667 "SECREL16", /* name */
668 true, /* partial_inplace */
669 0xffff, /* src_mask */
670 0xffff, /* dst_mask */
671 true), /* pcrel_offset */
672
673 /* IMAGE_REL_PPC_REFHI 0x0010 */
674 /* Unused: */
675 HOWTO (IMAGE_REL_PPC_REFHI, /* type */
676 0, /* rightshift */
677 1, /* size (0 = byte, 1 = short, 2 = long) */
678 16, /* bitsize */
679 false, /* pc_relative */
680 0, /* bitpos */
681 complain_overflow_signed, /* complain_on_overflow */
682 ppc_refhi_reloc, /* special_function */
683 "REFHI", /* name */
684 true, /* partial_inplace */
685 0xffffffff, /* src_mask */
686 0xffffffff, /* dst_mask */
687 false), /* pcrel_offset */
688
689 /* IMAGE_REL_PPC_REFLO 0x0011 */
690 /* Unused: */
691 HOWTO (IMAGE_REL_PPC_REFLO, /* type */
692 0, /* rightshift */
693 1, /* size (0 = byte, 1 = short, 2 = long) */
694 16, /* bitsize */
695 false, /* pc_relative */
696 0, /* bitpos */
697 complain_overflow_signed, /* complain_on_overflow */
698 ppc_refhi_reloc, /* special_function */
699 "REFLO", /* name */
700 true, /* partial_inplace */
701 0xffffffff, /* src_mask */
702 0xffffffff, /* dst_mask */
703 false), /* pcrel_offset */
704
705 /* IMAGE_REL_PPC_PAIR 0x0012 */
706 /* Unused: */
707 HOWTO (IMAGE_REL_PPC_PAIR, /* type */
708 0, /* rightshift */
709 1, /* size (0 = byte, 1 = short, 2 = long) */
710 16, /* bitsize */
711 false, /* pc_relative */
712 0, /* bitpos */
713 complain_overflow_signed, /* complain_on_overflow */
714 ppc_pair_reloc, /* special_function */
715 "PAIR", /* name */
716 true, /* partial_inplace */
717 0xffffffff, /* src_mask */
718 0xffffffff, /* dst_mask */
59066248
KK
719 false), /* pcrel_offset */
720
721 /* IMAGE_REL_PPC_TOCREL16_DEFN 0x0013 */
722 /* 16-bit offset from TOC base, without causing a definition */
723 /* Used: */
724 HOWTO ( (IMAGE_REL_PPC_TOCREL16 | IMAGE_REL_PPC_TOCDEFN), /* type */
725 0, /* rightshift */
726 1, /* size (0 = byte, 1 = short, 2 = long) */
727 16, /* bitsize */
728 false, /* pc_relative */
729 0, /* bitpos */
730 complain_overflow_dont, /* complain_on_overflow */
731 0, /* special_function */
732 "TOCREL16, TOCDEFN", /* name */
733 false, /* partial_inplace */
734 0xffff, /* src_mask */
735 0xffff, /* dst_mask */
736 false), /* pcrel_offset */
737
e7aa05bf
KK
738};
739
740
d6f41a7d
KK
741\f
742
743/* Some really cheezy macros that can be turned on to test stderr :-) */
744
d6f41a7d
KK
745#ifdef DEBUG_RELOC
746#define UN_IMPL(x) \
747{ \
748 static int i; \
749 if (i == 0) \
750 { \
751 i = 1; \
752 fprintf(stderr,"Unimplemented Relocation -- %s\n",x); \
753 } \
754}
755
756#define DUMP_RELOC(n,r) \
757{ \
758 fprintf(stderr,"%s sym %d, addr %d, addend %d\n", \
759 n, (*(r->sym_ptr_ptr))->name, \
760 r->address, r->addend); \
761}
762
763/* Given a reloc name, n, and a pointer to an internal_reloc,
764 dump out interesting information on the contents
765
766#define n_name _n._n_name
767#define n_zeroes _n._n_n._n_zeroes
768#define n_offset _n._n_n._n_offset
769
770*/
771
772#define DUMP_RELOC2(n,r) \
773{ \
cd2b2402
KK
774 fprintf(stderr,"%s sym %d, r_vaddr %d %s\n", \
775 n, r->r_symndx, r->r_vaddr,\
776 (((r->r_type) & IMAGE_REL_PPC_TOCDEFN) == 0) \
777 ?" ":" TOCDEFN" ); \
d6f41a7d
KK
778}
779
780#else
781#define UN_IMPL(x)
782#define DUMP_RELOC(n,r)
783#define DUMP_RELOC2(n,r)
784#endif
785
786
787\f
788/* toc construction and management routines */
789extern bfd* bfd_of_toc_owner;
790extern long int global_toc_size;
791
792extern long int import_table_size;
793extern long int first_thunk_address;
794extern long int thunk_size;
795
796enum toc_type
797{
798 default_toc,
799 toc_32,
800 toc_64
801};
802
a9713b91
ILT
803enum ref_category
804{
805 priv,
806 pub,
807 data
808};
809
93b6a3f8
KK
810struct list_ele
811{
812 struct list_ele *next;
813 bfd_vma addr;
a9713b91 814 enum ref_category cat;
93b6a3f8
KK
815 int offset;
816 const char *name;
817};
818
819extern struct list_ele *head;
820extern struct list_ele *tail;
821
822static void
a9713b91 823record_toc(toc_section, our_toc_offset, cat, name)
93b6a3f8
KK
824 asection *toc_section;
825 int our_toc_offset;
a9713b91 826 enum ref_category cat;
93b6a3f8
KK
827 const char *name;
828{
829 /* add this entry to our toc addr-offset-name list */
830 struct list_ele *t;
58142f10
ILT
831 t = bfd_malloc (sizeof (struct list_ele));
832 if (t == NULL)
833 abort ();
93b6a3f8
KK
834 t->next = 0;
835 t->offset = our_toc_offset;
836 t->name = name;
a9713b91 837 t->cat = cat;
93b6a3f8
KK
838 t->addr = toc_section->output_offset + our_toc_offset;
839
840 if (head == 0)
841 {
842 head = t;
843 tail = t;
844 }
845 else
846 {
847 tail->next = t;
848 tail = t;
849 }
850}
851
9addd1d4
ILT
852#ifdef COFF_IMAGE_WITH_PE
853
d6f41a7d
KK
854/* record a toc offset against a symbol */
855static int
856ppc_record_toc_entry(abfd, info, sec, sym, toc_kind)
857 bfd *abfd;
858 struct bfd_link_info *info;
859 asection *sec;
860 int sym;
861 enum toc_type toc_kind;
862{
93b6a3f8 863 struct ppc_coff_link_hash_entry *h;
d6f41a7d
KK
864 int ret_val;
865 const char *name;
866
867 int *local_syms;
868
869 h = 0;
870
93b6a3f8
KK
871 h = (struct ppc_coff_link_hash_entry *) (obj_coff_sym_hashes (abfd)[sym]);
872 if (h != 0)
873 {
874 CHECK_EYE(h->eye_catcher);
875 }
d6f41a7d
KK
876
877 if (h == 0)
878 {
879 local_syms = obj_coff_local_toc_table(abfd);
880 if (local_syms == 0)
881 {
882 int i;
883 /* allocate a table */
884 local_syms =
885 (int *) bfd_zalloc (abfd,
886 obj_raw_syment_count(abfd) * sizeof(int));
887 if (local_syms == 0)
a9713b91 888 return false;
d6f41a7d
KK
889 obj_coff_local_toc_table(abfd) = local_syms;
890 for (i = 0; i < obj_raw_syment_count(abfd); ++i)
59066248
KK
891 {
892 SET_UNALLOCATED(local_syms[i]);
893 }
d6f41a7d
KK
894 }
895
59066248 896 if (IS_UNALLOCATED(local_syms[sym]))
d6f41a7d
KK
897 {
898 local_syms[sym] = global_toc_size;
899 ret_val = global_toc_size;
900 global_toc_size += 4;
a9713b91
ILT
901
902 /* The size must fit in a 16bit displacment */
903 if (global_toc_size >= 65535)
904 {
905 fprintf(stderr,
906 "Exceeded toc size of 65535\n");
907 abort();
908 }
909
d6f41a7d
KK
910#ifdef TOC_DEBUG
911 fprintf(stderr,
912 "Setting toc_offset for local sym %d to %d\n",
913 sym, ret_val);
914#endif
915 }
916 else
917 {
918 ret_val = local_syms[sym];
919#ifdef TOC_DEBUG
920 fprintf(stderr,
921 "toc_offset already set for local sym %d to %d\n",
922 sym, ret_val);
923#endif
924 }
925 }
926 else
927 {
93b6a3f8 928 name = h->root.root.root.string;
d6f41a7d
KK
929
930 /* check to see if there's a toc slot allocated. If not, do it
931 here. It will be used in relocate_section */
59066248 932 if (IS_UNALLOCATED(h->toc_offset))
d6f41a7d
KK
933 {
934 h->toc_offset = global_toc_size;
935 ret_val = global_toc_size;
936 global_toc_size += 4;
a9713b91
ILT
937
938 /* The size must fit in a 16bit displacment */
939 if (global_toc_size >= 65535)
940 {
941 fprintf(stderr,
942 "Exceeded toc size of 65535\n");
943 abort();
944 }
945
d6f41a7d
KK
946#ifdef TOC_DEBUG
947 fprintf(stderr,
948 "Setting toc_offset for sym %d (%s) [h=%p] to %d\n",
949 sym, name, h, ret_val);
950#endif
951 }
952 else
953 {
954 ret_val = h->toc_offset;
955#ifdef TOC_DEBUG
956 fprintf(stderr,
957 "toc_offset already set for sym %d (%s) [h=%p] to %d\n",
958 sym, name, h, ret_val);
959#endif
960 }
961 }
962
963 return ret_val;
964}
9addd1d4
ILT
965
966#endif /* COFF_IMAGE_WITH_PE */
967
968#if 0
969
cd2b2402
KK
970/* FIXME: record a toc offset against a data-in-toc symbol */
971/* Now, there is currenly some confusion on what this means. In some
972 compilers one sees the moral equivalent of:
973 .tocd
974 define some data
975 .text
976 refer to the data with a [tocv] qualifier
977 In general, one sees something to indicate that a tocd has been
978 seen, and that would trigger the allocation of data in toc. The IBM
979 docs seem to suggest that anything with the TOCDEFN qualifier should
980 never trigger storage allocation. However, in the kernel32.lib that
981 we've been using for our test bed, there are a couple of variables
982 referenced that fail that test.
983
984 So it can't work that way.
985*/
986static int
987ppc_record_data_in_toc_entry(abfd, info, sec, sym, toc_kind)
988 bfd *abfd;
989 struct bfd_link_info *info;
990 asection *sec;
991 int sym;
992 enum toc_type toc_kind;
993{
cd2b2402 994 struct ppc_coff_link_hash_entry *h = 0;
cd2b2402
KK
995 int ret_val;
996 const char *name;
997
998 int *local_syms;
999
1000 h = (struct ppc_coff_link_hash_entry *) (obj_coff_sym_hashes (abfd)[sym]);
1001
1002 if (h == 0)
1003 {
1004 local_syms = obj_coff_local_toc_table(abfd);
1005 if (local_syms == 0)
1006 {
1007 int i;
1008 /* allocate a table */
1009 local_syms =
1010 (int *) bfd_zalloc (abfd,
1011 obj_raw_syment_count(abfd) * sizeof(int));
1012 if (local_syms == 0)
a9713b91 1013 return false;
cd2b2402
KK
1014 obj_coff_local_toc_table(abfd) = local_syms;
1015 for (i = 0; i < obj_raw_syment_count(abfd); ++i)
59066248
KK
1016 {
1017 SET_UNALLOCATED(local_syms[i]);
1018 }
cd2b2402
KK
1019 }
1020
59066248 1021 if (IS_UNALLOCATED(local_syms[sym]))
cd2b2402
KK
1022 {
1023 local_syms[sym] = global_toc_size;
1024 ret_val = global_toc_size;
1025 global_toc_size += 4;
1026#ifdef TOC_DEBUG
1027 fprintf(stderr,
1028 "Setting data_in_toc_offset for local sym %d to %d\n",
1029 sym, ret_val);
1030#endif
1031 }
1032 else
1033 {
1034 ret_val = local_syms[sym];
1035#ifdef TOC_DEBUG
1036 fprintf(stderr,
1037 "data_in_toc_offset already set for local sym %d to %d\n",
1038 sym, ret_val);
1039#endif
1040 }
1041 }
1042 else
1043 {
1044 CHECK_EYE(h->eye_catcher);
1045
1046 name = h->root.root.root.string;
1047
1048 /* check to see if there's a toc slot allocated. If not, do it
1049 here. It will be used in relocate_section */
59066248 1050 if (IS_UNALLOCATED(h->toc_offset))
cd2b2402
KK
1051 {
1052#if 0
1053 h->toc_offset = global_toc_size;
1054#endif
1055 ret_val = global_toc_size;
1056 /* We're allocating a chunk of the toc, as opposed to a slot */
1057 /* FIXME: alignment? */
1058
1059 global_toc_size += 4;
1060#ifdef TOC_DEBUG
1061 fprintf(stderr,
1062 "Setting data_in_toc_offset for sym %d (%s) [h=%p] to %d\n",
1063 sym, name, h, ret_val);
1064#endif
1065 }
1066 else
1067 {
1068 ret_val = h->toc_offset;
1069#ifdef TOC_DEBUG
1070 fprintf(stderr,
1071 "data_in_toc_offset already set for sym %d (%s) [h=%p] to %d\n",
1072 sym, name, h, ret_val);
1073#endif
1074 }
1075 }
1076
1077 return ret_val;
1078}
d6f41a7d 1079
9addd1d4
ILT
1080#endif /* 0 */
1081
1082#ifdef COFF_IMAGE_WITH_PE
1083
93b6a3f8
KK
1084/* record a toc offset against a symbol */
1085static void
1086ppc_mark_symbol_as_glue(abfd, sym, rel)
1087 bfd *abfd;
1088 int sym;
1089 struct internal_reloc *rel;
1090{
1091 struct ppc_coff_link_hash_entry *h;
1092
1093 h = (struct ppc_coff_link_hash_entry *) (obj_coff_sym_hashes (abfd)[sym]);
1094
1095 CHECK_EYE(h->eye_catcher);
1096
1097 h->symbol_is_glue = 1;
1098 h->glue_insn = bfd_get_32 (abfd, (bfd_byte *) &rel->r_vaddr);
1099
1100 return;
1101}
1102
9addd1d4 1103#endif /* COFF_IMAGE_WITH_PE */
d6f41a7d 1104\f
9addd1d4
ILT
1105#if 0
1106
e7aa05bf
KK
1107/* Provided the symbol, returns the value reffed */
1108static long get_symbol_value PARAMS ((asymbol *));
1109
1110static long
1111get_symbol_value (symbol)
1112 asymbol *symbol;
1113{
1114 long relocation = 0;
1115
1116 if (bfd_is_com_section (symbol->section))
d6f41a7d
KK
1117 {
1118 relocation = 0;
1119 }
e7aa05bf 1120 else
d6f41a7d
KK
1121 {
1122 relocation = symbol->value +
1123 symbol->section->output_section->vma +
1124 symbol->section->output_offset;
1125 }
e7aa05bf
KK
1126
1127 return(relocation);
1128}
1129
9addd1d4
ILT
1130#endif /* 0 */
1131
d6f41a7d
KK
1132/* Return true if this relocation should
1133 appear in the output .reloc section. */
1134
1135static boolean in_reloc_p(abfd, howto)
1136 bfd * abfd;
1137 reloc_howto_type *howto;
1138{
1139 return
1140 (! howto->pc_relative)
caa740be 1141 && (howto->type != IMAGE_REL_PPC_ADDR32NB)
d6f41a7d 1142 && (howto->type != IMAGE_REL_PPC_TOCREL16)
caa740be
KK
1143 && (howto->type != IMAGE_REL_PPC_IMGLUE)
1144 && (howto->type != IMAGE_REL_PPC_IFGLUE)
1145 && (howto->type != IMAGE_REL_PPC_SECREL)
1146 && (howto->type != IMAGE_REL_PPC_SECTION)
1147 && (howto->type != IMAGE_REL_PPC_SECREL16)
1148 && (howto->type != IMAGE_REL_PPC_REFHI)
1149 && (howto->type != IMAGE_REL_PPC_REFLO)
1150 && (howto->type != IMAGE_REL_PPC_PAIR)
1151 && (howto->type != IMAGE_REL_PPC_TOCREL16_DEFN) ;
d6f41a7d
KK
1152}
1153
9addd1d4
ILT
1154#if 0
1155
e7aa05bf
KK
1156/* this function is in charge of performing all the ppc PE relocations */
1157/* Don't yet know if we want to do this this particular way ... (krk) */
d6f41a7d 1158/* FIXME: (it is not yet enabled) */
e7aa05bf
KK
1159
1160static bfd_reloc_status_type
1161pe_ppc_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd,
d6f41a7d 1162 error_message)
e7aa05bf
KK
1163 bfd *abfd;
1164 arelent *reloc_entry;
1165 asymbol *symbol_in;
1166 PTR data;
1167 asection *input_section;
1168 bfd *output_bfd;
1169 char **error_message;
1170{
1171 /* the consth relocation comes in two parts, we have to remember
1172 the state between calls, in these variables */
1173 static boolean part1_consth_active = false;
1174 static unsigned long part1_consth_value;
1175
e7aa05bf 1176 unsigned long sym_value;
e7aa05bf 1177 unsigned short r_type;
e7aa05bf 1178 unsigned long addr = reloc_entry->address ; /*+ input_section->vma*/
e7aa05bf 1179
d6f41a7d 1180 fprintf(stderr, "pe_ppc_reloc (%s)\n", TARGET_LITTLE_NAME);
e7aa05bf 1181
d6f41a7d 1182 r_type = reloc_entry->howto->type;
e7aa05bf 1183
d6f41a7d
KK
1184 if (output_bfd)
1185 {
1186 /* Partial linking - do nothing */
1187 reloc_entry->address += input_section->output_offset;
1188 return bfd_reloc_ok;
1189 }
e7aa05bf
KK
1190
1191 if (symbol_in != NULL
1192 && bfd_is_und_section (symbol_in->section))
e7aa05bf 1193 {
d6f41a7d
KK
1194 /* Keep the state machine happy in case we're called again */
1195 if (r_type == IMAGE_REL_PPC_REFHI)
1196 {
1197 part1_consth_active = true;
1198 part1_consth_value = 0;
1199 }
1200 return(bfd_reloc_undefined);
e7aa05bf 1201 }
d6f41a7d 1202
e7aa05bf 1203 if ((part1_consth_active) && (r_type != IMAGE_REL_PPC_PAIR))
e7aa05bf 1204 {
d6f41a7d
KK
1205 part1_consth_active = false;
1206 *error_message = (char *) "Missing PAIR";
e7aa05bf
KK
1207 return(bfd_reloc_dangerous);
1208 }
e7aa05bf 1209
e7aa05bf 1210
d6f41a7d
KK
1211 sym_value = get_symbol_value(symbol_in);
1212
e7aa05bf
KK
1213 return(bfd_reloc_ok);
1214}
1215
9addd1d4
ILT
1216#endif /* 0 */
1217
e7aa05bf
KK
1218/* The reloc processing routine for the optimized COFF linker. */
1219
1220static boolean
1221coff_ppc_relocate_section (output_bfd, info, input_bfd, input_section,
d6f41a7d 1222 contents, relocs, syms, sections)
e7aa05bf
KK
1223 bfd *output_bfd;
1224 struct bfd_link_info *info;
1225 bfd *input_bfd;
1226 asection *input_section;
1227 bfd_byte *contents;
1228 struct internal_reloc *relocs;
1229 struct internal_syment *syms;
1230 asection **sections;
1231{
1232 struct internal_reloc *rel;
1233 struct internal_reloc *relend;
1234 boolean hihalf;
1235 bfd_vma hihalf_val;
d6f41a7d
KK
1236 asection *toc_section = 0;
1237 bfd_vma relocation;
1238 reloc_howto_type *howto = 0;
1239
1240#ifdef DEBUG_RELOC
1241 fprintf(stderr,
13d1a4dd 1242 "pe_ppc_relocate_section (%s) for %s in bfd %s\n",
d6f41a7d 1243 TARGET_LITTLE_NAME,
13d1a4dd
KK
1244 input_section->name,
1245 input_bfd->filename);
d6f41a7d
KK
1246
1247#endif
e7aa05bf
KK
1248
1249 /* If we are performing a relocateable link, we don't need to do a
1250 thing. The caller will take care of adjusting the reloc
1251 addresses and symbol indices. */
e7aa05bf
KK
1252 if (info->relocateable)
1253 return true;
d6f41a7d 1254
e7aa05bf
KK
1255 hihalf = false;
1256 hihalf_val = 0;
1257
1258 rel = relocs;
1259 relend = rel + input_section->reloc_count;
1260 for (; rel < relend; rel++)
1261 {
1262 long symndx;
93b6a3f8 1263 struct ppc_coff_link_hash_entry *h;
e7aa05bf 1264 struct internal_syment *sym;
e7aa05bf 1265 bfd_vma val;
d6f41a7d
KK
1266
1267 asection *sec;
e7aa05bf 1268 bfd_reloc_status_type rstat;
d6f41a7d
KK
1269 bfd_byte *loc;
1270
1271 unsigned short r_type = EXTRACT_TYPE (rel->r_type);
1272 unsigned short r_flags = EXTRACT_FLAGS(rel->r_type);
d6f41a7d
KK
1273
1274#ifdef DEBUG_RELOC
93b6a3f8
KK
1275 /* now examine flags */
1276 if (r_flags != 0)
1277 {
1278 fprintf (stderr, "Reloc with flags found!");
1279 if ( r_flags & IMAGE_REL_PPC_NEG )
1280 fprintf (stderr, " NEG");
1281 if ( r_flags & IMAGE_REL_PPC_BRTAKEN )
1282 fprintf (stderr, " BRTAKEN");
1283 if ( r_flags & IMAGE_REL_PPC_BRNTAKEN )
1284 fprintf (stderr, " BRNTAKEN");
1285 if ( r_flags & IMAGE_REL_PPC_TOCDEFN )
1286 fprintf (stderr, " TOCDEFN");
1287 fprintf(stderr, "\n");
1288 }
d6f41a7d 1289#endif
e7aa05bf
KK
1290
1291 symndx = rel->r_symndx;
1292 loc = contents + rel->r_vaddr - input_section->vma;
1293
d6f41a7d
KK
1294 /* FIXME: check bounds on r_type */
1295 howto = ppc_coff_howto_table + r_type;
1296
e7aa05bf 1297 if (symndx == -1)
d6f41a7d
KK
1298 {
1299 h = NULL;
1300 sym = NULL;
1301 }
e7aa05bf 1302 else
d6f41a7d 1303 {
93b6a3f8
KK
1304 h = (struct ppc_coff_link_hash_entry *)
1305 (obj_coff_sym_hashes (input_bfd)[symndx]);
1306 if (h != 0)
1307 {
1308 CHECK_EYE(h->eye_catcher);
1309 }
1310
d6f41a7d
KK
1311 sym = syms + symndx;
1312 }
e7aa05bf 1313
e7aa05bf
KK
1314 sec = NULL;
1315 val = 0;
1316
d6f41a7d
KK
1317 /* FIXME: PAIR unsupported in the following code */
1318 if (h == NULL)
1319 {
1320 if (symndx == -1)
1321 sec = bfd_abs_section_ptr;
1322 else
1323 {
1324 sec = sections[symndx];
1325 val = (sec->output_section->vma
1326 + sec->output_offset
1327 + sym->n_value
1328 - sec->vma);
1329 }
1330 }
1331 else
1332 {
93b6a3f8
KK
1333 CHECK_EYE(h->eye_catcher);
1334
1335 if (h->root.root.type == bfd_link_hash_defined
1336 || h->root.root.type == bfd_link_hash_defweak)
d6f41a7d 1337 {
93b6a3f8
KK
1338 sec = h->root.root.u.def.section;
1339 val = (h->root.root.u.def.value
d6f41a7d
KK
1340 + sec->output_section->vma
1341 + sec->output_offset);
1342 }
1343 else
1344 {
13d1a4dd
KK
1345fprintf(stderr,
1346 "missing %s\n",h->root.root.root.string);
d6f41a7d 1347 if (! ((*info->callbacks->undefined_symbol)
93b6a3f8 1348 (info, h->root.root.root.string, input_bfd, input_section,
d6f41a7d
KK
1349 rel->r_vaddr - input_section->vma)))
1350 return false;
1351 }
1352 }
e7aa05bf 1353
d6f41a7d
KK
1354 rstat = bfd_reloc_ok;
1355
1356 /* Each case must do its own relocation, setting rstat appropriately */
e7aa05bf
KK
1357 switch (r_type)
1358 {
1359 default:
d6f41a7d
KK
1360 fprintf( stderr,
1361 "ERROR: during reloc processing -- unsupported reloc %s\n",
1362 howto->name);
e7aa05bf 1363 bfd_set_error (bfd_error_bad_value);
d6f41a7d 1364 abort();
e7aa05bf
KK
1365 return false;
1366 case IMAGE_REL_PPC_TOCREL16:
d6f41a7d
KK
1367 {
1368 bfd_vma our_toc_offset;
1369 int fixit;
1370
1371 DUMP_RELOC2(howto->name, rel);
1372
1373 if (toc_section == 0)
1374 {
1375 toc_section = bfd_get_section_by_name (bfd_of_toc_owner,
1376 TOC_SECTION_NAME);
1377#ifdef TOC_DEBUG
1378
1379 fprintf(stderr,
13d1a4dd
KK
1380 "BFD of toc owner %p (%s), section addr of %s %p\n",
1381 bfd_of_toc_owner, bfd_of_toc_owner->filename,
1382 TOC_SECTION_NAME, toc_section);
d6f41a7d
KK
1383#endif
1384
1385 if ( toc_section == NULL )
1386 {
1387 fprintf(stderr, "No Toc section!\n");
1388 abort();
1389 }
1390 }
1391
1392 /*
1393 * Amazing bit tricks present. As we may have seen earlier, we
1394 * use the 1 bit to tell us whether or not a toc offset has been
1395 * allocated. Now that they've all been allocated, we will use
1396 * the 1 bit to tell us if we've written this particular toc
1397 * entry out.
1398 */
1399 fixit = false;
1400 if (h == 0)
1401 { /* it is a file local symbol */
1402 int *local_toc_table;
1403 const char *name;
1404
1405 sym = syms + symndx;
1406 name = sym->_n._n_name;
1407
1408 local_toc_table = obj_coff_local_toc_table(input_bfd);
1409 our_toc_offset = local_toc_table[symndx];
1410
59066248 1411 if (IS_WRITTEN(our_toc_offset))
d6f41a7d
KK
1412 {
1413 /* if it has been written out, it is marked with the
1414 1 bit. Fix up our offset, but do not write it out
1415 again.
1416 */
59066248 1417 MAKE_ADDR_AGAIN(our_toc_offset);
d6f41a7d
KK
1418#ifdef TOC_DEBUG
1419
1420 fprintf(stderr,
a9713b91
ILT
1421 "Not writing out toc_offset of %d for %s\n",
1422 our_toc_offset, name);
d6f41a7d
KK
1423#endif
1424 }
1425 else
1426 {
1427 /* write out the toc entry */
a9713b91 1428 record_toc(toc_section, our_toc_offset, priv, strdup(name));
d6f41a7d
KK
1429#ifdef TOC_DEBUG
1430 fprintf(stderr,
a9713b91
ILT
1431 "Writing out toc_offset "
1432 "toc_section (%p,%p)+%d val %d for %s\n",
d6f41a7d
KK
1433 toc_section,
1434 toc_section->contents,
1435 our_toc_offset,
1436 val,
1437 name);
1438#endif
1439
1440 bfd_put_32(output_bfd,
1441 val,
1442 toc_section->contents + our_toc_offset);
1443
59066248 1444 MARK_AS_WRITTEN(local_toc_table[symndx]);
d6f41a7d
KK
1445 fixit = true;
1446 }
1447 }
1448 else
1449 {
93b6a3f8 1450 const char *name = h->root.root.root.string;
d6f41a7d 1451 our_toc_offset = h->toc_offset;
93b6a3f8 1452
a9713b91 1453 if ((r_flags & IMAGE_REL_PPC_TOCDEFN)
13d1a4dd
KK
1454 == IMAGE_REL_PPC_TOCDEFN )
1455#if 0
1456 /* This is wrong. If tocdefn is on, we must unconditionally
1457 assume the following path */
59066248 1458 && IS_UNALLOCATED(our_toc_offset))
13d1a4dd 1459#endif
cd2b2402 1460 {
a9713b91
ILT
1461 /* This is unbelievable cheese. Some knowledgable asm
1462 hacker has decided to use r2 as a base for loading
1463 a value. He/She does this by setting the tocdefn bit,
1464 and not supplying a toc definition. The behaviour is
1465 then to use the difference between the value of the
1466 symbol and the actual location of the toc as the toc
1467 index.
1468
1469 In fact, what is usually happening is, because the
1470 Import Address Table is mapped immediately following
1471 the toc, some trippy library code trying for speed on
1472 dll linkage, takes advantage of that and considers
1473 the IAT to be part of the toc, thus saving a load.
cd2b2402 1474 */
13d1a4dd
KK
1475#ifdef DEBUG_RELOC
1476 fprintf(stderr,
1477 "TOCDEFN is on, (%s) (%p) our_toc_offset = %x\n",
1478 name, h, our_toc_offset);
1479#endif
1480
a9713b91
ILT
1481 our_toc_offset = val -
1482 (toc_section->output_section->vma +
1483 toc_section->output_offset);
1484
13d1a4dd
KK
1485#ifdef DEBUG_RELOC
1486 fprintf(stderr,
1487 " our_toc_offset set to %x\n", our_toc_offset);
1488#endif
1489
a9713b91
ILT
1490 /* The size must still fit in a 16bit displacment */
1491 if (our_toc_offset >= 65535)
1492 {
1493 fprintf(stderr,
1494 "TOCDEFN Relocation exceeded "
1495 "displacment of 65535\n");
1496 abort();
1497 }
1498
1499 record_toc(toc_section, our_toc_offset, pub, strdup(name));
cd2b2402 1500 }
59066248 1501 else if (IS_WRITTEN(our_toc_offset))
d6f41a7d
KK
1502 {
1503 /* if it has been written out, it is marked with the
1504 1 bit. Fix up our offset, but do not write it out
1505 again.
1506 */
59066248 1507 MAKE_ADDR_AGAIN(our_toc_offset);
d6f41a7d
KK
1508#ifdef TOC_DEBUG
1509 fprintf(stderr,
a9713b91
ILT
1510 "Not writing out toc_offset of %d for %s\n",
1511 our_toc_offset, name);
d6f41a7d
KK
1512#endif
1513 }
1514 else
1515 {
a9713b91 1516 record_toc(toc_section, our_toc_offset, pub, strdup(name));
93b6a3f8 1517
d6f41a7d
KK
1518#ifdef TOC_DEBUG
1519 /* write out the toc entry */
1520 fprintf(stderr,
a9713b91
ILT
1521 "Writing out toc_offset "
1522 "toc_section (%p,%p)+%d val %d for %s\n",
d6f41a7d
KK
1523 toc_section,
1524 toc_section->contents,
1525 our_toc_offset,
1526 val,
1527 name);
1528#endif
1529
1530 /* write out the toc entry */
1531 bfd_put_32(output_bfd,
1532 val,
1533 toc_section->contents + our_toc_offset);
1534
59066248 1535 MARK_AS_WRITTEN(h->toc_offset);
d6f41a7d
KK
1536 /* The tricky part is that this is the address that */
1537 /* needs a .reloc entry for it */
1538 fixit = true;
1539 }
1540 }
1541
1542 if (fixit && info->base_file)
1543 {
1544 /* So if this is non pcrelative, and is referenced
1545 to a section or a common symbol, then it needs a reloc */
1546
1547 /* relocation to a symbol in a section which
1548 isn't absolute - we output the address here
1549 to a file */
1550
1551 bfd_vma addr = toc_section->output_section->vma
1552 + toc_section->output_offset + our_toc_offset;
1553
d6f41a7d
KK
1554 if (coff_data(output_bfd)->pe)
1555 addr -= pe_data(output_bfd)->pe_opthdr.ImageBase;
caa740be 1556
3920d9c9 1557#ifdef DEBUG_RELOC
caa740be
KK
1558 fprintf(stderr,
1559 " Toc Section .reloc candidate addr = %x\n", addr);
3920d9c9 1560#endif
d6f41a7d
KK
1561 fwrite (&addr, 1,4, (FILE *) info->base_file);
1562 }
1563
1564
1565 /* FIXME: this test is conservative */
cd2b2402
KK
1566 if ( (r_flags & IMAGE_REL_PPC_TOCDEFN) != IMAGE_REL_PPC_TOCDEFN &&
1567 our_toc_offset > toc_section->_raw_size)
d6f41a7d
KK
1568 {
1569 fprintf(stderr,
1570 "reloc offset is bigger than the toc size!\n");
1571 abort();
1572 }
1573
1574 /* Now we know the relocation for this toc reference */
1575 relocation = our_toc_offset + TOC_LOAD_ADJUSTMENT;
1576 rstat = _bfd_relocate_contents (howto,
1577 input_bfd,
1578 relocation,
1579 loc);
1580 }
1581 break;
e7aa05bf 1582 case IMAGE_REL_PPC_IFGLUE:
93b6a3f8
KK
1583 {
1584 /* To solve this, we need to know whether or not the symbol */
1585 /* appearing on the call instruction is a glue function or not. */
1586 /* A glue function must announce itself via a IMGLUE reloc, and */
1587 /* the reloc contains the required toc restore instruction */
1588
1589 bfd_vma x;
1590 const char *my_name;
1591 DUMP_RELOC2(howto->name, rel);
1592
1593 if (h != 0)
1594 {
1595 my_name = h->root.root.root.string;
1596 if (h->symbol_is_glue == 1)
1597 {
1598 x = bfd_get_32(input_bfd, loc);
1599 bfd_put_32(input_bfd, h->glue_insn, loc);
1600 }
1601 }
1602 }
d6f41a7d 1603 break;
e7aa05bf 1604 case IMAGE_REL_PPC_SECREL:
d6f41a7d
KK
1605 /* Unimplemented: codeview debugging information */
1606 /* For fast access to the header of the section
1607 containing the item. */
1608 break;
1609 case IMAGE_REL_PPC_SECTION:
1610 /* Unimplemented: codeview debugging information */
1611 /* Is used to indicate that the value should be relative
1612 to the beginning of the section that contains the
1613 symbol */
1614 break;
e7aa05bf 1615 case IMAGE_REL_PPC_ABSOLUTE:
d6f41a7d
KK
1616 {
1617 const char *my_name;
1618 if (h == 0)
1619 my_name = (syms+symndx)->_n._n_name;
1620 else
93b6a3f8
KK
1621 {
1622 my_name = h->root.root.root.string;
1623 }
d6f41a7d
KK
1624
1625 fprintf(stderr,
1626 "Warning: unsupported reloc %s <file %s, section %s>\n",
1627 howto->name,
1628 bfd_get_filename(input_bfd),
1629 input_section->name);
1630
9addd1d4
ILT
1631 fprintf(stderr,"sym %ld (%s), r_vaddr %ld (%lx)\n",
1632 rel->r_symndx, my_name, (long) rel->r_vaddr,
1633 (unsigned long) rel->r_vaddr);
d6f41a7d
KK
1634 }
1635 break;
93b6a3f8
KK
1636 case IMAGE_REL_PPC_IMGLUE:
1637 {
1638 /* There is nothing to do now. This reloc was noted in the first
1639 pass over the relocs, and the glue instruction extracted */
1640 const char *my_name;
1641 if (h->symbol_is_glue == 1)
1642 break;
1643 my_name = h->root.root.root.string;
1644 fprintf(stderr,
1645 "Warning: previously missed IMGLUE reloc %s <file %s, section %s>\n",
1646 howto->name,
1647 bfd_get_filename(input_bfd),
1648 input_section->name);
1649 break;
1650
1651 }
1652 break;
d6f41a7d
KK
1653
1654 case IMAGE_REL_PPC_ADDR32NB:
1655 {
1656 struct coff_link_hash_entry *myh = 0;
1657 const char *name = 0;
1658 DUMP_RELOC2(howto->name, rel);
13d1a4dd
KK
1659
1660 if (strncmp(".idata$2",input_section->name,8) == 0 && first_thunk_address == 0)
1661 {
1662 /* set magic values */
1663 int idata5offset;
1664 struct coff_link_hash_entry *myh = 0;
1665 myh = coff_link_hash_lookup (coff_hash_table (info),
1666 "__idata5_magic__",
1667 false, false, true);
1668 first_thunk_address = myh->root.u.def.value +
1669 sec->output_section->vma +
1670 sec->output_offset -
1671 pe_data(output_bfd)->pe_opthdr.ImageBase;
1672
1673 idata5offset = myh->root.u.def.value;
1674 myh = coff_link_hash_lookup (coff_hash_table (info),
1675 "__idata6_magic__",
1676 false, false, true);
1677
1678 thunk_size = myh->root.u.def.value - idata5offset;
1679 myh = coff_link_hash_lookup (coff_hash_table (info),
1680 "__idata4_magic__",
1681 false, false, true);
1682 import_table_size = myh->root.u.def.value;
1683#ifdef DEBUG_RELOC
1684 fprintf(stderr,
1685 "first computation triggered fta %x, ts %d(%x), its %d(%x)\n",
1686 first_thunk_address, thunk_size, thunk_size, import_table_size,
1687 import_table_size);
1688#endif
1689 }
1690
d6f41a7d
KK
1691 if (h == 0)
1692 { /* it is a file local symbol */
1693 sym = syms + symndx;
1694 name = sym->_n._n_name;
1695 }
1696 else
1697 {
1698 char *target = 0;
1699
93b6a3f8 1700 name = h->root.root.root.string;
d6f41a7d
KK
1701 if (strcmp(".idata$2", name) == 0)
1702 target = "__idata2_magic__";
1703 else if (strcmp(".idata$4", name) == 0)
1704 target = "__idata4_magic__";
1705 else if (strcmp(".idata$5", name) == 0)
1706 target = "__idata5_magic__";
d6f41a7d 1707
59066248 1708 if (target != 0)
d6f41a7d 1709 {
59066248 1710 myh = 0;
d6f41a7d 1711
d6f41a7d 1712 myh = coff_link_hash_lookup (coff_hash_table (info),
59066248 1713 target,
d6f41a7d 1714 false, false, true);
59066248
KK
1715 if (myh == 0)
1716 {
1717 fprintf(stderr, "Missing idata magic cookies, "
1718 "this cannot work anyway...\n");
1719 abort();
1720 }
1721
1722 val = myh->root.u.def.value +
1723 sec->output_section->vma + sec->output_offset;
1724 if (first_thunk_address == 0)
1725 {
1726 int idata5offset;
1727 myh = coff_link_hash_lookup (coff_hash_table (info),
1728 "__idata5_magic__",
1729 false, false, true);
1730 first_thunk_address = myh->root.u.def.value +
1731 sec->output_section->vma +
1732 sec->output_offset -
1733 pe_data(output_bfd)->pe_opthdr.ImageBase;
1734
1735 idata5offset = myh->root.u.def.value;
1736 myh = coff_link_hash_lookup (coff_hash_table (info),
1737 "__idata6_magic__",
1738 false, false, true);
1739
1740 thunk_size = myh->root.u.def.value - idata5offset;
1741 myh = coff_link_hash_lookup (coff_hash_table (info),
1742 "__idata4_magic__",
1743 false, false, true);
1744 import_table_size = myh->root.u.def.value;
13d1a4dd
KK
1745#ifdef DEBUG_RELOC
1746
1747 fprintf(stderr,
1748 "second computation triggered fta %x, ts %d(%x), its %d(%x)\n",
1749 first_thunk_address, thunk_size, thunk_size, import_table_size,
1750 import_table_size);
1751#endif
59066248 1752 }
d6f41a7d
KK
1753 }
1754 }
1755
1756 rstat = _bfd_relocate_contents (howto,
93b6a3f8
KK
1757 input_bfd,
1758 val -
1759 pe_data(output_bfd)->pe_opthdr.ImageBase,
1760 loc);
d6f41a7d 1761 }
e7aa05bf
KK
1762 break;
1763
e7aa05bf 1764 case IMAGE_REL_PPC_REL24:
cd2b2402
KK
1765 DUMP_RELOC2(howto->name, rel);
1766 val -= (input_section->output_section->vma
1767 + input_section->output_offset);
1768
1769 rstat = _bfd_relocate_contents (howto,
1770 input_bfd,
1771 val,
1772 loc);
1773 break;
1774 case IMAGE_REL_PPC_ADDR16:
e7aa05bf
KK
1775 case IMAGE_REL_PPC_ADDR24:
1776 case IMAGE_REL_PPC_ADDR32:
d6f41a7d
KK
1777 DUMP_RELOC2(howto->name, rel);
1778 rstat = _bfd_relocate_contents (howto,
1779 input_bfd,
1780 val,
1781 loc);
e7aa05bf
KK
1782 break;
1783 }
1784
d6f41a7d 1785 if ( info->base_file )
e7aa05bf 1786 {
d6f41a7d
KK
1787 /* So if this is non pcrelative, and is referenced
1788 to a section or a common symbol, then it needs a reloc */
1789 if (sym && pe_data(output_bfd)->in_reloc_p(output_bfd, howto))
e7aa05bf 1790 {
d6f41a7d
KK
1791 /* relocation to a symbol in a section which
1792 isn't absolute - we output the address here
1793 to a file */
1794 bfd_vma addr = rel->r_vaddr
1795 - input_section->vma
1796 + input_section->output_offset
1797 + input_section->output_section->vma;
1798
1799 if (coff_data(output_bfd)->pe)
1800 {
9addd1d4 1801#ifdef DEBUG_RELOC
caa740be 1802 bfd_vma before_addr = addr;
9addd1d4 1803#endif
d6f41a7d 1804 addr -= pe_data(output_bfd)->pe_opthdr.ImageBase;
3920d9c9 1805#ifdef DEBUG_RELOC
d6f41a7d 1806 fprintf(stderr,
caa740be 1807 " adjusted down from %x to %x", before_addr, addr);
3920d9c9 1808#endif
d6f41a7d 1809 }
3920d9c9 1810#ifdef DEBUG_RELOC
d6f41a7d 1811 fprintf(stderr, "\n");
3920d9c9 1812#endif
d6f41a7d
KK
1813
1814 fwrite (&addr, 1,4, (FILE *) info->base_file);
e7aa05bf 1815 }
d6f41a7d 1816 }
e7aa05bf 1817
d6f41a7d
KK
1818 switch (rstat)
1819 {
1820 default:
1821 abort ();
1822 case bfd_reloc_ok:
1823 break;
1824 case bfd_reloc_overflow:
1825 {
1826 const char *name;
1827 char buf[SYMNMLEN + 1];
1828
1829 if (symndx == -1)
1830 name = "*ABS*";
1831 else if (h != NULL)
93b6a3f8 1832 name = h->root.root.root.string;
d6f41a7d
KK
1833 else if (sym == NULL)
1834 name = "*unknown*";
1835 else if (sym->_n._n_n._n_zeroes == 0
1836 && sym->_n._n_n._n_offset != 0)
1837 name = obj_coff_strings (input_bfd) + sym->_n._n_n._n_offset;
1838 else
1839 {
1840 strncpy (buf, sym->_n._n_name, SYMNMLEN);
1841 buf[SYMNMLEN] = '\0';
1842 name = buf;
1843 }
1844#if 0
1845 else
1846 {
1847 name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
1848 if (name == NULL)
1849 return false;
1850 }
1851#endif
1852
1853 if (! ((*info->callbacks->reloc_overflow)
1854 (info, name, howto->name,
1855 (bfd_vma) 0, input_bfd,
1856 input_section, rel->r_vaddr - input_section->vma)))
13d1a4dd
KK
1857 {
1858#ifdef DEBUG_RELOC
1859 fprintf(stderr,
1860 "pe_ppc_relocate_section (%s) for %s in bfd %s RETURNING TRUE\n",
1861 TARGET_LITTLE_NAME,
1862 input_section->name,
1863 input_bfd->filename);
1864
1865#endif
1866 return false;
1867 }
d6f41a7d 1868 }
e7aa05bf 1869 }
d6f41a7d 1870
e7aa05bf
KK
1871 }
1872
13d1a4dd
KK
1873#ifdef DEBUG_RELOC
1874 fprintf(stderr,
1875 "pe_ppc_relocate_section (%s) for %s in bfd %s RETURNING TRUE\n",
1876 TARGET_LITTLE_NAME,
1877 input_section->name,
1878 input_bfd->filename);
1879
1880#endif
1881
e7aa05bf
KK
1882 return true;
1883}
1884
13d1a4dd 1885
d6f41a7d 1886#ifdef COFF_IMAGE_WITH_PE
e7aa05bf 1887
13d1a4dd 1888long int global_toc_size = 4;
e7aa05bf 1889
d6f41a7d 1890bfd* bfd_of_toc_owner = 0;
e7aa05bf 1891
d6f41a7d
KK
1892long int import_table_size;
1893long int first_thunk_address;
1894long int thunk_size;
1895
93b6a3f8
KK
1896struct list_ele *head;
1897struct list_ele *tail;
1898
a9713b91
ILT
1899static char *
1900h1 = "\n\t\t\tTOC MAPPING\n\n";
1901static char *
1902h2 = " TOC disassembly Comments Name\n";
1903static char *
1904h3 = " Offset spelling (if present)\n";
1905
93b6a3f8
KK
1906void
1907dump_toc(vfile)
1908 void *vfile;
1909{
1910 FILE *file = vfile;
1911 struct list_ele *t;
1912
a9713b91
ILT
1913 fprintf(file, h1);
1914 fprintf(file, h2);
1915 fprintf(file, h3);
93b6a3f8
KK
1916
1917 for(t = head; t != 0; t=t->next)
1918 {
a9713b91
ILT
1919 char *cat;
1920
1921 if (t->cat == priv)
1922 cat = "private ";
1923 else if (t->cat == pub)
1924 cat = "public ";
1925 else if (t->cat == data)
1926 cat = "data-in-toc ";
1927
1928 if (t->offset > global_toc_size)
1929 {
1930 if (t->offset <= global_toc_size + thunk_size)
1931 cat = "IAT reference ";
1932 else
13d1a4dd
KK
1933 {
1934 fprintf(file,
9addd1d4 1935 "**** global_toc_size %ld(%lx), thunk_size %ld(%lx)\n",
13d1a4dd
KK
1936 global_toc_size, global_toc_size, thunk_size, thunk_size);
1937 cat = "Out of bounds!";
1938 }
a9713b91
ILT
1939 }
1940
93b6a3f8 1941 fprintf(file,
9addd1d4 1942 " %04lx (%d)", (unsigned long) t->offset, t->offset - 32768);
a9713b91
ILT
1943 fprintf(file,
1944 " %s %s\n",
1945 cat, t->name);
1946
93b6a3f8 1947 }
a9713b91
ILT
1948
1949 fprintf(file, "\n");
93b6a3f8 1950}
d6f41a7d
KK
1951
1952boolean
1953ppc_allocate_toc_section (info)
1954 struct bfd_link_info *info;
1955{
1956 asection *s;
1957 bfd_byte *foo;
1958 static char test_char = '1';
1959
d6f41a7d
KK
1960 if ( global_toc_size == 0 ) /* FIXME: does this get me in trouble? */
1961 return true;
1962
1963 if (bfd_of_toc_owner == 0)
1964 {
1965 fprintf(stderr,
1966 "There is no bfd that owns the toc section!\n");
1967 abort();
1968 }
1969
1970 s = bfd_get_section_by_name ( bfd_of_toc_owner , TOC_SECTION_NAME);
1971 if (s == NULL)
1972 {
1973 fprintf(stderr, "No Toc section!\n");
1974 abort();
1975 }
1976
1977 foo = bfd_alloc(bfd_of_toc_owner, global_toc_size);
1978 memset(foo, test_char, global_toc_size);
1979
1980 s->_raw_size = s->_cooked_size = global_toc_size;
1981 s->contents = foo;
1982
1983 return true;
e7aa05bf
KK
1984}
1985
d6f41a7d
KK
1986boolean
1987ppc_process_before_allocation (abfd, info)
1988 bfd *abfd;
1989 struct bfd_link_info *info;
1990{
1991 asection *sec;
1992 struct internal_reloc *i, *rel;
1993
59066248 1994#ifdef DEBUG_RELOC
d6f41a7d
KK
1995 fprintf(stderr,
1996 "ppc_process_before_allocation: BFD %s\n",
1997 bfd_get_filename(abfd));
1998#endif
1999
2000 /* here we have a bfd that is to be included on the link. We have a hook
2001 to do reloc rummaging, before section sizes are nailed down. */
2002
2003 _bfd_coff_get_external_symbols(abfd);
2004
2005 /* rummage around all the relocs and map the toc */
2006 sec = abfd->sections;
2007
2008 if (sec == 0)
2009 {
2010 return true;
2011 }
2012
2013 for (; sec != 0; sec = sec->next)
2014 {
2015 int toc_offset;
a9713b91 2016
d6f41a7d
KK
2017#ifdef DEBUG_RELOC
2018 fprintf(stderr,
2019 " section %s reloc count %d\n",
2020 sec->name,
2021 sec->reloc_count);
2022#endif
2023
2024 if (sec->reloc_count == 0)
2025 continue;
2026
2027 /* load the relocs */
2028 /* FIXME: there may be a storage leak here */
2029 i=_bfd_coff_read_internal_relocs(abfd,sec,1,0,0,0);
2030
2031 if (i == 0)
2032 abort();
2033
2034 for (rel=i;rel<i+sec->reloc_count;++rel)
2035 {
2036 unsigned short r_type = EXTRACT_TYPE (rel->r_type);
2037 unsigned short r_flags = EXTRACT_FLAGS(rel->r_type);
d6f41a7d
KK
2038
2039#ifdef DEBUG_RELOC
93b6a3f8
KK
2040 /* now examine flags */
2041 if (r_flags != 0)
2042 {
2043 fprintf (stderr, "Reloc with flags found!");
2044 if ( r_flags & IMAGE_REL_PPC_NEG )
2045 fprintf (stderr, " NEG");
2046 if ( r_flags & IMAGE_REL_PPC_BRTAKEN )
2047 fprintf (stderr, " BRTAKEN");
2048 if ( r_flags & IMAGE_REL_PPC_BRNTAKEN )
2049 fprintf (stderr, " BRNTAKEN");
2050 if ( r_flags & IMAGE_REL_PPC_TOCDEFN )
2051 fprintf (stderr, " TOCDEFN");
2052 fprintf(stderr, "\n");
2053 }
d6f41a7d
KK
2054#endif
2055
2056 DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel);
2057
2058 switch(r_type)
2059 {
2060 case IMAGE_REL_PPC_TOCREL16:
a9713b91
ILT
2061#if 0
2062 /* FIXME:
2063 This remains unimplemented for now, as it currently adds
2064 un-necessary elements to the toc. All we need to do today
2065 is not do anything if TOCDEFN is on.
2066 */
cd2b2402
KK
2067 if ( r_flags & IMAGE_REL_PPC_TOCDEFN )
2068 toc_offset = ppc_record_data_in_toc_entry(abfd, info, sec,
2069 rel->r_symndx,
2070 default_toc);
2071 else
2072 toc_offset = ppc_record_toc_entry(abfd, info, sec,
2073 rel->r_symndx, default_toc);
a9713b91
ILT
2074#endif
2075 if ( (r_flags & IMAGE_REL_PPC_TOCDEFN) != IMAGE_REL_PPC_TOCDEFN )
2076 toc_offset = ppc_record_toc_entry(abfd, info, sec,
2077 rel->r_symndx, default_toc);
d6f41a7d 2078 break;
93b6a3f8
KK
2079 case IMAGE_REL_PPC_IMGLUE:
2080 ppc_mark_symbol_as_glue(abfd, rel->r_symndx, rel);
2081 break;
d6f41a7d
KK
2082 default:
2083 break;
2084 }
2085 }
2086 }
9addd1d4
ILT
2087
2088 return true;
e7aa05bf
KK
2089}
2090
e7aa05bf
KK
2091#endif
2092
2093
2094static bfd_reloc_status_type
2095ppc_refhi_reloc (abfd,
2096 reloc_entry,
2097 symbol,
2098 data,
2099 input_section,
2100 output_bfd,
2101 error_message)
2102 bfd *abfd;
2103 arelent *reloc_entry;
2104 asymbol *symbol;
2105 PTR data;
2106 asection *input_section;
2107 bfd *output_bfd;
2108 char **error_message;
2109{
2110 UN_IMPL("REFHI");
2111 DUMP_RELOC("REFHI",reloc_entry);
2112
2113 if (output_bfd == (bfd *) NULL)
2114 return bfd_reloc_continue;
2115
2116 return bfd_reloc_undefined;
2117}
2118
9addd1d4
ILT
2119#if 0
2120
e7aa05bf
KK
2121static bfd_reloc_status_type
2122ppc_reflo_reloc (abfd,
2123 reloc_entry,
2124 symbol,
2125 data,
2126 input_section,
2127 output_bfd,
2128 error_message)
2129 bfd *abfd;
2130 arelent *reloc_entry;
2131 asymbol *symbol;
2132 PTR data;
2133 asection *input_section;
2134 bfd *output_bfd;
2135 char **error_message;
2136{
2137 UN_IMPL("REFLO");
2138 DUMP_RELOC("REFLO",reloc_entry);
2139
2140 if (output_bfd == (bfd *) NULL)
2141 return bfd_reloc_continue;
2142
2143 return bfd_reloc_undefined;
2144}
2145
9addd1d4
ILT
2146#endif
2147
e7aa05bf
KK
2148static bfd_reloc_status_type
2149ppc_pair_reloc (abfd,
2150 reloc_entry,
2151 symbol,
2152 data,
2153 input_section,
2154 output_bfd,
2155 error_message)
2156 bfd *abfd;
2157 arelent *reloc_entry;
2158 asymbol *symbol;
2159 PTR data;
2160 asection *input_section;
2161 bfd *output_bfd;
2162 char **error_message;
2163{
2164 UN_IMPL("PAIR");
2165 DUMP_RELOC("PAIR",reloc_entry);
2166
2167 if (output_bfd == (bfd *) NULL)
2168 return bfd_reloc_continue;
2169
2170 return bfd_reloc_undefined;
2171}
2172
2173\f
2174static bfd_reloc_status_type
2175ppc_toc16_reloc (abfd,
2176 reloc_entry,
2177 symbol,
2178 data,
2179 input_section,
2180 output_bfd,
2181 error_message)
2182 bfd *abfd;
2183 arelent *reloc_entry;
2184 asymbol *symbol;
2185 PTR data;
2186 asection *input_section;
2187 bfd *output_bfd;
2188 char **error_message;
2189{
2190 UN_IMPL("TOCREL16");
2191 DUMP_RELOC("TOCREL16",reloc_entry);
2192
2193 if (output_bfd == (bfd *) NULL)
2194 {
2195 return bfd_reloc_continue;
2196 }
2197
2198 return bfd_reloc_ok;
2199}
2200
9addd1d4
ILT
2201#if 0
2202
e7aa05bf
KK
2203/* ADDR32NB : 32 bit address relative to the virtual origin. */
2204/* (On the alpha, this is always a linker generated thunk)*/
2205/* (i.e. 32bit addr relative to the image base) */
2206/* */
2207/* */
2208
2209static bfd_reloc_status_type
2210ppc_addr32nb_reloc (abfd,
2211 reloc_entry,
2212 symbol,
2213 data,
2214 input_section,
2215 output_bfd,
2216 error_message)
2217 bfd *abfd;
2218 arelent *reloc_entry;
2219 asymbol *symbol;
2220 PTR data;
2221 asection *input_section;
2222 bfd *output_bfd;
2223 char **error_message;
2224{
2225 UN_IMPL("ADDR32NB");
2226 DUMP_RELOC("ADDR32NB",reloc_entry);
2227
2228 return bfd_reloc_ok;
2229}
2230
9addd1d4
ILT
2231#endif
2232
e7aa05bf
KK
2233static bfd_reloc_status_type
2234ppc_secrel_reloc (abfd,
2235 reloc_entry,
2236 symbol,
2237 data,
2238 input_section,
2239 output_bfd,
2240 error_message)
2241 bfd *abfd;
2242 arelent *reloc_entry;
2243 asymbol *symbol;
2244 PTR data;
2245 asection *input_section;
2246 bfd *output_bfd;
2247 char **error_message;
2248{
2249 UN_IMPL("SECREL");
2250 DUMP_RELOC("SECREL",reloc_entry);
2251
2252 if (output_bfd == (bfd *) NULL)
2253 return bfd_reloc_continue;
2254
2255 return bfd_reloc_ok;
2256}
2257
2258static bfd_reloc_status_type
2259ppc_section_reloc (abfd,
2260 reloc_entry,
2261 symbol,
2262 data,
2263 input_section,
2264 output_bfd,
2265 error_message)
2266 bfd *abfd;
2267 arelent *reloc_entry;
2268 asymbol *symbol;
2269 PTR data;
2270 asection *input_section;
2271 bfd *output_bfd;
2272 char **error_message;
2273{
2274 UN_IMPL("SECTION");
2275 DUMP_RELOC("SECTION",reloc_entry);
2276
2277 if (output_bfd == (bfd *) NULL)
2278 return bfd_reloc_continue;
2279
2280 return bfd_reloc_ok;
2281}
2282
2283static bfd_reloc_status_type
2284ppc_imglue_reloc (abfd,
2285 reloc_entry,
2286 symbol,
2287 data,
2288 input_section,
2289 output_bfd,
2290 error_message)
2291 bfd *abfd;
2292 arelent *reloc_entry;
2293 asymbol *symbol;
2294 PTR data;
2295 asection *input_section;
2296 bfd *output_bfd;
2297 char **error_message;
2298{
2299 UN_IMPL("IMGLUE");
2300 DUMP_RELOC("IMGLUE",reloc_entry);
2301
2302 if (output_bfd == (bfd *) NULL)
2303 return bfd_reloc_continue;
2304
2305 return bfd_reloc_ok;
2306}
2307
2308\f
2309
2310#define MAX_RELOC_INDEX \
2311 (sizeof(ppc_coff_howto_table) / sizeof(ppc_coff_howto_table[0]) - 1)
2312
2313
2314/* FIXME: There is a possiblity that when we read in a reloc from a file,
2315 that there are some bits encoded in the upper portion of the
2316 type field. Not yet implemented.
2317*/
2318static void ppc_coff_rtype2howto PARAMS ((arelent *relent,
2319 struct internal_reloc *internal));
2320
2321static void
2322ppc_coff_rtype2howto (relent, internal)
2323 arelent *relent;
2324 struct internal_reloc *internal;
2325{
2326
2327 /* We can encode one of three things in the type field, aside from the
2328 type:
2329 1. IMAGE_REL_PPC_NEG - indicates the value field is a subtraction
2330 value, rather than an addition value
2331 2. IMAGE_REL_PPC_BRTAKEN, IMAGE_REL_PPC_BRNTAKEN - indicates that
2332 the branch is expected to be taken or not.
2333 3. IMAGE_REL_PPC_TOCDEFN - toc slot definition in the file
2334 For now, we just strip this stuff to find the type, and ignore it other
2335 than that.
2336 */
59066248 2337 reloc_howto_type *howto;
e7aa05bf
KK
2338 unsigned short r_type = EXTRACT_TYPE (internal->r_type);
2339 unsigned short r_flags = EXTRACT_FLAGS(internal->r_type);
2340 unsigned short junk = EXTRACT_JUNK (internal->r_type);
2341
2342 /* the masking process only slices off the bottom byte for r_type. */
2343 if ( r_type > MAX_RELOC_INDEX )
2344 {
2345 fprintf(stderr,
9addd1d4
ILT
2346 "ppc_coff_rtype2howto: reloc index %d out of range [%d, %ld]\n",
2347 internal->r_type, 0, (long) MAX_RELOC_INDEX);
e7aa05bf
KK
2348 abort();
2349 }
2350
2351 /* check for absolute crap */
2352 if ( junk != 0 )
2353 {
2354 fprintf(stderr,
2355 "ppc_coff_rtype2howto: reloc index %d contains junk %d\n",
2356 internal->r_type, junk);
2357 abort();
2358 }
2359
2360#ifdef DEBUG_RELOC
2361 /* now examine flags */
2362 if (r_flags != 0)
2363 {
2364 fprintf (stderr, "Reloc with flags found!");
2365 if ( r_flags & IMAGE_REL_PPC_NEG )
2366 fprintf (stderr, " NEG");
2367 if ( r_flags & IMAGE_REL_PPC_BRTAKEN )
2368 fprintf (stderr, " BRTAKEN");
2369 if ( r_flags & IMAGE_REL_PPC_BRNTAKEN )
2370 fprintf (stderr, " BRNTAKEN");
2371 if ( r_flags & IMAGE_REL_PPC_TOCDEFN )
2372 fprintf (stderr, " TOCDEFN");
2373 fprintf(stderr, "\n");
2374 }
2375#endif
2376
2377 switch(r_type)
2378 {
2379 case IMAGE_REL_PPC_ADDR16:
2380 case IMAGE_REL_PPC_REL24:
2381 case IMAGE_REL_PPC_ADDR24:
e7aa05bf
KK
2382 case IMAGE_REL_PPC_ADDR32:
2383 case IMAGE_REL_PPC_IFGLUE:
2384 case IMAGE_REL_PPC_ADDR32NB:
2385 case IMAGE_REL_PPC_SECTION:
2386 case IMAGE_REL_PPC_SECREL:
2387 DUMP_RELOC2(ppc_coff_howto_table[r_type].name, internal);
59066248 2388 howto = ppc_coff_howto_table + r_type;
e7aa05bf
KK
2389 break;
2390 case IMAGE_REL_PPC_IMGLUE:
2391 DUMP_RELOC2(ppc_coff_howto_table[r_type].name, internal);
59066248
KK
2392 howto = ppc_coff_howto_table + r_type;
2393 break;
2394 case IMAGE_REL_PPC_TOCREL16:
2395 DUMP_RELOC2(ppc_coff_howto_table[r_type].name, internal);
2396 if (r_flags & IMAGE_REL_PPC_TOCDEFN)
2397 howto = ppc_coff_howto_table + IMAGE_REL_PPC_TOCREL16_DEFN;
2398 else
2399 howto = ppc_coff_howto_table + IMAGE_REL_PPC_TOCREL16;
e7aa05bf
KK
2400 break;
2401 default:
2402 fprintf(stderr,
2403 "Warning: Unsupported reloc %s [%d] used -- it may not work.\n",
2404 ppc_coff_howto_table[r_type].name,
2405 r_type);
59066248 2406 howto = ppc_coff_howto_table + r_type;
e7aa05bf
KK
2407 break;
2408 }
d6f41a7d 2409
59066248 2410 relent->howto = howto;
d6f41a7d 2411
e7aa05bf
KK
2412}
2413
2414static reloc_howto_type *
2415coff_ppc_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
2416 bfd *abfd;
2417 asection *sec;
2418 struct internal_reloc *rel;
2419 struct coff_link_hash_entry *h;
2420 struct internal_syment *sym;
2421 bfd_vma *addendp;
2422{
2423 reloc_howto_type *howto;
2424
2425 /* We can encode one of three things in the type field, aside from the
2426 type:
2427 1. IMAGE_REL_PPC_NEG - indicates the value field is a subtraction
2428 value, rather than an addition value
2429 2. IMAGE_REL_PPC_BRTAKEN, IMAGE_REL_PPC_BRNTAKEN - indicates that
2430 the branch is expected to be taken or not.
2431 3. IMAGE_REL_PPC_TOCDEFN - toc slot definition in the file
2432 For now, we just strip this stuff to find the type, and ignore it other
2433 than that.
2434 */
2435
2436 unsigned short r_type = EXTRACT_TYPE (rel->r_type);
2437 unsigned short r_flags = EXTRACT_FLAGS(rel->r_type);
2438 unsigned short junk = EXTRACT_JUNK (rel->r_type);
2439
2440 /* the masking process only slices off the bottom byte for r_type. */
2441 if ( r_type > MAX_RELOC_INDEX )
2442 {
2443 fprintf(stderr,
9addd1d4
ILT
2444 "coff_ppc_rtype_to_howto: index %d out of range [%d, %ld]\n",
2445 r_type, 0, (long) MAX_RELOC_INDEX);
e7aa05bf
KK
2446 abort();
2447 }
d6f41a7d 2448
e7aa05bf
KK
2449 /* check for absolute crap */
2450 if ( junk != 0 )
2451 {
2452 fprintf(stderr,
2453 "coff_ppc_rtype_to_howto: reloc index %d contains junk %d\n",
2454 rel->r_type, junk);
2455 abort();
2456 }
d6f41a7d 2457
e7aa05bf
KK
2458#ifdef DEBUG_RELOC
2459 /* now examine flags */
2460 if (r_flags != 0)
2461 {
2462 fprintf (stderr, "Reloc with flags found!");
2463 if ( r_flags & IMAGE_REL_PPC_NEG )
2464 fprintf (stderr, " NEG");
2465 if ( r_flags & IMAGE_REL_PPC_BRTAKEN )
2466 fprintf (stderr, " BRTAKEN");
2467 if ( r_flags & IMAGE_REL_PPC_BRNTAKEN )
2468 fprintf (stderr, " BRNTAKEN");
2469 if ( r_flags & IMAGE_REL_PPC_TOCDEFN )
2470 fprintf (stderr, " TOCDEFN");
2471 fprintf(stderr, "\n");
2472 }
2473#endif
d6f41a7d 2474
e7aa05bf
KK
2475 switch(r_type)
2476 {
2477 case IMAGE_REL_PPC_ADDR32NB:
2478 DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel);
2479 *addendp -= pe_data(sec->output_section->owner)->pe_opthdr.ImageBase;
59066248
KK
2480 howto = ppc_coff_howto_table + r_type;
2481 break;
2482 case IMAGE_REL_PPC_TOCREL16:
2483 DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel);
2484 if (r_flags & IMAGE_REL_PPC_TOCDEFN)
2485 howto = ppc_coff_howto_table + IMAGE_REL_PPC_TOCREL16_DEFN;
2486 else
2487 howto = ppc_coff_howto_table + IMAGE_REL_PPC_TOCREL16;
e7aa05bf
KK
2488 break;
2489 case IMAGE_REL_PPC_ADDR16:
2490 case IMAGE_REL_PPC_REL24:
2491 case IMAGE_REL_PPC_ADDR24:
e7aa05bf
KK
2492 case IMAGE_REL_PPC_ADDR32:
2493 case IMAGE_REL_PPC_IFGLUE:
2494 case IMAGE_REL_PPC_SECTION:
2495 case IMAGE_REL_PPC_SECREL:
2496 DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel);
59066248 2497 howto = ppc_coff_howto_table + r_type;
e7aa05bf
KK
2498 break;
2499 case IMAGE_REL_PPC_IMGLUE:
2500 DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel);
59066248 2501 howto = ppc_coff_howto_table + r_type;
e7aa05bf
KK
2502 break;
2503 default:
2504 fprintf(stderr,
2505 "Warning: Unsupported reloc %s [%d] used -- it may not work.\n",
2506 ppc_coff_howto_table[r_type].name,
2507 r_type);
59066248 2508 howto = ppc_coff_howto_table + r_type;
e7aa05bf
KK
2509 break;
2510 }
d6f41a7d 2511
e7aa05bf
KK
2512 return howto;
2513}
2514
2515
2516/* a cheesy little macro to make the code a little more readable */
2517#define HOW2MAP(bfd_rtype,ppc_rtype) \
d6f41a7d 2518 case bfd_rtype: return &ppc_coff_howto_table[ppc_rtype]
e7aa05bf
KK
2519
2520static reloc_howto_type *ppc_coff_reloc_type_lookup
d6f41a7d 2521PARAMS ((bfd *, bfd_reloc_code_real_type));
e7aa05bf
KK
2522
2523static reloc_howto_type *
2524ppc_coff_reloc_type_lookup (abfd, code)
2525 bfd *abfd;
2526 bfd_reloc_code_real_type code;
2527{
d6f41a7d 2528
e7aa05bf
KK
2529#ifdef DEBUG_RELOC
2530 fprintf(stderr, "ppc_coff_reloc_type_lookup for %s\n",
d6f41a7d 2531 bfd_get_reloc_code_name(code));
e7aa05bf 2532#endif
59066248 2533
e7aa05bf
KK
2534 switch (code)
2535 {
59066248 2536 HOW2MAP(BFD_RELOC_32_GOTOFF, IMAGE_REL_PPC_IMGLUE);
e7aa05bf
KK
2537 HOW2MAP(BFD_RELOC_16_GOT_PCREL, IMAGE_REL_PPC_IFGLUE);
2538 HOW2MAP(BFD_RELOC_16, IMAGE_REL_PPC_ADDR16);
2539 HOW2MAP(BFD_RELOC_PPC_B26, IMAGE_REL_PPC_REL24);
2540 HOW2MAP(BFD_RELOC_PPC_BA26, IMAGE_REL_PPC_ADDR24);
2541 HOW2MAP(BFD_RELOC_PPC_TOC16, IMAGE_REL_PPC_TOCREL16);
59066248 2542 HOW2MAP(BFD_RELOC_16_GOTOFF, IMAGE_REL_PPC_TOCREL16_DEFN);
e7aa05bf 2543 HOW2MAP(BFD_RELOC_32, IMAGE_REL_PPC_ADDR32);
d6f41a7d
KK
2544 HOW2MAP(BFD_RELOC_RVA, IMAGE_REL_PPC_ADDR32NB);
2545 default:
d6f41a7d 2546 return NULL;
e7aa05bf 2547 }
d6f41a7d 2548
e7aa05bf
KK
2549 return NULL;
2550}
2551
2552#undef HOW2MAP
2553
2554\f
2555/* Tailor coffcode.h -- macro heaven. */
2556
2557#define RTYPE2HOWTO(cache_ptr, dst) ppc_coff_rtype2howto (cache_ptr, dst)
2558
d6f41a7d
KK
2559#ifndef COFF_IMAGE_WITH_PE
2560static void
2561ppc_coff_swap_sym_in_hook ();
2562#endif
2563
2564/* We use the special COFF backend linker, with our own special touch. */
2565
e7aa05bf
KK
2566#define coff_bfd_reloc_type_lookup ppc_coff_reloc_type_lookup
2567#define coff_rtype_to_howto coff_ppc_rtype_to_howto
2568#define coff_relocate_section coff_ppc_relocate_section
13d1a4dd 2569#define coff_bfd_final_link ppc_bfd_coff_final_link
e7aa05bf 2570
d6f41a7d
KK
2571#ifndef COFF_IMAGE_WITH_PE
2572#define coff_swap_sym_in_hook ppc_coff_swap_sym_in_hook
2573#endif
2574
e7aa05bf
KK
2575#define SELECT_RELOC(internal, howto) {internal.r_type=howto->type;}
2576
2577#define COFF_PAGE_SIZE 0x1000
2578
d6f41a7d
KK
2579#define POWERPC_LE_PE
2580
e7aa05bf
KK
2581#include "coffcode.h"
2582
d6f41a7d
KK
2583\f
2584
2585#ifndef COFF_IMAGE_WITH_PE
a9713b91
ILT
2586/* FIXME:
2587 What we're trying to do here is allocate a toc section (early), and attach
2588 it to the last bfd to be processed. This avoids the problem of having a toc
2589 written out before all files have been processed. This code allocates
2590 a toc section for every file, and records the last one seen. There are
2591 at least two problems with this approach:
2592 1. We allocate whole bunches of toc sections that are ignored, but at
2593 at least we will not allocate a toc if no .toc is present.
2594 2. It's not clear to me that being the last bfd read necessarily means
2595 that you are the last bfd closed.
2596 3. Doing it on a "swap in" hook depends on when the "swap in" is called,
2597 and how often, etc. It's not clear to me that there isn't a hole here.
2598*/
2599
d6f41a7d
KK
2600static void
2601ppc_coff_swap_sym_in_hook (abfd, ext1, in1)
2602 bfd *abfd;
2603 PTR ext1;
2604 PTR in1;
2605{
d6f41a7d
KK
2606 struct internal_syment *in = (struct internal_syment *)in1;
2607
d6f41a7d
KK
2608 if (bfd_of_toc_owner != 0) /* we already have a toc, so go home */
2609 return;
d6f41a7d
KK
2610
2611 if (strcmp(in->_n._n_name, ".toc") == 0)
2612 {
2613 flagword flags;
2614 register asection *s;
d6f41a7d
KK
2615
2616 s = bfd_get_section_by_name ( abfd , TOC_SECTION_NAME);
2617 if (s != NULL)
2618 {
2619 return;
2620 }
2621
2622 flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY ;
2623
2624#ifdef TOC_DEBUG
2625 fprintf(stderr,
2626 "ppc_coff_swap_sym_in_hook: about to create the %s section\n",
2627 TOC_SECTION_NAME);
2628#endif
2629
2630 s = bfd_make_section (abfd, TOC_SECTION_NAME);
2631
2632 if (s == NULL
2633 || !bfd_set_section_flags (abfd, s, flags)
2634 || !bfd_set_section_alignment (abfd, s, 2))
2635 {
2636 fprintf(stderr,
2637 "toc section allocation failed!\n");
2638 abort();
2639 }
2640
2641 /* save the bfd for later allocation */
2642 bfd_of_toc_owner = abfd;
2643 }
2644
2645 return;
2646}
2647#endif
2648
13d1a4dd
KK
2649boolean
2650ppc_bfd_coff_final_link ();
2651
2652#ifndef COFF_IMAGE_WITH_PE
2653
2654static boolean
2655ppc_do_last(abfd)
2656 bfd *abfd;
2657{
2658 if (abfd == bfd_of_toc_owner)
2659 return true;
2660 else
2661 return false;
2662}
2663
2664static bfd *
2665ppc_get_last()
2666{
2667 return bfd_of_toc_owner;
2668}
2669
2670/* this piece of machinery exists only to guarantee that the bfd that holds
2671 the toc section is written last.
2672
2673 This does depend on bfd_make_section attaching a new section to the
2674 end of the section list for the bfd.
2675
2676 This is otherwise intended to be functionally the same as
2677 cofflink.c:_bfd_coff_final_link(). It is specifically different only
2678 where the POWERPC_LE_PE macro modifies the code. It is left in as a
2679 precise form of comment. krk@cygnus.com
2680*/
2681#define POWERPC_LE_PE
2682
2683
2684/* Do the final link step. */
2685
2686boolean
2687ppc_bfd_coff_final_link (abfd, info)
2688 bfd *abfd;
2689 struct bfd_link_info *info;
2690{
2691 bfd_size_type symesz;
2692 struct coff_final_link_info finfo;
2693 boolean debug_merge_allocated;
2694 asection *o;
2695 struct bfd_link_order *p;
2696 size_t max_sym_count;
2697 size_t max_lineno_count;
2698 size_t max_reloc_count;
2699 size_t max_output_reloc_count;
2700 size_t max_contents_size;
2701 file_ptr rel_filepos;
2702 unsigned int relsz;
2703 file_ptr line_filepos;
2704 unsigned int linesz;
2705 bfd *sub;
2706 bfd_byte *external_relocs = NULL;
2707 char strbuf[STRING_SIZE_SIZE];
2708
2709 symesz = bfd_coff_symesz (abfd);
2710
2711 finfo.info = info;
2712 finfo.output_bfd = abfd;
2713 finfo.strtab = NULL;
2714 finfo.section_info = NULL;
2715 finfo.last_file_index = -1;
d6e0e2f7 2716 finfo.last_bf_index = -1;
13d1a4dd
KK
2717 finfo.internal_syms = NULL;
2718 finfo.sec_ptrs = NULL;
2719 finfo.sym_indices = NULL;
2720 finfo.outsyms = NULL;
2721 finfo.linenos = NULL;
2722 finfo.contents = NULL;
2723 finfo.external_relocs = NULL;
2724 finfo.internal_relocs = NULL;
2725 debug_merge_allocated = false;
2726
2727 coff_data (abfd)->link_info = info;
2728
2729 finfo.strtab = _bfd_stringtab_init ();
2730 if (finfo.strtab == NULL)
2731 goto error_return;
2732
2733 if (! coff_debug_merge_hash_table_init (&finfo.debug_merge))
2734 goto error_return;
2735 debug_merge_allocated = true;
2736
2737 /* Compute the file positions for all the sections. */
2738 if (! abfd->output_has_begun)
2739 bfd_coff_compute_section_file_positions (abfd);
2740
2741 /* Count the line numbers and relocation entries required for the
2742 output file. Set the file positions for the relocs. */
2743 rel_filepos = obj_relocbase (abfd);
2744 relsz = bfd_coff_relsz (abfd);
2745 max_contents_size = 0;
2746 max_lineno_count = 0;
2747 max_reloc_count = 0;
2748
2749 for (o = abfd->sections; o != NULL; o = o->next)
2750 {
2751 o->reloc_count = 0;
2752 o->lineno_count = 0;
2753 for (p = o->link_order_head; p != NULL; p = p->next)
2754 {
2755
2756 if (p->type == bfd_indirect_link_order)
2757 {
2758 asection *sec;
2759
2760 sec = p->u.indirect.section;
2761
7ec49f91
ILT
2762 /* Mark all sections which are to be included in the
2763 link. This will normally be every section. We need
2764 to do this so that we can identify any sections which
2765 the linker has decided to not include. */
ff0e4a93 2766 sec->linker_mark = true;
7ec49f91 2767
13d1a4dd
KK
2768 if (info->strip == strip_none
2769 || info->strip == strip_some)
2770 o->lineno_count += sec->lineno_count;
2771
2772 if (info->relocateable)
2773 o->reloc_count += sec->reloc_count;
2774
2775 if (sec->_raw_size > max_contents_size)
2776 max_contents_size = sec->_raw_size;
2777 if (sec->lineno_count > max_lineno_count)
2778 max_lineno_count = sec->lineno_count;
2779 if (sec->reloc_count > max_reloc_count)
2780 max_reloc_count = sec->reloc_count;
2781 }
2782 else if (info->relocateable
2783 && (p->type == bfd_section_reloc_link_order
2784 || p->type == bfd_symbol_reloc_link_order))
2785 ++o->reloc_count;
2786 }
2787 if (o->reloc_count == 0)
2788 o->rel_filepos = 0;
2789 else
2790 {
2791 o->flags |= SEC_RELOC;
2792 o->rel_filepos = rel_filepos;
2793 rel_filepos += o->reloc_count * relsz;
2794 }
2795 }
2796
2797 /* If doing a relocateable link, allocate space for the pointers we
2798 need to keep. */
2799 if (info->relocateable)
2800 {
2801 unsigned int i;
2802
2803 /* We use section_count + 1, rather than section_count, because
2804 the target_index fields are 1 based. */
2805 finfo.section_info =
2806 ((struct coff_link_section_info *)
2807 bfd_malloc ((abfd->section_count + 1)
2808 * sizeof (struct coff_link_section_info)));
2809 if (finfo.section_info == NULL)
2810 goto error_return;
2811 for (i = 0; i <= abfd->section_count; i++)
2812 {
2813 finfo.section_info[i].relocs = NULL;
2814 finfo.section_info[i].rel_hashes = NULL;
2815 }
2816 }
2817
2818 /* We now know the size of the relocs, so we can determine the file
2819 positions of the line numbers. */
2820 line_filepos = rel_filepos;
2821 linesz = bfd_coff_linesz (abfd);
2822 max_output_reloc_count = 0;
2823 for (o = abfd->sections; o != NULL; o = o->next)
2824 {
2825 if (o->lineno_count == 0)
2826 o->line_filepos = 0;
2827 else
2828 {
2829 o->line_filepos = line_filepos;
2830 line_filepos += o->lineno_count * linesz;
2831 }
2832
2833 if (o->reloc_count != 0)
2834 {
2835 /* We don't know the indices of global symbols until we have
2836 written out all the local symbols. For each section in
2837 the output file, we keep an array of pointers to hash
2838 table entries. Each entry in the array corresponds to a
2839 reloc. When we find a reloc against a global symbol, we
2840 set the corresponding entry in this array so that we can
2841 fix up the symbol index after we have written out all the
2842 local symbols.
2843
2844 Because of this problem, we also keep the relocs in
2845 memory until the end of the link. This wastes memory,
2846 but only when doing a relocateable link, which is not the
2847 common case. */
2848 BFD_ASSERT (info->relocateable);
2849 finfo.section_info[o->target_index].relocs =
2850 ((struct internal_reloc *)
2851 bfd_malloc (o->reloc_count * sizeof (struct internal_reloc)));
2852 finfo.section_info[o->target_index].rel_hashes =
2853 ((struct coff_link_hash_entry **)
2854 bfd_malloc (o->reloc_count
2855 * sizeof (struct coff_link_hash_entry *)));
2856 if (finfo.section_info[o->target_index].relocs == NULL
2857 || finfo.section_info[o->target_index].rel_hashes == NULL)
2858 goto error_return;
2859
2860 if (o->reloc_count > max_output_reloc_count)
2861 max_output_reloc_count = o->reloc_count;
2862 }
2863
2864 /* Reset the reloc and lineno counts, so that we can use them to
2865 count the number of entries we have output so far. */
2866 o->reloc_count = 0;
2867 o->lineno_count = 0;
2868 }
2869
2870 obj_sym_filepos (abfd) = line_filepos;
2871
2872 /* Figure out the largest number of symbols in an input BFD. Take
2873 the opportunity to clear the output_has_begun fields of all the
2874 input BFD's. */
2875 max_sym_count = 0;
2876 for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
2877 {
2878 size_t sz;
2879
2880 sub->output_has_begun = false;
2881 sz = obj_raw_syment_count (sub);
2882 if (sz > max_sym_count)
2883 max_sym_count = sz;
2884 }
2885
2886 /* Allocate some buffers used while linking. */
2887 finfo.internal_syms = ((struct internal_syment *)
2888 bfd_malloc (max_sym_count
2889 * sizeof (struct internal_syment)));
2890 finfo.sec_ptrs = (asection **) bfd_malloc (max_sym_count
2891 * sizeof (asection *));
2892 finfo.sym_indices = (long *) bfd_malloc (max_sym_count * sizeof (long));
2893 finfo.outsyms = ((bfd_byte *)
2894 bfd_malloc ((size_t) ((max_sym_count + 1) * symesz)));
2895 finfo.linenos = (bfd_byte *) bfd_malloc (max_lineno_count
2896 * bfd_coff_linesz (abfd));
2897 finfo.contents = (bfd_byte *) bfd_malloc (max_contents_size);
2898 finfo.external_relocs = (bfd_byte *) bfd_malloc (max_reloc_count * relsz);
2899 if (! info->relocateable)
2900 finfo.internal_relocs = ((struct internal_reloc *)
2901 bfd_malloc (max_reloc_count
2902 * sizeof (struct internal_reloc)));
2903 if ((finfo.internal_syms == NULL && max_sym_count > 0)
2904 || (finfo.sec_ptrs == NULL && max_sym_count > 0)
2905 || (finfo.sym_indices == NULL && max_sym_count > 0)
2906 || finfo.outsyms == NULL
2907 || (finfo.linenos == NULL && max_lineno_count > 0)
2908 || (finfo.contents == NULL && max_contents_size > 0)
2909 || (finfo.external_relocs == NULL && max_reloc_count > 0)
2910 || (! info->relocateable
2911 && finfo.internal_relocs == NULL
2912 && max_reloc_count > 0))
2913 goto error_return;
2914
2915 /* We now know the position of everything in the file, except that
2916 we don't know the size of the symbol table and therefore we don't
2917 know where the string table starts. We just build the string
2918 table in memory as we go along. We process all the relocations
2919 for a single input file at once. */
2920 obj_raw_syment_count (abfd) = 0;
2921
2922 if (coff_backend_info (abfd)->_bfd_coff_start_final_link)
2923 {
2924 if (! bfd_coff_start_final_link (abfd, info))
2925 goto error_return;
2926 }
2927
2928 for (o = abfd->sections; o != NULL; o = o->next)
2929 {
2930 for (p = o->link_order_head; p != NULL; p = p->next)
2931 {
2932 if (p->type == bfd_indirect_link_order
2933 && (bfd_get_flavour (p->u.indirect.section->owner)
2934 == bfd_target_coff_flavour))
2935 {
2936 sub = p->u.indirect.section->owner;
2937#ifdef POWERPC_LE_PE
2938 if (! sub->output_has_begun && !ppc_do_last(sub))
2939#else
2940 if (! sub->output_has_begun)
2941#endif
2942 {
7ec49f91 2943 if (! _bfd_coff_link_input_bfd (&finfo, sub))
13d1a4dd
KK
2944 goto error_return;
2945 sub->output_has_begun = true;
2946 }
2947 }
2948 else if (p->type == bfd_section_reloc_link_order
2949 || p->type == bfd_symbol_reloc_link_order)
2950 {
7ec49f91 2951 if (! _bfd_coff_reloc_link_order (abfd, &finfo, o, p))
13d1a4dd
KK
2952 goto error_return;
2953 }
2954 else
2955 {
2956 if (! _bfd_default_link_order (abfd, info, o, p))
2957 goto error_return;
2958 }
2959 }
2960 }
2961
2962#ifdef POWERPC_LE_PE
2963 {
2964 extern bfd* ppc_get_last();
2965 bfd* last_one = ppc_get_last();
2966 if (last_one)
2967 {
7ec49f91 2968 if (! _bfd_coff_link_input_bfd (&finfo, last_one))
13d1a4dd
KK
2969 goto error_return;
2970 }
2971 last_one->output_has_begun = true;
2972 }
2973#endif
2974
7ec49f91 2975 /* Free up the buffers used by _bfd_coff_link_input_bfd. */
13d1a4dd
KK
2976
2977 coff_debug_merge_hash_table_free (&finfo.debug_merge);
2978 debug_merge_allocated = false;
2979
2980 if (finfo.internal_syms != NULL)
2981 {
2982 free (finfo.internal_syms);
2983 finfo.internal_syms = NULL;
2984 }
2985 if (finfo.sec_ptrs != NULL)
2986 {
2987 free (finfo.sec_ptrs);
2988 finfo.sec_ptrs = NULL;
2989 }
2990 if (finfo.sym_indices != NULL)
2991 {
2992 free (finfo.sym_indices);
2993 finfo.sym_indices = NULL;
2994 }
2995 if (finfo.linenos != NULL)
2996 {
2997 free (finfo.linenos);
2998 finfo.linenos = NULL;
2999 }
3000 if (finfo.contents != NULL)
3001 {
3002 free (finfo.contents);
3003 finfo.contents = NULL;
3004 }
3005 if (finfo.external_relocs != NULL)
3006 {
3007 free (finfo.external_relocs);
3008 finfo.external_relocs = NULL;
3009 }
3010 if (finfo.internal_relocs != NULL)
3011 {
3012 free (finfo.internal_relocs);
3013 finfo.internal_relocs = NULL;
3014 }
3015
3016 /* The value of the last C_FILE symbol is supposed to be the symbol
3017 index of the first external symbol. Write it out again if
3018 necessary. */
3019 if (finfo.last_file_index != -1
3020 && (unsigned int) finfo.last_file.n_value != obj_raw_syment_count (abfd))
3021 {
3022 finfo.last_file.n_value = obj_raw_syment_count (abfd);
3023 bfd_coff_swap_sym_out (abfd, (PTR) &finfo.last_file,
3024 (PTR) finfo.outsyms);
3025 if (bfd_seek (abfd,
3026 (obj_sym_filepos (abfd)
3027 + finfo.last_file_index * symesz),
3028 SEEK_SET) != 0
3029 || bfd_write (finfo.outsyms, symesz, 1, abfd) != symesz)
3030 return false;
3031 }
3032
3033 /* Write out the global symbols. */
3034 finfo.failed = false;
7ec49f91 3035 coff_link_hash_traverse (coff_hash_table (info), _bfd_coff_write_global_sym,
13d1a4dd
KK
3036 (PTR) &finfo);
3037 if (finfo.failed)
3038 goto error_return;
3039
7ec49f91 3040 /* The outsyms buffer is used by _bfd_coff_write_global_sym. */
13d1a4dd
KK
3041 if (finfo.outsyms != NULL)
3042 {
3043 free (finfo.outsyms);
3044 finfo.outsyms = NULL;
3045 }
3046
3047 if (info->relocateable)
3048 {
3049 /* Now that we have written out all the global symbols, we know
3050 the symbol indices to use for relocs against them, and we can
3051 finally write out the relocs. */
3052 external_relocs = ((bfd_byte *)
3053 bfd_malloc (max_output_reloc_count * relsz));
3054 if (external_relocs == NULL)
3055 goto error_return;
3056
3057 for (o = abfd->sections; o != NULL; o = o->next)
3058 {
3059 struct internal_reloc *irel;
3060 struct internal_reloc *irelend;
3061 struct coff_link_hash_entry **rel_hash;
3062 bfd_byte *erel;
3063
3064 if (o->reloc_count == 0)
3065 continue;
3066
3067 irel = finfo.section_info[o->target_index].relocs;
3068 irelend = irel + o->reloc_count;
3069 rel_hash = finfo.section_info[o->target_index].rel_hashes;
3070 erel = external_relocs;
3071 for (; irel < irelend; irel++, rel_hash++, erel += relsz)
3072 {
3073 if (*rel_hash != NULL)
3074 {
3075 BFD_ASSERT ((*rel_hash)->indx >= 0);
3076 irel->r_symndx = (*rel_hash)->indx;
3077 }
3078 bfd_coff_swap_reloc_out (abfd, (PTR) irel, (PTR) erel);
3079 }
3080
3081 if (bfd_seek (abfd, o->rel_filepos, SEEK_SET) != 0
3082 || bfd_write ((PTR) external_relocs, relsz, o->reloc_count,
3083 abfd) != relsz * o->reloc_count)
3084 goto error_return;
3085 }
3086
3087 free (external_relocs);
3088 external_relocs = NULL;
3089 }
3090
3091 /* Free up the section information. */
3092 if (finfo.section_info != NULL)
3093 {
3094 unsigned int i;
3095
3096 for (i = 0; i < abfd->section_count; i++)
3097 {
3098 if (finfo.section_info[i].relocs != NULL)
3099 free (finfo.section_info[i].relocs);
3100 if (finfo.section_info[i].rel_hashes != NULL)
3101 free (finfo.section_info[i].rel_hashes);
3102 }
3103 free (finfo.section_info);
3104 finfo.section_info = NULL;
3105 }
3106
3107 /* Write out the string table. */
3108 if (obj_raw_syment_count (abfd) != 0)
3109 {
3110 if (bfd_seek (abfd,
3111 (obj_sym_filepos (abfd)
3112 + obj_raw_syment_count (abfd) * symesz),
3113 SEEK_SET) != 0)
3114 return false;
3115
3116#if STRING_SIZE_SIZE == 4
3117 bfd_h_put_32 (abfd,
3118 _bfd_stringtab_size (finfo.strtab) + STRING_SIZE_SIZE,
3119 (bfd_byte *) strbuf);
3120#else
3121 #error Change bfd_h_put_32
3122#endif
3123
3124 if (bfd_write (strbuf, 1, STRING_SIZE_SIZE, abfd) != STRING_SIZE_SIZE)
3125 return false;
3126
3127 if (! _bfd_stringtab_emit (abfd, finfo.strtab))
3128 return false;
3129 }
3130
3131 _bfd_stringtab_free (finfo.strtab);
3132
3133 /* Setting bfd_get_symcount to 0 will cause write_object_contents to
3134 not try to write out the symbols. */
3135 bfd_get_symcount (abfd) = 0;
3136
3137 return true;
3138
3139 error_return:
3140 if (debug_merge_allocated)
3141 coff_debug_merge_hash_table_free (&finfo.debug_merge);
3142 if (finfo.strtab != NULL)
3143 _bfd_stringtab_free (finfo.strtab);
3144 if (finfo.section_info != NULL)
3145 {
3146 unsigned int i;
3147
3148 for (i = 0; i < abfd->section_count; i++)
3149 {
3150 if (finfo.section_info[i].relocs != NULL)
3151 free (finfo.section_info[i].relocs);
3152 if (finfo.section_info[i].rel_hashes != NULL)
3153 free (finfo.section_info[i].rel_hashes);
3154 }
3155 free (finfo.section_info);
3156 }
3157 if (finfo.internal_syms != NULL)
3158 free (finfo.internal_syms);
3159 if (finfo.sec_ptrs != NULL)
3160 free (finfo.sec_ptrs);
3161 if (finfo.sym_indices != NULL)
3162 free (finfo.sym_indices);
3163 if (finfo.outsyms != NULL)
3164 free (finfo.outsyms);
3165 if (finfo.linenos != NULL)
3166 free (finfo.linenos);
3167 if (finfo.contents != NULL)
3168 free (finfo.contents);
3169 if (finfo.external_relocs != NULL)
3170 free (finfo.external_relocs);
3171 if (finfo.internal_relocs != NULL)
3172 free (finfo.internal_relocs);
3173 if (external_relocs != NULL)
3174 free (external_relocs);
3175 return false;
3176}
3177#endif
d6f41a7d
KK
3178\f
3179
e7aa05bf
KK
3180/* The transfer vectors that lead the outside world to all of the above. */
3181
3182#ifdef TARGET_LITTLE_SYM
3183const bfd_target
3184TARGET_LITTLE_SYM =
3185{
3186 TARGET_LITTLE_NAME, /* name or coff-arm-little */
3187 bfd_target_coff_flavour,
13d1a4dd
KK
3188 BFD_ENDIAN_LITTLE, /* data byte order is little */
3189 BFD_ENDIAN_LITTLE, /* header byte order is little */
e7aa05bf
KK
3190
3191 (HAS_RELOC | EXEC_P | /* FIXME: object flags */
3192 HAS_LINENO | HAS_DEBUG |
3193 HAS_SYMS | HAS_LOCALS | WP_TEXT),
d6f41a7d 3194
5a28331f 3195#ifndef COFF_WITH_PE
e7aa05bf 3196 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
5a28331f
ILT
3197#else
3198 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */
3199 | SEC_LINK_ONCE | SEC_LINK_DUPLICATES),
3200#endif
3201
e7aa05bf
KK
3202 0, /* leading char */
3203 '/', /* ar_pad_char */
3204 15, /* ar_max_namelen??? FIXMEmgo */
3205
3206 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
d6f41a7d
KK
3207 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
3208 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
e7aa05bf 3209
d6f41a7d
KK
3210 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
3211 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
3212 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
3213
e7aa05bf
KK
3214 {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
3215 bfd_generic_archive_p, /* _bfd_dummy_target */ coff_object_p },
3216 {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
3217 bfd_false},
3218 {bfd_false, coff_write_object_contents, /* bfd_write_contents */
3219 _bfd_write_archive_contents, bfd_false},
d6f41a7d 3220
e7aa05bf
KK
3221 BFD_JUMP_TABLE_GENERIC (coff),
3222 BFD_JUMP_TABLE_COPY (coff),
3223 BFD_JUMP_TABLE_CORE (_bfd_nocore),
3224 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
3225 BFD_JUMP_TABLE_SYMBOLS (coff),
3226 BFD_JUMP_TABLE_RELOCS (coff),
3227 BFD_JUMP_TABLE_WRITE (coff),
3228 BFD_JUMP_TABLE_LINK (coff),
3229 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
d6f41a7d 3230
e7aa05bf
KK
3231 COFF_SWAP_TABLE,
3232};
3233#endif
3234
3235#ifdef TARGET_BIG_SYM
3236const bfd_target
3237TARGET_BIG_SYM =
3238{
3239 TARGET_BIG_NAME,
3240 bfd_target_coff_flavour,
13d1a4dd
KK
3241 BFD_ENDIAN_BIG, /* data byte order is big */
3242 BFD_ENDIAN_BIG, /* header byte order is big */
e7aa05bf
KK
3243
3244 (HAS_RELOC | EXEC_P | /* FIXME: object flags */
3245 HAS_LINENO | HAS_DEBUG |
3246 HAS_SYMS | HAS_LOCALS | WP_TEXT),
3247
5a28331f 3248#ifndef COFF_WITH_PE
e7aa05bf 3249 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
5a28331f
ILT
3250#else
3251 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */
3252 | SEC_LINK_ONCE | SEC_LINK_DUPLICATES),
3253#endif
3254
e7aa05bf
KK
3255 0, /* leading char */
3256 '/', /* ar_pad_char */
3257 15, /* ar_max_namelen??? FIXMEmgo */
3258
3259 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
d6f41a7d
KK
3260 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
3261 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
3262
e7aa05bf 3263 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
d6f41a7d
KK
3264 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
3265 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
e7aa05bf
KK
3266
3267 {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
3268 bfd_generic_archive_p, /* _bfd_dummy_target */ coff_object_p },
3269 {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
3270 bfd_false},
3271 {bfd_false, coff_write_object_contents, /* bfd_write_contents */
3272 _bfd_write_archive_contents, bfd_false},
3273
3274 BFD_JUMP_TABLE_GENERIC (coff),
3275 BFD_JUMP_TABLE_COPY (coff),
3276 BFD_JUMP_TABLE_CORE (_bfd_nocore),
3277 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
3278 BFD_JUMP_TABLE_SYMBOLS (coff),
3279 BFD_JUMP_TABLE_RELOCS (coff),
3280 BFD_JUMP_TABLE_WRITE (coff),
3281 BFD_JUMP_TABLE_LINK (coff),
3282 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
3283
3284 COFF_SWAP_TABLE,
3285};
3286
3287#endif
This page took 0.174766 seconds and 4 git commands to generate.