diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2015-04-06 18:30:23 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2015-04-06 18:30:23 +0000 |
commit | 536010081e277b2071264c2d130a2585ee872503 (patch) | |
tree | 731dfd9e4b0f6c68a70f542d35582c5b9a14aa55 /gnu | |
parent | 23abaf50e57d124ccb56f9f2e1c403756406beeb (diff) |
Add support for an efi-app-x86_64 target. Needed for UEFI bootloader work.
ok mlarkin@
Diffstat (limited to 'gnu')
26 files changed, 2046 insertions, 34 deletions
diff --git a/gnu/usr.bin/binutils-2.17/bfd/Makefile.in b/gnu/usr.bin/binutils-2.17/bfd/Makefile.in index f9668f3d828..3194dcfde89 100644 --- a/gnu/usr.bin/binutils-2.17/bfd/Makefile.in +++ b/gnu/usr.bin/binutils-2.17/bfd/Makefile.in @@ -776,6 +776,7 @@ BFD64_BACKENDS = \ coff64-rs6000.lo \ demo64.lo \ efi-app-ia64.lo \ + efi-app-x86_64.lo \ elf64-x86-64.lo \ elf64-alpha.lo \ elf64-hppa.lo \ @@ -802,6 +803,7 @@ BFD64_BACKENDS_CFILES = \ coff64-rs6000.c \ demo64.c \ efi-app-ia64.c \ + efi-app-x86_64.c \ elf64-x86-64.c \ elf64-alpha.c \ elf64-hppa.c \ @@ -2302,6 +2304,11 @@ efi-app-ia64.lo: efi-app-ia64.c $(INCDIR)/filenames.h \ $(INCDIR)/coff/external.h $(INCDIR)/coff/internal.h \ $(INCDIR)/coff/pe.h libcoff.h $(INCDIR)/bfdlink.h coffcode.h \ peicode.h libpei.h +efi-app-x86_64.lo: efi-app-x86_64.c $(INCDIR)/filenames.h \ + coff-x86_64.c $(INCDIR)/hashtab.h $(INCDIR)/coff/x86_64.h \ + $(INCDIR)/coff/external.h $(INCDIR)/coff/internal.h \ + $(INCDIR)/coff/pe.h libcoff.h $(INCDIR)/bfdlink.h coffcode.h \ + peicode.h libpei.h elf64-x86-64.lo: elf64-x86-64.c $(INCDIR)/filenames.h \ $(INCDIR)/bfdlink.h $(INCDIR)/hashtab.h elf-bfd.h $(INCDIR)/elf/common.h \ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/elf/x86-64.h \ diff --git a/gnu/usr.bin/binutils-2.17/bfd/coff-x86_64.c b/gnu/usr.bin/binutils-2.17/bfd/coff-x86_64.c new file mode 100644 index 00000000000..7f751232e31 --- /dev/null +++ b/gnu/usr.bin/binutils-2.17/bfd/coff-x86_64.c @@ -0,0 +1,789 @@ +/* BFD back-end for AMD 64 COFF files. + Copyright 2006, 2007 Free Software Foundation, Inc. + + This file is part of BFD, the Binary File Descriptor library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + + Written by Kai Tietz, OneVision Software GmbH&CoKg. */ + +#ifndef COFF_WITH_pex64 +#define COFF_WITH_pex64 +#endif + +#include "sysdep.h" +#include "bfd.h" +#include "libbfd.h" +#include "coff/x86_64.h" +#include "coff/internal.h" +#include "coff/pe.h" +#include "libcoff.h" +#include "libiberty.h" + +#define BADMAG(x) AMD64BADMAG(x) + +#ifdef COFF_WITH_pex64 +# undef AOUTSZ +# define AOUTSZ PEPAOUTSZ +# define PEAOUTHDR PEPAOUTHDR +#endif + +#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2) + +/* The page size is a guess based on ELF. */ + +#define COFF_PAGE_SIZE 0x1000 + +/* For some reason when using AMD COFF the value stored in the .text + section for a reference to a common symbol is the value itself plus + any desired offset. Ian Taylor, Cygnus Support. */ + +/* If we are producing relocatable output, we need to do some + adjustments to the object file that are not done by the + bfd_perform_relocation function. This function is called by every + reloc type to make any required adjustments. */ + +static bfd_reloc_status_type +coff_amd64_reloc (bfd *abfd, + arelent *reloc_entry, + asymbol *symbol, + void * data, + asection *input_section ATTRIBUTE_UNUSED, + bfd *output_bfd, + char **error_message ATTRIBUTE_UNUSED) +{ + symvalue diff; + +#if !defined(COFF_WITH_PE) + if (output_bfd == NULL) + return bfd_reloc_continue; +#endif + + if (bfd_is_com_section (symbol->section)) + { +#if !defined(COFF_WITH_PE) + /* We are relocating a common symbol. The current value in the + object file is ORIG + OFFSET, where ORIG is the value of the + common symbol as seen by the object file when it was compiled + (this may be zero if the symbol was undefined) and OFFSET is + the offset into the common symbol (normally zero, but may be + non-zero when referring to a field in a common structure). + ORIG is the negative of reloc_entry->addend, which is set by + the CALC_ADDEND macro below. We want to replace the value in + the object file with NEW + OFFSET, where NEW is the value of + the common symbol which we are going to put in the final + object file. NEW is symbol->value. */ + diff = symbol->value + reloc_entry->addend; +#else + /* In PE mode, we do not offset the common symbol. */ + diff = reloc_entry->addend; +#endif + } + else + { + /* For some reason bfd_perform_relocation always effectively + ignores the addend for a COFF target when producing + relocatable output. This seems to be always wrong for 386 + COFF, so we handle the addend here instead. */ +#if defined(COFF_WITH_PE) + if (output_bfd == NULL) + { + reloc_howto_type *howto = reloc_entry->howto; + + /* Although PC relative relocations are very similar between + PE and non-PE formats, but they are off by 1 << howto->size + bytes. For the external relocation, PE is very different + from others. See md_apply_fix3 () in gas/config/tc-amd64.c. + When we link PE and non-PE object files together to + generate a non-PE executable, we have to compensate it + here. */ + if(howto->pc_relative && howto->pcrel_offset) + diff = -(1 << howto->size); + else if(symbol->flags & BSF_WEAK) + diff = reloc_entry->addend - symbol->value; + else + diff = -reloc_entry->addend; + } + else +#endif + diff = reloc_entry->addend; + } + +#if defined(COFF_WITH_PE) + /* FIXME: How should this case be handled? */ + if (reloc_entry->howto->type == R_AMD64_IMAGEBASE + && output_bfd != NULL + && bfd_get_flavour (output_bfd) == bfd_target_coff_flavour) + diff -= pe_data (output_bfd)->pe_opthdr.ImageBase; +#endif + +#define DOIT(x) \ + x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask)) + + if (diff != 0) + { + reloc_howto_type *howto = reloc_entry->howto; + unsigned char *addr = (unsigned char *) data + reloc_entry->address; + + switch (howto->size) + { + case 0: + { + char x = bfd_get_8 (abfd, addr); + DOIT (x); + bfd_put_8 (abfd, x, addr); + } + break; + + case 1: + { + short x = bfd_get_16 (abfd, addr); + DOIT (x); + bfd_put_16 (abfd, (bfd_vma) x, addr); + } + break; + + case 2: + { + long x = bfd_get_32 (abfd, addr); + DOIT (x); + bfd_put_32 (abfd, (bfd_vma) x, addr); + } + break; + case 4: + { + long long x = bfd_get_64 (abfd, addr); + DOIT (x); + bfd_put_64 (abfd, (bfd_vma) x, addr); + } + break; + + default: + abort (); + } + } + + /* Now let bfd_perform_relocation finish everything up. */ + return bfd_reloc_continue; +} + +#if defined(COFF_WITH_PE) +/* Return TRUE if this relocation should appear in the output .reloc + section. */ + +static bfd_boolean +in_reloc_p (bfd *abfd ATTRIBUTE_UNUSED, reloc_howto_type *howto) +{ + return ! howto->pc_relative && howto->type != R_AMD64_IMAGEBASE; +} +#endif /* COFF_WITH_PE */ + +#ifndef PCRELOFFSET +#define PCRELOFFSET TRUE +#endif + +static reloc_howto_type howto_table[] = +{ + EMPTY_HOWTO (0), + HOWTO (R_AMD64_DIR64, /* type 1*/ + 0, /* rightshift */ + 4, /* size (0 = byte, 1 = short, 2 = long, 4 = long long) */ + 64, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + coff_amd64_reloc, /* special_function */ + "R_X86_64_64", /* name */ + TRUE, /* partial_inplace */ + 0xffffffffffffffffll, /* src_mask */ + 0xffffffffffffffffll, /* dst_mask */ + TRUE), /* pcrel_offset */ + HOWTO (R_AMD64_DIR32, /* type 2 */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + coff_amd64_reloc, /* special_function */ + "R_X86_64_32", /* name */ + TRUE, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + TRUE), /* pcrel_offset */ + /* PE IMAGE_REL_AMD64_ADDR32NB relocation (3). */ + HOWTO (R_AMD64_IMAGEBASE, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + coff_amd64_reloc, /* special_function */ + "rva32", /* name */ + TRUE, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + /* 32-bit longword PC relative relocation (4). */ + HOWTO (R_AMD64_PCRLONG, /* type 4 */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + coff_amd64_reloc, /* special_function */ + "R_X86_64_PC32", /* name */ + TRUE, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + PCRELOFFSET), /* pcrel_offset */ + + HOWTO (R_AMD64_PCRLONG_1, /* type 5 */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + coff_amd64_reloc, /* special_function */ + "DISP32+1", /* name */ + TRUE, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + PCRELOFFSET), /* pcrel_offset */ + HOWTO (R_AMD64_PCRLONG_2, /* type 6 */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + coff_amd64_reloc, /* special_function */ + "DISP32+2", /* name */ + TRUE, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + PCRELOFFSET), /* pcrel_offset */ + HOWTO (R_AMD64_PCRLONG_3, /* type 7 */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + coff_amd64_reloc, /* special_function */ + "DISP32+3", /* name */ + TRUE, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + PCRELOFFSET), /* pcrel_offset */ + HOWTO (R_AMD64_PCRLONG_4, /* type 8 */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + coff_amd64_reloc, /* special_function */ + "DISP32+4", /* name */ + TRUE, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + PCRELOFFSET), /* pcrel_offset */ + HOWTO (R_AMD64_PCRLONG_5, /* type 9 */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + coff_amd64_reloc, /* special_function */ + "DISP32+5", /* name */ + TRUE, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + PCRELOFFSET), /* pcrel_offset */ + EMPTY_HOWTO (10), /* R_AMD64_SECTION 10 */ +#if defined(COFF_WITH_PE) + /* 32-bit longword section relative relocation (11). */ + HOWTO (R_AMD64_SECREL, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + coff_amd64_reloc, /* special_function */ + "secrel32", /* name */ + TRUE, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + TRUE), /* pcrel_offset */ +#else + EMPTY_HOWTO (11), +#endif + EMPTY_HOWTO (12), + EMPTY_HOWTO (13), +#ifndef DONT_EXTEND_AMD64 + HOWTO (R_AMD64_PCRQUAD, + 0, /* rightshift */ + 4, /* size (0 = byte, 1 = short, 2 = long) */ + 64, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + coff_amd64_reloc, /* special_function */ + "R_X86_64_PC64", /* name */ + TRUE, /* partial_inplace */ + 0xffffffffffffffffll, /* src_mask */ + 0xffffffffffffffffll, /* dst_mask */ + PCRELOFFSET), /* pcrel_offset */ +#else + EMPTY_HOWTO (14), +#endif + /* Byte relocation (15). */ + HOWTO (R_RELBYTE, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 8, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + coff_amd64_reloc, /* special_function */ + "R_X86_64_8", /* name */ + TRUE, /* partial_inplace */ + 0x000000ff, /* src_mask */ + 0x000000ff, /* dst_mask */ + PCRELOFFSET), /* pcrel_offset */ + /* 16-bit word relocation (16). */ + HOWTO (R_RELWORD, /* type */ + 0, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + coff_amd64_reloc, /* special_function */ + "R_X86_64_16", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + PCRELOFFSET), /* pcrel_offset */ + /* 32-bit longword relocation (17). */ + HOWTO (R_RELLONG, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + coff_amd64_reloc, /* special_function */ + "R_X86_64_32S", /* name */ + TRUE, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + PCRELOFFSET), /* pcrel_offset */ + /* Byte PC relative relocation (18). */ + HOWTO (R_PCRBYTE, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 8, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + coff_amd64_reloc, /* special_function */ + "R_X86_64_PC8", /* name */ + TRUE, /* partial_inplace */ + 0x000000ff, /* src_mask */ + 0x000000ff, /* dst_mask */ + PCRELOFFSET), /* pcrel_offset */ + /* 16-bit word PC relative relocation (19). */ + HOWTO (R_PCRWORD, /* type */ + 0, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + coff_amd64_reloc, /* special_function */ + "R_X86_64_PC16", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + PCRELOFFSET), /* pcrel_offset */ + /* 32-bit longword PC relative relocation (20). */ + HOWTO (R_PCRLONG, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + coff_amd64_reloc, /* special_function */ + "R_X86_64_PC32", /* name */ + TRUE, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + PCRELOFFSET) /* pcrel_offset */ +}; + +/* Turn a howto into a reloc nunmber */ + +#define SELECT_RELOC(x,howto) { x.r_type = howto->type; } +#define I386 1 /* Customize coffcode.h */ +#define AMD64 1 + +#define RTYPE2HOWTO(cache_ptr, dst) \ + ((cache_ptr)->howto = \ + ((dst)->r_type < ARRAY_SIZE (howto_table)) \ + ? howto_table + (dst)->r_type \ + : NULL) + +/* For 386 COFF a STYP_NOLOAD | STYP_BSS section is part of a shared + library. On some other COFF targets STYP_BSS is normally + STYP_NOLOAD. */ +#define BSS_NOLOAD_IS_SHARED_LIBRARY + +/* Compute the addend of a reloc. If the reloc is to a common symbol, + the object file contains the value of the common symbol. By the + time this is called, the linker may be using a different symbol + from a different object file with a different value. Therefore, we + hack wildly to locate the original symbol from this file so that we + can make the correct adjustment. This macro sets coffsym to the + symbol from the original file, and uses it to set the addend value + correctly. If this is not a common symbol, the usual addend + calculation is done, except that an additional tweak is needed for + PC relative relocs. + FIXME: This macro refers to symbols and asect; these are from the + calling function, not the macro arguments. */ + +#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \ + { \ + coff_symbol_type *coffsym = NULL; \ + \ + if (ptr && bfd_asymbol_bfd (ptr) != abfd) \ + coffsym = (obj_symbols (abfd) \ + + (cache_ptr->sym_ptr_ptr - symbols)); \ + else if (ptr) \ + coffsym = coff_symbol_from (abfd, ptr); \ + \ + if (coffsym != NULL \ + && coffsym->native->u.syment.n_scnum == 0) \ + cache_ptr->addend = - coffsym->native->u.syment.n_value; \ + else if (ptr && bfd_asymbol_bfd (ptr) == abfd \ + && ptr->section != NULL) \ + cache_ptr->addend = - (ptr->section->vma + ptr->value); \ + else \ + cache_ptr->addend = 0; \ + if (ptr && howto_table[reloc.r_type].pc_relative) \ + cache_ptr->addend += asect->vma; \ + } + +/* We use the special COFF backend linker. For normal AMD64 COFF, we + can use the generic relocate_section routine. For PE, we need our + own routine. */ + +#if !defined(COFF_WITH_PE) + +#define coff_relocate_section _bfd_coff_generic_relocate_section + +#else /* COFF_WITH_PE */ + +/* The PE relocate section routine. The only difference between this + and the regular routine is that we don't want to do anything for a + relocatable link. */ + +static bfd_boolean +coff_pe_amd64_relocate_section (bfd *output_bfd, + struct bfd_link_info *info, + bfd *input_bfd, + asection *input_section, + bfd_byte *contents, + struct internal_reloc *relocs, + struct internal_syment *syms, + asection **sections) +{ + if (info->relocatable) + return TRUE; + + return _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd,input_section, contents,relocs, syms, sections); +} + +#define coff_relocate_section coff_pe_amd64_relocate_section + +#endif /* COFF_WITH_PE */ + +/* Convert an rtype to howto for the COFF backend linker. */ + +static reloc_howto_type * +coff_amd64_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED, + asection *sec, + struct internal_reloc *rel, + struct coff_link_hash_entry *h, + struct internal_syment *sym, + bfd_vma *addendp) +{ + reloc_howto_type *howto; + + if (rel->r_type > ARRAY_SIZE (howto_table)) + { + bfd_set_error (bfd_error_bad_value); + return NULL; + } + if (rel->r_type >= R_AMD64_PCRLONG_1 && rel->r_type <= R_AMD64_PCRLONG_5) + { + rel->r_vaddr += (bfd_vma)(rel->r_type-R_AMD64_PCRLONG); + rel->r_type = R_AMD64_PCRLONG; + } + howto = howto_table + rel->r_type; + +#if defined(COFF_WITH_PE) + /* Cancel out code in _bfd_coff_generic_relocate_section. */ + *addendp = 0; +#endif + + if (howto->pc_relative) + *addendp += sec->vma; + + if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0) + { + /* This is a common symbol. The section contents include the + size (sym->n_value) as an addend. The relocate_section + function will be adding in the final value of the symbol. We + need to subtract out the current size in order to get the + correct result. */ + BFD_ASSERT (h != NULL); + +#if !defined(COFF_WITH_PE) + /* I think we *do* want to bypass this. If we don't, I have + seen some data parameters get the wrong relocation address. + If I link two versions with and without this section bypassed + and then do a binary comparison, the addresses which are + different can be looked up in the map. The case in which + this section has been bypassed has addresses which correspond + to values I can find in the map. */ + *addendp -= sym->n_value; +#endif + } + +#if !defined(COFF_WITH_PE) + /* If the output symbol is common (in which case this must be a + relocatable link), we need to add in the final size of the + common symbol. */ + if (h != NULL && h->root.type == bfd_link_hash_common) + *addendp += h->root.u.c.size; +#endif + +#if defined(COFF_WITH_PE) + if (howto->pc_relative) + { + *addendp -= 4; + + /* If the symbol is defined, then the generic code is going to + add back the symbol value in order to cancel out an + adjustment it made to the addend. However, we set the addend + to 0 at the start of this function. We need to adjust here, + to avoid the adjustment the generic code will make. FIXME: + This is getting a bit hackish. */ + if (sym != NULL && sym->n_scnum != 0) + *addendp -= sym->n_value; + } + + if (rel->r_type == R_AMD64_IMAGEBASE + && (bfd_get_flavour (sec->output_section->owner) == bfd_target_coff_flavour)) + *addendp -= pe_data (sec->output_section->owner)->pe_opthdr.ImageBase; + + if (rel->r_type == R_AMD64_SECREL) + { + bfd_vma osect_vma; + + if (h && (h->type == bfd_link_hash_defined || h->type == bfd_link_hash_defweak)) + osect_vma = h->root.u.def.section->output_section->vma; + else + { + asection *sec; + int i; + + /* Sigh, the only way to get the section to offset against + is to find it the hard way. */ + for (sec = abfd->sections, i = 1; i < sym->n_scnum; i++) + sec = sec->next; + + osect_vma = sec->output_section->vma; + } + + *addendp -= osect_vma; + } +#endif + + return howto; +} + +#define coff_bfd_reloc_type_lookup coff_amd64_reloc_type_lookup +#ifdef notyet +#define coff_bfd_reloc_name_lookup coff_amd64_reloc_name_lookup +#endif + +static reloc_howto_type * +coff_amd64_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real_type code) +{ + switch (code) + { + case BFD_RELOC_RVA: + return howto_table + R_AMD64_IMAGEBASE; + case BFD_RELOC_32: + return howto_table + R_AMD64_DIR32; + case BFD_RELOC_64: + return howto_table + R_AMD64_DIR64; + case BFD_RELOC_64_PCREL: +#ifndef DONT_EXTEND_AMD64 + return howto_table + R_AMD64_PCRQUAD; +#else + /* Fall through. */ +#endif + case BFD_RELOC_32_PCREL: + return howto_table + R_AMD64_PCRLONG; + case BFD_RELOC_X86_64_32S: + return howto_table + R_RELLONG; + case BFD_RELOC_16: + return howto_table + R_RELWORD; + case BFD_RELOC_16_PCREL: + return howto_table + R_PCRWORD; + case BFD_RELOC_8: + return howto_table + R_RELBYTE; + case BFD_RELOC_8_PCREL: + return howto_table + R_PCRBYTE; +#ifdef notyet +#if defined(COFF_WITH_PE) + case BFD_RELOC_32_SECREL: + return howto_table + R_AMD64_SECREL; +#endif +#endif + default: + BFD_FAIL (); + return 0; + } +} + +#ifdef notyet +static reloc_howto_type * +coff_amd64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, + const char *r_name) +{ + unsigned int i; + + for (i = 0; i < sizeof (howto_table) / sizeof (howto_table[0]); i++) + if (howto_table[i].name != NULL + && strcasecmp (howto_table[i].name, r_name) == 0) + return &howto_table[i]; + + return NULL; +} +#endif + +#define coff_rtype_to_howto coff_amd64_rtype_to_howto + +#ifdef TARGET_UNDERSCORE + +/* If amd64 gcc uses underscores for symbol names, then it does not use + a leading dot for local labels, so if TARGET_UNDERSCORE is defined + we treat all symbols starting with L as local. */ + +static bfd_boolean +coff_amd64_is_local_label_name (bfd *abfd, const char *name) +{ + if (name[0] == 'L') + return TRUE; + + return _bfd_coff_is_local_label_name (abfd, name); +} + +#define coff_bfd_is_local_label_name coff_amd64_is_local_label_name + +#endif /* TARGET_UNDERSCORE */ + +#include "coffcode.h" + +#ifdef PE +#define amd64coff_object_p pe_bfd_object_p +#else +#define amd64coff_object_p coff_object_p +#endif + +const bfd_target +#ifdef TARGET_SYM + TARGET_SYM = +#else + x86_64coff_vec = +#endif +{ +#ifdef TARGET_NAME + TARGET_NAME, +#else + "coff-x86-64", /* Name. */ +#endif + bfd_target_coff_flavour, + BFD_ENDIAN_LITTLE, /* Data byte order is little. */ + BFD_ENDIAN_LITTLE, /* Header byte order is little. */ + + (HAS_RELOC | EXEC_P | /* Object flags. */ + HAS_LINENO | HAS_DEBUG | + HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), + + (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* Section flags. */ +#if defined(COFF_WITH_PE) + | SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_READONLY +#endif + | SEC_CODE | SEC_DATA), + +#ifdef TARGET_UNDERSCORE + TARGET_UNDERSCORE, /* Leading underscore. */ +#else + 0, /* Leading underscore. */ +#endif + '/', /* Ar_pad_char. */ + 15, /* Ar_max_namelen. */ + + bfd_getl64, bfd_getl_signed_64, bfd_putl64, + bfd_getl32, bfd_getl_signed_32, bfd_putl32, + bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Data. */ + bfd_getl64, bfd_getl_signed_64, bfd_putl64, + bfd_getl32, bfd_getl_signed_32, bfd_putl32, + bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Hdrs. */ + + /* Note that we allow an object file to be treated as a core file as well. */ + { _bfd_dummy_target, amd64coff_object_p, /* BFD_check_format. */ + bfd_generic_archive_p, amd64coff_object_p }, + { bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format. */ + bfd_false }, + { bfd_false, coff_write_object_contents, /* bfd_write_contents. */ + _bfd_write_archive_contents, bfd_false }, + + BFD_JUMP_TABLE_GENERIC (coff), + BFD_JUMP_TABLE_COPY (coff), + BFD_JUMP_TABLE_CORE (_bfd_nocore), + BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), + BFD_JUMP_TABLE_SYMBOLS (coff), + BFD_JUMP_TABLE_RELOCS (coff), + BFD_JUMP_TABLE_WRITE (coff), + BFD_JUMP_TABLE_LINK (coff), + BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), + + NULL, + + COFF_SWAP_TABLE +}; diff --git a/gnu/usr.bin/binutils-2.17/bfd/coffcode.h b/gnu/usr.bin/binutils-2.17/bfd/coffcode.h index aaf79c10325..7ac403d6c14 100644 --- a/gnu/usr.bin/binutils-2.17/bfd/coffcode.h +++ b/gnu/usr.bin/binutils-2.17/bfd/coffcode.h @@ -1883,6 +1883,12 @@ coff_set_arch_mach_hook (bfd *abfd, void * filehdr) arch = bfd_arch_i386; break; #endif +#ifdef AMD64MAGIC + case AMD64MAGIC: + arch = bfd_arch_i386; + machine = bfd_mach_x86_64; + break; +#endif #ifdef IA64MAGIC case IA64MAGIC: arch = bfd_arch_ia64; @@ -2713,13 +2719,18 @@ coff_set_flags (bfd * abfd, return TRUE; #endif -#ifdef I386MAGIC +#if defined(I386MAGIC) || defined(AMD64MAGIC) case bfd_arch_i386: +#if defined(I386MAGIC) *magicp = I386MAGIC; +#endif #ifdef LYNXOS /* Just overwrite the usual value if we're doing Lynx. */ *magicp = LYNXCOFFMAGIC; #endif +#if defined AMD64MAGIC + *magicp = AMD64MAGIC; +#endif return TRUE; #endif @@ -3751,6 +3762,7 @@ coff_write_object_contents (bfd * abfd) internal_f.f_flags |= IMAGE_FILE_LARGE_ADDRESS_AWARE; #endif +#ifndef COFF_WITH_pex64 #ifdef COFF_WITH_PE internal_f.f_flags |= IMAGE_FILE_32BIT_MACHINE; #else @@ -3759,6 +3771,7 @@ coff_write_object_contents (bfd * abfd) else internal_f.f_flags |= F_AR32W; #endif +#endif #ifdef TI_TARGET_ID /* Target id is used in TI COFF v1 and later; COFF0 won't use this field, @@ -3854,6 +3867,8 @@ coff_write_object_contents (bfd * abfd) #define __A_MAGIC_SET__ #if defined(LYNXOS) internal_a.magic = LYNXCOFFMAGIC; +#elif defined AMD64 + internal_a.magic = IMAGE_NT_OPTIONAL_HDR64_MAGIC; #else /* LYNXOS */ internal_a.magic = ZMAGIC; #endif /* LYNXOS */ diff --git a/gnu/usr.bin/binutils-2.17/bfd/config.bfd b/gnu/usr.bin/binutils-2.17/bfd/config.bfd index 32a0ef01c90..278e1c340f6 100644 --- a/gnu/usr.bin/binutils-2.17/bfd/config.bfd +++ b/gnu/usr.bin/binutils-2.17/bfd/config.bfd @@ -565,7 +565,7 @@ case "${targ}" in ;; x86_64-*-openbsd*) targ_defvec=bfd_elf64_x86_64_vec - targ_selvecs="bfd_elf32_i386_vec i386coff_vec bfd_efi_app_ia32_vec" + targ_selvecs="bfd_elf32_i386_vec i386coff_vec bfd_efi_app_ia32_vec bfd_efi_app_x86_64_vec" ;; x86_64-*-linux-*) targ_defvec=bfd_elf64_x86_64_vec diff --git a/gnu/usr.bin/binutils-2.17/bfd/configure b/gnu/usr.bin/binutils-2.17/bfd/configure index 2801f64dbb0..7b222197c0e 100755 --- a/gnu/usr.bin/binutils-2.17/bfd/configure +++ b/gnu/usr.bin/binutils-2.17/bfd/configure @@ -13072,6 +13072,7 @@ do b_out_vec_little_host) tb="$tb bout.lo aout32.lo" ;; bfd_efi_app_ia32_vec) tb="$tb efi-app-ia32.lo peigen.lo cofflink.lo" ;; bfd_efi_app_ia64_vec) tb="$tb efi-app-ia64.lo pepigen.lo cofflink.lo"; target_size=64 ;; + bfd_efi_app_x86_64_vec) tb="$tb efi-app-x86_64.lo pepigen.lo cofflink.lo"; target_size=64 ;; bfd_elf32_am33lin_vec) tb="$tb elf32-am33lin.lo elf32.lo $elf" ;; bfd_elf32_avr_vec) tb="$tb elf32-avr.lo elf32.lo $elf" ;; bfd_elf32_bfin_vec) tb="$tb elf32-bfin.lo elf32.lo $elf" ;; diff --git a/gnu/usr.bin/binutils-2.17/bfd/efi-app-x86_64.c b/gnu/usr.bin/binutils-2.17/bfd/efi-app-x86_64.c new file mode 100644 index 00000000000..130ba540997 --- /dev/null +++ b/gnu/usr.bin/binutils-2.17/bfd/efi-app-x86_64.c @@ -0,0 +1,34 @@ +/* BFD back-end for Intel64 UEFI application files. + Copyright 2007 Free Software Foundation, Inc. + +This file is part of BFD, the Binary File Descriptor library. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include "sysdep.h" +#include "bfd.h" + +#define TARGET_SYM bfd_efi_app_x86_64_vec +#define TARGET_NAME "efi-app-x86_64" +#define COFF_IMAGE_WITH_PE +#define COFF_WITH_PE +#define COFF_WITH_pep +#define PCRELOFFSET TRUE +#define TARGET_UNDERSCORE '_' +#define COFF_LONG_SECTION_NAMES +#define PEI_TARGET_SUBSYSTEM IMAGE_SUBSYSTEM_EFI_APPLICATION +#define PEI_FORCE_MINIMUM_ALIGNMENT + +#include "coff-x86_64.c" diff --git a/gnu/usr.bin/binutils-2.17/bfd/peXXigen.c b/gnu/usr.bin/binutils-2.17/bfd/peXXigen.c index 72cb056a8a3..b0fbcc28595 100644 --- a/gnu/usr.bin/binutils-2.17/bfd/peXXigen.c +++ b/gnu/usr.bin/binutils-2.17/bfd/peXXigen.c @@ -637,7 +637,8 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out) fix, strip munges the file. */ if (coff_section_data (abfd, sec) != NULL && pei_section_data (abfd, sec) != NULL) - isize += SA (FA (pei_section_data (abfd, sec)->virt_size)); + isize = (sec->vma - extra->ImageBase + + SA (FA (pei_section_data (abfd, sec)->virt_size))); } aouthdr_in->dsize = dsize; diff --git a/gnu/usr.bin/binutils-2.17/bfd/peicode.h b/gnu/usr.bin/binutils-2.17/bfd/peicode.h index 2061f415af6..1b23afa6709 100644 --- a/gnu/usr.bin/binutils-2.17/bfd/peicode.h +++ b/gnu/usr.bin/binutils-2.17/bfd/peicode.h @@ -1071,6 +1071,12 @@ pe_ILF_object_p (bfd * abfd) #endif break; + case IMAGE_FILE_MACHINE_AMD64: +#ifdef AMD64MAGIC + magic = AMD64MAGIC; +#endif + break; + case IMAGE_FILE_MACHINE_M68K: #ifdef MC68AGIC magic = MC68MAGIC; diff --git a/gnu/usr.bin/binutils-2.17/bfd/targets.c b/gnu/usr.bin/binutils-2.17/bfd/targets.c index a06872bc5a8..774aa32fb1e 100644 --- a/gnu/usr.bin/binutils-2.17/bfd/targets.c +++ b/gnu/usr.bin/binutils-2.17/bfd/targets.c @@ -551,6 +551,7 @@ extern const bfd_target armpei_little_vec; extern const bfd_target b_out_vec_big_host; extern const bfd_target b_out_vec_little_host; extern const bfd_target bfd_efi_app_ia32_vec; +extern const bfd_target bfd_efi_app_x86_64_vec; extern const bfd_target bfd_efi_app_ia64_vec; extern const bfd_target bfd_elf32_avr_vec; extern const bfd_target bfd_elf32_bfin_vec; @@ -853,6 +854,7 @@ static const bfd_target * const _bfd_target_vector[] = { &b_out_vec_big_host, &b_out_vec_little_host, &bfd_efi_app_ia32_vec, + &bfd_efi_app_x86_64_vec, #ifdef BFD64 &bfd_efi_app_ia64_vec, #endif diff --git a/gnu/usr.bin/binutils-2.17/include/coff/external.h b/gnu/usr.bin/binutils-2.17/include/coff/external.h index 9e760bd86da..8c7ab8f769b 100644 --- a/gnu/usr.bin/binutils-2.17/include/coff/external.h +++ b/gnu/usr.bin/binutils-2.17/include/coff/external.h @@ -57,6 +57,19 @@ AOUTHDR; #define AOUTSZ 28 #endif +typedef struct external_aouthdr64 +{ + char magic[2]; /* Type of file. */ + char vstamp[2]; /* Version stamp. */ + char tsize[4]; /* Text size in bytes, padded to FW bdry*/ + char dsize[4]; /* Initialized data " ". */ + char bsize[4]; /* Uninitialized data " ". */ + char entry[4]; /* Entry pt. */ + char text_start[4]; /* Base of text used for this file. */ +} +AOUTHDR64; +#define AOUTHDRSZ64 24 + #ifndef DO_NOT_DEFINE_SCNHDR /********************** SECTION HEADER **********************/ diff --git a/gnu/usr.bin/binutils-2.17/include/coff/internal.h b/gnu/usr.bin/binutils-2.17/include/coff/internal.h index ed0918a6aea..fb694d4b1f4 100644 --- a/gnu/usr.bin/binutils-2.17/include/coff/internal.h +++ b/gnu/usr.bin/binutils-2.17/include/coff/internal.h @@ -1,7 +1,7 @@ /* Internal format of COFF object file data structures, for GNU BFD. This file is part of BFD, the Binary File Descriptor library. - Copyright 1999, 2000, 2001, 2002, 2003, 2004. 2005 + Copyright 1999, 2000, 2001, 2002, 2003, 2004. 2005, 2006, 2007, 2009 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify @@ -58,10 +58,19 @@ struct internal_extra_pe_filehdr bfd_vma nt_signature; /* required NT signature, 0x4550 */ }; +#define GO32_STUBSIZE 2048 + struct internal_filehdr { struct internal_extra_pe_filehdr pe; + /* coff-stgo32 EXE stub header before BFD tdata has been allocated. + Its data is kept in INTERNAL_FILEHDR.GO32STUB afterwards. + + F_GO32STUB is set iff go32stub contains a valid data. Artifical headers + created in BFD have no pre-set go32stub. */ + char go32stub[GO32_STUBSIZE]; + /* Standard coff internal info. */ unsigned short f_magic; /* magic number */ unsigned short f_nscns; /* number of sections */ @@ -84,7 +93,8 @@ struct internal_filehdr F_AR32W file is 32-bit big-endian F_DYNLOAD rs/6000 aix: dynamically loadable w/imports & exports F_SHROBJ rs/6000 aix: file is a shared object - F_DLL PE format DLL. */ + F_DLL PE format DLL + F_GO32STUB Field go32stub contains valid data. */ #define F_RELFLG (0x0001) #define F_EXEC (0x0002) @@ -96,6 +106,7 @@ struct internal_filehdr #define F_DYNLOAD (0x1000) #define F_SHROBJ (0x2000) #define F_DLL (0x2000) +#define F_GO32STUB (0x4000) /* Extra structure which is used in the optional header. */ typedef struct _IMAGE_DATA_DIRECTORY @@ -103,6 +114,22 @@ typedef struct _IMAGE_DATA_DIRECTORY bfd_vma VirtualAddress; long Size; } IMAGE_DATA_DIRECTORY; +#define PE_EXPORT_TABLE 0 +#define PE_IMPORT_TABLE 1 +#define PE_RESOURCE_TABLE 2 +#define PE_EXCEPTION_TABLE 3 +#define PE_CERTIFICATE_TABLE 4 +#define PE_BASE_RELOCATION_TABLE 5 +#define PE_DEBUG_DATA 6 +#define PE_ARCHITECTURE 7 +#define PE_GLOBAL_PTR 8 +#define PE_TLS_TABLE 9 +#define PE_LOAD_CONFIG_TABLE 10 +#define PE_BOUND_IMPORT_TABLE 11 +#define PE_IMPORT_ADDRESS_TABLE 12 +#define PE_DELAY_IMPORT_DESCRIPTOR 13 +#define PE_CLR_RUNTIME_HEADER 14 +/* DataDirectory[15] is currently reserved, so no define. */ #define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 /* Default image base for NT. */ @@ -122,6 +149,28 @@ typedef struct _IMAGE_DATA_DIRECTORY struct internal_extra_pe_aouthdr { + /* FIXME: The following entries are in AOUTHDR. But they aren't + available internally in bfd. We add them here so that objdump + can dump them. */ + /* The state of the image file */ + short Magic; + /* Linker major version number */ + char MajorLinkerVersion; + /* Linker minor version number */ + char MinorLinkerVersion; + /* Total size of all code sections */ + long SizeOfCode; + /* Total size of all initialized data sections */ + long SizeOfInitializedData; + /* Total size of all uninitialized data sections */ + long SizeOfUninitializedData; + /* Address of entry point relative to image base. */ + bfd_vma AddressOfEntryPoint; + /* Address of the first code section relative to image base. */ + bfd_vma BaseOfCode; + /* Address of the first data section relative to image base. */ + bfd_vma BaseOfData; + /* PE stuff */ bfd_vma ImageBase; /* address of specific location in memory that file is located, NT default 0x10000 */ @@ -147,7 +196,7 @@ struct internal_extra_pe_aouthdr 3 - WINDOWS_CUI runs in Windows char sub. (console app) 5 - OS2_CUI runs in OS/2 character subsystem 7 - POSIX_CUI runs in Posix character subsystem */ - short DllCharacteristics; /* flags for DLL init, use 0 */ + unsigned short DllCharacteristics; /* flags for DLL init */ bfd_vma SizeOfStackReserve; /* amount of memory to reserve */ bfd_vma SizeOfStackCommit; /* amount of memory initially committed for initial thread's stack, default is 0x1000 */ @@ -235,12 +284,7 @@ struct internal_aouthdr #define C_LINE 104 /* line # reformatted as symbol table entry */ #define C_ALIAS 105 /* duplicate tag */ #define C_HIDDEN 106 /* ext symbol in dmert public lib */ - -#if defined _AIX52 || defined AIX_WEAK_SUPPORT -#define C_WEAKEXT 111 /* weak symbol -- AIX standard. */ -#else #define C_WEAKEXT 127 /* weak symbol -- GNU extension. */ -#endif /* New storage classes for TI COFF */ #define C_UEXT 19 /* Tentative external definition */ @@ -273,6 +317,12 @@ struct internal_aouthdr #define C_HIDEXT 107 /* Un-named external symbol */ #define C_BINCL 108 /* Marks beginning of include file */ #define C_EINCL 109 /* Marks ending of include file */ +#define C_AIX_WEAKEXT 111 /* AIX definition of C_WEAKEXT. */ + +#if defined _AIX52 || defined AIX_WEAK_SUPPORT +#undef C_WEAKEXT +#define C_WEAKEXT C_AIX_WEAKEXT +#endif /* storage classes for stab symbols for RS/6000 */ #define C_GSYM (0x80) @@ -298,6 +348,10 @@ struct internal_aouthdr #define C_THUMBEXTFUNC (C_THUMBEXT + 20) /* 150 */ #define C_THUMBSTATFUNC (C_THUMBSTAT + 20) /* 151 */ +/* True if XCOFF symbols of class CLASS have auxillary csect information. */ +#define CSECT_SYM_P(CLASS) \ + ((CLASS) == C_EXT || (CLASS) == C_AIX_WEAKEXT || (CLASS) == C_HIDEXT) + /********************** SECTION HEADER **********************/ #define SCNNMLEN (8) @@ -378,15 +432,15 @@ struct internal_syment { union { - char _n_name[SYMNMLEN]; /* old COFF version */ + char _n_name[SYMNMLEN]; /* old COFF version */ struct { - long _n_zeroes; /* new == 0 */ - long _n_offset; /* offset into string table */ + long _n_zeroes; /* new == 0 */ + long _n_offset; /* offset into string table */ } _n_n; char *_n_nptr[2]; /* allows for overlaying */ } _n; - bfd_vma n_value; /* value of symbol */ + bfd_vma n_value; /* value of symbol */ short n_scnum; /* section number */ unsigned short n_flags; /* copy of flags from filhdr */ unsigned short n_type; /* type and derived type */ @@ -604,6 +658,25 @@ struct internal_reloc unsigned long r_offset; /* Used by Alpha ECOFF, SPARC, others */ }; +/* X86-64 relocations. */ +#define R_AMD64_ABS 0 /* Reference is absolute, no relocation is necessary. */ +#define R_AMD64_DIR64 1 /* 64-bit address (VA). */ +#define R_AMD64_DIR32 2 /* 32-bit address (VA) R_DIR32. */ +#define R_AMD64_IMAGEBASE 3 /* 32-bit absolute ref w/o base R_IMAGEBASE. */ +#define R_AMD64_PCRLONG 4 /* 32-bit relative address from byte following reloc R_PCRLONG. */ +#define R_AMD64_PCRLONG_1 5 /* 32-bit relative address from byte distance 1 from reloc. */ +#define R_AMD64_PCRLONG_2 6 /* 32-bit relative address from byte distance 2 from reloc. */ +#define R_AMD64_PCRLONG_3 7 /* 32-bit relative address from byte distance 3 from reloc. */ +#define R_AMD64_PCRLONG_4 8 /* 32-bit relative address from byte distance 4 from reloc. */ +#define R_AMD64_PCRLONG_5 9 /* 32-bit relative address from byte distance 5 from reloc. */ +#define R_AMD64_SECTION 10 /* Section index. */ +#define R_AMD64_SECREL 11 /* 32 bit offset from base of section containing target R_SECREL. */ +#define R_AMD64_SECREL7 12 /* 7 bit unsigned offset from base of section containing target. */ +#define R_AMD64_TOKEN 13 /* 32 bit metadata token. */ +#define R_AMD64_PCRQUAD 14 /* Pseude PC64 relocation - Note: not specified by MS/AMD but need for gas pc-relative 64bit wide relocation generated by ELF. */ + +/* i386 Relocations. */ + #define R_DIR16 1 #define R_REL24 5 #define R_DIR32 6 diff --git a/gnu/usr.bin/binutils-2.17/include/coff/pe.h b/gnu/usr.bin/binutils-2.17/include/coff/pe.h index 643cea480c9..423465caa3a 100644 --- a/gnu/usr.bin/binutils-2.17/include/coff/pe.h +++ b/gnu/usr.bin/binutils-2.17/include/coff/pe.h @@ -267,8 +267,11 @@ typedef struct of just 4 bytes long. */ typedef struct { +#ifdef AOUTHDRSZ64 + AOUTHDR64 standard; +#else AOUTHDR standard; - +#endif /* NT extra fields; see internal.h for descriptions. */ char ImageBase[8]; char SectionAlignment[4]; @@ -294,7 +297,12 @@ typedef struct /* IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; */ char DataDirectory[16][2][4]; /* 16 entries, 2 elements/entry, 4 chars. */ } PEPAOUTHDR; + +#ifdef AOUTHDRSZ64 +#define PEPAOUTSZ (AOUTHDRSZ64 + 196 + 5 * 4) /* = 240 */ +#else #define PEPAOUTSZ 240 +#endif #undef E_FILNMLEN #define E_FILNMLEN 18 /* # characters in a file name. */ diff --git a/gnu/usr.bin/binutils-2.17/include/coff/x86_64.h b/gnu/usr.bin/binutils-2.17/include/coff/x86_64.h new file mode 100644 index 00000000000..ae432771aa5 --- /dev/null +++ b/gnu/usr.bin/binutils-2.17/include/coff/x86_64.h @@ -0,0 +1,56 @@ +/* COFF information for AMD 64. + Copyright 2006, 2009 Free Software Foundation, Inc. + + This file is part of BFD, the Binary File Descriptor library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + + Written by Kai Tietz, OneVision Software GmbH&CoKg. */ + +#define L_LNNO_SIZE 2 +#define INCLUDE_COMDAT_FIELDS_IN_AUXENT + +#include "coff/external.h" + +#define COFF_PAGE_SIZE 0x1000 + +#define AMD64MAGIC 0x8664 + +#define AMD64BADMAG(x) ((x).f_magic != AMD64MAGIC) +#define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b + +#define OMAGIC 0404 /* Object files, eg as output. */ +#define ZMAGIC IMAGE_NT_OPTIONAL_HDR64_MAGIC /* Demand load format, eg normal ld output 0x10b. */ +#define STMAGIC 0401 /* Target shlib. */ +#define SHMAGIC 0443 /* Host shlib. */ + +/* Define some NT default values. */ +/* #define NT_IMAGE_BASE 0x400000 moved to internal.h. */ +#define NT_SECTION_ALIGNMENT 0x1000 +#define NT_FILE_ALIGNMENT 0x200 +#define NT_DEF_RESERVE 0x100000 +#define NT_DEF_COMMIT 0x1000 + +/* Relocation directives. */ + +struct external_reloc +{ + char r_vaddr[4]; + char r_symndx[4]; + char r_type[2]; +}; + +#define RELOC struct external_reloc +#define RELSZ 10 diff --git a/gnu/usr.bin/binutils/bfd/Makefile.in b/gnu/usr.bin/binutils/bfd/Makefile.in index a5dcdcc9da9..1d76e140bef 100644 --- a/gnu/usr.bin/binutils/bfd/Makefile.in +++ b/gnu/usr.bin/binutils/bfd/Makefile.in @@ -633,6 +633,7 @@ BFD64_BACKENDS = \ coff64-rs6000.lo \ demo64.lo \ efi-app-ia64.lo \ + efi-app-x86_64.lo \ elf64-x86-64.lo \ elf64-alpha.lo \ elf64-hppa.lo \ @@ -659,6 +660,7 @@ BFD64_BACKENDS_CFILES = \ coff64-rs6000.c \ demo64.c \ efi-app-ia64.c \ + efi-app-x86_64.c \ elf64-x86-64.c \ elf64-alpha.c \ elf64-hppa.c \ @@ -2073,6 +2075,10 @@ efi-app-ia64.lo: efi-app-ia64.c $(INCDIR)/filenames.h \ coff-ia64.c $(INCDIR)/coff/ia64.h $(INCDIR)/coff/external.h \ $(INCDIR)/coff/internal.h $(INCDIR)/coff/pe.h libcoff.h \ $(INCDIR)/bfdlink.h coffcode.h peicode.h libpei.h +efi-app-x86_64.lo: efi-app-x86_64.c $(INCDIR)/filenames.h \ + coff-ia64.c $(INCDIR)/coff/x86_64.h $(INCDIR)/coff/external.h \ + $(INCDIR)/coff/internal.h $(INCDIR)/coff/pe.h libcoff.h \ + $(INCDIR)/bfdlink.h coffcode.h peicode.h libpei.h elf64-x86-64.lo: elf64-x86-64.c $(INCDIR)/filenames.h \ $(INCDIR)/bfdlink.h elf-bfd.h $(INCDIR)/elf/common.h \ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/elf/x86-64.h \ diff --git a/gnu/usr.bin/binutils/bfd/coff-x86_64.c b/gnu/usr.bin/binutils/bfd/coff-x86_64.c new file mode 100644 index 00000000000..84d5c6e5a1a --- /dev/null +++ b/gnu/usr.bin/binutils/bfd/coff-x86_64.c @@ -0,0 +1,785 @@ +/* BFD back-end for AMD 64 COFF files. + Copyright 2006, 2007 Free Software Foundation, Inc. + + This file is part of BFD, the Binary File Descriptor library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + + Written by Kai Tietz, OneVision Software GmbH&CoKg. */ + +#ifndef COFF_WITH_pex64 +#define COFF_WITH_pex64 +#endif + +#include "sysdep.h" +#include "bfd.h" +#include "libbfd.h" +#include "coff/x86_64.h" +#include "coff/internal.h" +#include "coff/pe.h" +#include "libcoff.h" +#include "libiberty.h" + +#define BADMAG(x) AMD64BADMAG(x) + +#ifdef COFF_WITH_pex64 +# undef AOUTSZ +# define AOUTSZ PEPAOUTSZ +# define PEAOUTHDR PEPAOUTHDR +#endif + +#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2) + +/* The page size is a guess based on ELF. */ + +#define COFF_PAGE_SIZE 0x1000 + +/* For some reason when using AMD COFF the value stored in the .text + section for a reference to a common symbol is the value itself plus + any desired offset. Ian Taylor, Cygnus Support. */ + +/* If we are producing relocatable output, we need to do some + adjustments to the object file that are not done by the + bfd_perform_relocation function. This function is called by every + reloc type to make any required adjustments. */ + +static bfd_reloc_status_type +coff_amd64_reloc (bfd *abfd, + arelent *reloc_entry, + asymbol *symbol, + void * data, + asection *input_section ATTRIBUTE_UNUSED, + bfd *output_bfd, + char **error_message ATTRIBUTE_UNUSED) +{ + symvalue diff; + +#if !defined(COFF_WITH_PE) + if (output_bfd == NULL) + return bfd_reloc_continue; +#endif + + if (bfd_is_com_section (symbol->section)) + { +#if !defined(COFF_WITH_PE) + /* We are relocating a common symbol. The current value in the + object file is ORIG + OFFSET, where ORIG is the value of the + common symbol as seen by the object file when it was compiled + (this may be zero if the symbol was undefined) and OFFSET is + the offset into the common symbol (normally zero, but may be + non-zero when referring to a field in a common structure). + ORIG is the negative of reloc_entry->addend, which is set by + the CALC_ADDEND macro below. We want to replace the value in + the object file with NEW + OFFSET, where NEW is the value of + the common symbol which we are going to put in the final + object file. NEW is symbol->value. */ + diff = symbol->value + reloc_entry->addend; +#else + /* In PE mode, we do not offset the common symbol. */ + diff = reloc_entry->addend; +#endif + } + else + { + /* For some reason bfd_perform_relocation always effectively + ignores the addend for a COFF target when producing + relocatable output. This seems to be always wrong for 386 + COFF, so we handle the addend here instead. */ +#if defined(COFF_WITH_PE) + if (output_bfd == NULL) + { + reloc_howto_type *howto = reloc_entry->howto; + + /* Although PC relative relocations are very similar between + PE and non-PE formats, but they are off by 1 << howto->size + bytes. For the external relocation, PE is very different + from others. See md_apply_fix3 () in gas/config/tc-amd64.c. + When we link PE and non-PE object files together to + generate a non-PE executable, we have to compensate it + here. */ + if(howto->pc_relative && howto->pcrel_offset) + diff = -(1 << howto->size); + else if(symbol->flags & BSF_WEAK) + diff = reloc_entry->addend - symbol->value; + else + diff = -reloc_entry->addend; + } + else +#endif + diff = reloc_entry->addend; + } + +#if defined(COFF_WITH_PE) + /* FIXME: How should this case be handled? */ + if (reloc_entry->howto->type == R_AMD64_IMAGEBASE + && output_bfd != NULL + && bfd_get_flavour (output_bfd) == bfd_target_coff_flavour) + diff -= pe_data (output_bfd)->pe_opthdr.ImageBase; +#endif + +#define DOIT(x) \ + x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask)) + + if (diff != 0) + { + reloc_howto_type *howto = reloc_entry->howto; + unsigned char *addr = (unsigned char *) data + reloc_entry->address; + + switch (howto->size) + { + case 0: + { + char x = bfd_get_8 (abfd, addr); + DOIT (x); + bfd_put_8 (abfd, x, addr); + } + break; + + case 1: + { + short x = bfd_get_16 (abfd, addr); + DOIT (x); + bfd_put_16 (abfd, (bfd_vma) x, addr); + } + break; + + case 2: + { + long x = bfd_get_32 (abfd, addr); + DOIT (x); + bfd_put_32 (abfd, (bfd_vma) x, addr); + } + break; + case 4: + { + long long x = bfd_get_64 (abfd, addr); + DOIT (x); + bfd_put_64 (abfd, (bfd_vma) x, addr); + } + break; + + default: + abort (); + } + } + + /* Now let bfd_perform_relocation finish everything up. */ + return bfd_reloc_continue; +} + +#if defined(COFF_WITH_PE) +/* Return TRUE if this relocation should appear in the output .reloc + section. */ + +static bfd_boolean +in_reloc_p (bfd *abfd ATTRIBUTE_UNUSED, reloc_howto_type *howto) +{ + return ! howto->pc_relative && howto->type != R_AMD64_IMAGEBASE; +} +#endif /* COFF_WITH_PE */ + +#ifndef PCRELOFFSET +#define PCRELOFFSET TRUE +#endif + +static reloc_howto_type howto_table[] = +{ + EMPTY_HOWTO (0), + HOWTO (R_AMD64_DIR64, /* type 1*/ + 0, /* rightshift */ + 4, /* size (0 = byte, 1 = short, 2 = long, 4 = long long) */ + 64, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + coff_amd64_reloc, /* special_function */ + "R_X86_64_64", /* name */ + TRUE, /* partial_inplace */ + 0xffffffffffffffffll, /* src_mask */ + 0xffffffffffffffffll, /* dst_mask */ + TRUE), /* pcrel_offset */ + HOWTO (R_AMD64_DIR32, /* type 2 */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + coff_amd64_reloc, /* special_function */ + "R_X86_64_32", /* name */ + TRUE, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + TRUE), /* pcrel_offset */ + /* PE IMAGE_REL_AMD64_ADDR32NB relocation (3). */ + HOWTO (R_AMD64_IMAGEBASE, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + coff_amd64_reloc, /* special_function */ + "rva32", /* name */ + TRUE, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + /* 32-bit longword PC relative relocation (4). */ + HOWTO (R_AMD64_PCRLONG, /* type 4 */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + coff_amd64_reloc, /* special_function */ + "R_X86_64_PC32", /* name */ + TRUE, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + PCRELOFFSET), /* pcrel_offset */ + + HOWTO (R_AMD64_PCRLONG_1, /* type 5 */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + coff_amd64_reloc, /* special_function */ + "DISP32+1", /* name */ + TRUE, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + PCRELOFFSET), /* pcrel_offset */ + HOWTO (R_AMD64_PCRLONG_2, /* type 6 */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + coff_amd64_reloc, /* special_function */ + "DISP32+2", /* name */ + TRUE, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + PCRELOFFSET), /* pcrel_offset */ + HOWTO (R_AMD64_PCRLONG_3, /* type 7 */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + coff_amd64_reloc, /* special_function */ + "DISP32+3", /* name */ + TRUE, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + PCRELOFFSET), /* pcrel_offset */ + HOWTO (R_AMD64_PCRLONG_4, /* type 8 */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + coff_amd64_reloc, /* special_function */ + "DISP32+4", /* name */ + TRUE, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + PCRELOFFSET), /* pcrel_offset */ + HOWTO (R_AMD64_PCRLONG_5, /* type 9 */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + coff_amd64_reloc, /* special_function */ + "DISP32+5", /* name */ + TRUE, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + PCRELOFFSET), /* pcrel_offset */ + EMPTY_HOWTO (10), /* R_AMD64_SECTION 10 */ +#if defined(COFF_WITH_PE) + /* 32-bit longword section relative relocation (11). */ + HOWTO (R_AMD64_SECREL, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + coff_amd64_reloc, /* special_function */ + "secrel32", /* name */ + TRUE, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + TRUE), /* pcrel_offset */ +#else + EMPTY_HOWTO (11), +#endif + EMPTY_HOWTO (12), + EMPTY_HOWTO (13), +#ifndef DONT_EXTEND_AMD64 + HOWTO (R_AMD64_PCRQUAD, + 0, /* rightshift */ + 4, /* size (0 = byte, 1 = short, 2 = long) */ + 64, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + coff_amd64_reloc, /* special_function */ + "R_X86_64_PC64", /* name */ + TRUE, /* partial_inplace */ + 0xffffffffffffffffll, /* src_mask */ + 0xffffffffffffffffll, /* dst_mask */ + PCRELOFFSET), /* pcrel_offset */ +#else + EMPTY_HOWTO (14), +#endif + /* Byte relocation (15). */ + HOWTO (R_RELBYTE, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 8, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + coff_amd64_reloc, /* special_function */ + "R_X86_64_8", /* name */ + TRUE, /* partial_inplace */ + 0x000000ff, /* src_mask */ + 0x000000ff, /* dst_mask */ + PCRELOFFSET), /* pcrel_offset */ + /* 16-bit word relocation (16). */ + HOWTO (R_RELWORD, /* type */ + 0, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + coff_amd64_reloc, /* special_function */ + "R_X86_64_16", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + PCRELOFFSET), /* pcrel_offset */ + /* 32-bit longword relocation (17). */ + HOWTO (R_RELLONG, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + coff_amd64_reloc, /* special_function */ + "R_X86_64_32S", /* name */ + TRUE, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + PCRELOFFSET), /* pcrel_offset */ + /* Byte PC relative relocation (18). */ + HOWTO (R_PCRBYTE, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 8, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + coff_amd64_reloc, /* special_function */ + "R_X86_64_PC8", /* name */ + TRUE, /* partial_inplace */ + 0x000000ff, /* src_mask */ + 0x000000ff, /* dst_mask */ + PCRELOFFSET), /* pcrel_offset */ + /* 16-bit word PC relative relocation (19). */ + HOWTO (R_PCRWORD, /* type */ + 0, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + coff_amd64_reloc, /* special_function */ + "R_X86_64_PC16", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + PCRELOFFSET), /* pcrel_offset */ + /* 32-bit longword PC relative relocation (20). */ + HOWTO (R_PCRLONG, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + coff_amd64_reloc, /* special_function */ + "R_X86_64_PC32", /* name */ + TRUE, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + PCRELOFFSET) /* pcrel_offset */ +}; + +/* Turn a howto into a reloc nunmber */ + +#define SELECT_RELOC(x,howto) { x.r_type = howto->type; } +#define I386 1 /* Customize coffcode.h */ +#define AMD64 1 + +#define RTYPE2HOWTO(cache_ptr, dst) \ + ((cache_ptr)->howto = \ + ((dst)->r_type < ARRAY_SIZE (howto_table)) \ + ? howto_table + (dst)->r_type \ + : NULL) + +/* For 386 COFF a STYP_NOLOAD | STYP_BSS section is part of a shared + library. On some other COFF targets STYP_BSS is normally + STYP_NOLOAD. */ +#define BSS_NOLOAD_IS_SHARED_LIBRARY + +/* Compute the addend of a reloc. If the reloc is to a common symbol, + the object file contains the value of the common symbol. By the + time this is called, the linker may be using a different symbol + from a different object file with a different value. Therefore, we + hack wildly to locate the original symbol from this file so that we + can make the correct adjustment. This macro sets coffsym to the + symbol from the original file, and uses it to set the addend value + correctly. If this is not a common symbol, the usual addend + calculation is done, except that an additional tweak is needed for + PC relative relocs. + FIXME: This macro refers to symbols and asect; these are from the + calling function, not the macro arguments. */ + +#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \ + { \ + coff_symbol_type *coffsym = NULL; \ + \ + if (ptr && bfd_asymbol_bfd (ptr) != abfd) \ + coffsym = (obj_symbols (abfd) \ + + (cache_ptr->sym_ptr_ptr - symbols)); \ + else if (ptr) \ + coffsym = coff_symbol_from (abfd, ptr); \ + \ + if (coffsym != NULL \ + && coffsym->native->u.syment.n_scnum == 0) \ + cache_ptr->addend = - coffsym->native->u.syment.n_value; \ + else if (ptr && bfd_asymbol_bfd (ptr) == abfd \ + && ptr->section != NULL) \ + cache_ptr->addend = - (ptr->section->vma + ptr->value); \ + else \ + cache_ptr->addend = 0; \ + if (ptr && howto_table[reloc.r_type].pc_relative) \ + cache_ptr->addend += asect->vma; \ + } + +/* We use the special COFF backend linker. For normal AMD64 COFF, we + can use the generic relocate_section routine. For PE, we need our + own routine. */ + +#if !defined(COFF_WITH_PE) + +#define coff_relocate_section _bfd_coff_generic_relocate_section + +#else /* COFF_WITH_PE */ + +/* The PE relocate section routine. The only difference between this + and the regular routine is that we don't want to do anything for a + relocatable link. */ + +static bfd_boolean +coff_pe_amd64_relocate_section (bfd *output_bfd, + struct bfd_link_info *info, + bfd *input_bfd, + asection *input_section, + bfd_byte *contents, + struct internal_reloc *relocs, + struct internal_syment *syms, + asection **sections) +{ + if (info->relocatable) + return TRUE; + + return _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd,input_section, contents,relocs, syms, sections); +} + +#define coff_relocate_section coff_pe_amd64_relocate_section + +#endif /* COFF_WITH_PE */ + +/* Convert an rtype to howto for the COFF backend linker. */ + +static reloc_howto_type * +coff_amd64_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED, + asection *sec, + struct internal_reloc *rel, + struct coff_link_hash_entry *h, + struct internal_syment *sym, + bfd_vma *addendp) +{ + reloc_howto_type *howto; + + if (rel->r_type > ARRAY_SIZE (howto_table)) + { + bfd_set_error (bfd_error_bad_value); + return NULL; + } + if (rel->r_type >= R_AMD64_PCRLONG_1 && rel->r_type <= R_AMD64_PCRLONG_5) + { + rel->r_vaddr += (bfd_vma)(rel->r_type-R_AMD64_PCRLONG); + rel->r_type = R_AMD64_PCRLONG; + } + howto = howto_table + rel->r_type; + +#if defined(COFF_WITH_PE) + /* Cancel out code in _bfd_coff_generic_relocate_section. */ + *addendp = 0; +#endif + + if (howto->pc_relative) + *addendp += sec->vma; + + if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0) + { + /* This is a common symbol. The section contents include the + size (sym->n_value) as an addend. The relocate_section + function will be adding in the final value of the symbol. We + need to subtract out the current size in order to get the + correct result. */ + BFD_ASSERT (h != NULL); + +#if !defined(COFF_WITH_PE) + /* I think we *do* want to bypass this. If we don't, I have + seen some data parameters get the wrong relocation address. + If I link two versions with and without this section bypassed + and then do a binary comparison, the addresses which are + different can be looked up in the map. The case in which + this section has been bypassed has addresses which correspond + to values I can find in the map. */ + *addendp -= sym->n_value; +#endif + } + +#if !defined(COFF_WITH_PE) + /* If the output symbol is common (in which case this must be a + relocatable link), we need to add in the final size of the + common symbol. */ + if (h != NULL && h->root.type == bfd_link_hash_common) + *addendp += h->root.u.c.size; +#endif + +#if defined(COFF_WITH_PE) + if (howto->pc_relative) + { + *addendp -= 4; + + /* If the symbol is defined, then the generic code is going to + add back the symbol value in order to cancel out an + adjustment it made to the addend. However, we set the addend + to 0 at the start of this function. We need to adjust here, + to avoid the adjustment the generic code will make. FIXME: + This is getting a bit hackish. */ + if (sym != NULL && sym->n_scnum != 0) + *addendp -= sym->n_value; + } + + if (rel->r_type == R_AMD64_IMAGEBASE + && (bfd_get_flavour (sec->output_section->owner) == bfd_target_coff_flavour)) + *addendp -= pe_data (sec->output_section->owner)->pe_opthdr.ImageBase; + + if (rel->r_type == R_AMD64_SECREL) + { + bfd_vma osect_vma; + + if (h && (h->type == bfd_link_hash_defined || h->type == bfd_link_hash_defweak)) + osect_vma = h->root.u.def.section->output_section->vma; + else + { + asection *sec; + int i; + + /* Sigh, the only way to get the section to offset against + is to find it the hard way. */ + for (sec = abfd->sections, i = 1; i < sym->n_scnum; i++) + sec = sec->next; + + osect_vma = sec->output_section->vma; + } + + *addendp -= osect_vma; + } +#endif + + return howto; +} + +#define coff_bfd_reloc_type_lookup coff_amd64_reloc_type_lookup +#define coff_bfd_reloc_name_lookup coff_amd64_reloc_name_lookup + +static reloc_howto_type * +coff_amd64_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real_type code) +{ + switch (code) + { + case BFD_RELOC_RVA: + return howto_table + R_AMD64_IMAGEBASE; + case BFD_RELOC_32: + return howto_table + R_AMD64_DIR32; + case BFD_RELOC_64: + return howto_table + R_AMD64_DIR64; + case BFD_RELOC_64_PCREL: +#ifndef DONT_EXTEND_AMD64 + return howto_table + R_AMD64_PCRQUAD; +#else + /* Fall through. */ +#endif + case BFD_RELOC_32_PCREL: + return howto_table + R_AMD64_PCRLONG; + case BFD_RELOC_X86_64_32S: + return howto_table + R_RELLONG; + case BFD_RELOC_16: + return howto_table + R_RELWORD; + case BFD_RELOC_16_PCREL: + return howto_table + R_PCRWORD; + case BFD_RELOC_8: + return howto_table + R_RELBYTE; + case BFD_RELOC_8_PCREL: + return howto_table + R_PCRBYTE; +#ifdef notyet +#if defined(COFF_WITH_PE) + case BFD_RELOC_32_SECREL: + return howto_table + R_AMD64_SECREL; +#endif +#endif + default: + BFD_FAIL (); + return 0; + } +} + +static reloc_howto_type * +coff_amd64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, + const char *r_name) +{ + unsigned int i; + + for (i = 0; i < sizeof (howto_table) / sizeof (howto_table[0]); i++) + if (howto_table[i].name != NULL + && strcasecmp (howto_table[i].name, r_name) == 0) + return &howto_table[i]; + + return NULL; +} + +#define coff_rtype_to_howto coff_amd64_rtype_to_howto + +#ifdef TARGET_UNDERSCORE + +/* If amd64 gcc uses underscores for symbol names, then it does not use + a leading dot for local labels, so if TARGET_UNDERSCORE is defined + we treat all symbols starting with L as local. */ + +static bfd_boolean +coff_amd64_is_local_label_name (bfd *abfd, const char *name) +{ + if (name[0] == 'L') + return TRUE; + + return _bfd_coff_is_local_label_name (abfd, name); +} + +#define coff_bfd_is_local_label_name coff_amd64_is_local_label_name + +#endif /* TARGET_UNDERSCORE */ + +#include "coffcode.h" + +#ifdef PE +#define amd64coff_object_p pe_bfd_object_p +#else +#define amd64coff_object_p coff_object_p +#endif + +const bfd_target +#ifdef TARGET_SYM + TARGET_SYM = +#else + x86_64coff_vec = +#endif +{ +#ifdef TARGET_NAME + TARGET_NAME, +#else + "coff-x86-64", /* Name. */ +#endif + bfd_target_coff_flavour, + BFD_ENDIAN_LITTLE, /* Data byte order is little. */ + BFD_ENDIAN_LITTLE, /* Header byte order is little. */ + + (HAS_RELOC | EXEC_P | /* Object flags. */ + HAS_LINENO | HAS_DEBUG | + HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), + + (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* Section flags. */ +#if defined(COFF_WITH_PE) + | SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_READONLY +#endif + | SEC_CODE | SEC_DATA), + +#ifdef TARGET_UNDERSCORE + TARGET_UNDERSCORE, /* Leading underscore. */ +#else + 0, /* Leading underscore. */ +#endif + '/', /* Ar_pad_char. */ + 15, /* Ar_max_namelen. */ + + bfd_getl64, bfd_getl_signed_64, bfd_putl64, + bfd_getl32, bfd_getl_signed_32, bfd_putl32, + bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Data. */ + bfd_getl64, bfd_getl_signed_64, bfd_putl64, + bfd_getl32, bfd_getl_signed_32, bfd_putl32, + bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Hdrs. */ + + /* Note that we allow an object file to be treated as a core file as well. */ + { _bfd_dummy_target, amd64coff_object_p, /* BFD_check_format. */ + bfd_generic_archive_p, amd64coff_object_p }, + { bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format. */ + bfd_false }, + { bfd_false, coff_write_object_contents, /* bfd_write_contents. */ + _bfd_write_archive_contents, bfd_false }, + + BFD_JUMP_TABLE_GENERIC (coff), + BFD_JUMP_TABLE_COPY (coff), + BFD_JUMP_TABLE_CORE (_bfd_nocore), + BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), + BFD_JUMP_TABLE_SYMBOLS (coff), + BFD_JUMP_TABLE_RELOCS (coff), + BFD_JUMP_TABLE_WRITE (coff), + BFD_JUMP_TABLE_LINK (coff), + BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), + + NULL, + + COFF_SWAP_TABLE +}; diff --git a/gnu/usr.bin/binutils/bfd/coffcode.h b/gnu/usr.bin/binutils/bfd/coffcode.h index 15d97093f67..c5c84f0806d 100644 --- a/gnu/usr.bin/binutils/bfd/coffcode.h +++ b/gnu/usr.bin/binutils/bfd/coffcode.h @@ -1913,6 +1913,12 @@ coff_set_arch_mach_hook (abfd, filehdr) arch = bfd_arch_i386; break; #endif +#ifdef AMD64MAGIC + case AMD64MAGIC: + arch = bfd_arch_i386; + machine = bfd_mach_x86_64; + break; +#endif #ifdef IA64MAGIC case IA64MAGIC: arch = bfd_arch_ia64; @@ -2742,13 +2748,18 @@ coff_set_flags (abfd, magicp, flagsp) return TRUE; break; #endif -#ifdef I386MAGIC +#if defined(I386MAGIC) || defined(AMD64MAGIC) case bfd_arch_i386: +#if defined(I386MAGIC) *magicp = I386MAGIC; +#endif #ifdef LYNXOS /* Just overwrite the usual value if we're doing Lynx. */ *magicp = LYNXCOFFMAGIC; #endif +#if defined AMD64MAGIC + *magicp = AMD64MAGIC; +#endif return TRUE; break; #endif @@ -3888,6 +3899,7 @@ coff_write_object_contents (abfd) internal_f.f_flags |= IMAGE_FILE_DEBUG_STRIPPED; #endif +#ifndef COFF_WITH_pex64 #ifdef COFF_WITH_PE internal_f.f_flags |= IMAGE_FILE_32BIT_MACHINE; #else @@ -3896,6 +3908,7 @@ coff_write_object_contents (abfd) else internal_f.f_flags |= F_AR32W; #endif +#endif #ifdef TI_TARGET_ID /* Target id is used in TI COFF v1 and later; COFF0 won't use this field, @@ -4003,6 +4016,8 @@ coff_write_object_contents (abfd) #define __A_MAGIC_SET__ #if defined(LYNXOS) internal_a.magic = LYNXCOFFMAGIC; +#elif defined AMD64 + internal_a.magic = IMAGE_NT_OPTIONAL_HDR64_MAGIC; #else /* LYNXOS */ internal_a.magic = ZMAGIC; #endif /* LYNXOS */ diff --git a/gnu/usr.bin/binutils/bfd/config.bfd b/gnu/usr.bin/binutils/bfd/config.bfd index 76a415fc2cd..6e17f73f2be 100644 --- a/gnu/usr.bin/binutils/bfd/config.bfd +++ b/gnu/usr.bin/binutils/bfd/config.bfd @@ -514,7 +514,7 @@ case "${targ}" in ;; x86_64-*-openbsd*) targ_defvec=bfd_elf64_x86_64_vec - targ_selvecs="bfd_elf32_i386_vec i386coff_vec bfd_efi_app_ia32_vec" + targ_selvecs="bfd_elf32_i386_vec i386coff_vec bfd_efi_app_ia32_vec bfd_efi_app_x86_64_vec" ;; x86_64-*-linux-gnu*) targ_defvec=bfd_elf64_x86_64_vec diff --git a/gnu/usr.bin/binutils/bfd/configure b/gnu/usr.bin/binutils/bfd/configure index 79345c064e7..aa7bbb6b25f 100644 --- a/gnu/usr.bin/binutils/bfd/configure +++ b/gnu/usr.bin/binutils/bfd/configure @@ -6286,6 +6286,7 @@ do b_out_vec_little_host) tb="$tb bout.lo aout32.lo" ;; bfd_efi_app_ia32_vec) tb="$tb efi-app-ia32.lo peigen.lo cofflink.lo" ;; bfd_efi_app_ia64_vec) tb="$tb efi-app-ia64.lo pepigen.lo cofflink.lo"; target_size=64 ;; + bfd_efi_app_x86_64_vec) tb="$tb efi-app-x86_64.lo pepigen.lo cofflink.lo"; target_size=64 ;; bfd_elf32_am33lin_vec) tb="$tb elf32-am33lin.lo elf32.lo $elf" ;; bfd_elf32_avr_vec) tb="$tb elf32-avr.lo elf32.lo $elf" ;; bfd_elf32_big_generic_vec) tb="$tb elf32-gen.lo elf32.lo $elf" ;; diff --git a/gnu/usr.bin/binutils/bfd/efi-app-x86_64.c b/gnu/usr.bin/binutils/bfd/efi-app-x86_64.c new file mode 100644 index 00000000000..130ba540997 --- /dev/null +++ b/gnu/usr.bin/binutils/bfd/efi-app-x86_64.c @@ -0,0 +1,34 @@ +/* BFD back-end for Intel64 UEFI application files. + Copyright 2007 Free Software Foundation, Inc. + +This file is part of BFD, the Binary File Descriptor library. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include "sysdep.h" +#include "bfd.h" + +#define TARGET_SYM bfd_efi_app_x86_64_vec +#define TARGET_NAME "efi-app-x86_64" +#define COFF_IMAGE_WITH_PE +#define COFF_WITH_PE +#define COFF_WITH_pep +#define PCRELOFFSET TRUE +#define TARGET_UNDERSCORE '_' +#define COFF_LONG_SECTION_NAMES +#define PEI_TARGET_SUBSYSTEM IMAGE_SUBSYSTEM_EFI_APPLICATION +#define PEI_FORCE_MINIMUM_ALIGNMENT + +#include "coff-x86_64.c" diff --git a/gnu/usr.bin/binutils/bfd/peXXigen.c b/gnu/usr.bin/binutils/bfd/peXXigen.c index b75fd9e6dad..ccc8f937c4f 100644 --- a/gnu/usr.bin/binutils/bfd/peXXigen.c +++ b/gnu/usr.bin/binutils/bfd/peXXigen.c @@ -661,7 +661,7 @@ _bfd_XXi_swap_aouthdr_out (abfd, in, out) { asection *sec; bfd_vma dsize = 0; - bfd_vma isize = SA(abfd->sections->filepos); + bfd_vma isize = 0; bfd_vma tsize = 0; for (sec = abfd->sections; sec; sec = sec->next) @@ -679,7 +679,8 @@ _bfd_XXi_swap_aouthdr_out (abfd, in, out) fix, strip munges the file. */ if (coff_section_data (abfd, sec) != NULL && pei_section_data (abfd, sec) != NULL) - isize += SA (FA (pei_section_data (abfd, sec)->virt_size)); + isize = (sec->vma - extra->ImageBase + + SA (FA (pei_section_data (abfd, sec)->virt_size))); } aouthdr_in->dsize = dsize; diff --git a/gnu/usr.bin/binutils/bfd/peicode.h b/gnu/usr.bin/binutils/bfd/peicode.h index 41445e592c3..ee6c31abd7f 100644 --- a/gnu/usr.bin/binutils/bfd/peicode.h +++ b/gnu/usr.bin/binutils/bfd/peicode.h @@ -1144,6 +1144,12 @@ pe_ILF_object_p (bfd * abfd) #endif break; + case IMAGE_FILE_MACHINE_AMD64: +#ifdef AMD64MAGIC + magic = AMD64MAGIC; +#endif + break; + case IMAGE_FILE_MACHINE_M68K: #ifdef MC68AGIC magic = MC68MAGIC; diff --git a/gnu/usr.bin/binutils/bfd/targets.c b/gnu/usr.bin/binutils/bfd/targets.c index 58042d51b31..9d1256bf60b 100644 --- a/gnu/usr.bin/binutils/bfd/targets.c +++ b/gnu/usr.bin/binutils/bfd/targets.c @@ -510,6 +510,7 @@ extern const bfd_target armpei_little_vec; extern const bfd_target b_out_vec_big_host; extern const bfd_target b_out_vec_little_host; extern const bfd_target bfd_efi_app_ia32_vec; +extern const bfd_target bfd_efi_app_x86_64_vec; extern const bfd_target bfd_efi_app_ia64_vec; extern const bfd_target bfd_elf32_avr_vec; extern const bfd_target bfd_elf32_big_generic_vec; @@ -797,6 +798,7 @@ static const bfd_target * const _bfd_target_vector[] = { &b_out_vec_big_host, &b_out_vec_little_host, &bfd_efi_app_ia32_vec, + &bfd_efi_app_x86_64_vec, #ifdef BFD64 &bfd_efi_app_ia64_vec, #endif diff --git a/gnu/usr.bin/binutils/include/coff/external.h b/gnu/usr.bin/binutils/include/coff/external.h index 19636dab7d7..e1845d429d6 100644 --- a/gnu/usr.bin/binutils/include/coff/external.h +++ b/gnu/usr.bin/binutils/include/coff/external.h @@ -57,6 +57,19 @@ AOUTHDR; #define AOUTSZ 28 #endif +typedef struct external_aouthdr64 +{ + char magic[2]; /* Type of file. */ + char vstamp[2]; /* Version stamp. */ + char tsize[4]; /* Text size in bytes, padded to FW bdry*/ + char dsize[4]; /* Initialized data " ". */ + char bsize[4]; /* Uninitialized data " ". */ + char entry[4]; /* Entry pt. */ + char text_start[4]; /* Base of text used for this file. */ +} +AOUTHDR64; +#define AOUTHDRSZ64 24 + #ifndef DO_NOT_DEFINE_SCNHDR /********************** SECTION HEADER **********************/ diff --git a/gnu/usr.bin/binutils/include/coff/internal.h b/gnu/usr.bin/binutils/include/coff/internal.h index 2d41bf9a5f4..fb694d4b1f4 100644 --- a/gnu/usr.bin/binutils/include/coff/internal.h +++ b/gnu/usr.bin/binutils/include/coff/internal.h @@ -1,7 +1,8 @@ /* Internal format of COFF object file data structures, for GNU BFD. This file is part of BFD, the Binary File Descriptor library. - Copyright 2001 Free Software Foundation, Inc. + Copyright 1999, 2000, 2001, 2002, 2003, 2004. 2005, 2006, 2007, 2009 + Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -15,7 +16,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef GNU_COFF_INTERNAL_H #define GNU_COFF_INTERNAL_H 1 @@ -57,10 +58,19 @@ struct internal_extra_pe_filehdr bfd_vma nt_signature; /* required NT signature, 0x4550 */ }; +#define GO32_STUBSIZE 2048 + struct internal_filehdr { struct internal_extra_pe_filehdr pe; + /* coff-stgo32 EXE stub header before BFD tdata has been allocated. + Its data is kept in INTERNAL_FILEHDR.GO32STUB afterwards. + + F_GO32STUB is set iff go32stub contains a valid data. Artifical headers + created in BFD have no pre-set go32stub. */ + char go32stub[GO32_STUBSIZE]; + /* Standard coff internal info. */ unsigned short f_magic; /* magic number */ unsigned short f_nscns; /* number of sections */ @@ -83,7 +93,8 @@ struct internal_filehdr F_AR32W file is 32-bit big-endian F_DYNLOAD rs/6000 aix: dynamically loadable w/imports & exports F_SHROBJ rs/6000 aix: file is a shared object - F_DLL PE format DLL. */ + F_DLL PE format DLL + F_GO32STUB Field go32stub contains valid data. */ #define F_RELFLG (0x0001) #define F_EXEC (0x0002) @@ -95,6 +106,7 @@ struct internal_filehdr #define F_DYNLOAD (0x1000) #define F_SHROBJ (0x2000) #define F_DLL (0x2000) +#define F_GO32STUB (0x4000) /* Extra structure which is used in the optional header. */ typedef struct _IMAGE_DATA_DIRECTORY @@ -102,6 +114,22 @@ typedef struct _IMAGE_DATA_DIRECTORY bfd_vma VirtualAddress; long Size; } IMAGE_DATA_DIRECTORY; +#define PE_EXPORT_TABLE 0 +#define PE_IMPORT_TABLE 1 +#define PE_RESOURCE_TABLE 2 +#define PE_EXCEPTION_TABLE 3 +#define PE_CERTIFICATE_TABLE 4 +#define PE_BASE_RELOCATION_TABLE 5 +#define PE_DEBUG_DATA 6 +#define PE_ARCHITECTURE 7 +#define PE_GLOBAL_PTR 8 +#define PE_TLS_TABLE 9 +#define PE_LOAD_CONFIG_TABLE 10 +#define PE_BOUND_IMPORT_TABLE 11 +#define PE_IMPORT_ADDRESS_TABLE 12 +#define PE_DELAY_IMPORT_DESCRIPTOR 13 +#define PE_CLR_RUNTIME_HEADER 14 +/* DataDirectory[15] is currently reserved, so no define. */ #define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 /* Default image base for NT. */ @@ -121,6 +149,28 @@ typedef struct _IMAGE_DATA_DIRECTORY struct internal_extra_pe_aouthdr { + /* FIXME: The following entries are in AOUTHDR. But they aren't + available internally in bfd. We add them here so that objdump + can dump them. */ + /* The state of the image file */ + short Magic; + /* Linker major version number */ + char MajorLinkerVersion; + /* Linker minor version number */ + char MinorLinkerVersion; + /* Total size of all code sections */ + long SizeOfCode; + /* Total size of all initialized data sections */ + long SizeOfInitializedData; + /* Total size of all uninitialized data sections */ + long SizeOfUninitializedData; + /* Address of entry point relative to image base. */ + bfd_vma AddressOfEntryPoint; + /* Address of the first code section relative to image base. */ + bfd_vma BaseOfCode; + /* Address of the first data section relative to image base. */ + bfd_vma BaseOfData; + /* PE stuff */ bfd_vma ImageBase; /* address of specific location in memory that file is located, NT default 0x10000 */ @@ -146,7 +196,7 @@ struct internal_extra_pe_aouthdr 3 - WINDOWS_CUI runs in Windows char sub. (console app) 5 - OS2_CUI runs in OS/2 character subsystem 7 - POSIX_CUI runs in Posix character subsystem */ - short DllCharacteristics; /* flags for DLL init, use 0 */ + unsigned short DllCharacteristics; /* flags for DLL init */ bfd_vma SizeOfStackReserve; /* amount of memory to reserve */ bfd_vma SizeOfStackCommit; /* amount of memory initially committed for initial thread's stack, default is 0x1000 */ @@ -234,12 +284,7 @@ struct internal_aouthdr #define C_LINE 104 /* line # reformatted as symbol table entry */ #define C_ALIAS 105 /* duplicate tag */ #define C_HIDDEN 106 /* ext symbol in dmert public lib */ - -#if defined _AIX52 || defined AIX_WEAK_SUPPORT -#define C_WEAKEXT 111 /* weak symbol -- AIX standard. */ -#else #define C_WEAKEXT 127 /* weak symbol -- GNU extension. */ -#endif /* New storage classes for TI COFF */ #define C_UEXT 19 /* Tentative external definition */ @@ -272,6 +317,12 @@ struct internal_aouthdr #define C_HIDEXT 107 /* Un-named external symbol */ #define C_BINCL 108 /* Marks beginning of include file */ #define C_EINCL 109 /* Marks ending of include file */ +#define C_AIX_WEAKEXT 111 /* AIX definition of C_WEAKEXT. */ + +#if defined _AIX52 || defined AIX_WEAK_SUPPORT +#undef C_WEAKEXT +#define C_WEAKEXT C_AIX_WEAKEXT +#endif /* storage classes for stab symbols for RS/6000 */ #define C_GSYM (0x80) @@ -297,6 +348,10 @@ struct internal_aouthdr #define C_THUMBEXTFUNC (C_THUMBEXT + 20) /* 150 */ #define C_THUMBSTATFUNC (C_THUMBSTAT + 20) /* 151 */ +/* True if XCOFF symbols of class CLASS have auxillary csect information. */ +#define CSECT_SYM_P(CLASS) \ + ((CLASS) == C_EXT || (CLASS) == C_AIX_WEAKEXT || (CLASS) == C_HIDEXT) + /********************** SECTION HEADER **********************/ #define SCNNMLEN (8) @@ -377,15 +432,15 @@ struct internal_syment { union { - char _n_name[SYMNMLEN]; /* old COFF version */ + char _n_name[SYMNMLEN]; /* old COFF version */ struct { - long _n_zeroes; /* new == 0 */ - long _n_offset; /* offset into string table */ + long _n_zeroes; /* new == 0 */ + long _n_offset; /* offset into string table */ } _n_n; char *_n_nptr[2]; /* allows for overlaying */ } _n; - bfd_vma n_value; /* value of symbol */ + bfd_vma n_value; /* value of symbol */ short n_scnum; /* section number */ unsigned short n_flags; /* copy of flags from filhdr */ unsigned short n_type; /* type and derived type */ @@ -603,10 +658,30 @@ struct internal_reloc unsigned long r_offset; /* Used by Alpha ECOFF, SPARC, others */ }; +/* X86-64 relocations. */ +#define R_AMD64_ABS 0 /* Reference is absolute, no relocation is necessary. */ +#define R_AMD64_DIR64 1 /* 64-bit address (VA). */ +#define R_AMD64_DIR32 2 /* 32-bit address (VA) R_DIR32. */ +#define R_AMD64_IMAGEBASE 3 /* 32-bit absolute ref w/o base R_IMAGEBASE. */ +#define R_AMD64_PCRLONG 4 /* 32-bit relative address from byte following reloc R_PCRLONG. */ +#define R_AMD64_PCRLONG_1 5 /* 32-bit relative address from byte distance 1 from reloc. */ +#define R_AMD64_PCRLONG_2 6 /* 32-bit relative address from byte distance 2 from reloc. */ +#define R_AMD64_PCRLONG_3 7 /* 32-bit relative address from byte distance 3 from reloc. */ +#define R_AMD64_PCRLONG_4 8 /* 32-bit relative address from byte distance 4 from reloc. */ +#define R_AMD64_PCRLONG_5 9 /* 32-bit relative address from byte distance 5 from reloc. */ +#define R_AMD64_SECTION 10 /* Section index. */ +#define R_AMD64_SECREL 11 /* 32 bit offset from base of section containing target R_SECREL. */ +#define R_AMD64_SECREL7 12 /* 7 bit unsigned offset from base of section containing target. */ +#define R_AMD64_TOKEN 13 /* 32 bit metadata token. */ +#define R_AMD64_PCRQUAD 14 /* Pseude PC64 relocation - Note: not specified by MS/AMD but need for gas pc-relative 64bit wide relocation generated by ELF. */ + +/* i386 Relocations. */ + #define R_DIR16 1 #define R_REL24 5 #define R_DIR32 6 #define R_IMAGEBASE 7 +#define R_SECREL32 11 #define R_RELBYTE 15 #define R_RELWORD 16 #define R_RELLONG 17 @@ -713,6 +788,11 @@ struct internal_reloc #define R_IMM4H 0x24 /* high nibble */ #define R_DISP7 0x25 /* djnz displacement */ +/* Z80 modes */ +#define R_OFF8 0x32 /* 8 bit signed abs, for (i[xy]+d) */ +#define R_IMM24 0x33 /* 24 bit abs */ +/* R_JR, R_IMM8, R_IMM16, R_IMM32 - as for Z8k */ + /* H8500 modes */ #define R_H8500_IMM8 1 /* 8 bit immediate */ diff --git a/gnu/usr.bin/binutils/include/coff/pe.h b/gnu/usr.bin/binutils/include/coff/pe.h index 363d307379b..1ce3de0f500 100644 --- a/gnu/usr.bin/binutils/include/coff/pe.h +++ b/gnu/usr.bin/binutils/include/coff/pe.h @@ -267,8 +267,11 @@ typedef struct of just 4 bytes long. */ typedef struct { +#ifdef AOUTHDRSZ64 + AOUTHDR64 standard; +#else AOUTHDR standard; - +#endif /* NT extra fields; see internal.h for descriptions. */ char ImageBase[8]; char SectionAlignment[4]; @@ -294,7 +297,12 @@ typedef struct /* IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; */ char DataDirectory[16][2][4]; /* 16 entries, 2 elements/entry, 4 chars. */ } PEPAOUTHDR; + +#ifdef AOUTHDRSZ64 +#define PEPAOUTSZ (AOUTHDRSZ64 + 196 + 5 * 4) /* = 240 */ +#else #define PEPAOUTSZ 240 +#endif #undef E_FILNMLEN #define E_FILNMLEN 18 /* # characters in a file name. */ diff --git a/gnu/usr.bin/binutils/include/coff/x86_64.h b/gnu/usr.bin/binutils/include/coff/x86_64.h new file mode 100644 index 00000000000..ae432771aa5 --- /dev/null +++ b/gnu/usr.bin/binutils/include/coff/x86_64.h @@ -0,0 +1,56 @@ +/* COFF information for AMD 64. + Copyright 2006, 2009 Free Software Foundation, Inc. + + This file is part of BFD, the Binary File Descriptor library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + + Written by Kai Tietz, OneVision Software GmbH&CoKg. */ + +#define L_LNNO_SIZE 2 +#define INCLUDE_COMDAT_FIELDS_IN_AUXENT + +#include "coff/external.h" + +#define COFF_PAGE_SIZE 0x1000 + +#define AMD64MAGIC 0x8664 + +#define AMD64BADMAG(x) ((x).f_magic != AMD64MAGIC) +#define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b + +#define OMAGIC 0404 /* Object files, eg as output. */ +#define ZMAGIC IMAGE_NT_OPTIONAL_HDR64_MAGIC /* Demand load format, eg normal ld output 0x10b. */ +#define STMAGIC 0401 /* Target shlib. */ +#define SHMAGIC 0443 /* Host shlib. */ + +/* Define some NT default values. */ +/* #define NT_IMAGE_BASE 0x400000 moved to internal.h. */ +#define NT_SECTION_ALIGNMENT 0x1000 +#define NT_FILE_ALIGNMENT 0x200 +#define NT_DEF_RESERVE 0x100000 +#define NT_DEF_COMMIT 0x1000 + +/* Relocation directives. */ + +struct external_reloc +{ + char r_vaddr[4]; + char r_symndx[4]; + char r_type[2]; +}; + +#define RELOC struct external_reloc +#define RELSZ 10 |