* pe-arm-wince.c (pe_print_compressed_pdata): Define new function to

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.
This commit is contained in:
Nick Clifton
2008-07-18 11:30:22 +00:00
parent a18f591e92
commit 2b5c217d45
40 changed files with 458 additions and 52 deletions

View File

@ -1,5 +1,5 @@
/* BFD back-end for ARM WINCE PE files.
Copyright 2006, 2007 Free Software Foundation, Inc.
Copyright 2006, 2007, 2008 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
@ -35,4 +35,191 @@
#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
}