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:
parent
028ed2b2b6
commit
2eb0390952
|
@ -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
|
||||
|
|
195
bfd/pei-x86_64.c
195
bfd/pei-x86_64.c
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue