summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2021-06-15 15:19:26 -0400
committerAnthony Green <green@moxielogic.com>2021-06-15 15:24:24 -0400
commit5651bea284ad0822eafe768e3443c2f4d7da2c8f (patch)
tree8d1df0d48e27ae7293c603a67ad6a17cd5bc8819 /src
parentf56eb85227bbcc7bd81232a338655146385a77ca (diff)
downloadlibffi-5651bea284ad0822eafe768e3443c2f4d7da2c8f.tar.gz
2021-06-15 Jakub Jelinek <jakub@redhat.com>
* src/x86/ffi64.c (classify_argument): For FFI_TYPE_STRUCT set words to number of words needed for type->size + byte_offset bytes rather than just type->size bytes. Compute pos before the loop and check total size of the structure. * testsuite/libffi.call/nested_struct12.c: New test.
Diffstat (limited to 'src')
-rw-r--r--src/x86/ffi64.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/src/x86/ffi64.c b/src/x86/ffi64.c
index 5264cdf..438b374 100644
--- a/src/x86/ffi64.c
+++ b/src/x86/ffi64.c
@@ -218,7 +218,8 @@ classify_argument (ffi_type *type, enum x86_64_reg_class classes[],
case FFI_TYPE_STRUCT:
{
const size_t UNITS_PER_WORD = 8;
- size_t words = (type->size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
+ size_t words = (type->size + byte_offset + UNITS_PER_WORD - 1)
+ / UNITS_PER_WORD;
ffi_type **ptr;
unsigned int i;
enum x86_64_reg_class subclasses[MAX_CLASSES];
@@ -242,14 +243,15 @@ classify_argument (ffi_type *type, enum x86_64_reg_class classes[],
/* Merge the fields of structure. */
for (ptr = type->elements; *ptr != NULL; ptr++)
{
- size_t num;
+ size_t num, pos;
byte_offset = FFI_ALIGN (byte_offset, (*ptr)->alignment);
num = classify_argument (*ptr, subclasses, byte_offset % 8);
if (num == 0)
return 0;
- for (i = 0; i < num; i++)
+ pos = byte_offset / 8;
+ for (i = 0; i < num && (i + pos) < words; i++)
{
size_t pos = byte_offset / 8;
classes[i + pos] =