ld/PDB: handle empty LF_FIELDLIST types

Message ID 20240729215826.27870-1-mark@harmstone.com
State New
Headers
Series ld/PDB: handle empty LF_FIELDLIST types |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_binutils_check--master-aarch64 success Test passed
linaro-tcwg-bot/tcwg_binutils_check--master-arm success Test passed

Commit Message

Mark Harmstone July 29, 2024, 9:57 p.m. UTC
  Empty structs in C++ lead to empty LF_FIELDLIST types in the .debug$T
section, but we were mistakenly rejecting these as invalid. Allow
CodeView types of two bytes, and add a test for this.
---
 ld/pdb.c                                 |  2 +-
 ld/testsuite/ld-pe/pdb-types1-typelist.d |  5 ++++-
 ld/testsuite/ld-pe/pdb-types1b.s         | 20 +++++++++++++++++++-
 ld/testsuite/ld-pe/pdb.exp               |  2 +-
 4 files changed, 25 insertions(+), 4 deletions(-)
  

Comments

Jan Beulich July 30, 2024, 7:02 a.m. UTC | #1
On 29.07.2024 23:57, Mark Harmstone wrote:
> Empty structs in C++ lead to empty LF_FIELDLIST types in the .debug$T
> section, but we were mistakenly rejecting these as invalid. Allow
> CodeView types of two bytes, and add a test for this.
> ---
>  ld/pdb.c                                 |  2 +-
>  ld/testsuite/ld-pe/pdb-types1-typelist.d |  5 ++++-
>  ld/testsuite/ld-pe/pdb-types1b.s         | 20 +++++++++++++++++++-
>  ld/testsuite/ld-pe/pdb.exp               |  2 +-
>  4 files changed, 25 insertions(+), 4 deletions(-)

Okay.

Jan
  

Patch

diff --git a/ld/pdb.c b/ld/pdb.c
index 7a08ae35e79..fcbe325603c 100644
--- a/ld/pdb.c
+++ b/ld/pdb.c
@@ -3582,7 +3582,7 @@  handle_debugt_section (asection *s, bfd *mod, struct types *types,
       size = bfd_getl16 (data + off);
       off += sizeof (uint16_t);
 
-      if (size + off > s->size || size <= sizeof (uint16_t))
+      if (size + off > s->size || size < sizeof (uint16_t))
 	{
 	  free (data);
 	  bfd_set_error (bfd_error_bad_value);
diff --git a/ld/testsuite/ld-pe/pdb-types1-typelist.d b/ld/testsuite/ld-pe/pdb-types1-typelist.d
index db08b52859f..1caa074ac56 100644
--- a/ld/testsuite/ld-pe/pdb-types1-typelist.d
+++ b/ld/testsuite/ld-pe/pdb-types1-typelist.d
@@ -77,4 +77,7 @@  Contents of section .data:
  0480 3a001d15 2a100000 00000000 00000000  :...*...........
  0490 27000000 49556e6b 6e6f776e 00517565  '...IUnknown.Que
  04a0 7279496e 74657266 61636500 41646452  ryInterface.AddR
- 04b0 65660052 656c6561 736500f1           ef.Release..    
+ 04b0 65660052 656c6561 736500f1 02000312  ef.Release......
+ 04c0 22000515 00000000 2c100000 00000000  ".......,.......
+ 04d0 00000000 0100656d 7074795f 73747275  ......empty_stru
+ 04e0 637400f1                             ct..            
diff --git a/ld/testsuite/ld-pe/pdb-types1b.s b/ld/testsuite/ld-pe/pdb-types1b.s
index e26b190b78f..8bfc973c1c8 100644
--- a/ld/testsuite/ld-pe/pdb-types1b.s
+++ b/ld/testsuite/ld-pe/pdb-types1b.s
@@ -593,7 +593,7 @@ 
 
 /* Type 102a, virtual function table */
 .vftable1:
-.short .types_end - .vftable1 - 2
+.short .fieldlist12 - .vftable1 - 2
 .short LF_VFTABLE
 .long 0x1029 /* type */
 .long 0 /* base vftable */
@@ -607,4 +607,22 @@ 
 .vftable1_names_end:
 .byte 0xf1 /* padding */
 
+/* Type 102b, empty LF_FIELDLIST */
+.fieldlist12:
+.short .struct7 - .fieldlist12 - 2
+.short LF_FIELDLIST
+
+/* Type 102c, empty struct */
+.struct7:
+.short .types_end - .struct7 - 2
+.short LF_STRUCTURE
+.short 0 /* no. members */
+.short 0 /* property */
+.long 0x102b /* field list */
+.long 0 /* type derived from */
+.long 0 /* type of vshape table */
+.short 1 /* size */
+.asciz "empty_struct" /* name */
+.byte 0xf1 /* padding */
+
 .types_end:
diff --git a/ld/testsuite/ld-pe/pdb.exp b/ld/testsuite/ld-pe/pdb.exp
index 124765109bf..b583e877f01 100644
--- a/ld/testsuite/ld-pe/pdb.exp
+++ b/ld/testsuite/ld-pe/pdb.exp
@@ -1036,7 +1036,7 @@  proc test5 { } {
     binary scan $data i end_type
 
     # end_type is one greater than the last type in the stream
-    if { $end_type != 0x102c } {
+    if { $end_type != 0x102e } {
 	fail "Incorrect end type value in TPI stream."
     } else {
 	pass "Correct end type value in TPI stream."