gdb: Fix numerical field extraction for target description "flags"
authorShahab Vahedi <shahab@synopsys.com>
Fri, 16 Jul 2021 14:49:15 +0000 (16:49 +0200)
committerShahab Vahedi <shahab@synopsys.com>
Mon, 26 Jul 2021 12:34:01 +0000 (14:34 +0200)
commitc9bd98593b785d9bf5f39c7aa74ed0226a23b830
tree290b6b9add1408d1855454b00415462698ce9f53
parent0264bf6fe3028a89c9a6a7b49c489831eb33f506
gdb: Fix numerical field extraction for target description "flags"

The "val_print_type_code_flags ()" function is responsible for
extraction of fields for "flags" data type.  These data types are
used when describing a custom register type in a target description
XML.  The logic used for the extraction though is not sound:

    unsigned field_len = TYPE_FIELD_BITSIZE (type, field);
    ULONGEST field_val
      = val >> (TYPE_FIELD_BITPOS (type, field) - field_len + 1);

TYPE_FIELD_BITSIZE: The bit length of the field to be extracted.
TYPE_FIELD_BITPOS:  The starting position of the field; 0 is LSB.
val:                The register value.

Imagine you have a field that starts at position 1 and its length
is 4 bits.  According to the third line of the code snippet the
shifting right would become "val >> -2", or "val >> 0xfff...fe"
to be precise.  That will result in a "field_val" of 0.

The correct extraction should be:

    ULONGEST field_val = val >> TYPE_FIELD_BITPOS (type, field);

The rest of the algorithm that masks out the higher bits is OK.

Co-Authored-By: Simon Marchi <simon.marchi@efficios.com>
gdb/valprint.c