
1: /* BFD back-end for PowerPC Microsoft Portable Executable files. 2: Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 3: 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 4: Free Software Foundation, Inc. 5: 6: Original version pieced together by Kim Knuttila (krk@cygnus.com) 7: 8: There is nothing new under the sun. This file draws a lot on other 9: coff files, in particular, those for the rs/6000, alpha, mips, and 10: intel backends, and the PE work for the arm. 11: 12: This file is part of BFD, the Binary File Descriptor library. 13: 14: This program is free software; you can redistribute it and/or modify 15: it under the terms of the GNU General Public License as published by 16: the Free Software Foundation; either version 3 of the License, or 17: (at your option) any later version. 18: 19: This program is distributed in the hope that it will be useful, 20: but WITHOUT ANY WARRANTY; without even the implied warranty of 21: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22: GNU General Public License for more details. 23: 24: You should have received a copy of the GNU General Public License 25: along with this program; if not, write to the Free Software 26: Foundation, 51 Franklin Street - Fifth Floor, 27: Boston, MA 02110-1301, USA. */ 28: 29: /* Current State: 30: - objdump works 31: - relocs generated by gas 32: - ld will link files, but they do not run. 33: - dlltool will not produce correct output in some .reloc cases, and will 34: not produce the right glue code for dll function calls. */ 35: 36: #include "sysdep.h" 37: #include "bfd.h" 38: #include "libbfd.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: /* This file is compiled more than once, but we only compile the 54: final_link routine once. */ 55: extern bfd_boolean ppc_bfd_coff_final_link 56: PARAMS ((bfd *, struct bfd_link_info *)); 57: extern void dump_toc PARAMS ((PTR)); 58: 59: /* The toc is a set of bfd_vma fields. We use the fact that valid 60: addresses are even (i.e. the bit representing "1" is off) to allow 61: us to encode a little extra information in the field 62: - Unallocated addresses are initialized to 1. 63: - Allocated addresses are even numbers. 64: The first time we actually write a reference to the toc in the bfd, 65: we want to record that fact in a fixup file (if it is asked for), so 66: we keep track of whether or not an address has been written by marking 67: the low order bit with a "1" upon writing. */ 68: 69: #define SET_UNALLOCATED(x) ((x) = 1) 70: #define IS_UNALLOCATED(x) ((x) == 1) 71: 72: #define IS_WRITTEN(x) ((x) & 1) 73: #define MARK_AS_WRITTEN(x) ((x) |= 1) 74: #define MAKE_ADDR_AGAIN(x) ((x) &= ~1) 75: 76: /* Turn on this check if you suspect something amiss in the hash tables. */ 77: #ifdef DEBUG_HASH 78: 79: /* Need a 7 char string for an eye catcher. */ 80: #define EYE "krkjunk" 81: 82: #define HASH_CHECK_DCL char eye_catcher[8]; 83: #define HASH_CHECK_INIT(ret) strcpy(ret->eye_catcher, EYE) 84: #define HASH_CHECK(addr) \ 85: if (strcmp(addr->eye_catcher, EYE) != 0) \ 86: { \ 87: fprintf (stderr,\ 88: _("File %s, line %d, Hash check failure, bad eye %8s\n"), \ 89: __FILE__, __LINE__, addr->eye_catcher); \ 90: abort (); \ 91: } 92: 93: #else 94: 95: #define HASH_CHECK_DCL 96: #define HASH_CHECK_INIT(ret) 97: #define HASH_CHECK(addr) 98: 99: #endif 100: 101: /* In order not to add an int to every hash table item for every coff 102: linker, we define our own hash table, derived from the coff one. */ 103: 104: /* PE linker hash table entries. */ 105: 106: struct ppc_coff_link_hash_entry 107: { 108: struct coff_link_hash_entry root; /* First entry, as required. */ 109: 110: /* As we wonder around the relocs, we'll keep the assigned toc_offset 111: here. */ 112: bfd_vma toc_offset; /* Our addition, as required. */ 113: int symbol_is_glue; 114: unsigned long int glue_insn; 115: 116: HASH_CHECK_DCL 117: }; 118: 119: /* PE linker hash table. */ 120: 121: struct ppc_coff_link_hash_table 122: { 123: struct coff_link_hash_table root; /* First entry, as required. */ 124: }; 125: 126: static struct bfd_hash_entry *ppc_coff_link_hash_newfunc 127: PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, 128: const char *)); 129: static struct bfd_link_hash_table *ppc_coff_link_hash_table_create 130: PARAMS ((bfd *)); 131: static bfd_boolean coff_ppc_relocate_section 132: PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, 133: struct internal_reloc *, struct internal_syment *, asection **)); 134: static reloc_howto_type *coff_ppc_rtype_to_howto 135: PARAMS ((bfd *, asection *, struct internal_reloc *, 136: struct coff_link_hash_entry *, struct internal_syment *, 137: bfd_vma *)); 138: 139: /* Routine to create an entry in the link hash table. */ 140: 141: static struct bfd_hash_entry * 142: ppc_coff_link_hash_newfunc (entry, table, string) 143: struct bfd_hash_entry *entry; 144: struct bfd_hash_table *table; 145: const char *string; 146: { 147: struct ppc_coff_link_hash_entry *ret = 148: (struct ppc_coff_link_hash_entry *) entry; 149: 150: /* Allocate the structure if it has not already been allocated by a 151: subclass. */ 152: if (ret == (struct ppc_coff_link_hash_entry *) NULL) 153: ret = (struct ppc_coff_link_hash_entry *) 154: bfd_hash_allocate (table, 155: sizeof (struct ppc_coff_link_hash_entry)); 156: 157: if (ret == (struct ppc_coff_link_hash_entry *) NULL) 158: return NULL; 159: 160: /* Call the allocation method of the superclass. */ 161: ret = ((struct ppc_coff_link_hash_entry *) 162: _bfd_coff_link_hash_newfunc ((struct bfd_hash_entry *) ret, 163: table, string)); 164: 165: if (ret) 166: { 167: /* Initialize the local fields. */ 168: SET_UNALLOCATED (ret->toc_offset); 169: ret->symbol_is_glue = 0; 170: ret->glue_insn = 0; 171: 172: HASH_CHECK_INIT (ret); 173: } 174: 175: return (struct bfd_hash_entry *) ret; 176: } 177: 178: /* Initialize a PE linker hash table. */ 179: 180: static bfd_boolean 181: ppc_coff_link_hash_table_init (struct ppc_coff_link_hash_table *table, 182: bfd *abfd, 183: struct bfd_hash_entry *(*newfunc) (struct bfd_hash_entry *, 184: struct bfd_hash_table *, 185: const char *), 186: unsigned int entsize) 187: { 188: return _bfd_coff_link_hash_table_init (&table->root, abfd, newfunc, entsize); 189: } 190: 191: /* Create a PE linker hash table. */ 192: 193: static struct bfd_link_hash_table * 194: ppc_coff_link_hash_table_create (abfd) 195: bfd *abfd; 196: { 197: struct ppc_coff_link_hash_table *ret; 198: bfd_size_type amt = sizeof (struct ppc_coff_link_hash_table); 199: 200: ret = (struct ppc_coff_link_hash_table *) bfd_malloc (amt); 201: if (ret == NULL) 202: return NULL; 203: if (!ppc_coff_link_hash_table_init (ret, abfd, 204: ppc_coff_link_hash_newfunc, 205: sizeof (struct ppc_coff_link_hash_entry))) 206: { 207: free (ret); 208: return (struct bfd_link_hash_table *) NULL; 209: } 210: return &ret->root.root; 211: } 212: 213: /* Now, tailor coffcode.h to use our hash stuff. */ 214: 215: #define coff_bfd_link_hash_table_create ppc_coff_link_hash_table_create 216: ^L 217: /* The nt loader points the toc register to &toc + 32768, in order to 218: use the complete range of a 16-bit displacement. We have to adjust 219: for this when we fix up loads displaced off the toc reg. */ 220: #define TOC_LOAD_ADJUSTMENT (-32768) 221: #define TOC_SECTION_NAME ".private.toc" 222: 223: /* The main body of code is in coffcode.h. */ 224: 225: #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3) 226: 227: /* In case we're on a 32-bit machine, construct a 64-bit "-1" value 228: from smaller values. Start with zero, widen, *then* decrement. */ 229: #define MINUS_ONE (((bfd_vma)0) - 1) 230: 231: /* These should definitely go in a header file somewhere... */ 232: 233: /* NOP */ 234: #define IMAGE_REL_PPC_ABSOLUTE 0x0000 235: 236: /* 64-bit address */ 237: #define IMAGE_REL_PPC_ADDR64 0x0001 238: 239: /* 32-bit address */ 240: #define IMAGE_REL_PPC_ADDR32 0x0002 241: 242: /* 26-bit address, shifted left 2 (branch absolute) */ 243: #define IMAGE_REL_PPC_ADDR24 0x0003 244: 245: /* 16-bit address */ 246: #define IMAGE_REL_PPC_ADDR16 0x0004 247: 248: /* 16-bit address, shifted left 2 (load doubleword) */ 249: #define IMAGE_REL_PPC_ADDR14 0x0005 250: 251: /* 26-bit PC-relative offset, shifted left 2 (branch relative) */ 252: #define IMAGE_REL_PPC_REL24 0x0006 253: 254: /* 16-bit PC-relative offset, shifted left 2 (br cond relative) */ 255: #define IMAGE_REL_PPC_REL14 0x0007 256: 257: /* 16-bit offset from TOC base */ 258: #define IMAGE_REL_PPC_TOCREL16 0x0008 259: 260: /* 16-bit offset from TOC base, shifted left 2 (load doubleword) */ 261: #define IMAGE_REL_PPC_TOCREL14 0x0009 262: 263: /* 32-bit addr w/o image base */ 264: #define IMAGE_REL_PPC_ADDR32NB 0x000A 265: 266: /* va of containing section (as in an image sectionhdr) */ 267: #define IMAGE_REL_PPC_SECREL 0x000B 268: 269: /* sectionheader number */ 270: #define IMAGE_REL_PPC_SECTION 0x000C 271: 272: /* substitute TOC restore instruction iff symbol is glue code */ 273: #define IMAGE_REL_PPC_IFGLUE 0x000D 274: 275: /* symbol is glue code; virtual address is TOC restore instruction */ 276: #define IMAGE_REL_PPC_IMGLUE 0x000E 277: 278: /* va of containing section (limited to 16 bits) */ 279: #define IMAGE_REL_PPC_SECREL16 0x000F 280: 281: /* Stuff to handle immediate data when the number of bits in the 282: data is greater than the number of bits in the immediate field 283: We need to do (usually) 32 bit arithmetic on 16 bit chunks. */ 284: #define IMAGE_REL_PPC_REFHI 0x0010 285: #define IMAGE_REL_PPC_REFLO 0x0011 286: #define IMAGE_REL_PPC_PAIR 0x0012 287: 288: /* This is essentially the same as tocrel16, with TOCDEFN assumed. */ 289: #define IMAGE_REL_PPC_TOCREL16_DEFN 0x0013 290: 291: /* Flag bits in IMAGE_RELOCATION.TYPE. */ 292: 293: /* Subtract reloc value rather than adding it. */ 294: #define IMAGE_REL_PPC_NEG 0x0100 295: 296: /* Fix branch prediction bit to predict branch taken. */ 297: #define IMAGE_REL_PPC_BRTAKEN 0x0200 298: 299: /* Fix branch prediction bit to predict branch not taken. */ 300: #define IMAGE_REL_PPC_BRNTAKEN 0x0400 301: 302: /* TOC slot defined in file (or, data in toc). */ 303: #define IMAGE_REL_PPC_TOCDEFN 0x0800 304: 305: /* Masks to isolate above values in IMAGE_RELOCATION.Type. */ 306: #define IMAGE_REL_PPC_TYPEMASK 0x00FF 307: #define IMAGE_REL_PPC_FLAGMASK 0x0F00 308: 309: #define EXTRACT_TYPE(x) ((x) & IMAGE_REL_PPC_TYPEMASK) 310: #define EXTRACT_FLAGS(x) ((x) & IMAGE_REL_PPC_FLAGMASK) 311: #define EXTRACT_JUNK(x) \ 312: ((x) & ~(IMAGE_REL_PPC_TYPEMASK | IMAGE_REL_PPC_FLAGMASK)) 313: ^L 314: /* Static helper functions to make relocation work. */ 315: /* (Work In Progress) */ 316: 317: static bfd_reloc_status_type ppc_refhi_reloc PARAMS ((bfd *abfd, 318: arelent *reloc, 319: asymbol *symbol, 320: PTR data, 321: asection *section, 322: bfd *output_bfd, 323: char **error)); 324: static bfd_reloc_status_type ppc_pair_reloc PARAMS ((bfd *abfd, 325: arelent *reloc, 326: asymbol *symbol, 327: PTR data, 328: asection *section, 329: bfd *output_bfd, 330: char **error)); 331: ^L 332: static bfd_reloc_status_type ppc_toc16_reloc PARAMS ((bfd *abfd, 333: arelent *reloc, 334: asymbol *symbol, 335: PTR data, 336: asection *section, 337: bfd *output_bfd, 338: char **error)); 339: 340: static bfd_reloc_status_type ppc_section_reloc PARAMS ((bfd *abfd, 341: arelent *reloc, 342: asymbol *symbol, 343: PTR data, 344: asection *section, 345: bfd *output_bfd, 346: char **error)); 347: 348: static bfd_reloc_status_type ppc_secrel_reloc PARAMS ((bfd *abfd, 349: arelent *reloc, 350: asymbol *symbol, 351: PTR data, 352: asection *section, 353: bfd *output_bfd, 354: char **error)); 355: 356: static bfd_reloc_status_type ppc_imglue_reloc PARAMS ((bfd *abfd, 357: arelent *reloc, 358: asymbol *symbol, 359: PTR data, 360: asection *section, 361: bfd *output_bfd, 362: char **error)); 363: 364: static bfd_boolean in_reloc_p PARAMS((bfd *abfd, reloc_howto_type *howto)); 365: ^L 366: /* FIXME: It'll take a while to get through all of these. I only need a few to 367: get us started, so those I'll make sure work. Those marked FIXME are either 368: completely unverified or have a specific unknown marked in the comment. */ 369: 370: /* Relocation entries for Windows/NT on PowerPC. 371: 372: From the document "" we find the following listed as used relocs: 373: 374: ABSOLUTE : The noop 375: ADDR[64|32|16] : fields that hold addresses in data fields or the 376: 16 bit displacement field on a load/store. 377: ADDR[24|14] : fields that hold addresses in branch and cond 378: branches. These represent [26|16] bit addresses. 379: The low order 2 bits are preserved. 380: REL[24|14] : branches relative to the Instruction Address 381: register. These represent [26|16] bit addresses, 382: as before. The instruction field will be zero, and 383: the address of the SYM will be inserted at link time. 384: TOCREL16 : 16 bit displacement field referring to a slot in 385: toc. 386: TOCREL14 : 16 bit displacement field, similar to REL14 or ADDR14. 387: ADDR32NB : 32 bit address relative to the virtual origin. 388: (On the alpha, this is always a linker generated thunk) 389: (i.e. 32bit addr relative to the image base) 390: SECREL : The value is relative to the start of the section 391: containing the symbol. 392: SECTION : access to the header containing the item. Supports the 393: codeview debugger. 394: 395: In particular, note that the document does not indicate that the 396: relocations listed in the header file are used. */ 397: 398: 399: static reloc_howto_type ppc_coff_howto_table[] = 400: { 401: /* IMAGE_REL_PPC_ABSOLUTE 0x0000 NOP */ 402: /* Unused: */ 403: HOWTO (IMAGE_REL_PPC_ABSOLUTE, /* type */ 404: 0, /* rightshift */ 405: 0, /* size (0 = byte, 1 = short, 2 = long) */ 406: 0, /* bitsize */ 407: FALSE, /* pc_relative */ 408: 0, /* bitpos */ 409: complain_overflow_dont, /* dont complain_on_overflow */ 410: 0, /* special_function */ 411: "ABSOLUTE", /* name */ 412: FALSE, /* partial_inplace */ 413: 0x00, /* src_mask */ 414: 0x00, /* dst_mask */ 415: FALSE), /* pcrel_offset */ 416: 417: /* IMAGE_REL_PPC_ADDR64 0x0001 64-bit address */ 418: /* Unused: */ 419: HOWTO(IMAGE_REL_PPC_ADDR64, /* type */ 420: 0, /* rightshift */ 421: 3, /* size (0 = byte, 1 = short, 2 = long) */ 422: 64, /* bitsize */ 423: FALSE, /* pc_relative */ 424: 0, /* bitpos */ 425: complain_overflow_bitfield, /* complain_on_overflow */ 426: 0, /* special_function */ 427: "ADDR64", /* name */ 428: TRUE, /* partial_inplace */ 429: MINUS_ONE, /* src_mask */ 430: MINUS_ONE, /* dst_mask */ 431: FALSE), /* pcrel_offset */ 432: 433: /* IMAGE_REL_PPC_ADDR32 0x0002 32-bit address */ 434: /* Used: */ 435: HOWTO (IMAGE_REL_PPC_ADDR32, /* type */ 436: 0, /* rightshift */ 437: 2, /* size (0 = byte, 1 = short, 2 = long) */ 438: 32, /* bitsize */ 439: FALSE, /* pc_relative */ 440: 0, /* bitpos */ 441: complain_overflow_bitfield, /* complain_on_overflow */ 442: 0, /* special_function */ 443: "ADDR32", /* name */ 444: TRUE, /* partial_inplace */ 445: 0xffffffff, /* src_mask */ 446: 0xffffffff, /* dst_mask */ 447: FALSE), /* pcrel_offset */ 448: 449: /* IMAGE_REL_PPC_ADDR24 0x0003 26-bit address, shifted left 2 (branch absolute) */ 450: /* the LI field is in bit 6 through bit 29 is 24 bits, + 2 for the shift */ 451: /* Of course, That's the IBM approved bit numbering, which is not what */ 452: /* anyone else uses.... The li field is in bit 2 thru 25 */ 453: /* Used: */ 454: HOWTO (IMAGE_REL_PPC_ADDR24, /* type */ 455: 0, /* rightshift */ 456: 2, /* size (0 = byte, 1 = short, 2 = long) */ 457: 26, /* bitsize */ 458: FALSE, /* pc_relative */ 459: 0, /* bitpos */ 460: complain_overflow_bitfield, /* complain_on_overflow */ 461: 0, /* special_function */ 462: "ADDR24", /* name */ 463: TRUE, /* partial_inplace */ 464: 0x07fffffc, /* src_mask */ 465: 0x07fffffc, /* dst_mask */ 466: FALSE), /* pcrel_offset */ 467: 468: /* IMAGE_REL_PPC_ADDR16 0x0004 16-bit address */ 469: /* Used: */ 470: HOWTO (IMAGE_REL_PPC_ADDR16, /* type */ 471: 0, /* rightshift */ 472: 1, /* size (0 = byte, 1 = short, 2 = long) */ 473: 16, /* bitsize */ 474: FALSE, /* pc_relative */ 475: 0, /* bitpos */ 476: complain_overflow_signed, /* complain_on_overflow */ 477: 0, /* special_function */ 478: "ADDR16", /* name */ 479: TRUE, /* partial_inplace */ 480: 0xffff, /* src_mask */ 481: 0xffff, /* dst_mask */ 482: FALSE), /* pcrel_offset */ 483: 484: /* IMAGE_REL_PPC_ADDR14 0x0005 */ 485: /* 16-bit address, shifted left 2 (load doubleword) */ 486: /* FIXME: the mask is likely wrong, and the bit position may be as well */ 487: /* Unused: */ 488: HOWTO (IMAGE_REL_PPC_ADDR14, /* type */ 489: 1, /* rightshift */ 490: 1, /* size (0 = byte, 1 = short, 2 = long) */ 491: 16, /* bitsize */ 492: FALSE, /* pc_relative */ 493: 0, /* bitpos */ 494: complain_overflow_signed, /* complain_on_overflow */ 495: 0, /* special_function */ 496: "ADDR16", /* name */ 497: TRUE, /* partial_inplace */ 498: 0xffff, /* src_mask */ 499: 0xffff, /* dst_mask */ 500: FALSE), /* pcrel_offset */ 501: 502: /* IMAGE_REL_PPC_REL24 0x0006 */ 503: /* 26-bit PC-relative offset, shifted left 2 (branch relative) */ 504: /* Used: */ 505: HOWTO (IMAGE_REL_PPC_REL24, /* type */ 506: 0, /* rightshift */ 507: 2, /* size (0 = byte, 1 = short, 2 = long) */ 508: 26, /* bitsize */ 509: TRUE, /* pc_relative */ 510: 0, /* bitpos */ 511: complain_overflow_signed, /* complain_on_overflow */ 512: 0, /* special_function */ 513: "REL24", /* name */ 514: TRUE, /* partial_inplace */ 515: 0x3fffffc, /* src_mask */ 516: 0x3fffffc, /* dst_mask */ 517: FALSE), /* pcrel_offset */ 518: 519: /* IMAGE_REL_PPC_REL14 0x0007 */ 520: /* 16-bit PC-relative offset, shifted left 2 (br cond relative) */ 521: /* FIXME: the mask is likely wrong, and the bit position may be as well */ 522: /* FIXME: how does it know how far to shift? */ 523: /* Unused: */ 524: HOWTO (IMAGE_REL_PPC_ADDR14, /* type */ 525: 1, /* rightshift */ 526: 1, /* size (0 = byte, 1 = short, 2 = long) */ 527: 16, /* bitsize */ 528: FALSE, /* pc_relative */ 529: 0, /* bitpos */ 530: complain_overflow_signed, /* complain_on_overflow */ 531: 0, /* special_function */ 532: "ADDR16", /* name */ 533: TRUE, /* partial_inplace */ 534: 0xffff, /* src_mask */ 535: 0xffff, /* dst_mask */ 536: TRUE), /* pcrel_offset */ 537: 538: /* IMAGE_REL_PPC_TOCREL16 0x0008 */ 539: /* 16-bit offset from TOC base */ 540: /* Used: */ 541: HOWTO (IMAGE_REL_PPC_TOCREL16,/* type */ 542: 0, /* rightshift */ 543: 1, /* size (0 = byte, 1 = short, 2 = long) */ 544: 16, /* bitsize */ 545: FALSE, /* pc_relative */ 546: 0, /* bitpos */ 547: complain_overflow_dont, /* complain_on_overflow */ 548: ppc_toc16_reloc, /* special_function */ 549: "TOCREL16", /* name */ 550: FALSE, /* partial_inplace */ 551: 0xffff, /* src_mask */ 552: 0xffff, /* dst_mask */ 553: FALSE), /* pcrel_offset */ 554: 555: /* IMAGE_REL_PPC_TOCREL14 0x0009 */ 556: /* 16-bit offset from TOC base, shifted left 2 (load doubleword) */ 557: /* Unused: */ 558: HOWTO (IMAGE_REL_PPC_TOCREL14,/* type */ 559: 1, /* rightshift */ 560: 1, /* size (0 = byte, 1 = short, 2 = long) */ 561: 16, /* bitsize */ 562: FALSE, /* pc_relative */ 563: 0, /* bitpos */ 564: