2010-09-15 Kai Tietz <kai.tietz@onevision.com>

* pei-x86_64.c (pex64_get_unwind_info): Reorgnized.
        (pex64_get_scope_entry): Removed.
        (find_next_xdata_or_end): New helper.
        (pex64_dump_xdata): Reworked.
        (pex64_bfd_print_pdata): Add checking for
        valid pdata sorting and values. Reworked
        output.
This commit is contained in:
Kai Tietz 2010-09-15 17:27:30 +00:00
parent 028ed2b2b6
commit 2eb0390952
2 changed files with 129 additions and 76 deletions

View File

@ -1,3 +1,13 @@
2010-09-15 Kai Tietz <kai.tietz@onevision.com>
* pei-x86_64.c (pex64_get_unwind_info): Reorgnized.
(pex64_get_scope_entry): Removed.
(find_next_xdata_or_end): New helper.
(pex64_dump_xdata): Reworked.
(pex64_bfd_print_pdata): Add checking for
valid pdata sorting and values. Reworked
output.
2010-09-15 H.J. Lu <hongjiu.lu@intel.com>
PR binutils/12004

View File

@ -114,17 +114,6 @@ pex64_get_unwind_info (bfd *abfd, struct pex64_unwind_info *ui, void *data)
ex_dta += ui->SizeOfBlock;
switch (ui->Flags)
{
case UNW_FLAG_EHANDLER:
ui->rva_ExceptionHandler = bfd_get_32 (abfd, ex_dta);
break;
case UNW_FLAG_UHANDLER:
ui->rva_TerminationHandler = bfd_get_32 (abfd, ex_dta);
break;
case UNW_FLAG_FHANDLER:
ui->rva_FrameHandler = bfd_get_32 (abfd, ex_dta);
ui->FrameHandlerArgument = bfd_get_32 (abfd, ex_dta + 4);
ui->SizeOfBlock += 8;
return;
case UNW_FLAG_CHAININFO:
ui->rva_FunctionEntry = bfd_get_32 (abfd, ex_dta);
ui->SizeOfBlock += 4;
@ -132,26 +121,6 @@ pex64_get_unwind_info (bfd *abfd, struct pex64_unwind_info *ui, void *data)
default:
return;
}
ex_dta += 4;
ui->SizeOfBlock += 8;
ui->CountOfScopes = bfd_get_32 (abfd, ex_dta);
ex_dta += 4;
ui->rawScopeEntries = ex_dta;
ui->SizeOfBlock += (ui->CountOfScopes * PEX64_SCOPE_ENTRY_SIZE);
}
static void
pex64_get_scope_entry (bfd *abfd, struct pex64_scope_entry *se,
bfd_vma idx, const bfd_byte *x)
{
const struct external_pex64_scope_entry *ex_se;
x += (idx * PEX64_SCOPE_ENTRY_SIZE);
ex_se = (const struct external_pex64_scope_entry *) x;
memset (se, 0, sizeof (struct pex64_scope_entry));
se->rva_BeginAddress = bfd_get_32 (abfd, ex_se->rva_BeginAddress);
se->rva_EndAddress = bfd_get_32 (abfd, ex_se->rva_EndAddress);
se->rva_HandlerAddress = bfd_get_32 (abfd, ex_se->rva_HandlerAddress);
se->rva_JumpAddress = bfd_get_32 (abfd, ex_se->rva_JumpAddress);
}
static void
@ -334,13 +303,46 @@ pex64_get_section_by_rva (bfd *abfd, bfd_vma addr, const char *sec_name)
return section;
}
static bfd_vma
find_next_xdata_or_end (bfd *abfd, bfd_byte *pdata, bfd_size_type stop,
int onaline, bfd_vma cur_address, bfd_vma max_size)
{
bfd_size_type i;
bfd_vma ret = 0;
for (i = 0; i < stop; i += onaline)
{
struct pex64_runtime_function rf;
if (i + PDATA_ROW_SIZE > stop)
break;
pex64_get_runtime_function (abfd, &rf, &pdata[i]);
if (rf.rva_BeginAddress == 0 && rf.rva_EndAddress == 0
&& rf.rva_UnwindData == 0)
/* We are probably into the padding of the section now. */
break;
if (rf.rva_UnwindData != 0 && !rf.isChained)
{
if (!ret && rf.rva_UnwindData > cur_address)
ret = rf.rva_UnwindData;
else if (rf.rva_UnwindData > cur_address && ret > rf.rva_UnwindData)
ret = rf.rva_UnwindData;
}
}
if (!ret)
return max_size;
return ret;
}
static void
pex64_dump_xdata (FILE *file, bfd *abfd, bfd_vma addr, bfd_vma pc_addr)
pex64_dump_xdata (FILE *file, bfd *abfd, bfd_vma addr, bfd_vma pc_addr,
bfd_size_type stop, int onaline, bfd_byte *pdata)
{
asection *section = pex64_get_section_by_rva (abfd, addr, ".rdata");
bfd_vma vsize;
bfd_byte *data = NULL;
bfd_vma i;
bfd_vma end_addr;
if (!section)
section = pex64_get_section_by_rva (abfd, addr, ".data");
@ -358,8 +360,14 @@ pex64_dump_xdata (FILE *file, bfd *abfd, bfd_vma addr, bfd_vma pc_addr)
}
if (!section)
return;
vsize = section->vma - pe_data (abfd)->pe_opthdr.ImageBase;
addr -= vsize;
end_addr = find_next_xdata_or_end (abfd, pdata, stop, onaline, addr + vsize,
vsize + (section->rawsize != 0 ? section->rawsize : section->size));
end_addr -= vsize;
if (bfd_malloc_and_get_section (abfd, section, &data))
{
struct pex64_unwind_info ui;
@ -408,40 +416,23 @@ pex64_dump_xdata (FILE *file, bfd *abfd, bfd_vma addr, bfd_vma pc_addr)
pex64_xdata_print_uwd_codes (file, &ui, pc_addr);
switch (ui.Flags)
{
case UNW_FLAG_NHANDLER:
return;
case UNW_FLAG_EHANDLER:
fprintf (file, "\texception_handler at 0x%x.\n", (unsigned int) ui.rva_ExceptionHandler);
break;
case UNW_FLAG_UHANDLER:
fprintf (file, "\ttermination_handler at 0x%x.\n", (unsigned int) ui.rva_TerminationHandler);
case UNW_FLAG_FHANDLER:
fprintf (file, "\tframe_handler at 0x%x.\n", (unsigned int) ui.rva_FrameHandler);
fprintf (file, "\t Argument for FrameHandler: 0x%x.\n",
(unsigned int) ui.FrameHandlerArgument);
return;
case UNW_FLAG_CHAININFO:
fprintf (file, "\t Function Entry: 0x%x\n", (unsigned int) ui.rva_FunctionEntry);
return;
default:
fprintf (file, "\t Unknown flag value of 0x%x\n", (unsigned int) ui.Flags);
return;
}
fprintf (file, "\t 0x%x # of scope(s)\n", (unsigned int) ui.CountOfScopes);
for (i = 0; i < ui.CountOfScopes; i++)
{
struct pex64_scope_entry se;
pex64_get_scope_entry (abfd, &se, i, ui.rawScopeEntries);
fprintf (file, "\t scope #%u: BeginAddress: 0x%x, EndAddress: 0x%x,"
"\n\t\tHandlerAddress:0x%x, JumpTarget:0x%x\n",
(unsigned int) (i + 1),
(unsigned int) se.rva_BeginAddress,
(unsigned int) se.rva_EndAddress,
(unsigned int) se.rva_HandlerAddress,
(unsigned int) se.rva_JumpAddress);
}
/* Now we need end of this xdata block. */
addr += ui.SizeOfBlock;
if (addr < end_addr)
{
unsigned int i;
fprintf (file,"\tUser data:\n");
for (i = 0; addr < end_addr; addr += 1, i++)
{
if ((i & 15) == 0)
fprintf (file, "\t %03x:", i);
fprintf (file, " %02x", data[addr]);
if ((i & 15) == 15)
fprintf (file, "\n");
}
if ((i & 15) != 0)
fprintf (file, "\n");
}
}
if (data != NULL)
free (data);
@ -455,8 +446,10 @@ pex64_bfd_print_pdata (bfd *abfd, void *vfile)
asection *section = bfd_get_section_by_name (abfd, ".pdata");
bfd_size_type datasize = 0;
bfd_size_type i;
bfd_size_type start, stop;
bfd_size_type stop;
bfd_vma prev_beginaddress = 0;
int onaline = PDATA_ROW_SIZE;
int seen_error = 0;
if (section == NULL
|| coff_section_data (abfd, section) == NULL
@ -485,9 +478,8 @@ pex64_bfd_print_pdata (bfd *abfd, void *vfile)
return FALSE;
}
start = 0;
for (i = start; i < stop; i += onaline)
/* Do sanity check of pdata. */
for (i = 0; i < stop; i += onaline)
{
struct pex64_runtime_function rf;
@ -499,29 +491,80 @@ pex64_bfd_print_pdata (bfd *abfd, void *vfile)
&& rf.rva_UnwindData == 0)
/* We are probably into the padding of the section now. */
break;
fputc (' ', file);
fprintf_vma (file, i + section->vma);
fprintf (file, ":\t");
rf.rva_BeginAddress += pe_data (abfd)->pe_opthdr.ImageBase;
fprintf_vma (file, rf.rva_BeginAddress);
fputc (' ', file);
rf.rva_EndAddress += pe_data (abfd)->pe_opthdr.ImageBase;
fprintf_vma (file, rf.rva_EndAddress);
fputc (' ', file);
fprintf_vma (file, rf.rva_UnwindData);
fprintf (file, "\n");
if (i != 0 && rf.rva_BeginAddress <= prev_beginaddress)
{
seen_error = 1;
fprintf (file, " has %s begin address as predecessor\n",
(rf.rva_BeginAddress < prev_beginaddress ? "smaller" : "same"));
}
prev_beginaddress = rf.rva_BeginAddress;
/* Now we check for negative addresses. */
if ((prev_beginaddress & 0x80000000) != 0)
{
seen_error = 1;
fprintf (file, " has negative begin address\n");
}
if ((rf.rva_EndAddress & 0x80000000) != 0)
{
seen_error = 1;
fprintf (file, " has negative end address\n");
}
if ((rf.rva_UnwindData & 0x80000000) != 0)
{
seen_error = 1;
fprintf (file, " has negative unwind address\n");
}
}
if (seen_error)
{
free (data);
return TRUE;
}
/* Do dump of pdata related xdata. */
for (i = 0; i < stop; i += onaline)
{
struct pex64_runtime_function rf;
if (i + PDATA_ROW_SIZE > stop)
break;
pex64_get_runtime_function (abfd, &rf, &data[i]);
if (rf.rva_BeginAddress == 0 && rf.rva_EndAddress == 0
&& rf.rva_UnwindData == 0)
/* We are probably into the padding of the section now. */
break;
if (i == 0)
fprintf (file, "\nDump of .xdata\n");
fputc (' ', file);
fprintf_vma (file, rf.rva_UnwindData);
fprintf (file, ":\n");
rf.rva_BeginAddress += pe_data (abfd)->pe_opthdr.ImageBase;
rf.rva_EndAddress += pe_data (abfd)->pe_opthdr.ImageBase;
if (rf.rva_UnwindData != 0)
{
if (rf.isChained)
{
fprintf (file, "\t shares information with pdata element at 0x");
fprintf_vma (file, rf.rva_UnwindData + pe_data (abfd)->pe_opthdr.ImageBase);
fprintf_vma (file, rf.rva_UnwindData);
fprintf (file, ".\n");
}
else
pex64_dump_xdata (file, abfd, rf.rva_UnwindData, rf.rva_BeginAddress);
pex64_dump_xdata (file, abfd, rf.rva_UnwindData, rf.rva_BeginAddress,
stop, onaline, data);
}
}