[PATCH 1/4] bfd: pe: Clarify pe_print_pdata() conditional
Jon Turney
jon.turney@dronecode.org.uk
Sun Sep 13 12:33:20 GMT 2026
Clarify what the conditional logic in pe_print_pdata() appears to be
doing. Update comments appropriately.
Notes:
This conditional is entirely pointless since PE MIPS support was removed
in 2018 (binutils 2.31).
The original intent seems to have been "if it's not pe ia64, then it
must be pe mips", with the check for pe x64 later added (pointlessly,
since pe x64 is interpreted by pex64_bfd_print_pdata_section so never
gets here) as a double check, but then it's accreted all these other
targets as well.
Also, for ia64, the pdata entry size is set to 3*8 bytes, whereas the
spec says it's the same as x6_64, 3*4 bytes. So we might be mangling the
pdata records we're outputting?
(pex64_bfd_print_pdata_section gets this right for x86_64 using a entry
size of 3*4)
(There's also some comedy unconstrained reads as we read data for a MIPS
pdata entry, even if we're only going to output a ia64 one, which could
presumably read off the end of the section in extremis).
---
bfd/peXXigen.c | 47 +++++++++++++++++++++++++++++++++--------------
1 file changed, 33 insertions(+), 14 deletions(-)
diff --git a/bfd/peXXigen.c b/bfd/peXXigen.c
index 17a94c461fe..dc82406a4aa 100644
--- a/bfd/peXXigen.c
+++ b/bfd/peXXigen.c
@@ -1887,22 +1887,40 @@ pe_print_edata (bfd * abfd, void * vfile)
return true;
}
-/* This really is architecture dependent. On IA-64, a .pdata entry
- consists of three dwords containing relative virtual addresses that
- specify the start and end address of the code range the entry
- covers and the address of the corresponding unwind info data.
+/* This really is architecture dependent.
- 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 .
+ First, note that this is the 'generic' implementation, if the coff backend
+ doesn't define a arch-specific bfd_pe_print_pdata function.
- This is the version for uncompressed data. */
+ On x86_64 and IA-64, a pdata entry consists of three dwords containing
+ relative virtual addresses that specify the start and end address of the code
+ range the entry covers and the address of the corresponding unwind info data.
+ (x86_64 is handled by pex64_bfd_print_pdata())
+
+ The pdata format for other PE32+ architectures is not (currently) documented
+ in the PE specification. (e.g. for aarch64, it's presumably based on
+ IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY, but not handled yet)
+
+ pdata is not expected to exist in x86 PE32 files (as they use stack-based
+ unwinding).
+
+ For PE32 ARM, PowerPC and SH-4, a compressed (8 byte) PDATA structure is
+ used : _IMAGE_CE_RUNTIME_FUNCTION_ENTRY.
+ (That format is handled by _bfd_pe_print_ce_compressed_pdata(),
+
+ PE32 MIPS is documented to use a _IMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY (5
+ dwords) structure. See
+ http://msdn2.microsoft.com/en-us/library/ms253988(VS.80).aspx
+*/
+
+#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64) || defined (COFF_WITH_peRiscV64)
+#define PDATA_FORMAT_MIPS32
+#endif
static bool
pe_print_pdata (bfd * abfd, void * vfile)
{
-#if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) && !defined (COFF_WITH_peRiscV64)
+#ifndef PDATA_FORMAT_MIPS32
# define PDATA_ROW_SIZE (3 * 8)
#else
# define PDATA_ROW_SIZE (5 * 4)
@@ -1930,7 +1948,7 @@ pe_print_pdata (bfd * abfd, void * vfile)
fprintf (file,
_("\nThe Function Table (interpreted .pdata section contents)\n"));
-#if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) && !defined (COFF_WITH_peRiscV64)
+#ifndef PDATA_FORMAT_MIPS32
fprintf (file,
_(" vma:\t\t\tBegin Address End Address Unwind Info\n"));
#else
@@ -1967,7 +1985,7 @@ pe_print_pdata (bfd * abfd, void * vfile)
bfd_vma eh_handler;
bfd_vma eh_data;
bfd_vma prolog_end_addr;
-#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64) || defined (COFF_WITH_peRiscV64)
+#ifdef PDATA_FORMAT_MIPS32
int em_data;
#endif
@@ -1985,7 +2003,7 @@ pe_print_pdata (bfd * abfd, void * vfile)
/* We are probably into the padding of the section now. */
break;
-#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64) || defined (COFF_WITH_peRiscV64)
+#ifdef PDATA_FORMAT_MIPS32
em_data = ((eh_handler & 0x1) << 2) | (prolog_end_addr & 0x3);
#endif
eh_handler &= ~(bfd_vma) 0x3;
@@ -1996,7 +2014,7 @@ pe_print_pdata (bfd * abfd, void * vfile)
bfd_fprintf_vma (abfd, file, begin_addr); fputc (' ', file);
bfd_fprintf_vma (abfd, file, end_addr); fputc (' ', file);
bfd_fprintf_vma (abfd, file, eh_handler);
-#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64) || defined (COFF_WITH_peRiscV64)
+#ifdef PDATA_FORMAT_MIPS32
fputc (' ', file);
bfd_fprintf_vma (abfd, file, eh_data); fputc (' ', file);
bfd_fprintf_vma (abfd, file, prolog_end_addr);
@@ -2009,6 +2027,7 @@ pe_print_pdata (bfd * abfd, void * vfile)
return true;
#undef PDATA_ROW_SIZE
+#undef PDATA_FORMAT_MIPS32
}
typedef struct sym_cache
--
2.51.0
More information about the Binutils
mailing list