This is the mail archive of the gdb@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

word addressing issues


Hi Experts,

The following gdbarch hook was introduced in GDB (I guess in v7.11) to be able to tackle architectures with word-addressed (where word = any multiple of 8-bits) memories. 
'gdbarch_addressable_memory_unit_size(gdbarch*)'

I have been making use of this hook for a word addressed processor architecture, in which I return back the word-size (aka addressable-unit size) of the memory. I am using gdb 7.12. Of late, I noticed a few places inside GDB code, where it seems that the word size is not being taken into account. I am listing those code snippets with some comments below:

1. )
I assume that now (i.e. after v7.11) the memory data transfers functions like read_value_memory, target_xfer_partial, memory_xfer_partial etc. operate at the word (or the unit) level, where the unit-size is obtained from gdbarch_addressable_memory_unit_size hook. So, for example, in case of 'memory_xfer_partial' i.e.
                        memory_xfer_partial (struct target_ops *ops, ..,  const gdb_byte *writebuf,  ULONGEST memaddr, ULONGEST len, ULONGEST *xfered_len)
the arguments 'memaddr' and 'len' will contain the address and the length resp. in terms of units which can be potentially bigger than 8-bits, right? But, looking inside the body of memory_xfer_partial:

1262 static enum target_xfer_status
1263 memory_xfer_partial (struct target_ops *ops, enum target_object object, ..)
...
1284   else
1285     {
1286       gdb_byte *buf;
1287       struct cleanup *old_chain;
...
1295       len = min (ops->to_get_memory_xfer_limit (ops), len);
1296 
1297       buf = (gdb_byte *) xmalloc (len);
1298       old_chain = make_cleanup (xfree, buf);
1299       memcpy (buf, writebuf, len);
...
Here the 'buf' is being allocated only 'len' bytes (instead of 'len' units) and similarly memcpy is copying only 'len' bytes (instead of 'len' units). I think here we should obtain the 'unit_size' from the gdbarch hook and use 'len*unit_size' instead of just 'len'. Do you agree?

2.)
The offsets for members in structs and classes when saved in the GDB's 'value' struct, should also now be saved in terms of words/units. I noticed a couple of places where the offsets are still being saved as byte offsets. For example, looking inside the 'value_primitive_field' function in value.c file i.e.

3115 struct value *
3116 value_primitive_field (struct value *arg1, LONGEST offset, ..)
...
3118 {
3163   else if (fieldno < TYPE_N_BASECLASSES (arg_type))
3164     {
...
3177       if (BASETYPE_VIA_VIRTUAL (arg_type, fieldno))
3178   boffset = baseclass_offset (arg_type, fieldno,
3179             value_contents (arg1),
3180             value_embedded_offset (arg1),
3181             value_address (arg1),
3182             arg1);
3183       else
3184   boffset = TYPE_FIELD_BITPOS (arg_type, fieldno) / 8;
3185 
....
3196    v->embedded_offset = offset + value_embedded_offset (arg1) + boffset;

The 'boffset' here is still being computed in terms of bytes and not units. Even the 'baseclass_offset' function returns the offset in terms of bytes. I assume the embedded_offset is now (i.e. from v7.11) saved in terms of units and so this looks like incorrect. I see the issue when accessing the "base" part of a derived object.

3.)

Noticed similar issue as (2) in functions cp_print_value_fields in cp-valprint.c:

155 void
156 cp_print_value_fields (struct type *type, struct type *real_type,
157            const gdb_byte *valaddr, LONGEST offset, ..)
...
350         else
351     {
352       struct value_print_options opts = *options;
353 
354       opts.deref_ref = 0;
355       val_print (TYPE_FIELD_TYPE (type, i),
356            valaddr,
357            offset + TYPE_FIELD_BITPOS (type, i) / 8,
358            address,
359            stream, recurse + 1, val, &opts,
360            current_language);
361     }
362       }

Here again the term ' TYPE_FIELD_BITPOS (type, i) / 8' added to 'offset' is in terms of bytes and not units.

And a similar issue in do_search_struct_field in valops.c:

1805 static void
1806 do_search_struct_field (const char *name, struct value *arg1, LONGEST offset, ..)
...
1835   if (t_field_name
1836       && t_field_name[0] == '\0')
1837     {
1838       struct type *field_type = TYPE_FIELD_TYPE (type, i);
1839 
...
1864     if (TYPE_CODE (field_type) == TYPE_CODE_STRUCT
1865         || (TYPE_NFIELDS (field_type) > 0
1866       && TYPE_FIELD_BITPOS (field_type, 0) == 0))
1867       new_offset += TYPE_FIELD_BITPOS (type, i) / 8;

Could you please check and let me know if my above observations are correct and if a bug request needs to be filed?

Thanks and Regards,
Ashutosh



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]