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