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