/* Support for the generic parts of PE/PEI; the common executable parts.
Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- 2005 Free Software Foundation, Inc.
+ 2005, 2006 Free Software Foundation, Inc.
Written by Cygnus Solutions.
This file is part of BFD, the Binary File Descriptor library.
on this code has a chance of getting something accomplished without
wasting too much time. */
-/* This expands into COFF_WITH_pe or COFF_WITH_pep depending on whether
- we're compiling for straight PE or PE+. */
+/* This expands into COFF_WITH_pe, COFF_WITH_pep, or COFF_WITH_pex64
+ depending on whether we're compiling for straight PE or PE+. */
#define COFF_WITH_XX
#include "bfd.h"
within PE/PEI, so we get them from there. FIXME: The lack of
variance is an assumption which may prove to be incorrect if new
PE/PEI targets are created. */
-#ifdef COFF_WITH_pep
+#if defined COFF_WITH_pex64
+# include "coff/x86_64.h"
+#elif defined COFF_WITH_pep
# include "coff/ia64.h"
#else
# include "coff/i386.h"
#include "libcoff.h"
#include "libpei.h"
-#ifdef COFF_WITH_pep
+#if defined COFF_WITH_pep || defined COFF_WITH_pex64
# undef AOUTSZ
# define AOUTSZ PEPAOUTSZ
# define PEAOUTHDR PEPAOUTHDR
int unused_section_number = 0;
asection *sec;
char *name;
+ flagword flags;
for (sec = abfd->sections; sec; sec = sec->next)
if (unused_section_number <= sec->target_index)
if (name == NULL)
return;
strcpy (name, in->n_name);
- sec = bfd_make_section_anyway (abfd, name);
+ flags = SEC_HAS_CONTENTS | SEC_ALLOC | SEC_DATA | SEC_LOAD;
+ sec = bfd_make_section_anyway_with_flags (abfd, name, flags);
sec->vma = 0;
sec->lma = 0;
sec->userdata = NULL;
sec->next = NULL;
sec->alignment_power = 2;
- sec->flags = SEC_HAS_CONTENTS | SEC_ALLOC | SEC_DATA | SEC_LOAD;
sec->target_index = unused_section_number;
aouthdr_int->entry = GET_AOUTHDR_ENTRY (abfd, aouthdr_ext->entry);
aouthdr_int->text_start =
GET_AOUTHDR_TEXT_START (abfd, aouthdr_ext->text_start);
-#ifndef COFF_WITH_pep
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
/* PE32+ does not have data_start member! */
aouthdr_int->data_start =
GET_AOUTHDR_DATA_START (abfd, aouthdr_ext->data_start);
/* If data directory is empty, rva also should be 0. */
int size =
H_GET_32 (abfd, src->DataDirectory[idx][1]);
+
a->DataDirectory[idx].Size = size;
if (size)
if (aouthdr_int->entry)
{
aouthdr_int->entry += a->ImageBase;
-#ifndef COFF_WITH_pep
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
aouthdr_int->entry &= 0xffffffff;
#endif
}
if (aouthdr_int->tsize)
{
aouthdr_int->text_start += a->ImageBase;
-#ifndef COFF_WITH_pep
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
aouthdr_int->text_start &= 0xffffffff;
#endif
}
-#ifndef COFF_WITH_pep
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
/* PE32+ does not have data_start member! */
if (aouthdr_int->dsize)
{
if (aouthdr_in->tsize)
{
aouthdr_in->text_start -= ib;
-#ifndef COFF_WITH_pep
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
aouthdr_in->text_start &= 0xffffffff;
#endif
}
if (aouthdr_in->dsize)
{
aouthdr_in->data_start -= ib;
-#ifndef COFF_WITH_pep
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
aouthdr_in->data_start &= 0xffffffff;
#endif
}
if (aouthdr_in->entry)
{
aouthdr_in->entry -= ib;
-#ifndef COFF_WITH_pep
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
aouthdr_in->entry &= 0xffffffff;
#endif
}
PUT_AOUTHDR_TEXT_START (abfd, aouthdr_in->text_start,
aouthdr_out->standard.text_start);
-#ifndef COFF_WITH_pep
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
/* PE32+ does not have data_start member! */
PUT_AOUTHDR_DATA_START (abfd, aouthdr_in->data_start,
aouthdr_out->standard.data_start);
}
/* Print HintName vector entries. */
+#ifdef COFF_WITH_pex64
+ for (j = 0; j < datasize; j += 8)
+ {
+ unsigned long member = bfd_get_32 (abfd, data + idx + j);
+ unsigned long member_high = bfd_get_32 (abfd, data + idx + j + 4);
+
+ if (!member && !member_high)
+ break;
+
+ if (member_high & 0x80000000)
+ fprintf (file, "\t%lx%08lx\t %4lx%08lx <none>",
+ member_high,member, member_high & 0x7fffffff, member);
+ else
+ {
+ int ordinal;
+ char *member_name;
+
+ ordinal = bfd_get_16 (abfd, data + member - adj);
+ member_name = (char *) data + member - adj + 2;
+ fprintf (file, "\t%04lx\t %4d %s",member, ordinal, member_name);
+ }
+
+ /* If the time stamp is not zero, the import address
+ table holds actual addresses. */
+ if (time_stamp != 0
+ && first_thunk != 0
+ && first_thunk != hint_addr)
+ fprintf (file, "\t%04lx",
+ (long) bfd_get_32 (abfd, ft_data + ft_idx + j));
+ fprintf (file, "\n");
+ }
+#else
for (j = 0; j < datasize; j += 4)
{
unsigned long member = bfd_get_32 (abfd, data + idx + j);
fprintf (file, "\n");
}
-
+#endif
if (ft_allocated)
free (ft_data);
}
static bfd_boolean
pe_print_pdata (bfd * abfd, void * vfile)
{
-#ifdef COFF_WITH_pep
-# define PDATA_ROW_SIZE (3*8)
+#if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+# define PDATA_ROW_SIZE (3 * 8)
#else
-# define PDATA_ROW_SIZE (5*4)
+# define PDATA_ROW_SIZE (5 * 4)
#endif
FILE *file = (FILE *) vfile;
bfd_byte *data = 0;
fprintf (file,
_("\nThe Function Table (interpreted .pdata section contents)\n"));
-#ifdef COFF_WITH_pep
+#if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
fprintf (file,
_(" vma:\t\t\tBegin Address End Address Unwind Info\n"));
#else
fprintf_vma (file, begin_addr); fputc (' ', file);
fprintf_vma (file, end_addr); fputc (' ', file);
fprintf_vma (file, eh_handler);
-#ifndef COFF_WITH_pep
+#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64)
fputc (' ', file);
fprintf_vma (file, eh_data); fputc (' ', file);
fprintf_vma (file, prolog_end_addr);
{
struct coff_link_hash_entry *h1;
struct bfd_link_info *info = pfinfo->info;
+ bfd_boolean result = TRUE;
/* There are a few fields that need to be filled in now while we
have symbol table access.
".idata$2", FALSE, FALSE, TRUE);
if (h1 != NULL)
{
- pe_data (abfd)->pe_opthdr.DataDirectory[1].VirtualAddress =
- (h1->root.u.def.value
- + h1->root.u.def.section->output_section->vma
- + h1->root.u.def.section->output_offset);
+ /* PR ld/2729: We cannot rely upon all the output sections having been
+ created properly, so check before referencing them. Issue a warning
+ message for any sections tht could not be found. */
+ if (h1->root.u.def.section != NULL
+ && h1->root.u.def.section->output_section != NULL)
+ pe_data (abfd)->pe_opthdr.DataDirectory[1].VirtualAddress =
+ (h1->root.u.def.value
+ + h1->root.u.def.section->output_section->vma
+ + h1->root.u.def.section->output_offset);
+ else
+ {
+ _bfd_error_handler
+ (_("%B: unable to fill in DataDictionary[1] because .idata$2 is missing"),
+ abfd);
+ result = FALSE;
+ }
+
h1 = coff_link_hash_lookup (coff_hash_table (info),
".idata$4", FALSE, FALSE, TRUE);
- pe_data (abfd)->pe_opthdr.DataDirectory[1].Size =
- ((h1->root.u.def.value
- + h1->root.u.def.section->output_section->vma
- + h1->root.u.def.section->output_offset)
- - pe_data (abfd)->pe_opthdr.DataDirectory[1].VirtualAddress);
+ if (h1 != NULL
+ && h1->root.u.def.section != NULL
+ && h1->root.u.def.section->output_section != NULL)
+ pe_data (abfd)->pe_opthdr.DataDirectory[1].Size =
+ ((h1->root.u.def.value
+ + h1->root.u.def.section->output_section->vma
+ + h1->root.u.def.section->output_offset)
+ - pe_data (abfd)->pe_opthdr.DataDirectory[1].VirtualAddress);
+ else
+ {
+ _bfd_error_handler
+ (_("%B: unable to fill in DataDictionary[1] because .idata$4 is missing"),
+ abfd);
+ result = FALSE;
+ }
/* The import address table. This is the size/address of
.idata$5. */
h1 = coff_link_hash_lookup (coff_hash_table (info),
".idata$5", FALSE, FALSE, TRUE);
- pe_data (abfd)->pe_opthdr.DataDirectory[12].VirtualAddress =
- (h1->root.u.def.value
- + h1->root.u.def.section->output_section->vma
- + h1->root.u.def.section->output_offset);
+ if (h1 != NULL
+ && h1->root.u.def.section != NULL
+ && h1->root.u.def.section->output_section != NULL)
+ pe_data (abfd)->pe_opthdr.DataDirectory[12].VirtualAddress =
+ (h1->root.u.def.value
+ + h1->root.u.def.section->output_section->vma
+ + h1->root.u.def.section->output_offset);
+ else
+ {
+ _bfd_error_handler
+ (_("%B: unable to fill in DataDictionary[12] because .idata$5 is missing"),
+ abfd);
+ result = FALSE;
+ }
+
h1 = coff_link_hash_lookup (coff_hash_table (info),
".idata$6", FALSE, FALSE, TRUE);
- pe_data (abfd)->pe_opthdr.DataDirectory[12].Size =
- ((h1->root.u.def.value
- + h1->root.u.def.section->output_section->vma
- + h1->root.u.def.section->output_offset)
- - pe_data (abfd)->pe_opthdr.DataDirectory[12].VirtualAddress);
+ if (h1 != NULL
+ && h1->root.u.def.section != NULL
+ && h1->root.u.def.section->output_section != NULL)
+ pe_data (abfd)->pe_opthdr.DataDirectory[12].Size =
+ ((h1->root.u.def.value
+ + h1->root.u.def.section->output_section->vma
+ + h1->root.u.def.section->output_offset)
+ - pe_data (abfd)->pe_opthdr.DataDirectory[12].VirtualAddress);
+ else
+ {
+ _bfd_error_handler
+ (_("%B: unable to fill in DataDictionary[12] because .idata$6 is missing"),
+ abfd);
+ result = FALSE;
+ }
}
h1 = coff_link_hash_lookup (coff_hash_table (info),
"__tls_used", FALSE, FALSE, TRUE);
if (h1 != NULL)
{
- pe_data (abfd)->pe_opthdr.DataDirectory[9].VirtualAddress =
- (h1->root.u.def.value
- + h1->root.u.def.section->output_section->vma
- + h1->root.u.def.section->output_offset
- - pe_data (abfd)->pe_opthdr.ImageBase);
+ if (h1->root.u.def.section != NULL
+ && h1->root.u.def.section->output_section != NULL)
+ pe_data (abfd)->pe_opthdr.DataDirectory[9].VirtualAddress =
+ (h1->root.u.def.value
+ + h1->root.u.def.section->output_section->vma
+ + h1->root.u.def.section->output_offset
+ - pe_data (abfd)->pe_opthdr.ImageBase);
+ else
+ {
+ _bfd_error_handler
+ (_("%B: unable to fill in DataDictionary[9] because __tls_used is missing"),
+ abfd);
+ result = FALSE;
+ }
+
pe_data (abfd)->pe_opthdr.DataDirectory[9].Size = 0x18;
}
/* If we couldn't find idata$2, we either have an excessively
trivial program or are in DEEP trouble; we have to assume trivial
program.... */
- return TRUE;
+ return result;
}