diff options
Diffstat (limited to '')
-rw-r--r-- | libsyscalls_get_struct_description.c | 69 |
1 files changed, 44 insertions, 25 deletions
diff --git a/libsyscalls_get_struct_description.c b/libsyscalls_get_struct_description.c index 4d9ce68..cc1c42b 100644 --- a/libsyscalls_get_struct_description.c +++ b/libsyscalls_get_struct_description.c @@ -41,8 +41,9 @@ struct padding { static enum libsyscalls_error -get_struct_description(enum libsyscalls_os os, enum libsyscalls_arch arch, enum libsyscalls_datatype datatype, const void *data, - size_t data_size, struct libsyscalls_structure_description **description_out, size_t *extra_sizep); +get_struct_description(enum libsyscalls_os os, enum libsyscalls_arch arch, + enum libsyscalls_datatype datatype, const void *data, size_t data_size, + struct libsyscalls_structure_description **description_out, size_t *extra_sizep); static struct libsyscalls_structure_description * @@ -74,7 +75,8 @@ create_pad_description(enum libsyscalls_os os, enum libsyscalls_arch arch, unsig static enum libsyscalls_error -shift_fields(enum libsyscalls_os os, enum libsyscalls_arch arch, struct libsyscalls_structure_description *description, +shift_fields(enum libsyscalls_os os, enum libsyscalls_arch arch, + struct libsyscalls_structure_description *description, const struct padding *paddings, size_t npaddings) { signed short int shift, map[description->num_fields], abs, rel; @@ -201,22 +203,28 @@ move_in_subdescriptions(char *buffer, size_t *offsetp, struct libsyscalls_struct static unsigned long long int read_field(const void *data, size_t data_size, const size_t *field_offsets, - const struct libsyscalls_structure_description *description, unsigned short int i, int *undetermined_out) + const struct libsyscalls_structure_description *description, + unsigned short int i, int *undetermined_out) { size_t offset, width, bits = 0; - enum libsyscalls_datatype type = description->fields[i].type; - const struct libsyscalls_datatype_description *type_description = description->fields[i].type_description.nonstructure; + enum libsyscalls_datatype type; + const struct libsyscalls_datatype_description *type_description; unsigned splits, expected_splits, end; unsigned long long int result = 0, subresult; signed long long int sresult; int is_negative; + type = description->fields[i].type; + type_description = description->fields[i].type_description.nonstructure; + if ((type & LIBSYSCALLS_TYPEBITSMASK) != LIBSYSCALLS_TYPEBITS_SCALAR) abort(); type ^= LIBSYSCALLS_TYPEBITS_SCALAR; - if (type >= LIBSYSCALLS_TYPEOFFSET_SPLIT_PRIMITIVES && type < LIBSYSCALLS_TYPEOFFSET_COMPOSITE_PRIMITIVES) + if (type >= LIBSYSCALLS_TYPEOFFSET_SPLIT_PRIMITIVES && + type < LIBSYSCALLS_TYPEOFFSET_COMPOSITE_PRIMITIVES) splits = LIBSYSCALLS_GET_SECTION_FRACTION(type_description->section); - else if (type >= LIBSYSCALLS_TYPEOFFSET_UNANNOTATED_NUMERICALS && type < LIBSYSCALLS_TYPEOFFSET_FIXED_ARRAYS) + else if (type >= LIBSYSCALLS_TYPEOFFSET_UNANNOTATED_NUMERICALS && + type < LIBSYSCALLS_TYPEOFFSET_FIXED_ARRAYS) splits = 1; else abort(); @@ -229,9 +237,11 @@ read_field(const void *data, size_t data_size, const size_t *field_offsets, if ((type & LIBSYSCALLS_TYPEBITSMASK) != LIBSYSCALLS_TYPEBITS_SCALAR) abort(); type ^= LIBSYSCALLS_TYPEBITS_SCALAR; - if (type >= LIBSYSCALLS_TYPEOFFSET_SPLIT_PRIMITIVES && type < LIBSYSCALLS_TYPEOFFSET_COMPOSITE_PRIMITIVES) + if (type >= LIBSYSCALLS_TYPEOFFSET_SPLIT_PRIMITIVES && + type < LIBSYSCALLS_TYPEOFFSET_COMPOSITE_PRIMITIVES) splits = LIBSYSCALLS_GET_SECTION_FRACTION(type_description->section); - else if (type >= LIBSYSCALLS_TYPEOFFSET_UNANNOTATED_NUMERICALS && type < LIBSYSCALLS_TYPEOFFSET_FIXED_ARRAYS) + else if (type >= LIBSYSCALLS_TYPEOFFSET_UNANNOTATED_NUMERICALS && + type < LIBSYSCALLS_TYPEOFFSET_FIXED_ARRAYS) splits = 1; else abort(); @@ -258,7 +268,8 @@ read_field(const void *data, size_t data_size, const size_t *field_offsets, } if (type_description->is_signed) { - if (libsyscalls_parse_signed_integer(result, type_description->sign_representation, bits, &result, &is_negative)) + if (libsyscalls_parse_signed_integer(result, type_description->sign_representation, + bits, &result, &is_negative)) abort(); if (is_negative) { #if LLONG_MIN == -LLONG_MAX @@ -397,9 +408,10 @@ adjust_for_struct(enum libsyscalls_os os, enum libsyscalls_arch arch, const void unsigned short int field; enum libsyscalls_error r; - r = get_struct_description(os, arch, description->fields[i].type, &((const char *)data)[field_offsets[i]], - data_size < field_offsets[i] ? 0 : data_size - field_offsets[i], - &struct_description, extra_sizep); + r = get_struct_description(os, arch, description->fields[i].type, + &((const char *)data)[field_offsets[i]], + USAT_MINUS(data_size, field_offsets[i]), + &struct_description, extra_sizep); if (r) return r; @@ -418,7 +430,7 @@ adjust_for_struct(enum libsyscalls_os os, enum libsyscalls_arch arch, const void if (field > i) abort(); set_subsize: - uvalue = read_field(data, data_size, field_offsets, description, i, undetermined_sizep); + uvalue = read_field(data, data_size, field_offsets, description, field, undetermined_sizep); /* TODO set `*subsizep` to `uvalue` (may overflow) */ } if (!struct_description->array_size) @@ -442,7 +454,7 @@ adjust_for_struct(enum libsyscalls_os os, enum libsyscalls_arch arch, const void static enum libsyscalls_error adjust_for_fields(enum libsyscalls_os os, enum libsyscalls_arch arch, const void *data, size_t data_size, - struct padding **paddingsp, size_t *npaddingsp, size_t *paddings_sizep, + struct padding **paddingsp, size_t *npaddingsp, size_t *paddings_sizep, struct libsyscalls_structure_description *description, int dont_align_fields, size_t *extra_sizep) { size_t field_offsets[description->num_fields]; @@ -494,8 +506,10 @@ adjust_for_fields(enum libsyscalls_os os, enum libsyscalls_arch arch, const void static enum libsyscalls_error -get_struct_description(enum libsyscalls_os os, enum libsyscalls_arch arch, enum libsyscalls_datatype datatype, const void *data, - size_t data_size, struct libsyscalls_structure_description **description_out, size_t *extra_sizep) +get_struct_description(enum libsyscalls_os os, enum libsyscalls_arch arch, + enum libsyscalls_datatype datatype, const void *data, size_t data_size, + struct libsyscalls_structure_description **description_out, + size_t *extra_sizep) { unsigned char fill_is_known; unsigned short int array_size; @@ -508,7 +522,7 @@ get_struct_description(enum libsyscalls_os os, enum libsyscalls_arch arch, enum size_t npaddings = 0, paddings_size = 0; struct padding *paddings = NULL; - if ((unsigned)datatype & ~(LIBSYSCALLS_TYPEBITSMASK | (LIBSYSCALLS_TYPEBITSMASK - 1U))) + if ((unsigned)datatype & ~SET_MASK_TRAIL(LIBSYSCALLS_TYPEBITSMASK)) return LIBSYSCALLS_E_INVAL; datatype ^= class = datatype & LIBSYSCALLS_TYPEBITSMASK; @@ -577,7 +591,8 @@ get_struct_description(enum libsyscalls_os os, enum libsyscalls_arch arch, enum #define CASE(UPPERCASE, LOWERCASE)\ case LIBSYSCALLS_OS_##UPPERCASE:\ - r = fix_##LOWERCASE##_struct_description(arch, datatype, class, data, data_size, description);\ + r = fix_##LOWERCASE##_struct_description(arch, datatype, class,\ + data, data_size, description);\ break switch ((int)os) { @@ -613,8 +628,10 @@ fail: enum libsyscalls_error -libsyscalls_get_struct_description(enum libsyscalls_os os, enum libsyscalls_arch arch, enum libsyscalls_datatype datatype, - const void *data, size_t data_size, struct libsyscalls_structure_description **description_out) +libsyscalls_get_struct_description(enum libsyscalls_os os, enum libsyscalls_arch arch, + enum libsyscalls_datatype datatype, + const void *data, size_t data_size, + struct libsyscalls_structure_description **description_out) { struct libsyscalls_structure_description *description, *new; size_t extra_size = 0, size, nalign, salign, align; @@ -637,7 +654,7 @@ libsyscalls_get_struct_description(enum libsyscalls_os os, enum libsyscalls_arch size = offsetof(struct libsyscalls_structure_description, fields); size += (size_t)description->num_fields * sizeof(*description->fields); - size += (align - (size & (align - 1))) & (align - 1); + size += ALIGNMENT_ADJUSTMENT(size, align); new = realloc(description, size + extra_size); if (!new) { @@ -647,9 +664,11 @@ libsyscalls_get_struct_description(enum libsyscalls_os os, enum libsyscalls_arch } description = new; - move_in_subdescriptions((void *)description, &size, description, nalign == align, salign == align); + move_in_subdescriptions((void *)description, &size, description, + nalign == align, salign == align); if (nalign != align || salign != align) - move_in_subdescriptions((void *)description, &size, description, nalign != align, salign != align); + move_in_subdescriptions((void *)description, &size, description, + nalign != align, salign != align); *description_out = description; return LIBSYSCALLS_E_OK; |