forked from Imagelibrary/binutils-gdb
libctf: create: structure and union member addition
There is one API addition here:
int ctf_add_member_bitfield (ctf_dict_t *, ctf_id_t souid,
const char *, ctf_id_t type,
unsigned long bit_offset,
int bit_width);
SoU addition handles the representational changes for bitfields and for
CTF_K_BIG structs (i.e. all structs you can add members to), errors out if
you add bitfields to structs that aren't created with the
CTF_ADD_STRUCT_BITFIELDS flag, and arranges to add padding as needed if
there is too much of a gap for the offsets to encode in one hop (that
part is still untested).
This commit is contained in:
@@ -1094,6 +1094,60 @@ ctf_type_size (ctf_dict_t *fp, ctf_id_t type)
|
||||
}
|
||||
}
|
||||
|
||||
/* Determine the natural alignment (in bits) for some type, given the previous
|
||||
TYPE at BIT_OFFSET.
|
||||
|
||||
Not public because doing this entirely right requires arch-dependent
|
||||
attention: this is just to reduce code repetition in ctf-create.c.
|
||||
|
||||
Errors if the TYPE or PREV_TYPE are unsuitable for automatic alignment
|
||||
determination: in particular, you can insert incomplete or nonrepresentable
|
||||
TYPEs, but PREV_TYPE cannot be incomplete or nonrepresentable. */
|
||||
|
||||
ssize_t
|
||||
ctf_type_align_natural (ctf_dict_t *fp, ctf_id_t prev_type,
|
||||
ctf_id_t type, ssize_t bit_offset)
|
||||
{
|
||||
ctf_encoding_t info;
|
||||
ssize_t size;
|
||||
ssize_t align;
|
||||
|
||||
if ((prev_type = ctf_type_resolve (fp, prev_type)) == CTF_ERR)
|
||||
return -1; /* errno is set for us. */
|
||||
|
||||
if ((align = ctf_type_align (fp, type)) < 0)
|
||||
{
|
||||
/* Ignore incompleteness and nonrepresentability of the type we're
|
||||
inserting: just assume such a type has no alignment constraints of its
|
||||
own. */
|
||||
if (ctf_errno (fp) == ECTF_NONREPRESENTABLE
|
||||
|| ctf_errno (fp) == ECTF_INCOMPLETE)
|
||||
align = 0;
|
||||
else
|
||||
return -1; /* errno is set for us. */
|
||||
}
|
||||
|
||||
if (ctf_type_encoding (fp, prev_type, &info) == 0)
|
||||
bit_offset += info.cte_bits;
|
||||
else if ((size = ctf_type_size (fp, prev_type)) > 0)
|
||||
bit_offset += size * CHAR_BIT;
|
||||
else if (size < 0)
|
||||
return -1; /* errno is set for us. */
|
||||
|
||||
/* Round up the offset of the end of the last member to the next byte
|
||||
boundary, convert 'off' to bytes, and then round it up again to the next
|
||||
multiple of the alignment required by the new member. Finally, convert
|
||||
back to bits and store the result. Technically we could do more efficient
|
||||
packing within structs if the new member is a bit-field, but we're the
|
||||
"compiler" and the Standard says we can do as we choose. */
|
||||
|
||||
bit_offset = roundup (bit_offset, CHAR_BIT) / CHAR_BIT;
|
||||
bit_offset = roundup (bit_offset, MAX (align, 1));
|
||||
bit_offset *= CHAR_BIT;
|
||||
|
||||
return bit_offset;
|
||||
}
|
||||
|
||||
/* Resolve the type down to a base type node, and then return the alignment
|
||||
needed for the type storage in bytes.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user