aboutsummaryrefslogtreecommitdiff
path: root/gdb/values.c
diff options
context:
space:
mode:
authorFred Fish <fnf@specifix.com>1992-05-03 23:05:07 +0000
committerFred Fish <fnf@specifix.com>1992-05-03 23:05:07 +0000
commit4db8e515c4db19f91a671c81fcc87bbc2b48c242 (patch)
tree6f5baa70bf3b92aa0ce5e19d909165c549b88b93 /gdb/values.c
parentd752f749c86c0b43e54d2da9f5963e27f5baa3e3 (diff)
downloadgdb-4db8e515c4db19f91a671c81fcc87bbc2b48c242.zip
gdb-4db8e515c4db19f91a671c81fcc87bbc2b48c242.tar.gz
gdb-4db8e515c4db19f91a671c81fcc87bbc2b48c242.tar.bz2
* Makefile.in (VERSION): Bump to 4.5.2.
* Makefile.in (DEMANGLE_OPTS): Add, default to -Dnounderscore. * configure.in: Simplify ncr3000 gdb_host logic, add gdb_target. * dwarfread.c (struct_type): Apply fix from Peggy Fieland for proper handling of bit fields. * gdbtypes.h (struct type): Clarify use of field.bitpos. * symtab.h: Fix couple of misspellings in comments. * value.h (struct value): Clarify use of bitpos. * value.h (unpack_field_as_long): Change prototype, returns LONGEST. * values.c (unpack_field_as_long): Change return type to LONGEST, sign extend unpacked fields that are signed, other rewriting. * config/ncr3000.mt: New target config file.
Diffstat (limited to 'gdb/values.c')
-rw-r--r--gdb/values.c51
1 files changed, 41 insertions, 10 deletions
diff --git a/gdb/values.c b/gdb/values.c
index 895df77..c7ab7b7 100644
--- a/gdb/values.c
+++ b/gdb/values.c
@@ -1190,29 +1190,60 @@ baseclass_addr (type, index, valaddr, valuep, errp)
return valaddr + TYPE_BASECLASS_BITPOS (type, index) / 8;
}
-long
+/* Unpack a field FIELDNO of the specified TYPE, from the anonymous object at
+ VALADDR.
+
+ Extracting bits depends on endianness of the machine. Compute the
+ number of least significant bits to discard. For big endian machines,
+ we compute the total number of bits in the anonymous object, subtract
+ off the bit count from the MSB of the object to the MSB of the
+ bitfield, then the size of the bitfield, which leaves the LSB discard
+ count. For little endian machines, the discard count is simply the
+ number of bits from the LSB of the anonymous object to the LSB of the
+ bitfield.
+
+ If the field is signed, we also do sign extension. */
+
+LONGEST
unpack_field_as_long (type, valaddr, fieldno)
struct type *type;
char *valaddr;
int fieldno;
{
- unsigned long val;
+ unsigned LONGEST val;
+ unsigned LONGEST valmask;
int bitpos = TYPE_FIELD_BITPOS (type, fieldno);
int bitsize = TYPE_FIELD_BITSIZE (type, fieldno);
+ int lsbcount;
- bcopy (valaddr + bitpos / 8, &val, sizeof val);
- SWAP_TARGET_AND_HOST (&val, sizeof val);
+ bcopy (valaddr + bitpos / 8, &val, sizeof (val));
+ SWAP_TARGET_AND_HOST (&val, sizeof (val));
+
+ /* Extract bits. See comment above. */
- /* Extracting bits depends on endianness of the machine. */
#if BITS_BIG_ENDIAN
- val = val >> (sizeof val * 8 - bitpos % 8 - bitsize);
+ lsbcount = (sizeof val * 8 - bitpos % 8 - bitsize);
#else
- val = val >> (bitpos % 8);
+ lsbcount = (bitpos % 8);
#endif
+ val >>= lsbcount;
- if (bitsize < 8 * sizeof (val))
- val &= (((unsigned long)1) << bitsize) - 1;
- return val;
+ /* If the field does not entirely fill a LONGEST, then zero the sign bits.
+ If the field is signed, and is negative, then sign extend. */
+
+ if ((bitsize > 0) && (bitsize < 8 * sizeof (val)))
+ {
+ valmask = (((unsigned LONGEST) 1) << bitsize) - 1;
+ val &= valmask;
+ if (!TYPE_UNSIGNED (TYPE_FIELD_TYPE (type, fieldno)))
+ {
+ if (val & (valmask ^ (valmask >> 1)))
+ {
+ val |= ~valmask;
+ }
+ }
+ }
+ return (val);
}
/* Modify the value of a bitfield. ADDR points to a block of memory in