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