Some structs are passed in registers. When they need more than one the implementation of __va_arg on x86-64 didn't correctly account for this. This fixes only the cases where the structs consist of integer types, as there the register save area is consecutive. Fixes some tests from 73_arm64.c, but still leaves those failing that use floating point in the large-but-regpassed structs.
Unified · Split
| @@ -688,11 +688,10 @@ void *__va_arg(__va_list_struct *ap, · 687 unmodified lines | |||
| 688 | align = (align + 7) & ~7; | 688 | align = (align + 7) & ~7; |
| 689 | switch (arg_type) { | 689 | switch (arg_type) { |
| 690 | case __va_gen_reg: | 690 | case __va_gen_reg: |
| 691 | if (ap->gp_offset < 48) { | 691 | if (ap->gp_offset + size <= 48) { |
| 692 | ap->gp_offset += 8; | 692 | ap->gp_offset += size; |
| 693 | return ap->reg_save_area + ap->gp_offset - 8; | 693 | return ap->reg_save_area + ap->gp_offset - size; |
| 694 | } | 694 | } |
| 695 | size = 8; | ||
| 696 | goto use_overflow_area; | 695 | goto use_overflow_area; |
| 697 | 696 | ||
| 698 | case __va_float_reg: | 697 | case __va_float_reg: |