case LF_MEMBER:
{
struct lf_member *mem = (struct lf_member *) ptr;
+ uint16_t offset;
size_t name_len, subtype_len;
if (left < offsetof (struct lf_member, name))
if (!remap_type (&mem->type, map, type_num, num_types))
return false;
+ subtype_len = offsetof (struct lf_member, name);
+
+ offset = bfd_getl16 (&mem->offset);
+
+ /* If offset >= 0x8000, actual value follows. */
+ if (offset >= 0x8000)
+ {
+ unsigned int param_len = extended_value_len (offset);
+
+ if (param_len == 0)
+ {
+ einfo (_("%P: warning: unhandled type %v within"
+ " LF_MEMBER\n"), offset);
+ return false;
+ }
+
+ subtype_len += param_len;
+
+ if (left < subtype_len)
+ {
+ einfo (_("%P: warning: truncated CodeView type record"
+ " LF_MEMBER\n"));
+ return false;
+ }
+ }
+
name_len =
- strnlen (mem->name,
- left - offsetof (struct lf_member, name));
+ strnlen ((char *) mem + subtype_len, left - subtype_len);
if (name_len == left - offsetof (struct lf_member, name))
{
name_len++;
- subtype_len = offsetof (struct lf_member, name) + name_len;
+ subtype_len += name_len;
if (subtype_len % 4 != 0)
subtype_len += 4 - (subtype_len % 4);
case LF_BCLASS:
{
struct lf_bclass *bc = (struct lf_bclass *) ptr;
+ size_t subtype_len;
+ uint16_t offset;
if (left < sizeof (struct lf_bclass))
{
num_types))
return false;
- ptr += sizeof (struct lf_bclass);
- left -= sizeof (struct lf_bclass);
+ subtype_len = sizeof (struct lf_bclass);
+
+ offset = bfd_getl16 (&bc->offset);
+
+ /* If offset >= 0x8000, actual value follows. */
+ if (offset >= 0x8000)
+ {
+ unsigned int param_len = extended_value_len (offset);
+
+ if (param_len == 0)
+ {
+ einfo (_("%P: warning: unhandled type %v within"
+ " LF_BCLASS\n"), offset);
+ return false;
+ }
+
+ subtype_len += param_len;
+
+ if (left < subtype_len)
+ {
+ einfo (_("%P: warning: truncated CodeView type record"
+ " LF_BCLASS\n"));
+ return false;
+ }
+ }
+
+ if (subtype_len % 4 != 0)
+ subtype_len += 4 - (subtype_len % 4);
+
+ if (left < subtype_len)
+ {
+ einfo (_("%P: warning: truncated CodeView type record"
+ " LF_BCLASS\n"));
+ return false;
+ }
+
+ ptr += subtype_len;
+ left -= subtype_len;
break;
}
case LF_IVBCLASS:
{
struct lf_vbclass *vbc = (struct lf_vbclass *) ptr;
+ size_t subtype_len;
+ uint16_t offset;
if (left < sizeof (struct lf_vbclass))
{
type_num, num_types))
return false;
- ptr += sizeof (struct lf_vbclass);
- left -= sizeof (struct lf_vbclass);
+ subtype_len = offsetof (struct lf_vbclass,
+ virtual_base_vbtable_offset);
+
+ offset = bfd_getl16 (&vbc->virtual_base_pointer_offset);
+
+ /* If offset >= 0x8000, actual value follows. */
+ if (offset >= 0x8000)
+ {
+ unsigned int param_len = extended_value_len (offset);
+
+ if (param_len == 0)
+ {
+ einfo (_("%P: warning: unhandled type %v within"
+ " LF_VBCLASS/LF_IVBCLASS\n"), offset);
+ return false;
+ }
+
+ subtype_len += param_len;
+
+ if (left < subtype_len)
+ {
+ einfo (_("%P: warning: truncated CodeView type record"
+ " LF_VBCLASS/LF_IVBCLASS\n"));
+ return false;
+ }
+ }
+
+ offset = bfd_getl16 ((char *)vbc + subtype_len);
+ subtype_len += sizeof (uint16_t);
+
+ /* If offset >= 0x8000, actual value follows. */
+ if (offset >= 0x8000)
+ {
+ unsigned int param_len = extended_value_len (offset);
+
+ if (param_len == 0)
+ {
+ einfo (_("%P: warning: unhandled type %v within"
+ " LF_VBCLASS/LF_IVBCLASS\n"), offset);
+ return false;
+ }
+
+ subtype_len += param_len;
+
+ if (left < subtype_len)
+ {
+ einfo (_("%P: warning: truncated CodeView type record"
+ " LF_VBCLASS/LF_IVBCLASS\n"));
+ return false;
+ }
+ }
+
+ if (subtype_len % 4 != 0)
+ subtype_len += 4 - (subtype_len % 4);
+
+ if (left < subtype_len)
+ {
+ einfo (_("%P: warning: truncated CodeView type record"
+ " LF_VBCLASS/LF_IVBCLASS\n"));
+ return false;
+ }
+
+ ptr += subtype_len;
+ left -= subtype_len;
break;
}
case LF_STRUCTURE:
{
struct lf_class *cl = (struct lf_class *) data;
- uint16_t prop;
- size_t name_len;
+ uint16_t prop, num_bytes;
+ size_t name_len, name_off;
if (size < offsetof (struct lf_class, name))
{
if (!remap_type (&cl->vshape, map, type_num, num_types))
return false;
- name_len = strnlen (cl->name, size - offsetof (struct lf_class, name));
+ name_off = offsetof (struct lf_class, name);
+
+ num_bytes = bfd_getl16 (&cl->length);
- if (name_len == size - offsetof (struct lf_class, name))
+ /* If num_bytes >= 0x8000, actual value follows. */
+ if (num_bytes >= 0x8000)
+ {
+ unsigned int param_len = extended_value_len (num_bytes);
+
+ if (param_len == 0)
+ {
+ einfo (_("%P: warning: unhandled type %v within"
+ " LF_CLASS/LF_STRUCTURE\n"), num_bytes);
+ return false;
+ }
+
+ name_off += param_len;
+
+ if (size < name_off)
+ {
+ einfo (_("%P: warning: truncated CodeView type record"
+ " LF_CLASS/LF_STRUCTURE\n"));
+ return false;
+ }
+ }
+
+ name_len = strnlen ((char *) cl + name_off, size - name_off);
+
+ if (name_len == size - name_off)
{
einfo (_("%P: warning: name for LF_CLASS/LF_STRUCTURE has no"
" terminating zero\n"));
{
/* Structure has another name following first one. */
- size_t len = offsetof (struct lf_class, name) + name_len + 1;
+ size_t len = name_off + name_len + 1;
size_t unique_name_len;
- unique_name_len = strnlen (cl->name + name_len + 1, size - len);
+ unique_name_len = strnlen ((char *) cl + name_off + name_len + 1,
+ size - len);
if (unique_name_len == size - len)
{
}
if (!(prop & (CV_PROP_FORWARD_REF | CV_PROP_SCOPED))
- && !is_name_anonymous (cl->name, name_len))
+ && !is_name_anonymous ((char *) cl + name_off, name_len))
{
other_hash = true;
- cv_hash = crc32 ((uint8_t *) cl->name, name_len);
+ cv_hash = crc32 ((uint8_t *) cl + name_off, name_len);
}
break;
case LF_UNION:
{
struct lf_union *un = (struct lf_union *) data;
- uint16_t prop;
- size_t name_len;
+ uint16_t prop, num_bytes;
+ size_t name_len, name_off;
if (size < offsetof (struct lf_union, name))
{
if (!remap_type (&un->field_list, map, type_num, num_types))
return false;
- name_len = strnlen (un->name, size - offsetof (struct lf_union, name));
+ name_off = offsetof (struct lf_union, name);
+
+ num_bytes = bfd_getl16 (&un->length);
+
+ /* If num_bytes >= 0x8000, actual value follows. */
+ if (num_bytes >= 0x8000)
+ {
+ unsigned int param_len = extended_value_len (num_bytes);
+
+ if (param_len == 0)
+ {
+ einfo (_("%P: warning: unhandled type %v within"
+ " LF_UNION\n"), num_bytes);
+ return false;
+ }
+
+ name_off += param_len;
+
+ if (size < name_off)
+ {
+ einfo (_("%P: warning: truncated CodeView type record"
+ " LF_UNION\n"));
+ return false;
+ }
+ }
+
+ name_len = strnlen ((char *) un + name_off, size - name_off);
- if (name_len == size - offsetof (struct lf_union, name))
+ if (name_len == size - name_off)
{
einfo (_("%P: warning: name for LF_UNION has no"
" terminating zero\n"));
{
/* Structure has another name following first one. */
- size_t len = offsetof (struct lf_union, name) + name_len + 1;
+ size_t len = name_off + name_len + 1;
size_t unique_name_len;
- unique_name_len = strnlen (un->name + name_len + 1, size - len);
+ unique_name_len = strnlen ((char *) un + name_off + name_len + 1,
+ size - len);
if (unique_name_len == size - len)
{
}
if (!(prop & (CV_PROP_FORWARD_REF | CV_PROP_SCOPED))
- && !is_name_anonymous (un->name, name_len))
+ && !is_name_anonymous ((char *) un + name_off, name_len))
{
other_hash = true;
- cv_hash = crc32 ((uint8_t *) un->name, name_len);
+ cv_hash = crc32 ((uint8_t *) un + name_off, name_len);
}
break;
.equ LF_USHORT, 0x8002
.equ LF_LONG, 0x8003
+.equ LF_ULONG, 0x8004
.equ LF_UQUADWORD, 0x800a
.equ CV_PTR_NEAR32, 0xa
# Type 1021, struct quux, field list 1020
.struct4:
-.short .types_end - .struct4 - 2
+.short .arr2 - .struct4 - 2
.short LF_STRUCTURE
.short 1 # no. members
.short 0 # property
.asciz "quux" # name
.byte 0xf1 # padding
+# Type 1022, array[60000] of char
+.arr2:
+.short .fieldlist8 - .arr2 - 2
+.short LF_ARRAY
+.long T_CHAR # element type
+.long T_INT4 # index type
+.short LF_USHORT
+.short 60000 # size in bytes
+.byte 0 # name
+.byte 0xf3 # padding
+.byte 0xf2 # padding
+.byte 0xf1 # padding
+
+# Type 1023, field list for struct longstruct
+.fieldlist8:
+.short .struct5 - .fieldlist8 - 2
+.short LF_FIELDLIST
+.short LF_MEMBER
+.short 3 # public
+.long 0x1022
+.short 0 # offset
+.asciz "a"
+.short LF_MEMBER
+.short 3 # public
+.long 0x1022
+.short LF_USHORT
+.short 60000 # offset
+.asciz "b"
+.byte 0xf2 # padding
+.byte 0xf1 # padding
+.short LF_MEMBER
+.short 3 # public
+.long 0x1022
+.short LF_ULONG
+.long 120000 # offset
+.asciz "c"
+
+# Type 1024, struct longstruct
+.struct5:
+.short .fieldlist9 - .struct5 - 2
+.short LF_STRUCTURE
+.short 3 # no. members
+.short 0 # property
+.long 0x1023 # field list
+.long 0 # type derived from
+.long 0 # type of vshape table
+.short LF_ULONG
+.long 180000 # size
+.asciz "longstruct" # name
+.byte 0xf3 # padding
+.byte 0xf2 # padding
+.byte 0xf1 # padding
+
+# Type 1025, field list for union longunion
+.fieldlist9:
+.short .union4 - .fieldlist9 - 2
+.short LF_FIELDLIST
+.short LF_MEMBER
+.short 3 # public
+.long 0x1022
+.short 0 # offset
+.asciz "a"
+.short LF_MEMBER
+.short 3 # public
+.long 0x1022
+.short 0 # offset
+.asciz "b"
+
+# Type 1026, union longunion (field list 1025)
+.union4:
+.short .fieldlist10 - .union4 - 2
+.short LF_UNION
+.short 2 # no. members
+.short 0 # property
+.long 0x1025 # field list
+.short LF_USHORT
+.short 60000 # size
+.asciz "longunion"
+.byte 0xf2 # padding
+.byte 0xf1 # padding
+
+# Type 1027, field list with base class longstruct
+.fieldlist10:
+.short .fieldlist11 - .fieldlist10 - 2
+.short LF_FIELDLIST
+.short LF_BCLASS
+.short 0 # attributes
+.long 0x1024 # base class
+.short LF_ULONG
+.long 120000 # offset within class
+.byte 0xf2 # padding
+.byte 0xf1 # padding
+.short LF_MEMBER
+.short 3 # public
+.long 0x1022
+.short 0 # offset
+.asciz "d"
+
+# Type 1028, field list with virtual base class longstruct
+.fieldlist11:
+.short .types_end - .fieldlist11 - 2
+.short LF_FIELDLIST
+.short LF_VBCLASS
+.short 0 # attributes
+.long 0x1024 # type index of direct virtual base class
+.long 0 # type index of virtual base pointer
+.short LF_USHORT
+.short 60000 # virtual base pointer offset
+.short LF_ULONG
+.long 120000 # virtual base offset from vbtable
+.byte 0xf2 # padding
+.byte 0xf1 # padding
+.short LF_MEMBER
+.short 3 # public
+.long 0x1022
+.short 0 # offset
+.asciz "d"
+
.types_end: