2b5c217d45
print compressed pdata structure as described on MSDN. This only applies to a limited set of architectures (ARM, SH4). (slurp_symtab, my_symbol_for_address): Define static helper functions for pe_print_compressed_pdata. * coffcode.h (bfd_coff_backend_data): Add _bfd_coff_print_pdata field. (bfd_coff_have_print_pdata, bfd_coff_print_pdata): Define. * bfd/peXXigen.c (_bfd_XX_print_private_bfd_data_common): Add check on bfd_coff_backend_data, call the function if non-null. * pei-mcore.c: Add target dependent initialisation for bfd_coff_backend_data. * coff-sh.c: Likewise. * coff64-rs6000.c: Likewise. * coff-rs6000.c: Likewise. * libcoff-in.h: Likewise. * cf-i386lynx.c: Likewise. * coff-alpha.c: Likewise. * coff-apollo.c: Likewise. * coff-arm.c: Likewise. * coff-aux.c: Likewise. * coff-h8300.c: Likewise. * coff-h8500.c: Likewise. * coff-i386.c: Likewise. * coff-i860.c: Likewise. * coff-i960.c: Likewise. * coff-ia64.c: Likewise. * coff-m68k.c: Likewise. * coff-m88k.c: Likewise. * coff-maxq.c: Likewise. * coff-mips.c: Likewise. * coff-or32.c: Likewise. * coff-sparc.c: Likewise. * coff-tic30.c: Likewise. * coff-tic4x.c: Likewise. * coff-tic54x.c: Likewise. * coff-tic80.c: Likewise. * coff-w65.c: Likewise. * coff-we32k.c: Likewise. * coff-x86_64.c: Likewise. * coff-z80.c: Likewise. * coff-z8k.c: Likewise. * pe-mcore.c: Likewise. * pe-mips.c: Likewise. * pe-ppc.c: Likewise. * peXXigen.c: Likewise. * pei-ppc.c: Likewise. * libcoff.h: Regenerate.
226 lines
6.0 KiB
C
226 lines
6.0 KiB
C
/* BFD back-end for ARM WINCE PE files.
|
|
Copyright 2006, 2007, 2008 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 3 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. */
|
|
|
|
#define TARGET_UNDERSCORE 0
|
|
#define USER_LABEL_PREFIX ""
|
|
|
|
#define TARGET_LITTLE_SYM arm_wince_pe_little_vec
|
|
#define TARGET_LITTLE_NAME "pe-arm-wince-little"
|
|
#define TARGET_BIG_SYM arm_wince_pe_big_vec
|
|
#define TARGET_BIG_NAME "pe-arm-wince-big"
|
|
|
|
#define bfd_arm_allocate_interworking_sections \
|
|
bfd_arm_wince_pe_allocate_interworking_sections
|
|
#define bfd_arm_get_bfd_for_interworking \
|
|
bfd_arm_wince_pe_get_bfd_for_interworking
|
|
#define bfd_arm_process_before_allocation \
|
|
bfd_arm_wince_pe_process_before_allocation
|
|
|
|
#define LOCAL_LABEL_PREFIX "."
|
|
|
|
#include "sysdep.h"
|
|
#include "bfd.h"
|
|
|
|
#undef bfd_pe_print_pdata
|
|
#define bfd_pe_print_pdata pe_print_ce_compressed_pdata
|
|
extern bfd_boolean pe_print_ce_compressed_pdata (bfd *, void *);
|
|
|
|
#include "pe-arm.c"
|
|
|
|
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 = 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
|
|
pe_print_ce_compressed_pdata (bfd * abfd, void * vfile)
|
|
{
|
|
# define PDATA_ROW_SIZE (2 * 4)
|
|
FILE *file = (FILE *) vfile;
|
|
bfd_byte *data = 0;
|
|
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);
|
|
fprintf_vma (file, i + section->vma); fputc ('\t', file);
|
|
fprintf_vma (file, begin_addr); fputc (' ', file);
|
|
fprintf_vma (file, prolog_length); fputc (' ', file);
|
|
fprintf_vma (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_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
|
|
}
|