#include "coff/internal.h"
#include "../bfd/libcoff.h"
#include "deffile.h"
+
+#ifdef pe_use_x86_64
+
+#define PE_IDATA4_SIZE 8
+#define PE_IDATA5_SIZE 8
+#include "pep-dll.h"
+#undef AOUTSZ
+#define AOUTSZ PEPAOUTSZ
+#define PEAOUTHDR PEPAOUTHDR
+
+#else
+
#include "pe-dll.h"
+#endif
+
+#ifndef PE_IDATA4_SIZE
+#define PE_IDATA4_SIZE 4
+#endif
+
+#ifndef PE_IDATA5_SIZE
+#define PE_IDATA5_SIZE 4
+#endif
+
/* This file turns a regular Windows PE image into a DLL. Because of
the complexity of this operation, it has been broken down into a
number of separate modules which are all called by the main function
normally only called once, so static variables are used to reduce
the number of parameters and return values required.
- See also: ld/emultempl/pe.em. */
+ See also: ld/emultempl/pe.em and ld/emultempl/pep.em. */
/* Auto-import feature by Paul Sokolovsky
not, prohibiting that (detecting violation) would require more work on
behalf of loader than not doing it.
- See also: ld/emultempl/pe.em. */
+ See also: ld/emultempl/pe.em and ld/emultempl/pep.em. */
static void add_bfd_to_link (bfd *, const char *, struct bfd_link_info *);
static pe_details_type pe_detail_list[] =
{
{
+#ifdef pe_use_x86_64
+ "pei-x86-64",
+ "pe-x86-64",
+ 3 /* R_IMAGEBASE */,
+#else
"pei-i386",
"pe-i386",
7 /* R_IMAGEBASE */,
+#endif
PE_ARCH_i386,
bfd_arch_i386,
TRUE,
it is too restrictive. Instead we have
a target specific list to use: */
afptr = pe_details->autofilter_symbollist;
+
while (afptr->name)
{
if (strcmp (n, afptr->name) == 0)
switch BITS_AND_SHIFT (relocs[i]->howto->bitsize,
relocs[i]->howto->rightshift)
{
+#ifdef pe_use_x86_64
+ case BITS_AND_SHIFT (64, 0):
+ reloc_data[total_relocs].type = 10;
+ total_relocs++;
+ break;
+#endif
case BITS_AND_SHIFT (32, 0):
reloc_data[total_relocs].type = 3;
total_relocs++;
quick_reloc (abfd, 16, BFD_RELOC_RVA, 1);
save_relocs (id2);
- bfd_set_section_size (abfd, id5, 4);
- d5 = xmalloc (4);
+ bfd_set_section_size (abfd, id5, PE_IDATA5_SIZE);
+ d5 = xmalloc (PE_IDATA5_SIZE);
id5->contents = d5;
- memset (d5, 0, 4);
+ memset (d5, 0, PE_IDATA5_SIZE);
- bfd_set_section_size (abfd, id4, 4);
- d4 = xmalloc (4);
+ bfd_set_section_size (abfd, id4, PE_IDATA4_SIZE);
+ d4 = xmalloc (PE_IDATA4_SIZE);
id4->contents = d4;
- memset (d4, 0, 4);
+ memset (d4, 0, PE_IDATA4_SIZE);
bfd_set_symtab (abfd, symtab, symptr);
bfd_set_section_contents (abfd, id2, d2, 0, 20);
- bfd_set_section_contents (abfd, id5, d5, 0, 4);
- bfd_set_section_contents (abfd, id4, d4, 0, 4);
+ bfd_set_section_contents (abfd, id5, d5, 0, PE_IDATA5_SIZE);
+ bfd_set_section_contents (abfd, id4, d4, 0, PE_IDATA4_SIZE);
bfd_make_readable (abfd);
return abfd;
/* .section .idata$4
.long 0
+ [.long 0] for PE+
.section .idata$5
.long 0
+ [.long 0] for PE+
.section idata$7
.global __my_dll_iname
__my_dll_iname:
id7 = quick_section (abfd, ".idata$7", SEC_HAS_CONTENTS, 2);
quick_symbol (abfd, U (""), dll_symname, "_iname", id7, BSF_GLOBAL, 0);
- bfd_set_section_size (abfd, id4, 4);
- d4 = xmalloc (4);
+ bfd_set_section_size (abfd, id4, PE_IDATA4_SIZE);
+ d4 = xmalloc (PE_IDATA4_SIZE);
id4->contents = d4;
- memset (d4, 0, 4);
+ memset (d4, 0, PE_IDATA4_SIZE);
- bfd_set_section_size (abfd, id5, 4);
- d5 = xmalloc (4);
+ bfd_set_section_size (abfd, id5, PE_IDATA5_SIZE);
+ d5 = xmalloc (PE_IDATA5_SIZE);
id5->contents = d5;
- memset (d5, 0, 4);
+ memset (d5, 0, PE_IDATA5_SIZE);
len = strlen (dll_filename) + 1;
if (len & 1)
bfd_set_symtab (abfd, symtab, symptr);
- bfd_set_section_contents (abfd, id4, d4, 0, 4);
- bfd_set_section_contents (abfd, id5, d5, 0, 4);
+ bfd_set_section_contents (abfd, id4, d4, 0, PE_IDATA4_SIZE);
+ bfd_set_section_contents (abfd, id5, d5, 0, PE_IDATA5_SIZE);
bfd_set_section_contents (abfd, id7, d7, 0, len);
bfd_make_readable (abfd);
quick_reloc (abfd, 0, BFD_RELOC_RVA, 5);
save_relocs (id7);
- bfd_set_section_size (abfd, id5, 4);
- d5 = xmalloc (4);
+ bfd_set_section_size (abfd, id5, PE_IDATA5_SIZE);
+ d5 = xmalloc (PE_IDATA5_SIZE);
id5->contents = d5;
- memset (d5, 0, 4);
+ memset (d5, 0, PE_IDATA5_SIZE);
if (exp->flag_noname)
{
d5[0] = exp->ordinal;
d5[1] = exp->ordinal >> 8;
- d5[3] = 0x80;
+ d5[PE_IDATA5_SIZE - 1] = 0x80;
}
else
{
save_relocs (id5);
}
- bfd_set_section_size (abfd, id4, 4);
- d4 = xmalloc (4);
+ bfd_set_section_size (abfd, id4, PE_IDATA4_SIZE);
+ d4 = xmalloc (PE_IDATA4_SIZE);
id4->contents = d4;
- memset (d4, 0, 4);
+ memset (d4, 0, PE_IDATA4_SIZE);
if (exp->flag_noname)
{
d4[0] = exp->ordinal;
d4[1] = exp->ordinal >> 8;
- d4[3] = 0x80;
+ d4[PE_IDATA4_SIZE - 1] = 0x80;
}
else
{
bfd_set_section_contents (abfd, tx, td, 0, jmp_byte_count);
bfd_set_section_contents (abfd, id7, d7, 0, 4);
- bfd_set_section_contents (abfd, id5, d5, 0, 4);
- bfd_set_section_contents (abfd, id4, d4, 0, 4);
+ bfd_set_section_contents (abfd, id5, d5, 0, PE_IDATA5_SIZE);
+ bfd_set_section_contents (abfd, id4, d4, 0, PE_IDATA4_SIZE);
if (!exp->flag_noname)
bfd_set_section_contents (abfd, id6, d6, 0, len);
quick_symbol (abfd, U ("_nm_thnk_"), import, "", id4, BSF_GLOBAL, 0);
quick_symbol (abfd, U ("_nm_"), import, "", UNDSEC, BSF_GLOBAL, 0);
- bfd_set_section_size (abfd, id4, 8);
- d4 = xmalloc (4);
+ bfd_set_section_size (abfd, id4, PE_IDATA4_SIZE);
+ d4 = xmalloc (PE_IDATA4_SIZE);
id4->contents = d4;
- memset (d4, 0, 8);
+ memset (d4, 0, PE_IDATA4_SIZE);
quick_reloc (abfd, 0, BFD_RELOC_RVA, 2);
save_relocs (id4);
bfd_set_symtab (abfd, symtab, symptr);
- bfd_set_section_contents (abfd, id4, d4, 0, 8);
+ bfd_set_section_contents (abfd, id4, d4, 0, PE_IDATA4_SIZE);
bfd_make_readable (abfd);
return abfd;
current_sec, /* sym->section, */
rel->address, NULL, TRUE, FALSE, &bh);
- if (0)
- {
- struct coff_link_hash_entry *myh;
-
- myh = (struct coff_link_hash_entry *) bh;
- printf ("type:%d\n", myh->type);
- printf ("%s\n", myh->root.u.def.section->name);
- }
-
return fixup_name;
}
/* Get pe_header, optional header and numbers of export entries. */
pe_header_offset = pe_get32 (dll, 0x3c);
opthdr_ofs = pe_header_offset + 4 + 20;
+#ifdef pe_use_x86_64
+ num_entries = pe_get32 (dll, opthdr_ofs + 92 + 4 * 4); /* & NumberOfRvaAndSizes. */
+#else
num_entries = pe_get32 (dll, opthdr_ofs + 92);
+#endif
if (num_entries < 1) /* No exports. */
return FALSE;
+#ifdef pe_use_x86_64
+ export_rva = pe_get32 (dll, opthdr_ofs + 96 + 4 * 4);
+ export_size = pe_get32 (dll, opthdr_ofs + 100 + 4 * 4);
+#else
export_rva = pe_get32 (dll, opthdr_ofs + 96);
export_size = pe_get32 (dll, opthdr_ofs + 100);
+#endif
+
nsections = pe_get16 (dll, pe_header_offset + 4 + 2);
secptr = (pe_header_offset + 4 + 20 +
pe_get16 (dll, pe_header_offset + 4 + 16));