]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - bfd/coff-ppc.c
Implemented IMGLUE reloc + dumping
[thirdparty/binutils-gdb.git] / bfd / coff-ppc.c
1 /* BFD back-end for PowerPC Microsoft Portable Executable files.
2 Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
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
10 This file is part of BFD, the Binary File Descriptor library.
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
25
26 /* Current State:
27 - objdump works
28 - relocs generated by gas
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.
32 */
33
34
35 #include "bfd.h"
36 #include "sysdep.h"
37 #include "libbfd.h"
38 #include "obstack.h"
39
40 #include "coff/powerpc.h"
41 #include "coff/internal.h"
42
43 #include "coff/pe.h"
44
45 #ifdef BADMAG
46 #undef BADMAG
47 #endif
48
49 #define BADMAG(x) PPCBADMAG(x)
50
51 #include "libcoff.h"
52
53 /* In order not to add an int to every hash table item for every coff
54 linker, we define our own hash table, derived from the coff one */
55
56 /* PE linker hash table entries. */
57
58 struct ppc_coff_link_hash_entry
59 {
60 struct coff_link_hash_entry root; /* First entry, as required */
61
62 /* As we wonder around the relocs, we'll keep the assigned toc_offset
63 here */
64 bfd_vma toc_offset; /* Our addition, as required */
65 int symbol_is_glue;
66 unsigned long int glue_insn;
67 char eye_catcher[8];
68 };
69
70 /* Need a 7 char string for an eye catcher */
71 #define EYE "krkjunk"
72
73 #define CHECK_EYE(addr) \
74 if (strcmp(addr, EYE) != 0) \
75 { \
76 fprintf(stderr,\
77 "File %s, line %d, Hash check failure, bad eye %8s\n", \
78 __FILE__, __LINE__, addr); \
79 abort(); \
80 }
81
82 /* PE linker hash table. */
83
84 struct ppc_coff_link_hash_table
85 {
86 struct coff_link_hash_table root; /* First entry, as required */
87 };
88
89 static struct bfd_hash_entry *ppc_coff_link_hash_newfunc
90 PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *,
91 const char *));
92
93 /* Routine to create an entry in the link hash table. */
94
95 static struct bfd_hash_entry *
96 ppc_coff_link_hash_newfunc (entry, table, string)
97 struct bfd_hash_entry *entry;
98 struct bfd_hash_table *table;
99 const char *string;
100 {
101 struct ppc_coff_link_hash_entry *ret =
102 (struct ppc_coff_link_hash_entry *) entry;
103
104 /* Allocate the structure if it has not already been allocated by a
105 subclass. */
106 if (ret == (struct ppc_coff_link_hash_entry *) NULL)
107 ret = (struct ppc_coff_link_hash_entry *)
108 bfd_hash_allocate (table,
109 sizeof (struct ppc_coff_link_hash_entry));
110
111 if (ret == (struct ppc_coff_link_hash_entry *) NULL)
112 return NULL;
113
114 /* Call the allocation method of the superclass. */
115 ret = ((struct ppc_coff_link_hash_entry *)
116 _bfd_coff_link_hash_newfunc ((struct bfd_hash_entry *) ret,
117 table, string));
118
119 if (ret)
120 {
121 /* Initialize the local fields. */
122 ret->toc_offset = 1;
123 ret->symbol_is_glue = 0;
124 ret->glue_insn = 0;
125 strcpy(ret->eye_catcher, EYE);
126 }
127
128 return (struct bfd_hash_entry *) ret;
129 }
130
131 /* Initialize a PE linker hash table. */
132
133 static boolean
134 ppc_coff_link_hash_table_init (table, abfd, newfunc)
135 struct ppc_coff_link_hash_table *table;
136 bfd *abfd;
137 struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *,
138 struct bfd_hash_table *,
139 const char *));
140 {
141 return _bfd_coff_link_hash_table_init (&table->root, abfd, newfunc);
142 }
143
144 /* Create a PE linker hash table. */
145
146 static struct bfd_link_hash_table *
147 ppc_coff_link_hash_table_create (abfd)
148 bfd *abfd;
149 {
150 struct ppc_coff_link_hash_table *ret;
151
152 ret = ((struct ppc_coff_link_hash_table *)
153 bfd_alloc (abfd, sizeof (struct ppc_coff_link_hash_table)));
154 if (ret == NULL)
155 {
156 bfd_set_error (bfd_error_no_memory);
157 return NULL;
158 }
159 if (! ppc_coff_link_hash_table_init (ret, abfd,
160 ppc_coff_link_hash_newfunc))
161 {
162 bfd_release (abfd, ret);
163 return (struct bfd_link_hash_table *) NULL;
164 }
165 return &ret->root.root;
166 }
167
168 /* Now, tailor coffcode.h to use our hash stuff */
169
170 #define coff_bfd_link_hash_table_create ppc_coff_link_hash_table_create
171
172 \f
173 /* The nt loader points the toc register to &toc + 32768, in order to */
174 /* use the complete range of a 16-bit displacement (I guess). We have */
175 /* to adjust for this when we fix up loads displaced off the toc reg. */
176 #define TOC_LOAD_ADJUSTMENT (-32768)
177 #define TOC_SECTION_NAME ".private.toc"
178
179 /* The main body of code is in coffcode.h. */
180
181 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
182
183 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
184 from smaller values. Start with zero, widen, *then* decrement. */
185 #define MINUS_ONE (((bfd_vma)0) - 1)
186
187 /* these should definitely go in a header file somewhere... */
188
189 /* NOP */
190 #define IMAGE_REL_PPC_ABSOLUTE 0x0000
191
192 /* 64-bit address */
193 #define IMAGE_REL_PPC_ADDR64 0x0001
194
195 /* 32-bit address */
196 #define IMAGE_REL_PPC_ADDR32 0x0002
197
198 /* 26-bit address, shifted left 2 (branch absolute) */
199 #define IMAGE_REL_PPC_ADDR24 0x0003
200
201 /* 16-bit address */
202 #define IMAGE_REL_PPC_ADDR16 0x0004
203
204 /* 16-bit address, shifted left 2 (load doubleword) */
205 #define IMAGE_REL_PPC_ADDR14 0x0005
206
207 /* 26-bit PC-relative offset, shifted left 2 (branch relative) */
208 #define IMAGE_REL_PPC_REL24 0x0006
209
210 /* 16-bit PC-relative offset, shifted left 2 (br cond relative) */
211 #define IMAGE_REL_PPC_REL14 0x0007
212
213 /* 16-bit offset from TOC base */
214 #define IMAGE_REL_PPC_TOCREL16 0x0008
215
216 /* 16-bit offset from TOC base, shifted left 2 (load doubleword) */
217 #define IMAGE_REL_PPC_TOCREL14 0x0009
218
219 /* 32-bit addr w/o image base */
220 #define IMAGE_REL_PPC_ADDR32NB 0x000A
221
222 /* va of containing section (as in an image sectionhdr) */
223 #define IMAGE_REL_PPC_SECREL 0x000B
224
225 /* sectionheader number */
226 #define IMAGE_REL_PPC_SECTION 0x000C
227
228 /* substitute TOC restore instruction iff symbol is glue code */
229 #define IMAGE_REL_PPC_IFGLUE 0x000D
230
231 /* symbol is glue code; virtual address is TOC restore instruction */
232 #define IMAGE_REL_PPC_IMGLUE 0x000E
233
234 /* va of containing section (limited to 16 bits) */
235 #define IMAGE_REL_PPC_SECREL16 0x000F
236
237 /* stuff to handle immediate data when the number of bits in the */
238 /* data is greater than the number of bits in the immediate field */
239 /* We need to do (usually) 32 bit arithmetic on 16 bit chunks */
240 #define IMAGE_REL_PPC_REFHI 0x0010
241 #define IMAGE_REL_PPC_REFLO 0x0011
242 #define IMAGE_REL_PPC_PAIR 0x0012
243
244
245 /* Flag bits in IMAGE_RELOCATION.TYPE */
246
247 /* subtract reloc value rather than adding it */
248 #define IMAGE_REL_PPC_NEG 0x0100
249
250 /* fix branch prediction bit to predict branch taken */
251 #define IMAGE_REL_PPC_BRTAKEN 0x0200
252
253 /* fix branch prediction bit to predict branch not taken */
254 #define IMAGE_REL_PPC_BRNTAKEN 0x0400
255
256 /* toc slot defined in file (or, data in toc) */
257 #define IMAGE_REL_PPC_TOCDEFN 0x0800
258
259 /* masks to isolate above values in IMAGE_RELOCATION.Type */
260 #define IMAGE_REL_PPC_TYPEMASK 0x00FF
261 #define IMAGE_REL_PPC_FLAGMASK 0x0F00
262
263 #define EXTRACT_TYPE(x) ((x) & IMAGE_REL_PPC_TYPEMASK)
264 #define EXTRACT_FLAGS(x) ((x) & IMAGE_REL_PPC_FLAGMASK)
265 #define EXTRACT_JUNK(x) \
266 ((x) & ~(IMAGE_REL_PPC_TYPEMASK | IMAGE_REL_PPC_FLAGMASK))
267
268 \f
269 /* static helper functions to make relocation work */
270 /* (Work In Progress) */
271
272 static bfd_reloc_status_type ppc_refhi_reloc PARAMS ((bfd *abfd,
273 arelent *reloc,
274 asymbol *symbol,
275 PTR data,
276 asection *section,
277 bfd *output_bfd,
278 char **error));
279 static bfd_reloc_status_type ppc_reflo_reloc PARAMS ((bfd *abfd,
280 arelent *reloc,
281 asymbol *symbol,
282 PTR data,
283 asection *section,
284 bfd *output_bfd,
285 char **error));
286 static bfd_reloc_status_type ppc_pair_reloc PARAMS ((bfd *abfd,
287 arelent *reloc,
288 asymbol *symbol,
289 PTR data,
290 asection *section,
291 bfd *output_bfd,
292 char **error));
293
294 \f
295 static bfd_reloc_status_type ppc_toc16_reloc PARAMS ((bfd *abfd,
296 arelent *reloc,
297 asymbol *symbol,
298 PTR data,
299 asection *section,
300 bfd *output_bfd,
301 char **error));
302
303 static bfd_reloc_status_type ppc_addr32nb_reloc PARAMS ((bfd *abfd,
304 arelent *reloc,
305 asymbol *symbol,
306 PTR data,
307 asection *section,
308 bfd *output_bfd,
309 char **error));
310
311 static bfd_reloc_status_type ppc_section_reloc PARAMS ((bfd *abfd,
312 arelent *reloc,
313 asymbol *symbol,
314 PTR data,
315 asection *section,
316 bfd *output_bfd,
317 char **error));
318
319 static bfd_reloc_status_type ppc_secrel_reloc PARAMS ((bfd *abfd,
320 arelent *reloc,
321 asymbol *symbol,
322 PTR data,
323 asection *section,
324 bfd *output_bfd,
325 char **error));
326
327 static bfd_reloc_status_type ppc_imglue_reloc PARAMS ((bfd *abfd,
328 arelent *reloc,
329 asymbol *symbol,
330 PTR data,
331 asection *section,
332 bfd *output_bfd,
333 char **error));
334
335
336
337 static boolean in_reloc_p PARAMS((bfd *abfd, reloc_howto_type *howto));
338
339 \f
340 /* FIXME: It'll take a while to get through all of these. I only need a few to
341 get us started, so those I'll make sure work. Those marked FIXME are either
342 completely unverified or have a specific unknown marked in the comment */
343
344 /*---------------------------------------------------------------------------*/
345 /* */
346 /* Relocation entries for Windows/NT on PowerPC. */
347 /* */
348 /* From the document "" we find the following listed as used relocs: */
349 /* */
350 /* ABSOLUTE : The noop */
351 /* ADDR[64|32|16] : fields that hold addresses in data fields or the */
352 /* 16 bit displacement field on a load/store. */
353 /* ADDR[24|14] : fields that hold addresses in branch and cond */
354 /* branches. These represent [26|16] bit addresses. */
355 /* The low order 2 bits are preserved. */
356 /* REL[24|14] : branches relative to the Instruction Address */
357 /* register. These represent [26|16] bit addresses, */
358 /* as before. The instruction field will be zero, and */
359 /* the address of the SYM will be inserted at link time. */
360 /* TOCREL16 : 16 bit displacement field referring to a slot in */
361 /* toc. */
362 /* TOCREL14 : 16 bit displacement field, similar to REL14 or ADDR14. */
363 /* ADDR32NB : 32 bit address relative to the virtual origin. */
364 /* (On the alpha, this is always a linker generated thunk)*/
365 /* (i.e. 32bit addr relative to the image base) */
366 /* SECREL : The value is relative to the start of the section */
367 /* containing the symbol. */
368 /* SECTION : access to the header containing the item. Supports the */
369 /* codeview debugger. */
370 /* */
371 /* In particular, note that the document does not indicate that the */
372 /* relocations listed in the header file are used. */
373 /* */
374 /* */
375 /* */
376 /*---------------------------------------------------------------------------*/
377
378 static reloc_howto_type ppc_coff_howto_table[] =
379 {
380 /* IMAGE_REL_PPC_ABSOLUTE 0x0000 NOP */
381 /* Unused: */
382 HOWTO (IMAGE_REL_PPC_ABSOLUTE, /* type */
383 0, /* rightshift */
384 0, /* size (0 = byte, 1 = short, 2 = long) */
385 0, /* bitsize */
386 false, /* pc_relative */
387 0, /* bitpos */
388 complain_overflow_dont, /* dont complain_on_overflow */
389 0, /* special_function */
390 "ABSOLUTE", /* name */
391 false, /* partial_inplace */
392 0x00, /* src_mask */
393 0x00, /* dst_mask */
394 false), /* pcrel_offset */
395
396 /* IMAGE_REL_PPC_ADDR64 0x0001 64-bit address */
397 /* Unused: */
398 HOWTO(IMAGE_REL_PPC_ADDR64, /* type */
399 0, /* rightshift */
400 3, /* size (0 = byte, 1 = short, 2 = long) */
401 64, /* bitsize */
402 false, /* pc_relative */
403 0, /* bitpos */
404 complain_overflow_bitfield, /* complain_on_overflow */
405 0, /* special_function */
406 "ADDR64", /* name */
407 true, /* partial_inplace */
408 MINUS_ONE, /* src_mask */
409 MINUS_ONE, /* dst_mask */
410 false), /* pcrel_offset */
411
412 /* IMAGE_REL_PPC_ADDR32 0x0002 32-bit address */
413 /* Used: */
414 HOWTO (IMAGE_REL_PPC_ADDR32, /* type */
415 0, /* rightshift */
416 2, /* size (0 = byte, 1 = short, 2 = long) */
417 32, /* bitsize */
418 false, /* pc_relative */
419 0, /* bitpos */
420 complain_overflow_bitfield, /* complain_on_overflow */
421 0, /* special_function */
422 "ADDR32", /* name */
423 true, /* partial_inplace */
424 0xffffffff, /* src_mask */
425 0xffffffff, /* dst_mask */
426 false), /* pcrel_offset */
427
428 /* IMAGE_REL_PPC_ADDR24 0x0003 26-bit address, shifted left 2 (branch absolute) */
429 /* the LI field is in bit 6 through bit 29 is 24 bits, + 2 for the shift */
430 /* Of course, That's the IBM approved bit numbering, which is not what */
431 /* anyone else uses.... The li field is in bit 2 thru 25 */
432 /* Used: */
433 HOWTO (IMAGE_REL_PPC_ADDR24, /* type */
434 0, /* rightshift */
435 2, /* size (0 = byte, 1 = short, 2 = long) */
436 26, /* bitsize */
437 false, /* pc_relative */
438 0, /* bitpos */
439 complain_overflow_bitfield, /* complain_on_overflow */
440 0, /* special_function */
441 "ADDR24", /* name */
442 true, /* partial_inplace */
443 0x07fffffc, /* src_mask */
444 0x07fffffc, /* dst_mask */
445 false), /* pcrel_offset */
446
447 /* IMAGE_REL_PPC_ADDR16 0x0004 16-bit address */
448 /* Used: */
449 HOWTO (IMAGE_REL_PPC_ADDR16, /* type */
450 0, /* rightshift */
451 1, /* size (0 = byte, 1 = short, 2 = long) */
452 16, /* bitsize */
453 false, /* pc_relative */
454 0, /* bitpos */
455 complain_overflow_signed, /* complain_on_overflow */
456 0, /* special_function */
457 "ADDR16", /* name */
458 true, /* partial_inplace */
459 0xffff, /* src_mask */
460 0xffff, /* dst_mask */
461 false), /* pcrel_offset */
462
463 /* IMAGE_REL_PPC_ADDR14 0x0005 */
464 /* 16-bit address, shifted left 2 (load doubleword) */
465 /* FIXME: the mask is likely wrong, and the bit position may be as well */
466 /* Unused: */
467 HOWTO (IMAGE_REL_PPC_ADDR14, /* type */
468 1, /* rightshift */
469 1, /* size (0 = byte, 1 = short, 2 = long) */
470 16, /* bitsize */
471 false, /* pc_relative */
472 0, /* bitpos */
473 complain_overflow_signed, /* complain_on_overflow */
474 0, /* special_function */
475 "ADDR16", /* name */
476 true, /* partial_inplace */
477 0xffff, /* src_mask */
478 0xffff, /* dst_mask */
479 false), /* pcrel_offset */
480
481 /* IMAGE_REL_PPC_REL24 0x0006 */
482 /* 26-bit PC-relative offset, shifted left 2 (branch relative) */
483 /* Used: */
484 HOWTO (IMAGE_REL_PPC_REL24, /* type */
485 0, /* rightshift */
486 2, /* size (0 = byte, 1 = short, 2 = long) */
487 26, /* bitsize */
488 true, /* pc_relative */
489 0, /* bitpos */
490 complain_overflow_signed, /* complain_on_overflow */
491 0, /* special_function */
492 "REL24", /* name */
493 true, /* partial_inplace */
494 0x3fffffc, /* src_mask */
495 0x3fffffc, /* dst_mask */
496 false), /* pcrel_offset */
497
498 /* IMAGE_REL_PPC_REL14 0x0007 */
499 /* 16-bit PC-relative offset, shifted left 2 (br cond relative) */
500 /* FIXME: the mask is likely wrong, and the bit position may be as well */
501 /* FIXME: how does it know how far to shift? */
502 /* Unused: */
503 HOWTO (IMAGE_REL_PPC_ADDR14, /* type */
504 1, /* rightshift */
505 1, /* size (0 = byte, 1 = short, 2 = long) */
506 16, /* bitsize */
507 false, /* pc_relative */
508 0, /* bitpos */
509 complain_overflow_signed, /* complain_on_overflow */
510 0, /* special_function */
511 "ADDR16", /* name */
512 true, /* partial_inplace */
513 0xffff, /* src_mask */
514 0xffff, /* dst_mask */
515 true), /* pcrel_offset */
516
517 /* IMAGE_REL_PPC_TOCREL16 0x0008 */
518 /* 16-bit offset from TOC base */
519 /* Used: */
520 HOWTO (IMAGE_REL_PPC_TOCREL16,/* type */
521 0, /* rightshift */
522 1, /* size (0 = byte, 1 = short, 2 = long) */
523 16, /* bitsize */
524 false, /* pc_relative */
525 0, /* bitpos */
526 complain_overflow_dont, /* complain_on_overflow */
527 ppc_toc16_reloc, /* special_function */
528 "TOCREL16", /* name */
529 false, /* partial_inplace */
530 0xffff, /* src_mask */
531 0xffff, /* dst_mask */
532 false), /* pcrel_offset */
533
534 /* IMAGE_REL_PPC_TOCREL14 0x0009 */
535 /* 16-bit offset from TOC base, shifted left 2 (load doubleword) */
536 /* Unused: */
537 HOWTO (IMAGE_REL_PPC_TOCREL14,/* type */
538 1, /* rightshift */
539 1, /* size (0 = byte, 1 = short, 2 = long) */
540 16, /* bitsize */
541 false, /* pc_relative */
542 0, /* bitpos */
543 complain_overflow_signed, /* complain_on_overflow */
544 0, /* special_function */
545 "TOCREL14", /* name */
546 false, /* partial_inplace */
547 0xffff, /* src_mask */
548 0xffff, /* dst_mask */
549 false), /* pcrel_offset */
550
551 /* IMAGE_REL_PPC_ADDR32NB 0x000A */
552 /* 32-bit addr w/ image base */
553 /* Unused: */
554 HOWTO (IMAGE_REL_PPC_ADDR32NB,/* type */
555 0, /* rightshift */
556 2, /* size (0 = byte, 1 = short, 2 = long) */
557 32, /* bitsize */
558 false, /* pc_relative */
559 0, /* bitpos */
560 complain_overflow_signed, /* complain_on_overflow */
561 0, /* special_function */
562 "ADDR32NB", /* name */
563 true, /* partial_inplace */
564 0xffffffff, /* src_mask */
565 0xffffffff, /* dst_mask */
566 false), /* pcrel_offset */
567
568 /* IMAGE_REL_PPC_SECREL 0x000B */
569 /* va of containing section (as in an image sectionhdr) */
570 /* Unused: */
571 HOWTO (IMAGE_REL_PPC_SECREL,/* type */
572 0, /* rightshift */
573 2, /* size (0 = byte, 1 = short, 2 = long) */
574 32, /* bitsize */
575 false, /* pc_relative */
576 0, /* bitpos */
577 complain_overflow_signed, /* complain_on_overflow */
578 ppc_secrel_reloc, /* special_function */
579 "SECREL", /* name */
580 true, /* partial_inplace */
581 0xffffffff, /* src_mask */
582 0xffffffff, /* dst_mask */
583 true), /* pcrel_offset */
584
585 /* IMAGE_REL_PPC_SECTION 0x000C */
586 /* sectionheader number */
587 /* Unused: */
588 HOWTO (IMAGE_REL_PPC_SECTION,/* type */
589 0, /* rightshift */
590 2, /* size (0 = byte, 1 = short, 2 = long) */
591 32, /* bitsize */
592 false, /* pc_relative */
593 0, /* bitpos */
594 complain_overflow_signed, /* complain_on_overflow */
595 ppc_section_reloc, /* special_function */
596 "SECTION", /* name */
597 true, /* partial_inplace */
598 0xffffffff, /* src_mask */
599 0xffffffff, /* dst_mask */
600 true), /* pcrel_offset */
601
602 /* IMAGE_REL_PPC_IFGLUE 0x000D */
603 /* substitute TOC restore instruction iff symbol is glue code */
604 /* Used: */
605 HOWTO (IMAGE_REL_PPC_IFGLUE,/* type */
606 0, /* rightshift */
607 2, /* size (0 = byte, 1 = short, 2 = long) */
608 32, /* bitsize */
609 false, /* pc_relative */
610 0, /* bitpos */
611 complain_overflow_signed, /* complain_on_overflow */
612 0, /* special_function */
613 "IFGLUE", /* name */
614 true, /* partial_inplace */
615 0xffffffff, /* src_mask */
616 0xffffffff, /* dst_mask */
617 false), /* pcrel_offset */
618
619 /* IMAGE_REL_PPC_IMGLUE 0x000E */
620 /* symbol is glue code; virtual address is TOC restore instruction */
621 /* Unused: */
622 HOWTO (IMAGE_REL_PPC_IMGLUE,/* type */
623 0, /* rightshift */
624 2, /* size (0 = byte, 1 = short, 2 = long) */
625 32, /* bitsize */
626 false, /* pc_relative */
627 0, /* bitpos */
628 complain_overflow_dont, /* complain_on_overflow */
629 ppc_imglue_reloc, /* special_function */
630 "IMGLUE", /* name */
631 false, /* partial_inplace */
632 0xffffffff, /* src_mask */
633 0xffffffff, /* dst_mask */
634 false), /* pcrel_offset */
635
636 /* IMAGE_REL_PPC_SECREL16 0x000F */
637 /* va of containing section (limited to 16 bits) */
638 /* Unused: */
639 HOWTO (IMAGE_REL_PPC_SECREL16,/* type */
640 0, /* rightshift */
641 1, /* size (0 = byte, 1 = short, 2 = long) */
642 16, /* bitsize */
643 false, /* pc_relative */
644 0, /* bitpos */
645 complain_overflow_signed, /* complain_on_overflow */
646 0, /* special_function */
647 "SECREL16", /* name */
648 true, /* partial_inplace */
649 0xffff, /* src_mask */
650 0xffff, /* dst_mask */
651 true), /* pcrel_offset */
652
653 /* IMAGE_REL_PPC_REFHI 0x0010 */
654 /* Unused: */
655 HOWTO (IMAGE_REL_PPC_REFHI, /* type */
656 0, /* rightshift */
657 1, /* size (0 = byte, 1 = short, 2 = long) */
658 16, /* bitsize */
659 false, /* pc_relative */
660 0, /* bitpos */
661 complain_overflow_signed, /* complain_on_overflow */
662 ppc_refhi_reloc, /* special_function */
663 "REFHI", /* name */
664 true, /* partial_inplace */
665 0xffffffff, /* src_mask */
666 0xffffffff, /* dst_mask */
667 false), /* pcrel_offset */
668
669 /* IMAGE_REL_PPC_REFLO 0x0011 */
670 /* Unused: */
671 HOWTO (IMAGE_REL_PPC_REFLO, /* type */
672 0, /* rightshift */
673 1, /* size (0 = byte, 1 = short, 2 = long) */
674 16, /* bitsize */
675 false, /* pc_relative */
676 0, /* bitpos */
677 complain_overflow_signed, /* complain_on_overflow */
678 ppc_refhi_reloc, /* special_function */
679 "REFLO", /* name */
680 true, /* partial_inplace */
681 0xffffffff, /* src_mask */
682 0xffffffff, /* dst_mask */
683 false), /* pcrel_offset */
684
685 /* IMAGE_REL_PPC_PAIR 0x0012 */
686 /* Unused: */
687 HOWTO (IMAGE_REL_PPC_PAIR, /* type */
688 0, /* rightshift */
689 1, /* size (0 = byte, 1 = short, 2 = long) */
690 16, /* bitsize */
691 false, /* pc_relative */
692 0, /* bitpos */
693 complain_overflow_signed, /* complain_on_overflow */
694 ppc_pair_reloc, /* special_function */
695 "PAIR", /* name */
696 true, /* partial_inplace */
697 0xffffffff, /* src_mask */
698 0xffffffff, /* dst_mask */
699 false) /* pcrel_offset */
700 };
701
702
703 \f
704
705 /* Some really cheezy macros that can be turned on to test stderr :-) */
706
707 #define DEBUG_RELOC
708
709 #ifdef DEBUG_RELOC
710 #define UN_IMPL(x) \
711 { \
712 static int i; \
713 if (i == 0) \
714 { \
715 i = 1; \
716 fprintf(stderr,"Unimplemented Relocation -- %s\n",x); \
717 } \
718 }
719
720 #define DUMP_RELOC(n,r) \
721 { \
722 fprintf(stderr,"%s sym %d, addr %d, addend %d\n", \
723 n, (*(r->sym_ptr_ptr))->name, \
724 r->address, r->addend); \
725 }
726
727 /* Given a reloc name, n, and a pointer to an internal_reloc,
728 dump out interesting information on the contents
729
730 #define n_name _n._n_name
731 #define n_zeroes _n._n_n._n_zeroes
732 #define n_offset _n._n_n._n_offset
733
734 */
735
736 #define DUMP_RELOC2(n,r) \
737 { \
738 fprintf(stderr,"%s sym %d, r_vaddr %d\n", \
739 n, r->r_symndx, r->r_vaddr); \
740 }
741
742 #else
743 #define UN_IMPL(x)
744 #define DUMP_RELOC(n,r)
745 #define DUMP_RELOC2(n,r)
746 #endif
747
748
749 \f
750 /* toc construction and management routines */
751 extern bfd* bfd_of_toc_owner;
752 extern long int global_toc_size;
753
754 extern long int import_table_size;
755 extern long int first_thunk_address;
756 extern long int thunk_size;
757
758 enum toc_type
759 {
760 default_toc,
761 toc_32,
762 toc_64
763 };
764
765 struct list_ele
766 {
767 struct list_ele *next;
768 bfd_vma addr;
769 int offset;
770 const char *name;
771 };
772
773 extern struct list_ele *head;
774 extern struct list_ele *tail;
775
776 static void
777 record_toc(toc_section, our_toc_offset, name)
778 asection *toc_section;
779 int our_toc_offset;
780 const char *name;
781 {
782 /* add this entry to our toc addr-offset-name list */
783 struct list_ele *t;
784 t = malloc(sizeof(struct list_ele));
785 t->next = 0;
786 t->offset = our_toc_offset;
787 t->name = name;
788 t->addr = toc_section->output_offset + our_toc_offset;
789
790 if (head == 0)
791 {
792 head = t;
793 tail = t;
794 }
795 else
796 {
797 tail->next = t;
798 tail = t;
799 }
800 }
801
802 /* record a toc offset against a symbol */
803 static int
804 ppc_record_toc_entry(abfd, info, sec, sym, toc_kind)
805 bfd *abfd;
806 struct bfd_link_info *info;
807 asection *sec;
808 int sym;
809 enum toc_type toc_kind;
810 {
811 bfd_byte *t;
812 bfd_byte *old_contents;
813 asection *s;
814 int element_size;
815 int data;
816 int offset;
817 struct ppc_coff_link_hash_entry *h;
818 struct coff_symbol_struct *target;
819 int ret_val;
820 const char *name;
821
822 int *local_syms;
823
824 h = 0;
825
826 h = (struct ppc_coff_link_hash_entry *) (obj_coff_sym_hashes (abfd)[sym]);
827 if (h != 0)
828 {
829 CHECK_EYE(h->eye_catcher);
830 }
831
832 if (h == 0)
833 {
834 local_syms = obj_coff_local_toc_table(abfd);
835 if (local_syms == 0)
836 {
837 int i;
838 /* allocate a table */
839 local_syms =
840 (int *) bfd_zalloc (abfd,
841 obj_raw_syment_count(abfd) * sizeof(int));
842 if (local_syms == 0)
843 {
844 bfd_set_error (bfd_error_no_memory);
845 return false;
846 }
847 obj_coff_local_toc_table(abfd) = local_syms;
848 for (i = 0; i < obj_raw_syment_count(abfd); ++i)
849 local_syms[i] = 1;
850 }
851
852 if (local_syms[sym] == 1)
853 {
854 local_syms[sym] = global_toc_size;
855 ret_val = global_toc_size;
856 global_toc_size += 4;
857 #ifdef TOC_DEBUG
858 fprintf(stderr,
859 "Setting toc_offset for local sym %d to %d\n",
860 sym, ret_val);
861 #endif
862 }
863 else
864 {
865 ret_val = local_syms[sym];
866 #ifdef TOC_DEBUG
867 fprintf(stderr,
868 "toc_offset already set for local sym %d to %d\n",
869 sym, ret_val);
870 #endif
871 }
872 }
873 else
874 {
875 name = h->root.root.root.string;
876
877 /* check to see if there's a toc slot allocated. If not, do it
878 here. It will be used in relocate_section */
879 if (h->toc_offset == 1)
880 {
881 h->toc_offset = global_toc_size;
882 ret_val = global_toc_size;
883 global_toc_size += 4;
884 #ifdef TOC_DEBUG
885 fprintf(stderr,
886 "Setting toc_offset for sym %d (%s) [h=%p] to %d\n",
887 sym, name, h, ret_val);
888 #endif
889 }
890 else
891 {
892 ret_val = h->toc_offset;
893 #ifdef TOC_DEBUG
894 fprintf(stderr,
895 "toc_offset already set for sym %d (%s) [h=%p] to %d\n",
896 sym, name, h, ret_val);
897 #endif
898 }
899 }
900
901 return ret_val;
902 }
903
904 /* record a toc offset against a symbol */
905 static void
906 ppc_mark_symbol_as_glue(abfd, sym, rel)
907 bfd *abfd;
908 int sym;
909 struct internal_reloc *rel;
910 {
911 struct ppc_coff_link_hash_entry *h;
912
913 h = (struct ppc_coff_link_hash_entry *) (obj_coff_sym_hashes (abfd)[sym]);
914
915 CHECK_EYE(h->eye_catcher);
916
917 h->symbol_is_glue = 1;
918 h->glue_insn = bfd_get_32 (abfd, (bfd_byte *) &rel->r_vaddr);
919
920 return;
921 }
922
923 \f
924 /* Provided the symbol, returns the value reffed */
925 static long get_symbol_value PARAMS ((asymbol *));
926
927 static long
928 get_symbol_value (symbol)
929 asymbol *symbol;
930 {
931 long relocation = 0;
932
933 if (bfd_is_com_section (symbol->section))
934 {
935 relocation = 0;
936 }
937 else
938 {
939 relocation = symbol->value +
940 symbol->section->output_section->vma +
941 symbol->section->output_offset;
942 }
943
944 return(relocation);
945 }
946
947 /* Return true if this relocation should
948 appear in the output .reloc section. */
949
950 static boolean in_reloc_p(abfd, howto)
951 bfd * abfd;
952 reloc_howto_type *howto;
953 {
954 return
955 (! howto->pc_relative)
956 && (howto->type != IMAGE_REL_PPC_TOCREL16)
957 && (howto->type != IMAGE_REL_PPC_IMGLUE);
958 }
959
960 /* this function is in charge of performing all the ppc PE relocations */
961 /* Don't yet know if we want to do this this particular way ... (krk) */
962 /* FIXME: (it is not yet enabled) */
963
964 static bfd_reloc_status_type
965 pe_ppc_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd,
966 error_message)
967 bfd *abfd;
968 arelent *reloc_entry;
969 asymbol *symbol_in;
970 PTR data;
971 asection *input_section;
972 bfd *output_bfd;
973 char **error_message;
974 {
975 /* the consth relocation comes in two parts, we have to remember
976 the state between calls, in these variables */
977 static boolean part1_consth_active = false;
978 static unsigned long part1_consth_value;
979
980 unsigned long insn;
981 unsigned long sym_value;
982 unsigned long unsigned_value;
983 unsigned short r_type;
984 long signed_value;
985
986 unsigned long addr = reloc_entry->address ; /*+ input_section->vma*/
987 bfd_byte *hit_data =addr + (bfd_byte *)(data);
988
989 fprintf(stderr, "pe_ppc_reloc (%s)\n", TARGET_LITTLE_NAME);
990
991 r_type = reloc_entry->howto->type;
992
993 if (output_bfd)
994 {
995 /* Partial linking - do nothing */
996 reloc_entry->address += input_section->output_offset;
997 return bfd_reloc_ok;
998 }
999
1000 if (symbol_in != NULL
1001 && bfd_is_und_section (symbol_in->section))
1002 {
1003 /* Keep the state machine happy in case we're called again */
1004 if (r_type == IMAGE_REL_PPC_REFHI)
1005 {
1006 part1_consth_active = true;
1007 part1_consth_value = 0;
1008 }
1009 return(bfd_reloc_undefined);
1010 }
1011
1012 if ((part1_consth_active) && (r_type != IMAGE_REL_PPC_PAIR))
1013 {
1014 part1_consth_active = false;
1015 *error_message = (char *) "Missing PAIR";
1016 return(bfd_reloc_dangerous);
1017 }
1018
1019
1020 sym_value = get_symbol_value(symbol_in);
1021
1022 return(bfd_reloc_ok);
1023 }
1024
1025 /* The reloc processing routine for the optimized COFF linker. */
1026
1027 static boolean
1028 coff_ppc_relocate_section (output_bfd, info, input_bfd, input_section,
1029 contents, relocs, syms, sections)
1030 bfd *output_bfd;
1031 struct bfd_link_info *info;
1032 bfd *input_bfd;
1033 asection *input_section;
1034 bfd_byte *contents;
1035 struct internal_reloc *relocs;
1036 struct internal_syment *syms;
1037 asection **sections;
1038 {
1039 struct internal_reloc *rel;
1040 struct internal_reloc *relend;
1041 boolean hihalf;
1042 bfd_vma hihalf_val;
1043 asection *toc_section = 0;
1044 bfd_vma relocation;
1045 reloc_howto_type *howto = 0;
1046
1047 #ifdef DEBUG_RELOC
1048 fprintf(stderr,
1049 "pe_ppc_relocate_section (%s) for %s \n",
1050 TARGET_LITTLE_NAME,
1051 input_section->name);
1052
1053 #endif
1054
1055 /* If we are performing a relocateable link, we don't need to do a
1056 thing. The caller will take care of adjusting the reloc
1057 addresses and symbol indices. */
1058 if (info->relocateable)
1059 return true;
1060
1061 hihalf = false;
1062 hihalf_val = 0;
1063
1064 rel = relocs;
1065 relend = rel + input_section->reloc_count;
1066 for (; rel < relend; rel++)
1067 {
1068 long symndx;
1069 struct ppc_coff_link_hash_entry *h;
1070 struct internal_syment *sym;
1071 bfd_vma val;
1072
1073 asection *sec;
1074 bfd_reloc_status_type rstat;
1075 bfd_byte *loc;
1076
1077 unsigned short r_type = EXTRACT_TYPE (rel->r_type);
1078 unsigned short r_flags = EXTRACT_FLAGS(rel->r_type);
1079 unsigned short junk = EXTRACT_JUNK (rel->r_type);
1080
1081 #ifdef DEBUG_RELOC
1082 /* now examine flags */
1083 if (r_flags != 0)
1084 {
1085 fprintf (stderr, "Reloc with flags found!");
1086 if ( r_flags & IMAGE_REL_PPC_NEG )
1087 fprintf (stderr, " NEG");
1088 if ( r_flags & IMAGE_REL_PPC_BRTAKEN )
1089 fprintf (stderr, " BRTAKEN");
1090 if ( r_flags & IMAGE_REL_PPC_BRNTAKEN )
1091 fprintf (stderr, " BRNTAKEN");
1092 if ( r_flags & IMAGE_REL_PPC_TOCDEFN )
1093 fprintf (stderr, " TOCDEFN");
1094 fprintf(stderr, "\n");
1095 }
1096 #endif
1097
1098 symndx = rel->r_symndx;
1099 loc = contents + rel->r_vaddr - input_section->vma;
1100
1101 /* FIXME: check bounds on r_type */
1102 howto = ppc_coff_howto_table + r_type;
1103
1104 if (symndx == -1)
1105 {
1106 h = NULL;
1107 sym = NULL;
1108 }
1109 else
1110 {
1111 h = (struct ppc_coff_link_hash_entry *)
1112 (obj_coff_sym_hashes (input_bfd)[symndx]);
1113 if (h != 0)
1114 {
1115 CHECK_EYE(h->eye_catcher);
1116 }
1117
1118 sym = syms + symndx;
1119 }
1120
1121 sec = NULL;
1122 val = 0;
1123
1124 /* FIXME: PAIR unsupported in the following code */
1125 if (h == NULL)
1126 {
1127 if (symndx == -1)
1128 sec = bfd_abs_section_ptr;
1129 else
1130 {
1131 sec = sections[symndx];
1132 val = (sec->output_section->vma
1133 + sec->output_offset
1134 + sym->n_value
1135 - sec->vma);
1136 }
1137 }
1138 else
1139 {
1140 CHECK_EYE(h->eye_catcher);
1141
1142 if (h->root.root.type == bfd_link_hash_defined
1143 || h->root.root.type == bfd_link_hash_defweak)
1144 {
1145 sec = h->root.root.u.def.section;
1146 val = (h->root.root.u.def.value
1147 + sec->output_section->vma
1148 + sec->output_offset);
1149 }
1150 else
1151 {
1152 if (! ((*info->callbacks->undefined_symbol)
1153 (info, h->root.root.root.string, input_bfd, input_section,
1154 rel->r_vaddr - input_section->vma)))
1155 return false;
1156 }
1157 }
1158
1159 rstat = bfd_reloc_ok;
1160
1161 /* Each case must do its own relocation, setting rstat appropriately */
1162 switch (r_type)
1163 {
1164 default:
1165 fprintf( stderr,
1166 "ERROR: during reloc processing -- unsupported reloc %s\n",
1167 howto->name);
1168 bfd_set_error (bfd_error_bad_value);
1169 abort();
1170 return false;
1171 case IMAGE_REL_PPC_TOCREL16:
1172 {
1173 bfd_vma our_toc_offset;
1174 int fixit;
1175
1176 DUMP_RELOC2(howto->name, rel);
1177
1178 if (toc_section == 0)
1179 {
1180 toc_section = bfd_get_section_by_name (bfd_of_toc_owner,
1181 TOC_SECTION_NAME);
1182 #ifdef TOC_DEBUG
1183
1184 fprintf(stderr,
1185 "BFD of toc owner %p, section addr of %s %p\n",
1186 bfd_of_toc_owner, TOC_SECTION_NAME, toc_section);
1187 #endif
1188
1189 if ( toc_section == NULL )
1190 {
1191 fprintf(stderr, "No Toc section!\n");
1192 abort();
1193 }
1194 }
1195
1196 #if 0
1197 if ( r_flags & IMAGE_REL_PPC_TOCDEFN )
1198 {
1199 /* Somehow, we are to assume that the toc has already been
1200 done for this one, and the offset is the value of
1201 the symbol? */
1202 fprintf(stderr,
1203 "Symbol value %d\n", val);
1204 }
1205 #endif
1206
1207 /*
1208 * Amazing bit tricks present. As we may have seen earlier, we
1209 * use the 1 bit to tell us whether or not a toc offset has been
1210 * allocated. Now that they've all been allocated, we will use
1211 * the 1 bit to tell us if we've written this particular toc
1212 * entry out.
1213 */
1214 fixit = false;
1215 if (h == 0)
1216 { /* it is a file local symbol */
1217 int *local_toc_table;
1218 const char *name;
1219
1220 sym = syms + symndx;
1221 name = sym->_n._n_name;
1222
1223 local_toc_table = obj_coff_local_toc_table(input_bfd);
1224 our_toc_offset = local_toc_table[symndx];
1225
1226 if ((our_toc_offset & 1) != 0)
1227 {
1228 /* if it has been written out, it is marked with the
1229 1 bit. Fix up our offset, but do not write it out
1230 again.
1231 */
1232 our_toc_offset &= ~1;
1233 #ifdef TOC_DEBUG
1234
1235 fprintf(stderr,
1236 "Not writing out toc_offset of %d for %s\n", our_toc_offset, name);
1237 #endif
1238 }
1239 else
1240 {
1241 /* write out the toc entry */
1242 record_toc(toc_section, our_toc_offset, strdup(name));
1243 #ifdef TOC_DEBUG
1244 fprintf(stderr,
1245 "Writing out toc_offset toc_section (%p,%p)+%d val %d for %s\n",
1246 toc_section,
1247 toc_section->contents,
1248 our_toc_offset,
1249 val,
1250 name);
1251 #endif
1252
1253 bfd_put_32(output_bfd,
1254 val,
1255 toc_section->contents + our_toc_offset);
1256
1257 local_toc_table[symndx] |= 1;
1258 fixit = true;
1259 }
1260 }
1261 else
1262 {
1263 const char *name = h->root.root.root.string;
1264 our_toc_offset = h->toc_offset;
1265
1266 if ((our_toc_offset & 1) != 0)
1267 {
1268 /* if it has been written out, it is marked with the
1269 1 bit. Fix up our offset, but do not write it out
1270 again.
1271 */
1272 our_toc_offset &= ~1;
1273 #ifdef TOC_DEBUG
1274 fprintf(stderr,
1275 "Not writing out toc_offset of %d for %s\n", our_toc_offset, name);
1276 #endif
1277 }
1278 else
1279 {
1280 record_toc(toc_section, our_toc_offset, strdup(name));
1281
1282 #ifdef TOC_DEBUG
1283 /* write out the toc entry */
1284 fprintf(stderr,
1285 "Writing out toc_offset toc_section (%p,%p)+%d val %d for %s\n",
1286 toc_section,
1287 toc_section->contents,
1288 our_toc_offset,
1289 val,
1290 name);
1291 #endif
1292
1293 /* write out the toc entry */
1294 bfd_put_32(output_bfd,
1295 val,
1296 toc_section->contents + our_toc_offset);
1297
1298 h->toc_offset |= 1;
1299 /* The tricky part is that this is the address that */
1300 /* needs a .reloc entry for it */
1301 fixit = true;
1302 }
1303 }
1304
1305 if (fixit && info->base_file)
1306 {
1307 /* So if this is non pcrelative, and is referenced
1308 to a section or a common symbol, then it needs a reloc */
1309
1310 /* relocation to a symbol in a section which
1311 isn't absolute - we output the address here
1312 to a file */
1313
1314 bfd_vma addr = toc_section->output_section->vma
1315 + toc_section->output_offset + our_toc_offset;
1316
1317 fprintf(stderr,
1318 " Toc Section reloc candidate\n");
1319
1320 if (coff_data(output_bfd)->pe)
1321 addr -= pe_data(output_bfd)->pe_opthdr.ImageBase;
1322 fwrite (&addr, 1,4, (FILE *) info->base_file);
1323 }
1324
1325
1326 /* FIXME: this test is conservative */
1327 if (our_toc_offset > toc_section->_raw_size)
1328 {
1329 fprintf(stderr,
1330 "reloc offset is bigger than the toc size!\n");
1331 abort();
1332 }
1333
1334 /* Now we know the relocation for this toc reference */
1335 relocation = our_toc_offset + TOC_LOAD_ADJUSTMENT;
1336 rstat = _bfd_relocate_contents (howto,
1337 input_bfd,
1338 relocation,
1339 loc);
1340 }
1341 break;
1342 case IMAGE_REL_PPC_IFGLUE:
1343 {
1344 /* To solve this, we need to know whether or not the symbol */
1345 /* appearing on the call instruction is a glue function or not. */
1346 /* A glue function must announce itself via a IMGLUE reloc, and */
1347 /* the reloc contains the required toc restore instruction */
1348
1349 bfd_vma x;
1350 const char *my_name;
1351 DUMP_RELOC2(howto->name, rel);
1352
1353 if (h != 0)
1354 {
1355 my_name = h->root.root.root.string;
1356 if (h->symbol_is_glue == 1)
1357 {
1358 x = bfd_get_32(input_bfd, loc);
1359 bfd_put_32(input_bfd, h->glue_insn, loc);
1360 }
1361 }
1362 }
1363 break;
1364 case IMAGE_REL_PPC_SECREL:
1365 /* Unimplemented: codeview debugging information */
1366 /* For fast access to the header of the section
1367 containing the item. */
1368 break;
1369 case IMAGE_REL_PPC_SECTION:
1370 /* Unimplemented: codeview debugging information */
1371 /* Is used to indicate that the value should be relative
1372 to the beginning of the section that contains the
1373 symbol */
1374 break;
1375 case IMAGE_REL_PPC_ABSOLUTE:
1376 {
1377 const char *my_name;
1378 if (h == 0)
1379 my_name = (syms+symndx)->_n._n_name;
1380 else
1381 {
1382 my_name = h->root.root.root.string;
1383 }
1384
1385 fprintf(stderr,
1386 "Warning: unsupported reloc %s <file %s, section %s>\n",
1387 howto->name,
1388 bfd_get_filename(input_bfd),
1389 input_section->name);
1390
1391 fprintf(stderr,"sym %d (%s), r_vaddr %d (%x)\n",
1392 rel->r_symndx, my_name, rel->r_vaddr, rel->r_vaddr);
1393 }
1394 break;
1395 case IMAGE_REL_PPC_IMGLUE:
1396 {
1397 /* There is nothing to do now. This reloc was noted in the first
1398 pass over the relocs, and the glue instruction extracted */
1399 const char *my_name;
1400 if (h->symbol_is_glue == 1)
1401 break;
1402 my_name = h->root.root.root.string;
1403 fprintf(stderr,
1404 "Warning: previously missed IMGLUE reloc %s <file %s, section %s>\n",
1405 howto->name,
1406 bfd_get_filename(input_bfd),
1407 input_section->name);
1408 break;
1409
1410 }
1411 break;
1412
1413 case IMAGE_REL_PPC_ADDR32NB:
1414 {
1415 struct coff_link_hash_entry *myh = 0;
1416 const char *name = 0;
1417 DUMP_RELOC2(howto->name, rel);
1418 if (h == 0)
1419 { /* it is a file local symbol */
1420 sym = syms + symndx;
1421 name = sym->_n._n_name;
1422 }
1423 else
1424 {
1425 char *target = 0;
1426
1427 name = h->root.root.root.string;
1428 if (strcmp(".idata$2", name) == 0)
1429 target = "__idata2_magic__";
1430 else if (strcmp(".idata$4", name) == 0)
1431 target = "__idata4_magic__";
1432 else if (strcmp(".idata$5", name) == 0)
1433 target = "__idata5_magic__";
1434 else
1435 abort();
1436
1437 myh = 0;
1438
1439 myh = coff_link_hash_lookup (coff_hash_table (info),
1440 target,
1441 false, false, true);
1442 if (myh == 0)
1443 {
1444 fprintf(stderr, "Missing idata magic cookies, this cannot work anyway...\n");
1445 abort();
1446 }
1447
1448 val = myh->root.u.def.value +
1449 sec->output_section->vma + sec->output_offset;
1450 if (first_thunk_address == 0)
1451 {
1452 int idata5offset;
1453 myh = coff_link_hash_lookup (coff_hash_table (info),
1454 "__idata5_magic__",
1455 false, false, true);
1456 first_thunk_address = myh->root.u.def.value +
1457 sec->output_section->vma +
1458 sec->output_offset -
1459 pe_data(output_bfd)->pe_opthdr.ImageBase;
1460
1461 idata5offset = myh->root.u.def.value;
1462 myh = coff_link_hash_lookup (coff_hash_table (info),
1463 "__idata6_magic__",
1464 false, false, true);
1465
1466 thunk_size = myh->root.u.def.value - idata5offset;
1467 myh = coff_link_hash_lookup (coff_hash_table (info),
1468 "__idata4_magic__",
1469 false, false, true);
1470 import_table_size = myh->root.u.def.value;
1471 }
1472 }
1473
1474 rstat = _bfd_relocate_contents (howto,
1475 input_bfd,
1476 val -
1477 pe_data(output_bfd)->pe_opthdr.ImageBase,
1478 loc);
1479 }
1480 break;
1481
1482 case IMAGE_REL_PPC_ADDR16:
1483 case IMAGE_REL_PPC_REL24:
1484 case IMAGE_REL_PPC_ADDR24:
1485 case IMAGE_REL_PPC_ADDR32:
1486 DUMP_RELOC2(howto->name, rel);
1487 rstat = _bfd_relocate_contents (howto,
1488 input_bfd,
1489 val,
1490 loc);
1491 break;
1492 }
1493
1494 if ( info->base_file )
1495 {
1496 /* So if this is non pcrelative, and is referenced
1497 to a section or a common symbol, then it needs a reloc */
1498 if (sym && pe_data(output_bfd)->in_reloc_p(output_bfd, howto))
1499 {
1500 /* relocation to a symbol in a section which
1501 isn't absolute - we output the address here
1502 to a file */
1503 bfd_vma addr = rel->r_vaddr
1504 - input_section->vma
1505 + input_section->output_offset
1506 + input_section->output_section->vma;
1507
1508 if (coff_data(output_bfd)->pe)
1509 {
1510 addr -= pe_data(output_bfd)->pe_opthdr.ImageBase;
1511 fprintf(stderr,
1512 " adjusted down to %d", addr);
1513 }
1514 fprintf(stderr, "\n");
1515
1516 fwrite (&addr, 1,4, (FILE *) info->base_file);
1517 }
1518 }
1519
1520 switch (rstat)
1521 {
1522 default:
1523 abort ();
1524 case bfd_reloc_ok:
1525 break;
1526 case bfd_reloc_overflow:
1527 {
1528 const char *name;
1529 char buf[SYMNMLEN + 1];
1530
1531 if (symndx == -1)
1532 name = "*ABS*";
1533 else if (h != NULL)
1534 name = h->root.root.root.string;
1535 else if (sym == NULL)
1536 name = "*unknown*";
1537 else if (sym->_n._n_n._n_zeroes == 0
1538 && sym->_n._n_n._n_offset != 0)
1539 name = obj_coff_strings (input_bfd) + sym->_n._n_n._n_offset;
1540 else
1541 {
1542 strncpy (buf, sym->_n._n_name, SYMNMLEN);
1543 buf[SYMNMLEN] = '\0';
1544 name = buf;
1545 }
1546 #if 0
1547 else
1548 {
1549 name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
1550 if (name == NULL)
1551 return false;
1552 }
1553 #endif
1554
1555 if (! ((*info->callbacks->reloc_overflow)
1556 (info, name, howto->name,
1557 (bfd_vma) 0, input_bfd,
1558 input_section, rel->r_vaddr - input_section->vma)))
1559 return false;
1560 }
1561 }
1562
1563 }
1564
1565 return true;
1566 }
1567
1568 #ifdef COFF_IMAGE_WITH_PE
1569
1570 long int global_toc_size = 0;
1571
1572 bfd* bfd_of_toc_owner = 0;
1573
1574 long int import_table_size;
1575 long int first_thunk_address;
1576 long int thunk_size;
1577
1578 struct list_ele *head;
1579 struct list_ele *tail;
1580
1581 void
1582 dump_toc(vfile)
1583 void *vfile;
1584 {
1585 FILE *file = vfile;
1586 struct list_ele *t;
1587
1588 fprintf(file,
1589 " Offset Offset Name if present\n");
1590
1591 for(t = head; t != 0; t=t->next)
1592 {
1593 fprintf(file,
1594 " %2x %04lx %s\n",
1595 t->offset - 32768, t->offset, t->name);
1596 }
1597 }
1598
1599 boolean
1600 ppc_allocate_toc_section (info)
1601 struct bfd_link_info *info;
1602 {
1603 asection *s;
1604 bfd_byte *foo;
1605 static char test_char = '1';
1606
1607 #ifdef DEBUG_TOC
1608 fprintf(stderr,
1609 "ppc_allocate_toc_section: allocating %s section of size %d\n",
1610 TOC_SECTION_NAME, global_toc_size);
1611 #endif
1612
1613 if ( global_toc_size == 0 ) /* FIXME: does this get me in trouble? */
1614 return true;
1615
1616 if (bfd_of_toc_owner == 0)
1617 {
1618 fprintf(stderr,
1619 "There is no bfd that owns the toc section!\n");
1620 abort();
1621 }
1622
1623 s = bfd_get_section_by_name ( bfd_of_toc_owner , TOC_SECTION_NAME);
1624 if (s == NULL)
1625 {
1626 fprintf(stderr, "No Toc section!\n");
1627 abort();
1628 }
1629
1630 foo = bfd_alloc(bfd_of_toc_owner, global_toc_size);
1631 memset(foo, test_char, global_toc_size);
1632
1633 s->_raw_size = s->_cooked_size = global_toc_size;
1634 s->contents = foo;
1635
1636 return true;
1637 }
1638
1639 boolean
1640 ppc_process_before_allocation (abfd, info)
1641 bfd *abfd;
1642 struct bfd_link_info *info;
1643 {
1644 asection *sec;
1645 struct internal_reloc *i, *rel;
1646
1647 #if 0
1648 fprintf(stderr,
1649 "ppc_process_before_allocation: BFD %s\n",
1650 bfd_get_filename(abfd));
1651 #endif
1652
1653 /* here we have a bfd that is to be included on the link. We have a hook
1654 to do reloc rummaging, before section sizes are nailed down. */
1655
1656 _bfd_coff_get_external_symbols(abfd);
1657
1658 /* rummage around all the relocs and map the toc */
1659 sec = abfd->sections;
1660
1661 if (sec == 0)
1662 {
1663 return true;
1664 }
1665
1666 for (; sec != 0; sec = sec->next)
1667 {
1668 int toc_offset;
1669 #ifdef DEBUG_RELOC
1670 fprintf(stderr,
1671 " section %s reloc count %d\n",
1672 sec->name,
1673 sec->reloc_count);
1674 #endif
1675
1676 if (sec->reloc_count == 0)
1677 continue;
1678
1679 /* load the relocs */
1680 /* FIXME: there may be a storage leak here */
1681 i=_bfd_coff_read_internal_relocs(abfd,sec,1,0,0,0);
1682
1683 if (i == 0)
1684 abort();
1685
1686 for (rel=i;rel<i+sec->reloc_count;++rel)
1687 {
1688 unsigned short r_type = EXTRACT_TYPE (rel->r_type);
1689 unsigned short r_flags = EXTRACT_FLAGS(rel->r_type);
1690 unsigned short junk = EXTRACT_JUNK (rel->r_type);
1691
1692 #ifdef DEBUG_RELOC
1693 /* now examine flags */
1694 if (r_flags != 0)
1695 {
1696 fprintf (stderr, "Reloc with flags found!");
1697 if ( r_flags & IMAGE_REL_PPC_NEG )
1698 fprintf (stderr, " NEG");
1699 if ( r_flags & IMAGE_REL_PPC_BRTAKEN )
1700 fprintf (stderr, " BRTAKEN");
1701 if ( r_flags & IMAGE_REL_PPC_BRNTAKEN )
1702 fprintf (stderr, " BRNTAKEN");
1703 if ( r_flags & IMAGE_REL_PPC_TOCDEFN )
1704 fprintf (stderr, " TOCDEFN");
1705 fprintf(stderr, "\n");
1706 }
1707 #endif
1708
1709 DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel);
1710
1711 switch(r_type)
1712 {
1713 case IMAGE_REL_PPC_TOCREL16:
1714 toc_offset = ppc_record_toc_entry(abfd, info, sec,
1715 rel->r_symndx, default_toc);
1716 break;
1717 case IMAGE_REL_PPC_IMGLUE:
1718 ppc_mark_symbol_as_glue(abfd, rel->r_symndx, rel);
1719 break;
1720 default:
1721 break;
1722 }
1723 }
1724 }
1725 }
1726
1727 #endif
1728
1729
1730 static bfd_reloc_status_type
1731 ppc_refhi_reloc (abfd,
1732 reloc_entry,
1733 symbol,
1734 data,
1735 input_section,
1736 output_bfd,
1737 error_message)
1738 bfd *abfd;
1739 arelent *reloc_entry;
1740 asymbol *symbol;
1741 PTR data;
1742 asection *input_section;
1743 bfd *output_bfd;
1744 char **error_message;
1745 {
1746 UN_IMPL("REFHI");
1747 DUMP_RELOC("REFHI",reloc_entry);
1748
1749 if (output_bfd == (bfd *) NULL)
1750 return bfd_reloc_continue;
1751
1752 return bfd_reloc_undefined;
1753 }
1754
1755 static bfd_reloc_status_type
1756 ppc_reflo_reloc (abfd,
1757 reloc_entry,
1758 symbol,
1759 data,
1760 input_section,
1761 output_bfd,
1762 error_message)
1763 bfd *abfd;
1764 arelent *reloc_entry;
1765 asymbol *symbol;
1766 PTR data;
1767 asection *input_section;
1768 bfd *output_bfd;
1769 char **error_message;
1770 {
1771 UN_IMPL("REFLO");
1772 DUMP_RELOC("REFLO",reloc_entry);
1773
1774 if (output_bfd == (bfd *) NULL)
1775 return bfd_reloc_continue;
1776
1777 return bfd_reloc_undefined;
1778 }
1779
1780 static bfd_reloc_status_type
1781 ppc_pair_reloc (abfd,
1782 reloc_entry,
1783 symbol,
1784 data,
1785 input_section,
1786 output_bfd,
1787 error_message)
1788 bfd *abfd;
1789 arelent *reloc_entry;
1790 asymbol *symbol;
1791 PTR data;
1792 asection *input_section;
1793 bfd *output_bfd;
1794 char **error_message;
1795 {
1796 UN_IMPL("PAIR");
1797 DUMP_RELOC("PAIR",reloc_entry);
1798
1799 if (output_bfd == (bfd *) NULL)
1800 return bfd_reloc_continue;
1801
1802 return bfd_reloc_undefined;
1803 }
1804
1805 \f
1806 static bfd_reloc_status_type
1807 ppc_toc16_reloc (abfd,
1808 reloc_entry,
1809 symbol,
1810 data,
1811 input_section,
1812 output_bfd,
1813 error_message)
1814 bfd *abfd;
1815 arelent *reloc_entry;
1816 asymbol *symbol;
1817 PTR data;
1818 asection *input_section;
1819 bfd *output_bfd;
1820 char **error_message;
1821 {
1822 UN_IMPL("TOCREL16");
1823 DUMP_RELOC("TOCREL16",reloc_entry);
1824
1825 if (output_bfd == (bfd *) NULL)
1826 {
1827 return bfd_reloc_continue;
1828 }
1829
1830 return bfd_reloc_ok;
1831 }
1832
1833 /* ADDR32NB : 32 bit address relative to the virtual origin. */
1834 /* (On the alpha, this is always a linker generated thunk)*/
1835 /* (i.e. 32bit addr relative to the image base) */
1836 /* */
1837 /* */
1838
1839 static bfd_reloc_status_type
1840 ppc_addr32nb_reloc (abfd,
1841 reloc_entry,
1842 symbol,
1843 data,
1844 input_section,
1845 output_bfd,
1846 error_message)
1847 bfd *abfd;
1848 arelent *reloc_entry;
1849 asymbol *symbol;
1850 PTR data;
1851 asection *input_section;
1852 bfd *output_bfd;
1853 char **error_message;
1854 {
1855 UN_IMPL("ADDR32NB");
1856 DUMP_RELOC("ADDR32NB",reloc_entry);
1857
1858 return bfd_reloc_ok;
1859 }
1860
1861 static bfd_reloc_status_type
1862 ppc_secrel_reloc (abfd,
1863 reloc_entry,
1864 symbol,
1865 data,
1866 input_section,
1867 output_bfd,
1868 error_message)
1869 bfd *abfd;
1870 arelent *reloc_entry;
1871 asymbol *symbol;
1872 PTR data;
1873 asection *input_section;
1874 bfd *output_bfd;
1875 char **error_message;
1876 {
1877 UN_IMPL("SECREL");
1878 DUMP_RELOC("SECREL",reloc_entry);
1879
1880 if (output_bfd == (bfd *) NULL)
1881 return bfd_reloc_continue;
1882
1883 return bfd_reloc_ok;
1884 }
1885
1886 static bfd_reloc_status_type
1887 ppc_section_reloc (abfd,
1888 reloc_entry,
1889 symbol,
1890 data,
1891 input_section,
1892 output_bfd,
1893 error_message)
1894 bfd *abfd;
1895 arelent *reloc_entry;
1896 asymbol *symbol;
1897 PTR data;
1898 asection *input_section;
1899 bfd *output_bfd;
1900 char **error_message;
1901 {
1902 UN_IMPL("SECTION");
1903 DUMP_RELOC("SECTION",reloc_entry);
1904
1905 if (output_bfd == (bfd *) NULL)
1906 return bfd_reloc_continue;
1907
1908 return bfd_reloc_ok;
1909 }
1910
1911 static bfd_reloc_status_type
1912 ppc_imglue_reloc (abfd,
1913 reloc_entry,
1914 symbol,
1915 data,
1916 input_section,
1917 output_bfd,
1918 error_message)
1919 bfd *abfd;
1920 arelent *reloc_entry;
1921 asymbol *symbol;
1922 PTR data;
1923 asection *input_section;
1924 bfd *output_bfd;
1925 char **error_message;
1926 {
1927 UN_IMPL("IMGLUE");
1928 DUMP_RELOC("IMGLUE",reloc_entry);
1929
1930 if (output_bfd == (bfd *) NULL)
1931 return bfd_reloc_continue;
1932
1933 return bfd_reloc_ok;
1934 }
1935
1936 \f
1937
1938 #define MAX_RELOC_INDEX \
1939 (sizeof(ppc_coff_howto_table) / sizeof(ppc_coff_howto_table[0]) - 1)
1940
1941
1942 /* FIXME: There is a possiblity that when we read in a reloc from a file,
1943 that there are some bits encoded in the upper portion of the
1944 type field. Not yet implemented.
1945 */
1946 static void ppc_coff_rtype2howto PARAMS ((arelent *relent,
1947 struct internal_reloc *internal));
1948
1949 static void
1950 ppc_coff_rtype2howto (relent, internal)
1951 arelent *relent;
1952 struct internal_reloc *internal;
1953 {
1954
1955 /* We can encode one of three things in the type field, aside from the
1956 type:
1957 1. IMAGE_REL_PPC_NEG - indicates the value field is a subtraction
1958 value, rather than an addition value
1959 2. IMAGE_REL_PPC_BRTAKEN, IMAGE_REL_PPC_BRNTAKEN - indicates that
1960 the branch is expected to be taken or not.
1961 3. IMAGE_REL_PPC_TOCDEFN - toc slot definition in the file
1962 For now, we just strip this stuff to find the type, and ignore it other
1963 than that.
1964 */
1965
1966 unsigned short r_type = EXTRACT_TYPE (internal->r_type);
1967 unsigned short r_flags = EXTRACT_FLAGS(internal->r_type);
1968 unsigned short junk = EXTRACT_JUNK (internal->r_type);
1969
1970 /* the masking process only slices off the bottom byte for r_type. */
1971 if ( r_type > MAX_RELOC_INDEX )
1972 {
1973 fprintf(stderr,
1974 "ppc_coff_rtype2howto: reloc index %d out of range [%d, %d]\n",
1975 internal->r_type, 0, MAX_RELOC_INDEX);
1976 abort();
1977 }
1978
1979 /* check for absolute crap */
1980 if ( junk != 0 )
1981 {
1982 fprintf(stderr,
1983 "ppc_coff_rtype2howto: reloc index %d contains junk %d\n",
1984 internal->r_type, junk);
1985 abort();
1986 }
1987
1988 #ifdef DEBUG_RELOC
1989 /* now examine flags */
1990 if (r_flags != 0)
1991 {
1992 fprintf (stderr, "Reloc with flags found!");
1993 if ( r_flags & IMAGE_REL_PPC_NEG )
1994 fprintf (stderr, " NEG");
1995 if ( r_flags & IMAGE_REL_PPC_BRTAKEN )
1996 fprintf (stderr, " BRTAKEN");
1997 if ( r_flags & IMAGE_REL_PPC_BRNTAKEN )
1998 fprintf (stderr, " BRNTAKEN");
1999 if ( r_flags & IMAGE_REL_PPC_TOCDEFN )
2000 fprintf (stderr, " TOCDEFN");
2001 fprintf(stderr, "\n");
2002 }
2003 #endif
2004
2005 switch(r_type)
2006 {
2007 case IMAGE_REL_PPC_ADDR16:
2008 case IMAGE_REL_PPC_REL24:
2009 case IMAGE_REL_PPC_ADDR24:
2010 case IMAGE_REL_PPC_TOCREL16:
2011 case IMAGE_REL_PPC_ADDR32:
2012 case IMAGE_REL_PPC_IFGLUE:
2013 case IMAGE_REL_PPC_ADDR32NB:
2014 case IMAGE_REL_PPC_SECTION:
2015 case IMAGE_REL_PPC_SECREL:
2016 DUMP_RELOC2(ppc_coff_howto_table[r_type].name, internal);
2017 break;
2018 case IMAGE_REL_PPC_IMGLUE:
2019 DUMP_RELOC2(ppc_coff_howto_table[r_type].name, internal);
2020 break;
2021 default:
2022 fprintf(stderr,
2023 "Warning: Unsupported reloc %s [%d] used -- it may not work.\n",
2024 ppc_coff_howto_table[r_type].name,
2025 r_type);
2026 break;
2027 }
2028
2029 relent->howto = ppc_coff_howto_table + r_type;
2030
2031 }
2032
2033 static reloc_howto_type *
2034 coff_ppc_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
2035 bfd *abfd;
2036 asection *sec;
2037 struct internal_reloc *rel;
2038 struct coff_link_hash_entry *h;
2039 struct internal_syment *sym;
2040 bfd_vma *addendp;
2041 {
2042 reloc_howto_type *howto;
2043
2044 /* We can encode one of three things in the type field, aside from the
2045 type:
2046 1. IMAGE_REL_PPC_NEG - indicates the value field is a subtraction
2047 value, rather than an addition value
2048 2. IMAGE_REL_PPC_BRTAKEN, IMAGE_REL_PPC_BRNTAKEN - indicates that
2049 the branch is expected to be taken or not.
2050 3. IMAGE_REL_PPC_TOCDEFN - toc slot definition in the file
2051 For now, we just strip this stuff to find the type, and ignore it other
2052 than that.
2053 */
2054
2055 unsigned short r_type = EXTRACT_TYPE (rel->r_type);
2056 unsigned short r_flags = EXTRACT_FLAGS(rel->r_type);
2057 unsigned short junk = EXTRACT_JUNK (rel->r_type);
2058
2059 fprintf(stderr,
2060 "coff_ppc_rtype_to_howto\n");
2061
2062 /* the masking process only slices off the bottom byte for r_type. */
2063 if ( r_type > MAX_RELOC_INDEX )
2064 {
2065 fprintf(stderr,
2066 "coff_ppc_rtype_to_howto: index %d out of range [%d, %d]\n",
2067 r_type, 0, MAX_RELOC_INDEX);
2068 abort();
2069 }
2070
2071 /* check for absolute crap */
2072 if ( junk != 0 )
2073 {
2074 fprintf(stderr,
2075 "coff_ppc_rtype_to_howto: reloc index %d contains junk %d\n",
2076 rel->r_type, junk);
2077 abort();
2078 }
2079
2080 #ifdef DEBUG_RELOC
2081 /* now examine flags */
2082 if (r_flags != 0)
2083 {
2084 fprintf (stderr, "Reloc with flags found!");
2085 if ( r_flags & IMAGE_REL_PPC_NEG )
2086 fprintf (stderr, " NEG");
2087 if ( r_flags & IMAGE_REL_PPC_BRTAKEN )
2088 fprintf (stderr, " BRTAKEN");
2089 if ( r_flags & IMAGE_REL_PPC_BRNTAKEN )
2090 fprintf (stderr, " BRNTAKEN");
2091 if ( r_flags & IMAGE_REL_PPC_TOCDEFN )
2092 fprintf (stderr, " TOCDEFN");
2093 fprintf(stderr, "\n");
2094 }
2095 #endif
2096
2097 switch(r_type)
2098 {
2099 case IMAGE_REL_PPC_ADDR32NB:
2100 DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel);
2101 *addendp -= pe_data(sec->output_section->owner)->pe_opthdr.ImageBase;
2102 break;
2103 case IMAGE_REL_PPC_ADDR16:
2104 case IMAGE_REL_PPC_REL24:
2105 case IMAGE_REL_PPC_ADDR24:
2106 case IMAGE_REL_PPC_TOCREL16:
2107 case IMAGE_REL_PPC_ADDR32:
2108 case IMAGE_REL_PPC_IFGLUE:
2109 case IMAGE_REL_PPC_SECTION:
2110 case IMAGE_REL_PPC_SECREL:
2111 DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel);
2112 break;
2113 case IMAGE_REL_PPC_IMGLUE:
2114 DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel);
2115 break;
2116 default:
2117 fprintf(stderr,
2118 "Warning: Unsupported reloc %s [%d] used -- it may not work.\n",
2119 ppc_coff_howto_table[r_type].name,
2120 r_type);
2121 break;
2122 }
2123
2124 howto = ppc_coff_howto_table + r_type;
2125 return howto;
2126 }
2127
2128
2129 /* a cheesy little macro to make the code a little more readable */
2130 #define HOW2MAP(bfd_rtype,ppc_rtype) \
2131 case bfd_rtype: return &ppc_coff_howto_table[ppc_rtype]
2132
2133 static reloc_howto_type *ppc_coff_reloc_type_lookup
2134 PARAMS ((bfd *, bfd_reloc_code_real_type));
2135
2136 static reloc_howto_type *
2137 ppc_coff_reloc_type_lookup (abfd, code)
2138 bfd *abfd;
2139 bfd_reloc_code_real_type code;
2140 {
2141
2142 #ifdef DEBUG_RELOC
2143 fprintf(stderr, "ppc_coff_reloc_type_lookup for %s\n",
2144 bfd_get_reloc_code_name(code));
2145 #endif
2146
2147 switch (code)
2148 {
2149 HOW2MAP(BFD_RELOC_16_GOT_PCREL, IMAGE_REL_PPC_IFGLUE);
2150 HOW2MAP(BFD_RELOC_16, IMAGE_REL_PPC_ADDR16);
2151 HOW2MAP(BFD_RELOC_PPC_B26, IMAGE_REL_PPC_REL24);
2152 HOW2MAP(BFD_RELOC_PPC_BA26, IMAGE_REL_PPC_ADDR24);
2153 HOW2MAP(BFD_RELOC_PPC_TOC16, IMAGE_REL_PPC_TOCREL16);
2154 HOW2MAP(BFD_RELOC_32, IMAGE_REL_PPC_ADDR32);
2155 HOW2MAP(BFD_RELOC_RVA, IMAGE_REL_PPC_ADDR32NB);
2156 default:
2157 fprintf(stderr,
2158 "\treturning NULL\n");
2159 return NULL;
2160 }
2161
2162 return NULL;
2163 }
2164
2165 #undef HOW2MAP
2166
2167 \f
2168 /* Tailor coffcode.h -- macro heaven. */
2169
2170 #define RTYPE2HOWTO(cache_ptr, dst) ppc_coff_rtype2howto (cache_ptr, dst)
2171
2172 #ifndef COFF_IMAGE_WITH_PE
2173 static void
2174 ppc_coff_swap_sym_in_hook ();
2175 #endif
2176
2177 /* We use the special COFF backend linker, with our own special touch. */
2178
2179 #define coff_bfd_reloc_type_lookup ppc_coff_reloc_type_lookup
2180 #define coff_rtype_to_howto coff_ppc_rtype_to_howto
2181 #define coff_relocate_section coff_ppc_relocate_section
2182
2183 #ifndef COFF_IMAGE_WITH_PE
2184 #define coff_swap_sym_in_hook ppc_coff_swap_sym_in_hook
2185 #endif
2186
2187 #define SELECT_RELOC(internal, howto) {internal.r_type=howto->type;}
2188
2189 #define COFF_PAGE_SIZE 0x1000
2190
2191 #define POWERPC_LE_PE
2192
2193 #include "coffcode.h"
2194
2195 \f
2196
2197 #ifndef COFF_IMAGE_WITH_PE
2198 static void
2199 ppc_coff_swap_sym_in_hook (abfd, ext1, in1)
2200 bfd *abfd;
2201 PTR ext1;
2202 PTR in1;
2203 {
2204 SYMENT *ext = (SYMENT *)ext1;
2205 struct internal_syment *in = (struct internal_syment *)in1;
2206
2207 #if 0
2208 if (bfd_of_toc_owner != 0) /* we already have a toc, so go home */
2209 return;
2210 #endif
2211
2212 if (strcmp(in->_n._n_name, ".toc") == 0)
2213 {
2214 flagword flags;
2215 register asection *s;
2216 char *foo;
2217
2218 s = bfd_get_section_by_name ( abfd , TOC_SECTION_NAME);
2219 if (s != NULL)
2220 {
2221 return;
2222 }
2223
2224 flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY ;
2225
2226 #ifdef TOC_DEBUG
2227 fprintf(stderr,
2228 "ppc_coff_swap_sym_in_hook: about to create the %s section\n",
2229 TOC_SECTION_NAME);
2230 #endif
2231
2232 s = bfd_make_section (abfd, TOC_SECTION_NAME);
2233
2234 if (s == NULL
2235 || !bfd_set_section_flags (abfd, s, flags)
2236 || !bfd_set_section_alignment (abfd, s, 2))
2237 {
2238 fprintf(stderr,
2239 "toc section allocation failed!\n");
2240 abort();
2241 }
2242
2243 /* save the bfd for later allocation */
2244 bfd_of_toc_owner = abfd;
2245 }
2246
2247 return;
2248 }
2249 #endif
2250
2251 \f
2252
2253 /* The transfer vectors that lead the outside world to all of the above. */
2254
2255 #ifdef TARGET_LITTLE_SYM
2256 const bfd_target
2257 TARGET_LITTLE_SYM =
2258 {
2259 TARGET_LITTLE_NAME, /* name or coff-arm-little */
2260 bfd_target_coff_flavour,
2261 false, /* data byte order is little */
2262 false, /* header byte order is little */
2263
2264 (HAS_RELOC | EXEC_P | /* FIXME: object flags */
2265 HAS_LINENO | HAS_DEBUG |
2266 HAS_SYMS | HAS_LOCALS | WP_TEXT),
2267
2268 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
2269 0, /* leading char */
2270 '/', /* ar_pad_char */
2271 15, /* ar_max_namelen??? FIXMEmgo */
2272
2273 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
2274 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
2275 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
2276
2277 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
2278 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
2279 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
2280
2281 {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
2282 bfd_generic_archive_p, /* _bfd_dummy_target */ coff_object_p },
2283 {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
2284 bfd_false},
2285 {bfd_false, coff_write_object_contents, /* bfd_write_contents */
2286 _bfd_write_archive_contents, bfd_false},
2287
2288 BFD_JUMP_TABLE_GENERIC (coff),
2289 BFD_JUMP_TABLE_COPY (coff),
2290 BFD_JUMP_TABLE_CORE (_bfd_nocore),
2291 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
2292 BFD_JUMP_TABLE_SYMBOLS (coff),
2293 BFD_JUMP_TABLE_RELOCS (coff),
2294 BFD_JUMP_TABLE_WRITE (coff),
2295 BFD_JUMP_TABLE_LINK (coff),
2296 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
2297
2298 COFF_SWAP_TABLE,
2299 };
2300 #endif
2301
2302 #ifdef TARGET_BIG_SYM
2303 const bfd_target
2304 TARGET_BIG_SYM =
2305 {
2306 TARGET_BIG_NAME,
2307 bfd_target_coff_flavour,
2308 true, /* data byte order is big */
2309 true, /* header byte order is big */
2310
2311 (HAS_RELOC | EXEC_P | /* FIXME: object flags */
2312 HAS_LINENO | HAS_DEBUG |
2313 HAS_SYMS | HAS_LOCALS | WP_TEXT),
2314
2315 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
2316 0, /* leading char */
2317 '/', /* ar_pad_char */
2318 15, /* ar_max_namelen??? FIXMEmgo */
2319
2320 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
2321 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
2322 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
2323
2324 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
2325 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
2326 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
2327
2328 {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
2329 bfd_generic_archive_p, /* _bfd_dummy_target */ coff_object_p },
2330 {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
2331 bfd_false},
2332 {bfd_false, coff_write_object_contents, /* bfd_write_contents */
2333 _bfd_write_archive_contents, bfd_false},
2334
2335 BFD_JUMP_TABLE_GENERIC (coff),
2336 BFD_JUMP_TABLE_COPY (coff),
2337 BFD_JUMP_TABLE_CORE (_bfd_nocore),
2338 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
2339 BFD_JUMP_TABLE_SYMBOLS (coff),
2340 BFD_JUMP_TABLE_RELOCS (coff),
2341 BFD_JUMP_TABLE_WRITE (coff),
2342 BFD_JUMP_TABLE_LINK (coff),
2343 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
2344
2345 COFF_SWAP_TABLE,
2346 };
2347
2348 #endif