Reloc fixes for PowerPC PE
[deliverable/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 #ifdef DEBUG_RELOC
708 #define UN_IMPL(x) \
709 { \
710 static int i; \
711 if (i == 0) \
712 { \
713 i = 1; \
714 fprintf(stderr,"Unimplemented Relocation -- %s\n",x); \
715 } \
716 }
717
718 #define DUMP_RELOC(n,r) \
719 { \
720 fprintf(stderr,"%s sym %d, addr %d, addend %d\n", \
721 n, (*(r->sym_ptr_ptr))->name, \
722 r->address, r->addend); \
723 }
724
725 /* Given a reloc name, n, and a pointer to an internal_reloc,
726 dump out interesting information on the contents
727
728 #define n_name _n._n_name
729 #define n_zeroes _n._n_n._n_zeroes
730 #define n_offset _n._n_n._n_offset
731
732 */
733
734 #define DUMP_RELOC2(n,r) \
735 { \
736 fprintf(stderr,"%s sym %d, r_vaddr %d %s\n", \
737 n, r->r_symndx, r->r_vaddr,\
738 (((r->r_type) & IMAGE_REL_PPC_TOCDEFN) == 0) \
739 ?" ":" TOCDEFN" ); \
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 /* FIXME: record a toc offset against a data-in-toc symbol */
904 /* Now, there is currenly some confusion on what this means. In some
905 compilers one sees the moral equivalent of:
906 .tocd
907 define some data
908 .text
909 refer to the data with a [tocv] qualifier
910 In general, one sees something to indicate that a tocd has been
911 seen, and that would trigger the allocation of data in toc. The IBM
912 docs seem to suggest that anything with the TOCDEFN qualifier should
913 never trigger storage allocation. However, in the kernel32.lib that
914 we've been using for our test bed, there are a couple of variables
915 referenced that fail that test.
916
917 So it can't work that way.
918 */
919 static int
920 ppc_record_data_in_toc_entry(abfd, info, sec, sym, toc_kind)
921 bfd *abfd;
922 struct bfd_link_info *info;
923 asection *sec;
924 int sym;
925 enum toc_type toc_kind;
926 {
927 bfd_byte *t;
928 bfd_byte *old_contents;
929 asection *s;
930 int element_size;
931 int data;
932 int offset;
933 struct ppc_coff_link_hash_entry *h = 0;
934 struct coff_symbol_struct *target;
935 int ret_val;
936 const char *name;
937
938 int *local_syms;
939
940 h = (struct ppc_coff_link_hash_entry *) (obj_coff_sym_hashes (abfd)[sym]);
941
942 if (h == 0)
943 {
944 local_syms = obj_coff_local_toc_table(abfd);
945 if (local_syms == 0)
946 {
947 int i;
948 /* allocate a table */
949 local_syms =
950 (int *) bfd_zalloc (abfd,
951 obj_raw_syment_count(abfd) * sizeof(int));
952 if (local_syms == 0)
953 {
954 bfd_set_error (bfd_error_no_memory);
955 return false;
956 }
957 obj_coff_local_toc_table(abfd) = local_syms;
958 for (i = 0; i < obj_raw_syment_count(abfd); ++i)
959 local_syms[i] = 1;
960 }
961
962 if (local_syms[sym] == 1)
963 {
964 local_syms[sym] = global_toc_size;
965 ret_val = global_toc_size;
966 global_toc_size += 4;
967 #ifdef TOC_DEBUG
968 fprintf(stderr,
969 "Setting data_in_toc_offset for local sym %d to %d\n",
970 sym, ret_val);
971 #endif
972 }
973 else
974 {
975 ret_val = local_syms[sym];
976 #ifdef TOC_DEBUG
977 fprintf(stderr,
978 "data_in_toc_offset already set for local sym %d to %d\n",
979 sym, ret_val);
980 #endif
981 }
982 }
983 else
984 {
985 CHECK_EYE(h->eye_catcher);
986
987 name = h->root.root.root.string;
988
989 /* check to see if there's a toc slot allocated. If not, do it
990 here. It will be used in relocate_section */
991 if (h->toc_offset == 1)
992 {
993 #if 0
994 h->toc_offset = global_toc_size;
995 #endif
996 ret_val = global_toc_size;
997 /* We're allocating a chunk of the toc, as opposed to a slot */
998 /* FIXME: alignment? */
999
1000 global_toc_size += 4;
1001 #ifdef TOC_DEBUG
1002 fprintf(stderr,
1003 "Setting data_in_toc_offset for sym %d (%s) [h=%p] to %d\n",
1004 sym, name, h, ret_val);
1005 #endif
1006 }
1007 else
1008 {
1009 ret_val = h->toc_offset;
1010 #ifdef TOC_DEBUG
1011 fprintf(stderr,
1012 "data_in_toc_offset already set for sym %d (%s) [h=%p] to %d\n",
1013 sym, name, h, ret_val);
1014 #endif
1015 }
1016 }
1017
1018 return ret_val;
1019 }
1020
1021 /* record a toc offset against a symbol */
1022 static void
1023 ppc_mark_symbol_as_glue(abfd, sym, rel)
1024 bfd *abfd;
1025 int sym;
1026 struct internal_reloc *rel;
1027 {
1028 struct ppc_coff_link_hash_entry *h;
1029
1030 h = (struct ppc_coff_link_hash_entry *) (obj_coff_sym_hashes (abfd)[sym]);
1031
1032 CHECK_EYE(h->eye_catcher);
1033
1034 h->symbol_is_glue = 1;
1035 h->glue_insn = bfd_get_32 (abfd, (bfd_byte *) &rel->r_vaddr);
1036
1037 return;
1038 }
1039
1040 \f
1041 /* Provided the symbol, returns the value reffed */
1042 static long get_symbol_value PARAMS ((asymbol *));
1043
1044 static long
1045 get_symbol_value (symbol)
1046 asymbol *symbol;
1047 {
1048 long relocation = 0;
1049
1050 if (bfd_is_com_section (symbol->section))
1051 {
1052 relocation = 0;
1053 }
1054 else
1055 {
1056 relocation = symbol->value +
1057 symbol->section->output_section->vma +
1058 symbol->section->output_offset;
1059 }
1060
1061 return(relocation);
1062 }
1063
1064 /* Return true if this relocation should
1065 appear in the output .reloc section. */
1066
1067 static boolean in_reloc_p(abfd, howto)
1068 bfd * abfd;
1069 reloc_howto_type *howto;
1070 {
1071 return
1072 (! howto->pc_relative)
1073 && (howto->type != IMAGE_REL_PPC_TOCREL16)
1074 && (howto->type != IMAGE_REL_PPC_IMGLUE);
1075 }
1076
1077 /* this function is in charge of performing all the ppc PE relocations */
1078 /* Don't yet know if we want to do this this particular way ... (krk) */
1079 /* FIXME: (it is not yet enabled) */
1080
1081 static bfd_reloc_status_type
1082 pe_ppc_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd,
1083 error_message)
1084 bfd *abfd;
1085 arelent *reloc_entry;
1086 asymbol *symbol_in;
1087 PTR data;
1088 asection *input_section;
1089 bfd *output_bfd;
1090 char **error_message;
1091 {
1092 /* the consth relocation comes in two parts, we have to remember
1093 the state between calls, in these variables */
1094 static boolean part1_consth_active = false;
1095 static unsigned long part1_consth_value;
1096
1097 unsigned long insn;
1098 unsigned long sym_value;
1099 unsigned long unsigned_value;
1100 unsigned short r_type;
1101 long signed_value;
1102
1103 unsigned long addr = reloc_entry->address ; /*+ input_section->vma*/
1104 bfd_byte *hit_data =addr + (bfd_byte *)(data);
1105
1106 fprintf(stderr, "pe_ppc_reloc (%s)\n", TARGET_LITTLE_NAME);
1107
1108 r_type = reloc_entry->howto->type;
1109
1110 if (output_bfd)
1111 {
1112 /* Partial linking - do nothing */
1113 reloc_entry->address += input_section->output_offset;
1114 return bfd_reloc_ok;
1115 }
1116
1117 if (symbol_in != NULL
1118 && bfd_is_und_section (symbol_in->section))
1119 {
1120 /* Keep the state machine happy in case we're called again */
1121 if (r_type == IMAGE_REL_PPC_REFHI)
1122 {
1123 part1_consth_active = true;
1124 part1_consth_value = 0;
1125 }
1126 return(bfd_reloc_undefined);
1127 }
1128
1129 if ((part1_consth_active) && (r_type != IMAGE_REL_PPC_PAIR))
1130 {
1131 part1_consth_active = false;
1132 *error_message = (char *) "Missing PAIR";
1133 return(bfd_reloc_dangerous);
1134 }
1135
1136
1137 sym_value = get_symbol_value(symbol_in);
1138
1139 return(bfd_reloc_ok);
1140 }
1141
1142 /* The reloc processing routine for the optimized COFF linker. */
1143
1144 static boolean
1145 coff_ppc_relocate_section (output_bfd, info, input_bfd, input_section,
1146 contents, relocs, syms, sections)
1147 bfd *output_bfd;
1148 struct bfd_link_info *info;
1149 bfd *input_bfd;
1150 asection *input_section;
1151 bfd_byte *contents;
1152 struct internal_reloc *relocs;
1153 struct internal_syment *syms;
1154 asection **sections;
1155 {
1156 struct internal_reloc *rel;
1157 struct internal_reloc *relend;
1158 boolean hihalf;
1159 bfd_vma hihalf_val;
1160 asection *toc_section = 0;
1161 bfd_vma relocation;
1162 reloc_howto_type *howto = 0;
1163
1164 #ifdef DEBUG_RELOC
1165 fprintf(stderr,
1166 "pe_ppc_relocate_section (%s) for %s \n",
1167 TARGET_LITTLE_NAME,
1168 input_section->name);
1169
1170 #endif
1171
1172 /* If we are performing a relocateable link, we don't need to do a
1173 thing. The caller will take care of adjusting the reloc
1174 addresses and symbol indices. */
1175 if (info->relocateable)
1176 return true;
1177
1178 hihalf = false;
1179 hihalf_val = 0;
1180
1181 rel = relocs;
1182 relend = rel + input_section->reloc_count;
1183 for (; rel < relend; rel++)
1184 {
1185 long symndx;
1186 struct ppc_coff_link_hash_entry *h;
1187 struct internal_syment *sym;
1188 bfd_vma val;
1189
1190 asection *sec;
1191 bfd_reloc_status_type rstat;
1192 bfd_byte *loc;
1193
1194 unsigned short r_type = EXTRACT_TYPE (rel->r_type);
1195 unsigned short r_flags = EXTRACT_FLAGS(rel->r_type);
1196 unsigned short junk = EXTRACT_JUNK (rel->r_type);
1197
1198 #ifdef DEBUG_RELOC
1199 /* now examine flags */
1200 if (r_flags != 0)
1201 {
1202 fprintf (stderr, "Reloc with flags found!");
1203 if ( r_flags & IMAGE_REL_PPC_NEG )
1204 fprintf (stderr, " NEG");
1205 if ( r_flags & IMAGE_REL_PPC_BRTAKEN )
1206 fprintf (stderr, " BRTAKEN");
1207 if ( r_flags & IMAGE_REL_PPC_BRNTAKEN )
1208 fprintf (stderr, " BRNTAKEN");
1209 if ( r_flags & IMAGE_REL_PPC_TOCDEFN )
1210 fprintf (stderr, " TOCDEFN");
1211 fprintf(stderr, "\n");
1212 }
1213 #endif
1214
1215 symndx = rel->r_symndx;
1216 loc = contents + rel->r_vaddr - input_section->vma;
1217
1218 /* FIXME: check bounds on r_type */
1219 howto = ppc_coff_howto_table + r_type;
1220
1221 if (symndx == -1)
1222 {
1223 h = NULL;
1224 sym = NULL;
1225 }
1226 else
1227 {
1228 h = (struct ppc_coff_link_hash_entry *)
1229 (obj_coff_sym_hashes (input_bfd)[symndx]);
1230 if (h != 0)
1231 {
1232 CHECK_EYE(h->eye_catcher);
1233 }
1234
1235 sym = syms + symndx;
1236 }
1237
1238 sec = NULL;
1239 val = 0;
1240
1241 /* FIXME: PAIR unsupported in the following code */
1242 if (h == NULL)
1243 {
1244 if (symndx == -1)
1245 sec = bfd_abs_section_ptr;
1246 else
1247 {
1248 sec = sections[symndx];
1249 val = (sec->output_section->vma
1250 + sec->output_offset
1251 + sym->n_value
1252 - sec->vma);
1253 }
1254 }
1255 else
1256 {
1257 CHECK_EYE(h->eye_catcher);
1258
1259 if (h->root.root.type == bfd_link_hash_defined
1260 || h->root.root.type == bfd_link_hash_defweak)
1261 {
1262 sec = h->root.root.u.def.section;
1263 val = (h->root.root.u.def.value
1264 + sec->output_section->vma
1265 + sec->output_offset);
1266 }
1267 else
1268 {
1269 if (! ((*info->callbacks->undefined_symbol)
1270 (info, h->root.root.root.string, input_bfd, input_section,
1271 rel->r_vaddr - input_section->vma)))
1272 return false;
1273 }
1274 }
1275
1276 rstat = bfd_reloc_ok;
1277
1278 /* Each case must do its own relocation, setting rstat appropriately */
1279 switch (r_type)
1280 {
1281 default:
1282 fprintf( stderr,
1283 "ERROR: during reloc processing -- unsupported reloc %s\n",
1284 howto->name);
1285 bfd_set_error (bfd_error_bad_value);
1286 abort();
1287 return false;
1288 case IMAGE_REL_PPC_TOCREL16:
1289 {
1290 bfd_vma our_toc_offset;
1291 int fixit;
1292
1293 DUMP_RELOC2(howto->name, rel);
1294
1295 if (toc_section == 0)
1296 {
1297 toc_section = bfd_get_section_by_name (bfd_of_toc_owner,
1298 TOC_SECTION_NAME);
1299 #ifdef TOC_DEBUG
1300
1301 fprintf(stderr,
1302 "BFD of toc owner %p, section addr of %s %p\n",
1303 bfd_of_toc_owner, TOC_SECTION_NAME, toc_section);
1304 #endif
1305
1306 if ( toc_section == NULL )
1307 {
1308 fprintf(stderr, "No Toc section!\n");
1309 abort();
1310 }
1311 }
1312
1313 /*
1314 * Amazing bit tricks present. As we may have seen earlier, we
1315 * use the 1 bit to tell us whether or not a toc offset has been
1316 * allocated. Now that they've all been allocated, we will use
1317 * the 1 bit to tell us if we've written this particular toc
1318 * entry out.
1319 */
1320 fixit = false;
1321 if (h == 0)
1322 { /* it is a file local symbol */
1323 int *local_toc_table;
1324 const char *name;
1325
1326 sym = syms + symndx;
1327 name = sym->_n._n_name;
1328
1329 local_toc_table = obj_coff_local_toc_table(input_bfd);
1330 our_toc_offset = local_toc_table[symndx];
1331
1332 if ((our_toc_offset & 1) != 0)
1333 {
1334 /* if it has been written out, it is marked with the
1335 1 bit. Fix up our offset, but do not write it out
1336 again.
1337 */
1338 our_toc_offset &= ~1;
1339 #ifdef TOC_DEBUG
1340
1341 fprintf(stderr,
1342 "Not writing out toc_offset of %d for %s\n", our_toc_offset, name);
1343 #endif
1344 }
1345 else
1346 {
1347 /* write out the toc entry */
1348 record_toc(toc_section, our_toc_offset, strdup(name));
1349 #ifdef TOC_DEBUG
1350 fprintf(stderr,
1351 "Writing out toc_offset toc_section (%p,%p)+%d val %d for %s\n",
1352 toc_section,
1353 toc_section->contents,
1354 our_toc_offset,
1355 val,
1356 name);
1357 #endif
1358
1359 bfd_put_32(output_bfd,
1360 val,
1361 toc_section->contents + our_toc_offset);
1362
1363 local_toc_table[symndx] |= 1;
1364 fixit = true;
1365 }
1366 }
1367 else
1368 {
1369 const char *name = h->root.root.root.string;
1370 our_toc_offset = h->toc_offset;
1371
1372 if ( (r_flags & IMAGE_REL_PPC_TOCDEFN) == IMAGE_REL_PPC_TOCDEFN &&
1373 our_toc_offset == 1)
1374 {
1375 /* This is unbelievable cheese. Some knowledgable asm hacker has decided to
1376 use r2 as a base for loading a value. He/She does this by setting the
1377 tocdefn bit, and not supplying a toc definition. The behaviour is then
1378 to use the value of the symbol as a toc index. Good Grief.
1379 */
1380 our_toc_offset = val - (toc_section->output_section->vma + toc_section->output_offset);
1381 }
1382 else if ((our_toc_offset & 1) != 0)
1383 {
1384 /* if it has been written out, it is marked with the
1385 1 bit. Fix up our offset, but do not write it out
1386 again.
1387 */
1388 our_toc_offset &= ~1;
1389 #ifdef TOC_DEBUG
1390 fprintf(stderr,
1391 "Not writing out toc_offset of %d for %s\n", our_toc_offset, name);
1392 #endif
1393 }
1394 else
1395 {
1396 record_toc(toc_section, our_toc_offset, strdup(name));
1397
1398 #ifdef TOC_DEBUG
1399 /* write out the toc entry */
1400 fprintf(stderr,
1401 "Writing out toc_offset toc_section (%p,%p)+%d val %d for %s\n",
1402 toc_section,
1403 toc_section->contents,
1404 our_toc_offset,
1405 val,
1406 name);
1407 #endif
1408
1409 /* write out the toc entry */
1410 bfd_put_32(output_bfd,
1411 val,
1412 toc_section->contents + our_toc_offset);
1413
1414 h->toc_offset |= 1;
1415 /* The tricky part is that this is the address that */
1416 /* needs a .reloc entry for it */
1417 fixit = true;
1418 }
1419 }
1420
1421 if (fixit && info->base_file)
1422 {
1423 /* So if this is non pcrelative, and is referenced
1424 to a section or a common symbol, then it needs a reloc */
1425
1426 /* relocation to a symbol in a section which
1427 isn't absolute - we output the address here
1428 to a file */
1429
1430 bfd_vma addr = toc_section->output_section->vma
1431 + toc_section->output_offset + our_toc_offset;
1432
1433 fprintf(stderr,
1434 " Toc Section reloc candidate\n");
1435
1436 if (coff_data(output_bfd)->pe)
1437 addr -= pe_data(output_bfd)->pe_opthdr.ImageBase;
1438 fwrite (&addr, 1,4, (FILE *) info->base_file);
1439 }
1440
1441
1442 /* FIXME: this test is conservative */
1443 if ( (r_flags & IMAGE_REL_PPC_TOCDEFN) != IMAGE_REL_PPC_TOCDEFN &&
1444 our_toc_offset > toc_section->_raw_size)
1445 {
1446 fprintf(stderr,
1447 "reloc offset is bigger than the toc size!\n");
1448 abort();
1449 }
1450
1451 /* Now we know the relocation for this toc reference */
1452 relocation = our_toc_offset + TOC_LOAD_ADJUSTMENT;
1453 rstat = _bfd_relocate_contents (howto,
1454 input_bfd,
1455 relocation,
1456 loc);
1457 }
1458 break;
1459 case IMAGE_REL_PPC_IFGLUE:
1460 {
1461 /* To solve this, we need to know whether or not the symbol */
1462 /* appearing on the call instruction is a glue function or not. */
1463 /* A glue function must announce itself via a IMGLUE reloc, and */
1464 /* the reloc contains the required toc restore instruction */
1465
1466 bfd_vma x;
1467 const char *my_name;
1468 DUMP_RELOC2(howto->name, rel);
1469
1470 if (h != 0)
1471 {
1472 my_name = h->root.root.root.string;
1473 if (h->symbol_is_glue == 1)
1474 {
1475 x = bfd_get_32(input_bfd, loc);
1476 bfd_put_32(input_bfd, h->glue_insn, loc);
1477 }
1478 }
1479 }
1480 break;
1481 case IMAGE_REL_PPC_SECREL:
1482 /* Unimplemented: codeview debugging information */
1483 /* For fast access to the header of the section
1484 containing the item. */
1485 break;
1486 case IMAGE_REL_PPC_SECTION:
1487 /* Unimplemented: codeview debugging information */
1488 /* Is used to indicate that the value should be relative
1489 to the beginning of the section that contains the
1490 symbol */
1491 break;
1492 case IMAGE_REL_PPC_ABSOLUTE:
1493 {
1494 const char *my_name;
1495 if (h == 0)
1496 my_name = (syms+symndx)->_n._n_name;
1497 else
1498 {
1499 my_name = h->root.root.root.string;
1500 }
1501
1502 fprintf(stderr,
1503 "Warning: unsupported reloc %s <file %s, section %s>\n",
1504 howto->name,
1505 bfd_get_filename(input_bfd),
1506 input_section->name);
1507
1508 fprintf(stderr,"sym %d (%s), r_vaddr %d (%x)\n",
1509 rel->r_symndx, my_name, rel->r_vaddr, rel->r_vaddr);
1510 }
1511 break;
1512 case IMAGE_REL_PPC_IMGLUE:
1513 {
1514 /* There is nothing to do now. This reloc was noted in the first
1515 pass over the relocs, and the glue instruction extracted */
1516 const char *my_name;
1517 if (h->symbol_is_glue == 1)
1518 break;
1519 my_name = h->root.root.root.string;
1520 fprintf(stderr,
1521 "Warning: previously missed IMGLUE reloc %s <file %s, section %s>\n",
1522 howto->name,
1523 bfd_get_filename(input_bfd),
1524 input_section->name);
1525 break;
1526
1527 }
1528 break;
1529
1530 case IMAGE_REL_PPC_ADDR32NB:
1531 {
1532 struct coff_link_hash_entry *myh = 0;
1533 const char *name = 0;
1534 DUMP_RELOC2(howto->name, rel);
1535 if (h == 0)
1536 { /* it is a file local symbol */
1537 sym = syms + symndx;
1538 name = sym->_n._n_name;
1539 }
1540 else
1541 {
1542 char *target = 0;
1543
1544 name = h->root.root.root.string;
1545 if (strcmp(".idata$2", name) == 0)
1546 target = "__idata2_magic__";
1547 else if (strcmp(".idata$4", name) == 0)
1548 target = "__idata4_magic__";
1549 else if (strcmp(".idata$5", name) == 0)
1550 target = "__idata5_magic__";
1551 else
1552 abort();
1553
1554 myh = 0;
1555
1556 myh = coff_link_hash_lookup (coff_hash_table (info),
1557 target,
1558 false, false, true);
1559 if (myh == 0)
1560 {
1561 fprintf(stderr, "Missing idata magic cookies, this cannot work anyway...\n");
1562 abort();
1563 }
1564
1565 val = myh->root.u.def.value +
1566 sec->output_section->vma + sec->output_offset;
1567 if (first_thunk_address == 0)
1568 {
1569 int idata5offset;
1570 myh = coff_link_hash_lookup (coff_hash_table (info),
1571 "__idata5_magic__",
1572 false, false, true);
1573 first_thunk_address = myh->root.u.def.value +
1574 sec->output_section->vma +
1575 sec->output_offset -
1576 pe_data(output_bfd)->pe_opthdr.ImageBase;
1577
1578 idata5offset = myh->root.u.def.value;
1579 myh = coff_link_hash_lookup (coff_hash_table (info),
1580 "__idata6_magic__",
1581 false, false, true);
1582
1583 thunk_size = myh->root.u.def.value - idata5offset;
1584 myh = coff_link_hash_lookup (coff_hash_table (info),
1585 "__idata4_magic__",
1586 false, false, true);
1587 import_table_size = myh->root.u.def.value;
1588 }
1589 }
1590
1591 rstat = _bfd_relocate_contents (howto,
1592 input_bfd,
1593 val -
1594 pe_data(output_bfd)->pe_opthdr.ImageBase,
1595 loc);
1596 }
1597 break;
1598
1599 case IMAGE_REL_PPC_REL24:
1600 DUMP_RELOC2(howto->name, rel);
1601 val -= (input_section->output_section->vma
1602 + input_section->output_offset);
1603
1604 rstat = _bfd_relocate_contents (howto,
1605 input_bfd,
1606 val,
1607 loc);
1608 break;
1609 case IMAGE_REL_PPC_ADDR16:
1610 case IMAGE_REL_PPC_ADDR24:
1611 case IMAGE_REL_PPC_ADDR32:
1612 DUMP_RELOC2(howto->name, rel);
1613 rstat = _bfd_relocate_contents (howto,
1614 input_bfd,
1615 val,
1616 loc);
1617 break;
1618 }
1619
1620 if ( info->base_file )
1621 {
1622 /* So if this is non pcrelative, and is referenced
1623 to a section or a common symbol, then it needs a reloc */
1624 if (sym && pe_data(output_bfd)->in_reloc_p(output_bfd, howto))
1625 {
1626 /* relocation to a symbol in a section which
1627 isn't absolute - we output the address here
1628 to a file */
1629 bfd_vma addr = rel->r_vaddr
1630 - input_section->vma
1631 + input_section->output_offset
1632 + input_section->output_section->vma;
1633
1634 if (coff_data(output_bfd)->pe)
1635 {
1636 addr -= pe_data(output_bfd)->pe_opthdr.ImageBase;
1637 fprintf(stderr,
1638 " adjusted down to %d", addr);
1639 }
1640 fprintf(stderr, "\n");
1641
1642 fwrite (&addr, 1,4, (FILE *) info->base_file);
1643 }
1644 }
1645
1646 switch (rstat)
1647 {
1648 default:
1649 abort ();
1650 case bfd_reloc_ok:
1651 break;
1652 case bfd_reloc_overflow:
1653 {
1654 const char *name;
1655 char buf[SYMNMLEN + 1];
1656
1657 if (symndx == -1)
1658 name = "*ABS*";
1659 else if (h != NULL)
1660 name = h->root.root.root.string;
1661 else if (sym == NULL)
1662 name = "*unknown*";
1663 else if (sym->_n._n_n._n_zeroes == 0
1664 && sym->_n._n_n._n_offset != 0)
1665 name = obj_coff_strings (input_bfd) + sym->_n._n_n._n_offset;
1666 else
1667 {
1668 strncpy (buf, sym->_n._n_name, SYMNMLEN);
1669 buf[SYMNMLEN] = '\0';
1670 name = buf;
1671 }
1672 #if 0
1673 else
1674 {
1675 name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
1676 if (name == NULL)
1677 return false;
1678 }
1679 #endif
1680
1681 if (! ((*info->callbacks->reloc_overflow)
1682 (info, name, howto->name,
1683 (bfd_vma) 0, input_bfd,
1684 input_section, rel->r_vaddr - input_section->vma)))
1685 return false;
1686 }
1687 }
1688
1689 }
1690
1691 return true;
1692 }
1693
1694 #ifdef COFF_IMAGE_WITH_PE
1695
1696 long int global_toc_size = 0;
1697
1698 bfd* bfd_of_toc_owner = 0;
1699
1700 long int import_table_size;
1701 long int first_thunk_address;
1702 long int thunk_size;
1703
1704 struct list_ele *head;
1705 struct list_ele *tail;
1706
1707 void
1708 dump_toc(vfile)
1709 void *vfile;
1710 {
1711 FILE *file = vfile;
1712 struct list_ele *t;
1713
1714 fprintf(file,
1715 " Offset Offset Name if present\n");
1716
1717 for(t = head; t != 0; t=t->next)
1718 {
1719 fprintf(file,
1720 " %2x %04lx %s\n",
1721 t->offset - 32768, t->offset, t->name);
1722 }
1723 }
1724
1725 boolean
1726 ppc_allocate_toc_section (info)
1727 struct bfd_link_info *info;
1728 {
1729 asection *s;
1730 bfd_byte *foo;
1731 static char test_char = '1';
1732
1733 if ( global_toc_size == 0 ) /* FIXME: does this get me in trouble? */
1734 return true;
1735
1736 if (bfd_of_toc_owner == 0)
1737 {
1738 fprintf(stderr,
1739 "There is no bfd that owns the toc section!\n");
1740 abort();
1741 }
1742
1743 s = bfd_get_section_by_name ( bfd_of_toc_owner , TOC_SECTION_NAME);
1744 if (s == NULL)
1745 {
1746 fprintf(stderr, "No Toc section!\n");
1747 abort();
1748 }
1749
1750 foo = bfd_alloc(bfd_of_toc_owner, global_toc_size);
1751 memset(foo, test_char, global_toc_size);
1752
1753 s->_raw_size = s->_cooked_size = global_toc_size;
1754 s->contents = foo;
1755
1756 return true;
1757 }
1758
1759 boolean
1760 ppc_process_before_allocation (abfd, info)
1761 bfd *abfd;
1762 struct bfd_link_info *info;
1763 {
1764 asection *sec;
1765 struct internal_reloc *i, *rel;
1766
1767 #if 0
1768 fprintf(stderr,
1769 "ppc_process_before_allocation: BFD %s\n",
1770 bfd_get_filename(abfd));
1771 #endif
1772
1773 /* here we have a bfd that is to be included on the link. We have a hook
1774 to do reloc rummaging, before section sizes are nailed down. */
1775
1776 _bfd_coff_get_external_symbols(abfd);
1777
1778 /* rummage around all the relocs and map the toc */
1779 sec = abfd->sections;
1780
1781 if (sec == 0)
1782 {
1783 return true;
1784 }
1785
1786 for (; sec != 0; sec = sec->next)
1787 {
1788 int toc_offset;
1789 #ifdef DEBUG_RELOC
1790 fprintf(stderr,
1791 " section %s reloc count %d\n",
1792 sec->name,
1793 sec->reloc_count);
1794 #endif
1795
1796 if (sec->reloc_count == 0)
1797 continue;
1798
1799 /* load the relocs */
1800 /* FIXME: there may be a storage leak here */
1801 i=_bfd_coff_read_internal_relocs(abfd,sec,1,0,0,0);
1802
1803 if (i == 0)
1804 abort();
1805
1806 for (rel=i;rel<i+sec->reloc_count;++rel)
1807 {
1808 unsigned short r_type = EXTRACT_TYPE (rel->r_type);
1809 unsigned short r_flags = EXTRACT_FLAGS(rel->r_type);
1810 unsigned short junk = EXTRACT_JUNK (rel->r_type);
1811
1812 #ifdef DEBUG_RELOC
1813 /* now examine flags */
1814 if (r_flags != 0)
1815 {
1816 fprintf (stderr, "Reloc with flags found!");
1817 if ( r_flags & IMAGE_REL_PPC_NEG )
1818 fprintf (stderr, " NEG");
1819 if ( r_flags & IMAGE_REL_PPC_BRTAKEN )
1820 fprintf (stderr, " BRTAKEN");
1821 if ( r_flags & IMAGE_REL_PPC_BRNTAKEN )
1822 fprintf (stderr, " BRNTAKEN");
1823 if ( r_flags & IMAGE_REL_PPC_TOCDEFN )
1824 fprintf (stderr, " TOCDEFN");
1825 fprintf(stderr, "\n");
1826 }
1827 #endif
1828
1829 DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel);
1830
1831 switch(r_type)
1832 {
1833 case IMAGE_REL_PPC_TOCREL16:
1834 if ( r_flags & IMAGE_REL_PPC_TOCDEFN )
1835 toc_offset = ppc_record_data_in_toc_entry(abfd, info, sec,
1836 rel->r_symndx,
1837 default_toc);
1838 else
1839 toc_offset = ppc_record_toc_entry(abfd, info, sec,
1840 rel->r_symndx, default_toc);
1841 break;
1842 case IMAGE_REL_PPC_IMGLUE:
1843 ppc_mark_symbol_as_glue(abfd, rel->r_symndx, rel);
1844 break;
1845 default:
1846 break;
1847 }
1848 }
1849 }
1850 }
1851
1852 #endif
1853
1854
1855 static bfd_reloc_status_type
1856 ppc_refhi_reloc (abfd,
1857 reloc_entry,
1858 symbol,
1859 data,
1860 input_section,
1861 output_bfd,
1862 error_message)
1863 bfd *abfd;
1864 arelent *reloc_entry;
1865 asymbol *symbol;
1866 PTR data;
1867 asection *input_section;
1868 bfd *output_bfd;
1869 char **error_message;
1870 {
1871 UN_IMPL("REFHI");
1872 DUMP_RELOC("REFHI",reloc_entry);
1873
1874 if (output_bfd == (bfd *) NULL)
1875 return bfd_reloc_continue;
1876
1877 return bfd_reloc_undefined;
1878 }
1879
1880 static bfd_reloc_status_type
1881 ppc_reflo_reloc (abfd,
1882 reloc_entry,
1883 symbol,
1884 data,
1885 input_section,
1886 output_bfd,
1887 error_message)
1888 bfd *abfd;
1889 arelent *reloc_entry;
1890 asymbol *symbol;
1891 PTR data;
1892 asection *input_section;
1893 bfd *output_bfd;
1894 char **error_message;
1895 {
1896 UN_IMPL("REFLO");
1897 DUMP_RELOC("REFLO",reloc_entry);
1898
1899 if (output_bfd == (bfd *) NULL)
1900 return bfd_reloc_continue;
1901
1902 return bfd_reloc_undefined;
1903 }
1904
1905 static bfd_reloc_status_type
1906 ppc_pair_reloc (abfd,
1907 reloc_entry,
1908 symbol,
1909 data,
1910 input_section,
1911 output_bfd,
1912 error_message)
1913 bfd *abfd;
1914 arelent *reloc_entry;
1915 asymbol *symbol;
1916 PTR data;
1917 asection *input_section;
1918 bfd *output_bfd;
1919 char **error_message;
1920 {
1921 UN_IMPL("PAIR");
1922 DUMP_RELOC("PAIR",reloc_entry);
1923
1924 if (output_bfd == (bfd *) NULL)
1925 return bfd_reloc_continue;
1926
1927 return bfd_reloc_undefined;
1928 }
1929
1930 \f
1931 static bfd_reloc_status_type
1932 ppc_toc16_reloc (abfd,
1933 reloc_entry,
1934 symbol,
1935 data,
1936 input_section,
1937 output_bfd,
1938 error_message)
1939 bfd *abfd;
1940 arelent *reloc_entry;
1941 asymbol *symbol;
1942 PTR data;
1943 asection *input_section;
1944 bfd *output_bfd;
1945 char **error_message;
1946 {
1947 UN_IMPL("TOCREL16");
1948 DUMP_RELOC("TOCREL16",reloc_entry);
1949
1950 if (output_bfd == (bfd *) NULL)
1951 {
1952 return bfd_reloc_continue;
1953 }
1954
1955 return bfd_reloc_ok;
1956 }
1957
1958 /* ADDR32NB : 32 bit address relative to the virtual origin. */
1959 /* (On the alpha, this is always a linker generated thunk)*/
1960 /* (i.e. 32bit addr relative to the image base) */
1961 /* */
1962 /* */
1963
1964 static bfd_reloc_status_type
1965 ppc_addr32nb_reloc (abfd,
1966 reloc_entry,
1967 symbol,
1968 data,
1969 input_section,
1970 output_bfd,
1971 error_message)
1972 bfd *abfd;
1973 arelent *reloc_entry;
1974 asymbol *symbol;
1975 PTR data;
1976 asection *input_section;
1977 bfd *output_bfd;
1978 char **error_message;
1979 {
1980 UN_IMPL("ADDR32NB");
1981 DUMP_RELOC("ADDR32NB",reloc_entry);
1982
1983 return bfd_reloc_ok;
1984 }
1985
1986 static bfd_reloc_status_type
1987 ppc_secrel_reloc (abfd,
1988 reloc_entry,
1989 symbol,
1990 data,
1991 input_section,
1992 output_bfd,
1993 error_message)
1994 bfd *abfd;
1995 arelent *reloc_entry;
1996 asymbol *symbol;
1997 PTR data;
1998 asection *input_section;
1999 bfd *output_bfd;
2000 char **error_message;
2001 {
2002 UN_IMPL("SECREL");
2003 DUMP_RELOC("SECREL",reloc_entry);
2004
2005 if (output_bfd == (bfd *) NULL)
2006 return bfd_reloc_continue;
2007
2008 return bfd_reloc_ok;
2009 }
2010
2011 static bfd_reloc_status_type
2012 ppc_section_reloc (abfd,
2013 reloc_entry,
2014 symbol,
2015 data,
2016 input_section,
2017 output_bfd,
2018 error_message)
2019 bfd *abfd;
2020 arelent *reloc_entry;
2021 asymbol *symbol;
2022 PTR data;
2023 asection *input_section;
2024 bfd *output_bfd;
2025 char **error_message;
2026 {
2027 UN_IMPL("SECTION");
2028 DUMP_RELOC("SECTION",reloc_entry);
2029
2030 if (output_bfd == (bfd *) NULL)
2031 return bfd_reloc_continue;
2032
2033 return bfd_reloc_ok;
2034 }
2035
2036 static bfd_reloc_status_type
2037 ppc_imglue_reloc (abfd,
2038 reloc_entry,
2039 symbol,
2040 data,
2041 input_section,
2042 output_bfd,
2043 error_message)
2044 bfd *abfd;
2045 arelent *reloc_entry;
2046 asymbol *symbol;
2047 PTR data;
2048 asection *input_section;
2049 bfd *output_bfd;
2050 char **error_message;
2051 {
2052 UN_IMPL("IMGLUE");
2053 DUMP_RELOC("IMGLUE",reloc_entry);
2054
2055 if (output_bfd == (bfd *) NULL)
2056 return bfd_reloc_continue;
2057
2058 return bfd_reloc_ok;
2059 }
2060
2061 \f
2062
2063 #define MAX_RELOC_INDEX \
2064 (sizeof(ppc_coff_howto_table) / sizeof(ppc_coff_howto_table[0]) - 1)
2065
2066
2067 /* FIXME: There is a possiblity that when we read in a reloc from a file,
2068 that there are some bits encoded in the upper portion of the
2069 type field. Not yet implemented.
2070 */
2071 static void ppc_coff_rtype2howto PARAMS ((arelent *relent,
2072 struct internal_reloc *internal));
2073
2074 static void
2075 ppc_coff_rtype2howto (relent, internal)
2076 arelent *relent;
2077 struct internal_reloc *internal;
2078 {
2079
2080 /* We can encode one of three things in the type field, aside from the
2081 type:
2082 1. IMAGE_REL_PPC_NEG - indicates the value field is a subtraction
2083 value, rather than an addition value
2084 2. IMAGE_REL_PPC_BRTAKEN, IMAGE_REL_PPC_BRNTAKEN - indicates that
2085 the branch is expected to be taken or not.
2086 3. IMAGE_REL_PPC_TOCDEFN - toc slot definition in the file
2087 For now, we just strip this stuff to find the type, and ignore it other
2088 than that.
2089 */
2090
2091 unsigned short r_type = EXTRACT_TYPE (internal->r_type);
2092 unsigned short r_flags = EXTRACT_FLAGS(internal->r_type);
2093 unsigned short junk = EXTRACT_JUNK (internal->r_type);
2094
2095 /* the masking process only slices off the bottom byte for r_type. */
2096 if ( r_type > MAX_RELOC_INDEX )
2097 {
2098 fprintf(stderr,
2099 "ppc_coff_rtype2howto: reloc index %d out of range [%d, %d]\n",
2100 internal->r_type, 0, MAX_RELOC_INDEX);
2101 abort();
2102 }
2103
2104 /* check for absolute crap */
2105 if ( junk != 0 )
2106 {
2107 fprintf(stderr,
2108 "ppc_coff_rtype2howto: reloc index %d contains junk %d\n",
2109 internal->r_type, junk);
2110 abort();
2111 }
2112
2113 #ifdef DEBUG_RELOC
2114 /* now examine flags */
2115 if (r_flags != 0)
2116 {
2117 fprintf (stderr, "Reloc with flags found!");
2118 if ( r_flags & IMAGE_REL_PPC_NEG )
2119 fprintf (stderr, " NEG");
2120 if ( r_flags & IMAGE_REL_PPC_BRTAKEN )
2121 fprintf (stderr, " BRTAKEN");
2122 if ( r_flags & IMAGE_REL_PPC_BRNTAKEN )
2123 fprintf (stderr, " BRNTAKEN");
2124 if ( r_flags & IMAGE_REL_PPC_TOCDEFN )
2125 fprintf (stderr, " TOCDEFN");
2126 fprintf(stderr, "\n");
2127 }
2128 #endif
2129
2130 switch(r_type)
2131 {
2132 case IMAGE_REL_PPC_ADDR16:
2133 case IMAGE_REL_PPC_REL24:
2134 case IMAGE_REL_PPC_ADDR24:
2135 case IMAGE_REL_PPC_TOCREL16:
2136 case IMAGE_REL_PPC_ADDR32:
2137 case IMAGE_REL_PPC_IFGLUE:
2138 case IMAGE_REL_PPC_ADDR32NB:
2139 case IMAGE_REL_PPC_SECTION:
2140 case IMAGE_REL_PPC_SECREL:
2141 DUMP_RELOC2(ppc_coff_howto_table[r_type].name, internal);
2142 break;
2143 case IMAGE_REL_PPC_IMGLUE:
2144 DUMP_RELOC2(ppc_coff_howto_table[r_type].name, internal);
2145 break;
2146 default:
2147 fprintf(stderr,
2148 "Warning: Unsupported reloc %s [%d] used -- it may not work.\n",
2149 ppc_coff_howto_table[r_type].name,
2150 r_type);
2151 break;
2152 }
2153
2154 relent->howto = ppc_coff_howto_table + r_type;
2155
2156 }
2157
2158 static reloc_howto_type *
2159 coff_ppc_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
2160 bfd *abfd;
2161 asection *sec;
2162 struct internal_reloc *rel;
2163 struct coff_link_hash_entry *h;
2164 struct internal_syment *sym;
2165 bfd_vma *addendp;
2166 {
2167 reloc_howto_type *howto;
2168
2169 /* We can encode one of three things in the type field, aside from the
2170 type:
2171 1. IMAGE_REL_PPC_NEG - indicates the value field is a subtraction
2172 value, rather than an addition value
2173 2. IMAGE_REL_PPC_BRTAKEN, IMAGE_REL_PPC_BRNTAKEN - indicates that
2174 the branch is expected to be taken or not.
2175 3. IMAGE_REL_PPC_TOCDEFN - toc slot definition in the file
2176 For now, we just strip this stuff to find the type, and ignore it other
2177 than that.
2178 */
2179
2180 unsigned short r_type = EXTRACT_TYPE (rel->r_type);
2181 unsigned short r_flags = EXTRACT_FLAGS(rel->r_type);
2182 unsigned short junk = EXTRACT_JUNK (rel->r_type);
2183
2184 fprintf(stderr,
2185 "coff_ppc_rtype_to_howto\n");
2186
2187 /* the masking process only slices off the bottom byte for r_type. */
2188 if ( r_type > MAX_RELOC_INDEX )
2189 {
2190 fprintf(stderr,
2191 "coff_ppc_rtype_to_howto: index %d out of range [%d, %d]\n",
2192 r_type, 0, MAX_RELOC_INDEX);
2193 abort();
2194 }
2195
2196 /* check for absolute crap */
2197 if ( junk != 0 )
2198 {
2199 fprintf(stderr,
2200 "coff_ppc_rtype_to_howto: reloc index %d contains junk %d\n",
2201 rel->r_type, junk);
2202 abort();
2203 }
2204
2205 #ifdef DEBUG_RELOC
2206 /* now examine flags */
2207 if (r_flags != 0)
2208 {
2209 fprintf (stderr, "Reloc with flags found!");
2210 if ( r_flags & IMAGE_REL_PPC_NEG )
2211 fprintf (stderr, " NEG");
2212 if ( r_flags & IMAGE_REL_PPC_BRTAKEN )
2213 fprintf (stderr, " BRTAKEN");
2214 if ( r_flags & IMAGE_REL_PPC_BRNTAKEN )
2215 fprintf (stderr, " BRNTAKEN");
2216 if ( r_flags & IMAGE_REL_PPC_TOCDEFN )
2217 fprintf (stderr, " TOCDEFN");
2218 fprintf(stderr, "\n");
2219 }
2220 #endif
2221
2222 switch(r_type)
2223 {
2224 case IMAGE_REL_PPC_ADDR32NB:
2225 DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel);
2226 *addendp -= pe_data(sec->output_section->owner)->pe_opthdr.ImageBase;
2227 break;
2228 case IMAGE_REL_PPC_ADDR16:
2229 case IMAGE_REL_PPC_REL24:
2230 case IMAGE_REL_PPC_ADDR24:
2231 case IMAGE_REL_PPC_TOCREL16:
2232 case IMAGE_REL_PPC_ADDR32:
2233 case IMAGE_REL_PPC_IFGLUE:
2234 case IMAGE_REL_PPC_SECTION:
2235 case IMAGE_REL_PPC_SECREL:
2236 DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel);
2237 break;
2238 case IMAGE_REL_PPC_IMGLUE:
2239 DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel);
2240 break;
2241 default:
2242 fprintf(stderr,
2243 "Warning: Unsupported reloc %s [%d] used -- it may not work.\n",
2244 ppc_coff_howto_table[r_type].name,
2245 r_type);
2246 break;
2247 }
2248
2249 howto = ppc_coff_howto_table + r_type;
2250 return howto;
2251 }
2252
2253
2254 /* a cheesy little macro to make the code a little more readable */
2255 #define HOW2MAP(bfd_rtype,ppc_rtype) \
2256 case bfd_rtype: return &ppc_coff_howto_table[ppc_rtype]
2257
2258 static reloc_howto_type *ppc_coff_reloc_type_lookup
2259 PARAMS ((bfd *, bfd_reloc_code_real_type));
2260
2261 static reloc_howto_type *
2262 ppc_coff_reloc_type_lookup (abfd, code)
2263 bfd *abfd;
2264 bfd_reloc_code_real_type code;
2265 {
2266
2267 #ifdef DEBUG_RELOC
2268 fprintf(stderr, "ppc_coff_reloc_type_lookup for %s\n",
2269 bfd_get_reloc_code_name(code));
2270 #endif
2271
2272 switch (code)
2273 {
2274 HOW2MAP(BFD_RELOC_16_GOT_PCREL, IMAGE_REL_PPC_IFGLUE);
2275 HOW2MAP(BFD_RELOC_16, IMAGE_REL_PPC_ADDR16);
2276 HOW2MAP(BFD_RELOC_PPC_B26, IMAGE_REL_PPC_REL24);
2277 HOW2MAP(BFD_RELOC_PPC_BA26, IMAGE_REL_PPC_ADDR24);
2278 HOW2MAP(BFD_RELOC_PPC_TOC16, IMAGE_REL_PPC_TOCREL16);
2279 HOW2MAP(BFD_RELOC_32, IMAGE_REL_PPC_ADDR32);
2280 HOW2MAP(BFD_RELOC_RVA, IMAGE_REL_PPC_ADDR32NB);
2281 default:
2282 fprintf(stderr,
2283 "\treturning NULL\n");
2284 return NULL;
2285 }
2286
2287 return NULL;
2288 }
2289
2290 #undef HOW2MAP
2291
2292 \f
2293 /* Tailor coffcode.h -- macro heaven. */
2294
2295 #define RTYPE2HOWTO(cache_ptr, dst) ppc_coff_rtype2howto (cache_ptr, dst)
2296
2297 #ifndef COFF_IMAGE_WITH_PE
2298 static void
2299 ppc_coff_swap_sym_in_hook ();
2300 #endif
2301
2302 /* We use the special COFF backend linker, with our own special touch. */
2303
2304 #define coff_bfd_reloc_type_lookup ppc_coff_reloc_type_lookup
2305 #define coff_rtype_to_howto coff_ppc_rtype_to_howto
2306 #define coff_relocate_section coff_ppc_relocate_section
2307
2308 #ifndef COFF_IMAGE_WITH_PE
2309 #define coff_swap_sym_in_hook ppc_coff_swap_sym_in_hook
2310 #endif
2311
2312 #define SELECT_RELOC(internal, howto) {internal.r_type=howto->type;}
2313
2314 #define COFF_PAGE_SIZE 0x1000
2315
2316 #define POWERPC_LE_PE
2317
2318 #include "coffcode.h"
2319
2320 \f
2321
2322 #ifndef COFF_IMAGE_WITH_PE
2323 static void
2324 ppc_coff_swap_sym_in_hook (abfd, ext1, in1)
2325 bfd *abfd;
2326 PTR ext1;
2327 PTR in1;
2328 {
2329 SYMENT *ext = (SYMENT *)ext1;
2330 struct internal_syment *in = (struct internal_syment *)in1;
2331
2332 #if 0
2333 if (bfd_of_toc_owner != 0) /* we already have a toc, so go home */
2334 return;
2335 #endif
2336
2337 if (strcmp(in->_n._n_name, ".toc") == 0)
2338 {
2339 flagword flags;
2340 register asection *s;
2341 char *foo;
2342
2343 s = bfd_get_section_by_name ( abfd , TOC_SECTION_NAME);
2344 if (s != NULL)
2345 {
2346 return;
2347 }
2348
2349 flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY ;
2350
2351 #ifdef TOC_DEBUG
2352 fprintf(stderr,
2353 "ppc_coff_swap_sym_in_hook: about to create the %s section\n",
2354 TOC_SECTION_NAME);
2355 #endif
2356
2357 s = bfd_make_section (abfd, TOC_SECTION_NAME);
2358
2359 if (s == NULL
2360 || !bfd_set_section_flags (abfd, s, flags)
2361 || !bfd_set_section_alignment (abfd, s, 2))
2362 {
2363 fprintf(stderr,
2364 "toc section allocation failed!\n");
2365 abort();
2366 }
2367
2368 /* save the bfd for later allocation */
2369 bfd_of_toc_owner = abfd;
2370 }
2371
2372 return;
2373 }
2374 #endif
2375
2376 \f
2377
2378 /* The transfer vectors that lead the outside world to all of the above. */
2379
2380 #ifdef TARGET_LITTLE_SYM
2381 const bfd_target
2382 TARGET_LITTLE_SYM =
2383 {
2384 TARGET_LITTLE_NAME, /* name or coff-arm-little */
2385 bfd_target_coff_flavour,
2386 false, /* data byte order is little */
2387 false, /* header byte order is little */
2388
2389 (HAS_RELOC | EXEC_P | /* FIXME: object flags */
2390 HAS_LINENO | HAS_DEBUG |
2391 HAS_SYMS | HAS_LOCALS | WP_TEXT),
2392
2393 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
2394 0, /* leading char */
2395 '/', /* ar_pad_char */
2396 15, /* ar_max_namelen??? FIXMEmgo */
2397
2398 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
2399 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
2400 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
2401
2402 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
2403 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
2404 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
2405
2406 {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
2407 bfd_generic_archive_p, /* _bfd_dummy_target */ coff_object_p },
2408 {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
2409 bfd_false},
2410 {bfd_false, coff_write_object_contents, /* bfd_write_contents */
2411 _bfd_write_archive_contents, bfd_false},
2412
2413 BFD_JUMP_TABLE_GENERIC (coff),
2414 BFD_JUMP_TABLE_COPY (coff),
2415 BFD_JUMP_TABLE_CORE (_bfd_nocore),
2416 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
2417 BFD_JUMP_TABLE_SYMBOLS (coff),
2418 BFD_JUMP_TABLE_RELOCS (coff),
2419 BFD_JUMP_TABLE_WRITE (coff),
2420 BFD_JUMP_TABLE_LINK (coff),
2421 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
2422
2423 COFF_SWAP_TABLE,
2424 };
2425 #endif
2426
2427 #ifdef TARGET_BIG_SYM
2428 const bfd_target
2429 TARGET_BIG_SYM =
2430 {
2431 TARGET_BIG_NAME,
2432 bfd_target_coff_flavour,
2433 true, /* data byte order is big */
2434 true, /* header byte order is big */
2435
2436 (HAS_RELOC | EXEC_P | /* FIXME: object flags */
2437 HAS_LINENO | HAS_DEBUG |
2438 HAS_SYMS | HAS_LOCALS | WP_TEXT),
2439
2440 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
2441 0, /* leading char */
2442 '/', /* ar_pad_char */
2443 15, /* ar_max_namelen??? FIXMEmgo */
2444
2445 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
2446 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
2447 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
2448
2449 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
2450 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
2451 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
2452
2453 {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
2454 bfd_generic_archive_p, /* _bfd_dummy_target */ coff_object_p },
2455 {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
2456 bfd_false},
2457 {bfd_false, coff_write_object_contents, /* bfd_write_contents */
2458 _bfd_write_archive_contents, bfd_false},
2459
2460 BFD_JUMP_TABLE_GENERIC (coff),
2461 BFD_JUMP_TABLE_COPY (coff),
2462 BFD_JUMP_TABLE_CORE (_bfd_nocore),
2463 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
2464 BFD_JUMP_TABLE_SYMBOLS (coff),
2465 BFD_JUMP_TABLE_RELOCS (coff),
2466 BFD_JUMP_TABLE_WRITE (coff),
2467 BFD_JUMP_TABLE_LINK (coff),
2468 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
2469
2470 COFF_SWAP_TABLE,
2471 };
2472
2473 #endif
This page took 0.076783 seconds and 5 git commands to generate.