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