Line 1... |
Line 1... |
/* Support for the generic parts of PE/PEI; the common executable parts.
|
/* Support for the generic parts of PE/PEI; the common executable parts.
|
Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
2005, 2006, 2007 Free Software Foundation, Inc.
|
2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
|
Written by Cygnus Solutions.
|
Written by Cygnus Solutions.
|
|
|
This file is part of BFD, the Binary File Descriptor library.
|
This file is part of BFD, the Binary File Descriptor library.
|
|
|
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
Line 127... |
Line 127... |
copy of the .idata section's flags rather than something useful.
|
copy of the .idata section's flags rather than something useful.
|
When these symbols are encountered, change the value to 0 so that
|
When these symbols are encountered, change the value to 0 so that
|
they will be handled somewhat correctly in the bfd code. */
|
they will be handled somewhat correctly in the bfd code. */
|
if (in->n_sclass == C_SECTION)
|
if (in->n_sclass == C_SECTION)
|
{
|
{
|
|
char namebuf[SYMNMLEN + 1];
|
|
const char *name = NULL;
|
|
|
in->n_value = 0x0;
|
in->n_value = 0x0;
|
|
|
/* Create synthetic empty sections as needed. DJ */
|
/* Create synthetic empty sections as needed. DJ */
|
if (in->n_scnum == 0)
|
if (in->n_scnum == 0)
|
{
|
{
|
asection *sec;
|
asection *sec;
|
|
|
for (sec = abfd->sections; sec; sec = sec->next)
|
name = _bfd_coff_internal_syment_name (abfd, in, namebuf);
|
{
|
if (name == NULL)
|
if (strcmp (sec->name, in->n_name) == 0)
|
/* FIXME: Return error. */
|
{
|
abort ();
|
|
sec = bfd_get_section_by_name (abfd, name);
|
|
if (sec != NULL)
|
in->n_scnum = sec->target_index;
|
in->n_scnum = sec->target_index;
|
break;
|
|
}
|
|
}
|
|
}
|
}
|
|
|
if (in->n_scnum == 0)
|
if (in->n_scnum == 0)
|
{
|
{
|
int unused_section_number = 0;
|
int unused_section_number = 0;
|
asection *sec;
|
asection *sec;
|
char *name;
|
|
flagword flags;
|
flagword flags;
|
|
|
for (sec = abfd->sections; sec; sec = sec->next)
|
for (sec = abfd->sections; sec; sec = sec->next)
|
if (unused_section_number <= sec->target_index)
|
if (unused_section_number <= sec->target_index)
|
unused_section_number = sec->target_index + 1;
|
unused_section_number = sec->target_index + 1;
|
|
|
name = bfd_alloc (abfd, (bfd_size_type) strlen (in->n_name) + 10);
|
if (name == namebuf)
|
|
{
|
|
name = (const char *) bfd_alloc (abfd, strlen (namebuf) + 1);
|
if (name == NULL)
|
if (name == NULL)
|
return;
|
/* FIXME: Return error. */
|
strcpy (name, in->n_name);
|
abort ();
|
|
strcpy ((char *) name, namebuf);
|
|
}
|
flags = SEC_HAS_CONTENTS | SEC_ALLOC | SEC_DATA | SEC_LOAD;
|
flags = SEC_HAS_CONTENTS | SEC_ALLOC | SEC_DATA | SEC_LOAD;
|
sec = bfd_make_section_anyway_with_flags (abfd, name, flags);
|
sec = bfd_make_section_anyway_with_flags (abfd, name, flags);
|
|
if (sec == NULL)
|
|
/* FIXME: Return error. */
|
|
abort ();
|
|
|
sec->vma = 0;
|
sec->vma = 0;
|
sec->lma = 0;
|
sec->lma = 0;
|
sec->size = 0;
|
sec->size = 0;
|
sec->filepos = 0;
|
sec->filepos = 0;
|
Line 221... |
Line 229... |
|
|
void
|
void
|
_bfd_XXi_swap_aux_in (bfd * abfd,
|
_bfd_XXi_swap_aux_in (bfd * abfd,
|
void * ext1,
|
void * ext1,
|
int type,
|
int type,
|
int class,
|
int in_class,
|
int indx ATTRIBUTE_UNUSED,
|
int indx ATTRIBUTE_UNUSED,
|
int numaux ATTRIBUTE_UNUSED,
|
int numaux ATTRIBUTE_UNUSED,
|
void * in1)
|
void * in1)
|
{
|
{
|
AUXENT *ext = (AUXENT *) ext1;
|
AUXENT *ext = (AUXENT *) ext1;
|
union internal_auxent *in = (union internal_auxent *) in1;
|
union internal_auxent *in = (union internal_auxent *) in1;
|
|
|
switch (class)
|
switch (in_class)
|
{
|
{
|
case C_FILE:
|
case C_FILE:
|
if (ext->x_file.x_fname[0] == 0)
|
if (ext->x_file.x_fname[0] == 0)
|
{
|
{
|
in->x_file.x_n.x_zeroes = 0;
|
in->x_file.x_n.x_zeroes = 0;
|
Line 260... |
Line 268... |
}
|
}
|
|
|
in->x_sym.x_tagndx.l = H_GET_32 (abfd, ext->x_sym.x_tagndx);
|
in->x_sym.x_tagndx.l = H_GET_32 (abfd, ext->x_sym.x_tagndx);
|
in->x_sym.x_tvndx = H_GET_16 (abfd, ext->x_sym.x_tvndx);
|
in->x_sym.x_tvndx = H_GET_16 (abfd, ext->x_sym.x_tvndx);
|
|
|
if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
|
if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
|
|
|| ISTAG (in_class))
|
{
|
{
|
in->x_sym.x_fcnary.x_fcn.x_lnnoptr = GET_FCN_LNNOPTR (abfd, ext);
|
in->x_sym.x_fcnary.x_fcn.x_lnnoptr = GET_FCN_LNNOPTR (abfd, ext);
|
in->x_sym.x_fcnary.x_fcn.x_endndx.l = GET_FCN_ENDNDX (abfd, ext);
|
in->x_sym.x_fcnary.x_fcn.x_endndx.l = GET_FCN_ENDNDX (abfd, ext);
|
}
|
}
|
else
|
else
|
Line 292... |
Line 301... |
|
|
unsigned int
|
unsigned int
|
_bfd_XXi_swap_aux_out (bfd * abfd,
|
_bfd_XXi_swap_aux_out (bfd * abfd,
|
void * inp,
|
void * inp,
|
int type,
|
int type,
|
int class,
|
int in_class,
|
int indx ATTRIBUTE_UNUSED,
|
int indx ATTRIBUTE_UNUSED,
|
int numaux ATTRIBUTE_UNUSED,
|
int numaux ATTRIBUTE_UNUSED,
|
void * extp)
|
void * extp)
|
{
|
{
|
union internal_auxent *in = (union internal_auxent *) inp;
|
union internal_auxent *in = (union internal_auxent *) inp;
|
AUXENT *ext = (AUXENT *) extp;
|
AUXENT *ext = (AUXENT *) extp;
|
|
|
memset (ext, 0, AUXESZ);
|
memset (ext, 0, AUXESZ);
|
|
|
switch (class)
|
switch (in_class)
|
{
|
{
|
case C_FILE:
|
case C_FILE:
|
if (in->x_file.x_fname[0] == 0)
|
if (in->x_file.x_fname[0] == 0)
|
{
|
{
|
H_PUT_32 (abfd, 0, ext->x_file.x_n.x_zeroes);
|
H_PUT_32 (abfd, 0, ext->x_file.x_n.x_zeroes);
|
Line 334... |
Line 343... |
}
|
}
|
|
|
H_PUT_32 (abfd, in->x_sym.x_tagndx.l, ext->x_sym.x_tagndx);
|
H_PUT_32 (abfd, in->x_sym.x_tagndx.l, ext->x_sym.x_tagndx);
|
H_PUT_16 (abfd, in->x_sym.x_tvndx, ext->x_sym.x_tvndx);
|
H_PUT_16 (abfd, in->x_sym.x_tvndx, ext->x_sym.x_tvndx);
|
|
|
if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
|
if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
|
|
|| ISTAG (in_class))
|
{
|
{
|
PUT_FCN_LNNOPTR (abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr, ext);
|
PUT_FCN_LNNOPTR (abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr, ext);
|
PUT_FCN_ENDNDX (abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l, ext);
|
PUT_FCN_ENDNDX (abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l, ext);
|
}
|
}
|
else
|
else
|
Line 538... |
Line 548... |
struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
|
struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
|
PEAOUTHDR *aouthdr_out = (PEAOUTHDR *) out;
|
PEAOUTHDR *aouthdr_out = (PEAOUTHDR *) out;
|
bfd_vma sa, fa, ib;
|
bfd_vma sa, fa, ib;
|
IMAGE_DATA_DIRECTORY idata2, idata5, tls;
|
IMAGE_DATA_DIRECTORY idata2, idata5, tls;
|
|
|
if (pe->force_minimum_alignment)
|
|
{
|
|
if (!extra->FileAlignment)
|
|
extra->FileAlignment = PE_DEF_FILE_ALIGNMENT;
|
|
if (!extra->SectionAlignment)
|
|
extra->SectionAlignment = PE_DEF_SECTION_ALIGNMENT;
|
|
}
|
|
|
|
if (extra->Subsystem == IMAGE_SUBSYSTEM_UNKNOWN)
|
|
extra->Subsystem = pe->target_subsystem;
|
|
|
|
sa = extra->SectionAlignment;
|
sa = extra->SectionAlignment;
|
fa = extra->FileAlignment;
|
fa = extra->FileAlignment;
|
ib = extra->ImageBase;
|
ib = extra->ImageBase;
|
|
|
idata2 = pe->pe_opthdr.DataDirectory[PE_IMPORT_TABLE];
|
idata2 = pe->pe_opthdr.DataDirectory[PE_IMPORT_TABLE];
|
Line 877... |
Line 876... |
/* NT wants the size data to be rounded up to the next
|
/* NT wants the size data to be rounded up to the next
|
NT_FILE_ALIGNMENT, but zero if it has no content (as in .bss,
|
NT_FILE_ALIGNMENT, but zero if it has no content (as in .bss,
|
sometimes). */
|
sometimes). */
|
if ((scnhdr_int->s_flags & IMAGE_SCN_CNT_UNINITIALIZED_DATA) != 0)
|
if ((scnhdr_int->s_flags & IMAGE_SCN_CNT_UNINITIALIZED_DATA) != 0)
|
{
|
{
|
if (bfd_pe_executable_p (abfd))
|
if (bfd_pei_p (abfd))
|
{
|
{
|
ps = scnhdr_int->s_size;
|
ps = scnhdr_int->s_size;
|
ss = 0;
|
ss = 0;
|
}
|
}
|
else
|
else
|
Line 890... |
Line 889... |
ss = scnhdr_int->s_size;
|
ss = scnhdr_int->s_size;
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
if (bfd_pe_executable_p (abfd))
|
if (bfd_pei_p (abfd))
|
ps = scnhdr_int->s_paddr;
|
ps = scnhdr_int->s_paddr;
|
else
|
else
|
ps = 0;
|
ps = 0;
|
|
|
ss = scnhdr_int->s_size;
|
ss = scnhdr_int->s_size;
|
Line 1262... |
Line 1261... |
ft_idx = first_thunk - adj;
|
ft_idx = first_thunk - adj;
|
}
|
}
|
else
|
else
|
{
|
{
|
ft_idx = first_thunk - (ft_section->vma - extra->ImageBase);
|
ft_idx = first_thunk - (ft_section->vma - extra->ImageBase);
|
ft_data = bfd_malloc (datasize);
|
ft_data = (bfd_byte *) bfd_malloc (datasize);
|
if (ft_data == NULL)
|
if (ft_data == NULL)
|
continue;
|
continue;
|
|
|
/* Read datasize bfd_bytes starting at offset ft_idx. */
|
/* Read datasize bfd_bytes starting at offset ft_idx. */
|
if (! bfd_get_section_contents
|
if (! bfd_get_section_contents
|
Line 1308... |
Line 1307... |
table holds actual addresses. */
|
table holds actual addresses. */
|
if (time_stamp != 0
|
if (time_stamp != 0
|
&& first_thunk != 0
|
&& first_thunk != 0
|
&& first_thunk != hint_addr)
|
&& first_thunk != hint_addr)
|
fprintf (file, "\t%04lx",
|
fprintf (file, "\t%04lx",
|
(long) bfd_get_32 (abfd, ft_data + ft_idx + j));
|
(unsigned long) bfd_get_32 (abfd, ft_data + ft_idx + j));
|
fprintf (file, "\n");
|
fprintf (file, "\n");
|
}
|
}
|
#else
|
#else
|
for (j = 0; j < datasize; j += 4)
|
for (j = 0; j < datasize; j += 4)
|
{
|
{
|
Line 1340... |
Line 1339... |
table holds actual addresses. */
|
table holds actual addresses. */
|
if (time_stamp != 0
|
if (time_stamp != 0
|
&& first_thunk != 0
|
&& first_thunk != 0
|
&& first_thunk != hint_addr)
|
&& first_thunk != hint_addr)
|
fprintf (file, "\t%04lx",
|
fprintf (file, "\t%04lx",
|
(long) bfd_get_32 (abfd, ft_data + ft_idx + j));
|
(unsigned long) bfd_get_32 (abfd, ft_data + ft_idx + j));
|
|
|
fprintf (file, "\n");
|
fprintf (file, "\n");
|
}
|
}
|
#endif
|
#endif
|
if (ft_allocated)
|
if (ft_allocated)
|
Line 1431... |
Line 1430... |
}
|
}
|
|
|
fprintf (file, _("\nThere is an export table in %s at 0x%lx\n"),
|
fprintf (file, _("\nThere is an export table in %s at 0x%lx\n"),
|
section->name, (unsigned long) addr);
|
section->name, (unsigned long) addr);
|
|
|
data = bfd_malloc (datasize);
|
data = (bfd_byte *) bfd_malloc (datasize);
|
if (data == NULL)
|
if (data == NULL)
|
return FALSE;
|
return FALSE;
|
|
|
if (! bfd_get_section_contents (abfd, section, data,
|
if (! bfd_get_section_contents (abfd, section, data,
|
(file_ptr) dataoff, datasize))
|
(file_ptr) dataoff, datasize))
|
Line 1470... |
Line 1469... |
fprintf (file,
|
fprintf (file,
|
_("Major/Minor \t\t\t%d/%d\n"), edt.major_ver, edt.minor_ver);
|
_("Major/Minor \t\t\t%d/%d\n"), edt.major_ver, edt.minor_ver);
|
|
|
fprintf (file,
|
fprintf (file,
|
_("Name \t\t\t\t"));
|
_("Name \t\t\t\t"));
|
fprintf_vma (file, edt.name);
|
bfd_fprintf_vma (abfd, file, edt.name);
|
fprintf (file,
|
fprintf (file,
|
" %s\n", data + edt.name - adj);
|
" %s\n", data + edt.name - adj);
|
|
|
fprintf (file,
|
fprintf (file,
|
_("Ordinal Base \t\t\t%ld\n"), edt.base);
|
_("Ordinal Base \t\t\t%ld\n"), edt.base);
|
Line 1492... |
Line 1491... |
fprintf (file,
|
fprintf (file,
|
_("Table Addresses\n"));
|
_("Table Addresses\n"));
|
|
|
fprintf (file,
|
fprintf (file,
|
_("\tExport Address Table \t\t"));
|
_("\tExport Address Table \t\t"));
|
fprintf_vma (file, edt.eat_addr);
|
bfd_fprintf_vma (abfd, file, edt.eat_addr);
|
fprintf (file, "\n");
|
fprintf (file, "\n");
|
|
|
fprintf (file,
|
fprintf (file,
|
_("\tName Pointer Table \t\t"));
|
_("\tName Pointer Table \t\t"));
|
fprintf_vma (file, edt.npt_addr);
|
bfd_fprintf_vma (abfd, file, edt.npt_addr);
|
fprintf (file, "\n");
|
fprintf (file, "\n");
|
|
|
fprintf (file,
|
fprintf (file,
|
_("\tOrdinal Table \t\t\t"));
|
_("\tOrdinal Table \t\t\t"));
|
fprintf_vma (file, edt.ot_addr);
|
bfd_fprintf_vma (abfd, file, edt.ot_addr);
|
fprintf (file, "\n");
|
fprintf (file, "\n");
|
|
|
/* The next table to find is the Export Address Table. It's basically
|
/* The next table to find is the Export Address Table. It's basically
|
a list of pointers that either locate a function in this dll, or
|
a list of pointers that either locate a function in this dll, or
|
forward the call to another dll. Something like:
|
forward the call to another dll. Something like:
|
Line 1579... |
Line 1578... |
}
|
}
|
|
|
/* This really is architecture dependent. On IA-64, a .pdata entry
|
/* This really is architecture dependent. On IA-64, a .pdata entry
|
consists of three dwords containing relative virtual addresses that
|
consists of three dwords containing relative virtual addresses that
|
specify the start and end address of the code range the entry
|
specify the start and end address of the code range the entry
|
covers and the address of the corresponding unwind info data. */
|
covers and the address of the corresponding unwind info data.
|
|
|
|
On ARM and SH-4, a compressed PDATA structure is used :
|
|
_IMAGE_CE_RUNTIME_FUNCTION_ENTRY, whereas MIPS is documented to use
|
|
_IMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY.
|
|
See http://msdn2.microsoft.com/en-us/library/ms253988(VS.80).aspx .
|
|
|
|
This is the version for uncompressed data. */
|
|
|
static bfd_boolean
|
static bfd_boolean
|
pe_print_pdata (bfd * abfd, void * vfile)
|
pe_print_pdata (bfd * abfd, void * vfile)
|
{
|
{
|
#if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
|
#if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
|
Line 1660... |
Line 1666... |
em_data = ((eh_handler & 0x1) << 2) | (prolog_end_addr & 0x3);
|
em_data = ((eh_handler & 0x1) << 2) | (prolog_end_addr & 0x3);
|
eh_handler &= ~(bfd_vma) 0x3;
|
eh_handler &= ~(bfd_vma) 0x3;
|
prolog_end_addr &= ~(bfd_vma) 0x3;
|
prolog_end_addr &= ~(bfd_vma) 0x3;
|
|
|
fputc (' ', file);
|
fputc (' ', file);
|
fprintf_vma (file, i + section->vma); fputc ('\t', file);
|
bfd_fprintf_vma (abfd, file, i + section->vma); fputc ('\t', file);
|
fprintf_vma (file, begin_addr); fputc (' ', file);
|
bfd_fprintf_vma (abfd, file, begin_addr); fputc (' ', file);
|
fprintf_vma (file, end_addr); fputc (' ', file);
|
bfd_fprintf_vma (abfd, file, end_addr); fputc (' ', file);
|
fprintf_vma (file, eh_handler);
|
bfd_fprintf_vma (abfd, file, eh_handler);
|
#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64)
|
#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64)
|
fputc (' ', file);
|
fputc (' ', file);
|
fprintf_vma (file, eh_data); fputc (' ', file);
|
bfd_fprintf_vma (abfd, file, eh_data); fputc (' ', file);
|
fprintf_vma (file, prolog_end_addr);
|
bfd_fprintf_vma (abfd, file, prolog_end_addr);
|
fprintf (file, " %x", em_data);
|
fprintf (file, " %x", em_data);
|
#endif
|
#endif
|
|
|
#ifdef POWERPC_LE_PE
|
#ifdef POWERPC_LE_PE
|
if (eh_handler == 0 && eh_data != 0)
|
if (eh_handler == 0 && eh_data != 0)
|
Line 1703... |
Line 1709... |
}
|
}
|
|
|
free (data);
|
free (data);
|
|
|
return TRUE;
|
return TRUE;
|
|
#undef PDATA_ROW_SIZE
|
|
}
|
|
|
|
typedef struct sym_cache
|
|
{
|
|
int symcount;
|
|
asymbol ** syms;
|
|
} sym_cache;
|
|
|
|
static asymbol **
|
|
slurp_symtab (bfd *abfd, sym_cache *psc)
|
|
{
|
|
asymbol ** sy = NULL;
|
|
long storage;
|
|
|
|
if (!(bfd_get_file_flags (abfd) & HAS_SYMS))
|
|
{
|
|
psc->symcount = 0;
|
|
return NULL;
|
}
|
}
|
|
|
|
storage = bfd_get_symtab_upper_bound (abfd);
|
|
if (storage < 0)
|
|
return NULL;
|
|
if (storage)
|
|
sy = (asymbol **) bfd_malloc (storage);
|
|
|
|
psc->symcount = bfd_canonicalize_symtab (abfd, sy);
|
|
if (psc->symcount < 0)
|
|
return NULL;
|
|
return sy;
|
|
}
|
|
|
|
static const char *
|
|
my_symbol_for_address (bfd *abfd, bfd_vma func, sym_cache *psc)
|
|
{
|
|
int i;
|
|
|
|
if (psc->syms == 0)
|
|
psc->syms = slurp_symtab (abfd, psc);
|
|
|
|
for (i = 0; i < psc->symcount; i++)
|
|
{
|
|
if (psc->syms[i]->section->vma + psc->syms[i]->value == func)
|
|
return psc->syms[i]->name;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static void
|
|
cleanup_syms (sym_cache *psc)
|
|
{
|
|
psc->symcount = 0;
|
|
free (psc->syms);
|
|
psc->syms = NULL;
|
|
}
|
|
|
|
/* This is the version for "compressed" pdata. */
|
|
|
|
bfd_boolean
|
|
_bfd_XX_print_ce_compressed_pdata (bfd * abfd, void * vfile)
|
|
{
|
|
# define PDATA_ROW_SIZE (2 * 4)
|
|
FILE *file = (FILE *) vfile;
|
|
bfd_byte *data = NULL;
|
|
asection *section = bfd_get_section_by_name (abfd, ".pdata");
|
|
bfd_size_type datasize = 0;
|
|
bfd_size_type i;
|
|
bfd_size_type start, stop;
|
|
int onaline = PDATA_ROW_SIZE;
|
|
struct sym_cache sym_cache = {0, 0} ;
|
|
|
|
if (section == NULL
|
|
|| coff_section_data (abfd, section) == NULL
|
|
|| pei_section_data (abfd, section) == NULL)
|
|
return TRUE;
|
|
|
|
stop = pei_section_data (abfd, section)->virt_size;
|
|
if ((stop % onaline) != 0)
|
|
fprintf (file,
|
|
_("Warning, .pdata section size (%ld) is not a multiple of %d\n"),
|
|
(long) stop, onaline);
|
|
|
|
fprintf (file,
|
|
_("\nThe Function Table (interpreted .pdata section contents)\n"));
|
|
|
|
fprintf (file, _("\
|
|
vma:\t\tBegin Prolog Function Flags Exception EH\n\
|
|
\t\tAddress Length Length 32b exc Handler Data\n"));
|
|
|
|
datasize = section->size;
|
|
if (datasize == 0)
|
|
return TRUE;
|
|
|
|
if (! bfd_malloc_and_get_section (abfd, section, &data))
|
|
{
|
|
if (data != NULL)
|
|
free (data);
|
|
return FALSE;
|
|
}
|
|
|
|
start = 0;
|
|
|
|
for (i = start; i < stop; i += onaline)
|
|
{
|
|
bfd_vma begin_addr;
|
|
bfd_vma other_data;
|
|
bfd_vma prolog_length, function_length;
|
|
int flag32bit, exception_flag;
|
|
bfd_byte *tdata = 0;
|
|
asection *tsection;
|
|
|
|
if (i + PDATA_ROW_SIZE > stop)
|
|
break;
|
|
|
|
begin_addr = GET_PDATA_ENTRY (abfd, data + i );
|
|
other_data = GET_PDATA_ENTRY (abfd, data + i + 4);
|
|
|
|
if (begin_addr == 0 && other_data == 0)
|
|
/* We are probably into the padding of the section now. */
|
|
break;
|
|
|
|
prolog_length = (other_data & 0x000000FF);
|
|
function_length = (other_data & 0x3FFFFF00) >> 8;
|
|
flag32bit = (int)((other_data & 0x40000000) >> 30);
|
|
exception_flag = (int)((other_data & 0x80000000) >> 31);
|
|
|
|
fputc (' ', file);
|
|
bfd_fprintf_vma (abfd, file, i + section->vma); fputc ('\t', file);
|
|
bfd_fprintf_vma (abfd, file, begin_addr); fputc (' ', file);
|
|
bfd_fprintf_vma (abfd, file, prolog_length); fputc (' ', file);
|
|
bfd_fprintf_vma (abfd, file, function_length); fputc (' ', file);
|
|
fprintf (file, "%2d %2d ", flag32bit, exception_flag);
|
|
|
|
/* Get the exception handler's address and the data passed from the
|
|
.text section. This is really the data that belongs with the .pdata
|
|
but got "compressed" out for the ARM and SH4 architectures. */
|
|
tsection = bfd_get_section_by_name (abfd, ".text");
|
|
if (tsection && coff_section_data (abfd, tsection)
|
|
&& pei_section_data (abfd, tsection))
|
|
{
|
|
if (bfd_malloc_and_get_section (abfd, tsection, & tdata))
|
|
{
|
|
int xx = (begin_addr - 8) - tsection->vma;
|
|
|
|
tdata = (bfd_byte *) bfd_malloc (8);
|
|
if (bfd_get_section_contents (abfd, tsection, tdata, (bfd_vma) xx, 8))
|
|
{
|
|
bfd_vma eh, eh_data;
|
|
|
|
eh = bfd_get_32 (abfd, tdata);
|
|
eh_data = bfd_get_32 (abfd, tdata + 4);
|
|
fprintf (file, "%08x ", (unsigned int) eh);
|
|
fprintf (file, "%08x", (unsigned int) eh_data);
|
|
if (eh != 0)
|
|
{
|
|
const char *s = my_symbol_for_address (abfd, eh, &sym_cache);
|
|
|
|
if (s)
|
|
fprintf (file, " (%s) ", s);
|
|
}
|
|
}
|
|
free (tdata);
|
|
}
|
|
else
|
|
{
|
|
if (tdata)
|
|
free (tdata);
|
|
}
|
|
}
|
|
|
|
fprintf (file, "\n");
|
|
}
|
|
|
|
free (data);
|
|
|
|
cleanup_syms (& sym_cache);
|
|
|
|
return TRUE;
|
|
#undef PDATA_ROW_SIZE
|
|
}
|
|
|
|
|
#define IMAGE_REL_BASED_HIGHADJ 4
|
#define IMAGE_REL_BASED_HIGHADJ 4
|
static const char * const tbl[] =
|
static const char * const tbl[] =
|
{
|
{
|
"ABSOLUTE",
|
"ABSOLUTE",
|
"HIGH",
|
"HIGH",
|
Line 1771... |
Line 1959... |
if (size == 0)
|
if (size == 0)
|
break;
|
break;
|
|
|
fprintf (file,
|
fprintf (file,
|
_("\nVirtual Address: %08lx Chunk size %ld (0x%lx) Number of fixups %ld\n"),
|
_("\nVirtual Address: %08lx Chunk size %ld (0x%lx) Number of fixups %ld\n"),
|
(unsigned long) virtual_address, size, size, number);
|
(unsigned long) virtual_address, size, (unsigned long) size, number);
|
|
|
for (j = 0; j < number; ++j)
|
for (j = 0; j < number; ++j)
|
{
|
{
|
unsigned short e = bfd_get_16 (abfd, data + i + 8 + j * 2);
|
unsigned short e = bfd_get_16 (abfd, data + i + 8 + j * 2);
|
unsigned int t = (e & 0xF000) >> 12;
|
unsigned int t = (e & 0xF000) >> 12;
|
Line 1784... |
Line 1972... |
if (t >= sizeof (tbl) / sizeof (tbl[0]))
|
if (t >= sizeof (tbl) / sizeof (tbl[0]))
|
t = (sizeof (tbl) / sizeof (tbl[0])) - 1;
|
t = (sizeof (tbl) / sizeof (tbl[0])) - 1;
|
|
|
fprintf (file,
|
fprintf (file,
|
_("\treloc %4d offset %4x [%4lx] %s"),
|
_("\treloc %4d offset %4x [%4lx] %s"),
|
j, off, (long) (off + virtual_address), tbl[t]);
|
j, off, (unsigned long) (off + virtual_address), tbl[t]);
|
|
|
/* HIGHADJ takes an argument, - the next record *is* the
|
/* HIGHADJ takes an argument, - the next record *is* the
|
low 16 bits of addend. */
|
low 16 bits of addend. */
|
if (t == IMAGE_REL_BASED_HIGHADJ)
|
if (t == IMAGE_REL_BASED_HIGHADJ)
|
{
|
{
|
Line 1874... |
Line 2062... |
fprintf (file, "Magic\t\t\t%04x", i->Magic);
|
fprintf (file, "Magic\t\t\t%04x", i->Magic);
|
if (name)
|
if (name)
|
fprintf (file, "\t(%s)",name);
|
fprintf (file, "\t(%s)",name);
|
fprintf (file, "\nMajorLinkerVersion\t%d\n", i->MajorLinkerVersion);
|
fprintf (file, "\nMajorLinkerVersion\t%d\n", i->MajorLinkerVersion);
|
fprintf (file, "MinorLinkerVersion\t%d\n", i->MinorLinkerVersion);
|
fprintf (file, "MinorLinkerVersion\t%d\n", i->MinorLinkerVersion);
|
fprintf (file, "SizeOfCode\t\t%08lx\n", i->SizeOfCode);
|
fprintf (file, "SizeOfCode\t\t%08lx\n", (unsigned long) i->SizeOfCode);
|
fprintf (file, "SizeOfInitializedData\t%08lx\n",
|
fprintf (file, "SizeOfInitializedData\t%08lx\n",
|
i->SizeOfInitializedData);
|
(unsigned long) i->SizeOfInitializedData);
|
fprintf (file, "SizeOfUninitializedData\t%08lx\n",
|
fprintf (file, "SizeOfUninitializedData\t%08lx\n",
|
i->SizeOfUninitializedData);
|
(unsigned long) i->SizeOfUninitializedData);
|
fprintf (file, "AddressOfEntryPoint\t");
|
fprintf (file, "AddressOfEntryPoint\t");
|
fprintf_vma (file, i->AddressOfEntryPoint);
|
bfd_fprintf_vma (abfd, file, i->AddressOfEntryPoint);
|
fprintf (file, "\nBaseOfCode\t\t");
|
fprintf (file, "\nBaseOfCode\t\t");
|
fprintf_vma (file, i->BaseOfCode);
|
bfd_fprintf_vma (abfd, file, i->BaseOfCode);
|
#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
|
#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
|
/* PE32+ does not have BaseOfData member! */
|
/* PE32+ does not have BaseOfData member! */
|
fprintf (file, "\nBaseOfData\t\t");
|
fprintf (file, "\nBaseOfData\t\t");
|
fprintf_vma (file, i->BaseOfData);
|
bfd_fprintf_vma (abfd, file, i->BaseOfData);
|
#endif
|
#endif
|
|
|
fprintf (file, "\nImageBase\t\t");
|
fprintf (file, "\nImageBase\t\t");
|
fprintf_vma (file, i->ImageBase);
|
bfd_fprintf_vma (abfd, file, i->ImageBase);
|
fprintf (file, "\nSectionAlignment\t");
|
fprintf (file, "\nSectionAlignment\t");
|
fprintf_vma (file, i->SectionAlignment);
|
bfd_fprintf_vma (abfd, file, i->SectionAlignment);
|
fprintf (file, "\nFileAlignment\t\t");
|
fprintf (file, "\nFileAlignment\t\t");
|
fprintf_vma (file, i->FileAlignment);
|
bfd_fprintf_vma (abfd, file, i->FileAlignment);
|
fprintf (file, "\nMajorOSystemVersion\t%d\n", i->MajorOperatingSystemVersion);
|
fprintf (file, "\nMajorOSystemVersion\t%d\n", i->MajorOperatingSystemVersion);
|
fprintf (file, "MinorOSystemVersion\t%d\n", i->MinorOperatingSystemVersion);
|
fprintf (file, "MinorOSystemVersion\t%d\n", i->MinorOperatingSystemVersion);
|
fprintf (file, "MajorImageVersion\t%d\n", i->MajorImageVersion);
|
fprintf (file, "MajorImageVersion\t%d\n", i->MajorImageVersion);
|
fprintf (file, "MinorImageVersion\t%d\n", i->MinorImageVersion);
|
fprintf (file, "MinorImageVersion\t%d\n", i->MinorImageVersion);
|
fprintf (file, "MajorSubsystemVersion\t%d\n", i->MajorSubsystemVersion);
|
fprintf (file, "MajorSubsystemVersion\t%d\n", i->MajorSubsystemVersion);
|
fprintf (file, "MinorSubsystemVersion\t%d\n", i->MinorSubsystemVersion);
|
fprintf (file, "MinorSubsystemVersion\t%d\n", i->MinorSubsystemVersion);
|
fprintf (file, "Win32Version\t\t%08lx\n", i->Reserved1);
|
fprintf (file, "Win32Version\t\t%08lx\n", (unsigned long) i->Reserved1);
|
fprintf (file, "SizeOfImage\t\t%08lx\n", i->SizeOfImage);
|
fprintf (file, "SizeOfImage\t\t%08lx\n", (unsigned long) i->SizeOfImage);
|
fprintf (file, "SizeOfHeaders\t\t%08lx\n", i->SizeOfHeaders);
|
fprintf (file, "SizeOfHeaders\t\t%08lx\n", (unsigned long) i->SizeOfHeaders);
|
fprintf (file, "CheckSum\t\t%08lx\n", i->CheckSum);
|
fprintf (file, "CheckSum\t\t%08lx\n", (unsigned long) i->CheckSum);
|
|
|
switch (i->Subsystem)
|
switch (i->Subsystem)
|
{
|
{
|
case IMAGE_SUBSYSTEM_UNKNOWN:
|
case IMAGE_SUBSYSTEM_UNKNOWN:
|
subsystem_name = "unspecified";
|
subsystem_name = "unspecified";
|
Line 1926... |
Line 2114... |
subsystem_name = "POSIX CUI";
|
subsystem_name = "POSIX CUI";
|
break;
|
break;
|
case IMAGE_SUBSYSTEM_WINDOWS_CE_GUI:
|
case IMAGE_SUBSYSTEM_WINDOWS_CE_GUI:
|
subsystem_name = "Wince CUI";
|
subsystem_name = "Wince CUI";
|
break;
|
break;
|
|
// These are from UEFI Platform Initialization Specification 1.1.
|
case IMAGE_SUBSYSTEM_EFI_APPLICATION:
|
case IMAGE_SUBSYSTEM_EFI_APPLICATION:
|
subsystem_name = "EFI application";
|
subsystem_name = "EFI application";
|
break;
|
break;
|
case IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER:
|
case IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER:
|
subsystem_name = "EFI boot service driver";
|
subsystem_name = "EFI boot service driver";
|
break;
|
break;
|
case IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:
|
case IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:
|
subsystem_name = "EFI runtime driver";
|
subsystem_name = "EFI runtime driver";
|
break;
|
break;
|
// These are from revision 8.0 of the MS PE/COFF spec
|
case IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER:
|
case IMAGE_SUBSYSTEM_EFI_ROM:
|
subsystem_name = "SAL runtime driver";
|
subsystem_name = "EFI ROM";
|
|
break;
|
break;
|
|
// This is from revision 8.0 of the MS PE/COFF spec
|
case IMAGE_SUBSYSTEM_XBOX:
|
case IMAGE_SUBSYSTEM_XBOX:
|
subsystem_name = "XBOX";
|
subsystem_name = "XBOX";
|
break;
|
break;
|
// Added default case for clarity - subsystem_name is NULL anyway.
|
// Added default case for clarity - subsystem_name is NULL anyway.
|
default:
|
default:
|
Line 1952... |
Line 2141... |
fprintf (file, "Subsystem\t\t%08x", i->Subsystem);
|
fprintf (file, "Subsystem\t\t%08x", i->Subsystem);
|
if (subsystem_name)
|
if (subsystem_name)
|
fprintf (file, "\t(%s)", subsystem_name);
|
fprintf (file, "\t(%s)", subsystem_name);
|
fprintf (file, "\nDllCharacteristics\t%08x\n", i->DllCharacteristics);
|
fprintf (file, "\nDllCharacteristics\t%08x\n", i->DllCharacteristics);
|
fprintf (file, "SizeOfStackReserve\t");
|
fprintf (file, "SizeOfStackReserve\t");
|
fprintf_vma (file, i->SizeOfStackReserve);
|
bfd_fprintf_vma (abfd, file, i->SizeOfStackReserve);
|
fprintf (file, "\nSizeOfStackCommit\t");
|
fprintf (file, "\nSizeOfStackCommit\t");
|
fprintf_vma (file, i->SizeOfStackCommit);
|
bfd_fprintf_vma (abfd, file, i->SizeOfStackCommit);
|
fprintf (file, "\nSizeOfHeapReserve\t");
|
fprintf (file, "\nSizeOfHeapReserve\t");
|
fprintf_vma (file, i->SizeOfHeapReserve);
|
bfd_fprintf_vma (abfd, file, i->SizeOfHeapReserve);
|
fprintf (file, "\nSizeOfHeapCommit\t");
|
fprintf (file, "\nSizeOfHeapCommit\t");
|
fprintf_vma (file, i->SizeOfHeapCommit);
|
bfd_fprintf_vma (abfd, file, i->SizeOfHeapCommit);
|
fprintf (file, "\nLoaderFlags\t\t%08lx\n", i->LoaderFlags);
|
fprintf (file, "\nLoaderFlags\t\t%08lx\n", (unsigned long) i->LoaderFlags);
|
fprintf (file, "NumberOfRvaAndSizes\t%08lx\n", i->NumberOfRvaAndSizes);
|
fprintf (file, "NumberOfRvaAndSizes\t%08lx\n",
|
|
(unsigned long) i->NumberOfRvaAndSizes);
|
|
|
fprintf (file, "\nThe Data Directory\n");
|
fprintf (file, "\nThe Data Directory\n");
|
for (j = 0; j < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; j++)
|
for (j = 0; j < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; j++)
|
{
|
{
|
fprintf (file, "Entry %1x ", j);
|
fprintf (file, "Entry %1x ", j);
|
fprintf_vma (file, i->DataDirectory[j].VirtualAddress);
|
bfd_fprintf_vma (abfd, file, i->DataDirectory[j].VirtualAddress);
|
fprintf (file, " %08lx ", i->DataDirectory[j].Size);
|
fprintf (file, " %08lx ", (unsigned long) i->DataDirectory[j].Size);
|
fprintf (file, "%s\n", dir_names[j]);
|
fprintf (file, "%s\n", dir_names[j]);
|
}
|
}
|
|
|
pe_print_idata (abfd, vfile);
|
pe_print_idata (abfd, vfile);
|
pe_print_edata (abfd, vfile);
|
pe_print_edata (abfd, vfile);
|
|
if (bfd_coff_have_print_pdata (abfd))
|
|
bfd_coff_print_pdata (abfd, vfile);
|
|
else
|
pe_print_pdata (abfd, vfile);
|
pe_print_pdata (abfd, vfile);
|
pe_print_reloc (abfd, vfile);
|
pe_print_reloc (abfd, vfile);
|
|
|
return TRUE;
|
return TRUE;
|
}
|
}
|
Line 1995... |
Line 2188... |
return TRUE;
|
return TRUE;
|
|
|
ipe = pe_data (ibfd);
|
ipe = pe_data (ibfd);
|
ope = pe_data (obfd);
|
ope = pe_data (obfd);
|
|
|
ope->pe_opthdr = ipe->pe_opthdr;
|
/* pe_opthdr is copied in copy_object. */
|
ope->dll = ipe->dll;
|
ope->dll = ipe->dll;
|
|
|
/* Don't copy input subsystem if output is different from input. */
|
/* Don't copy input subsystem if output is different from input. */
|
if (obfd->xvec != ibfd->xvec)
|
if (obfd->xvec != ibfd->xvec)
|
ope->pe_opthdr.Subsystem = IMAGE_SUBSYSTEM_UNKNOWN;
|
ope->pe_opthdr.Subsystem = IMAGE_SUBSYSTEM_UNKNOWN;
|
Line 2083... |
Line 2276... |
if (h1 != NULL)
|
if (h1 != NULL)
|
{
|
{
|
/* PR ld/2729: We cannot rely upon all the output sections having been
|
/* PR ld/2729: We cannot rely upon all the output sections having been
|
created properly, so check before referencing them. Issue a warning
|
created properly, so check before referencing them. Issue a warning
|
message for any sections tht could not be found. */
|
message for any sections tht could not be found. */
|
if (h1->root.u.def.section != NULL
|
if ((h1->root.type == bfd_link_hash_defined
|
|
|| h1->root.type == bfd_link_hash_defweak)
|
|
&& h1->root.u.def.section != NULL
|
&& h1->root.u.def.section->output_section != NULL)
|
&& h1->root.u.def.section->output_section != NULL)
|
pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_TABLE].VirtualAddress =
|
pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_TABLE].VirtualAddress =
|
(h1->root.u.def.value
|
(h1->root.u.def.value
|
+ h1->root.u.def.section->output_section->vma
|
+ h1->root.u.def.section->output_section->vma
|
+ h1->root.u.def.section->output_offset);
|
+ h1->root.u.def.section->output_offset);
|
Line 2100... |
Line 2295... |
}
|
}
|
|
|
h1 = coff_link_hash_lookup (coff_hash_table (info),
|
h1 = coff_link_hash_lookup (coff_hash_table (info),
|
".idata$4", FALSE, FALSE, TRUE);
|
".idata$4", FALSE, FALSE, TRUE);
|
if (h1 != NULL
|
if (h1 != NULL
|
|
&& (h1->root.type == bfd_link_hash_defined
|
|
|| h1->root.type == bfd_link_hash_defweak)
|
&& h1->root.u.def.section != NULL
|
&& h1->root.u.def.section != NULL
|
&& h1->root.u.def.section->output_section != NULL)
|
&& h1->root.u.def.section->output_section != NULL)
|
pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_TABLE].Size =
|
pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_TABLE].Size =
|
((h1->root.u.def.value
|
((h1->root.u.def.value
|
+ h1->root.u.def.section->output_section->vma
|
+ h1->root.u.def.section->output_section->vma
|
Line 2120... |
Line 2317... |
/* The import address table. This is the size/address of
|
/* The import address table. This is the size/address of
|
.idata$5. */
|
.idata$5. */
|
h1 = coff_link_hash_lookup (coff_hash_table (info),
|
h1 = coff_link_hash_lookup (coff_hash_table (info),
|
".idata$5", FALSE, FALSE, TRUE);
|
".idata$5", FALSE, FALSE, TRUE);
|
if (h1 != NULL
|
if (h1 != NULL
|
|
&& (h1->root.type == bfd_link_hash_defined
|
|
|| h1->root.type == bfd_link_hash_defweak)
|
&& h1->root.u.def.section != NULL
|
&& h1->root.u.def.section != NULL
|
&& h1->root.u.def.section->output_section != NULL)
|
&& h1->root.u.def.section->output_section != NULL)
|
pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_ADDRESS_TABLE].VirtualAddress =
|
pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_ADDRESS_TABLE].VirtualAddress =
|
(h1->root.u.def.value
|
(h1->root.u.def.value
|
+ h1->root.u.def.section->output_section->vma
|
+ h1->root.u.def.section->output_section->vma
|
Line 2137... |
Line 2336... |
}
|
}
|
|
|
h1 = coff_link_hash_lookup (coff_hash_table (info),
|
h1 = coff_link_hash_lookup (coff_hash_table (info),
|
".idata$6", FALSE, FALSE, TRUE);
|
".idata$6", FALSE, FALSE, TRUE);
|
if (h1 != NULL
|
if (h1 != NULL
|
|
&& (h1->root.type == bfd_link_hash_defined
|
|
|| h1->root.type == bfd_link_hash_defweak)
|
&& h1->root.u.def.section != NULL
|
&& h1->root.u.def.section != NULL
|
&& h1->root.u.def.section->output_section != NULL)
|
&& h1->root.u.def.section->output_section != NULL)
|
pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_ADDRESS_TABLE].Size =
|
pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_ADDRESS_TABLE].Size =
|
((h1->root.u.def.value
|
((h1->root.u.def.value
|
+ h1->root.u.def.section->output_section->vma
|
+ h1->root.u.def.section->output_section->vma
|
Line 2157... |
Line 2358... |
|
|
h1 = coff_link_hash_lookup (coff_hash_table (info),
|
h1 = coff_link_hash_lookup (coff_hash_table (info),
|
"__tls_used", FALSE, FALSE, TRUE);
|
"__tls_used", FALSE, FALSE, TRUE);
|
if (h1 != NULL)
|
if (h1 != NULL)
|
{
|
{
|
if (h1->root.u.def.section != NULL
|
if ((h1->root.type == bfd_link_hash_defined
|
|
|| h1->root.type == bfd_link_hash_defweak)
|
|
&& h1->root.u.def.section != NULL
|
&& h1->root.u.def.section->output_section != NULL)
|
&& h1->root.u.def.section->output_section != NULL)
|
pe_data (abfd)->pe_opthdr.DataDirectory[PE_TLS_TABLE].VirtualAddress =
|
pe_data (abfd)->pe_opthdr.DataDirectory[PE_TLS_TABLE].VirtualAddress =
|
(h1->root.u.def.value
|
(h1->root.u.def.value
|
+ h1->root.u.def.section->output_section->vma
|
+ h1->root.u.def.section->output_section->vma
|
+ h1->root.u.def.section->output_offset
|
+ h1->root.u.def.section->output_offset
|