History

x86-64: Fix psABI stdarg prologue

If there were more than 6 integer arguments before the ellipsis, or there were used more than 8 slots used until the ellipsis (e.g. by a large intermediate struct) we generated wrong code. See testcase.

Michael Matz committed 9 years ago

Commit 7cd1ae71 parent 53c5fc22 files · +37 −12Browse files

Unified · Split

2 files
  1. tests/abitest.c +31 −0
  2. x86_64-gen.c +6 −12
tests/abitest.c+31−0
@@ -558,6 +558,36 @@ static int stdarg_test(void) { · 557 unmodified lines
558 return run_callback(src, stdarg_test_callback);558 return run_callback(src, stdarg_test_callback);
559}559}
560 560
561typedef struct {long long a, b;} stdarg_many_test_struct_type;
562typedef void (*stdarg_many_test_function_type) (int, int, int, int, int,
563 stdarg_many_test_struct_type,
564 int, int, ...);
565
566static int stdarg_many_test_callback(void *ptr)
567{
568 stdarg_many_test_function_type f = (stdarg_many_test_function_type)ptr;
569 int x;
570 stdarg_many_test_struct_type l = {10, 11};
571 f(1, 2, 3, 4, 5, l, 6, 7, &x, 44);
572 return x == 44 ? 0 : -1;
573}
574
575static int stdarg_many_test(void)
576{
577 const char *src =
578 "#include <stdarg.h>\n"
579 "typedef struct {long long a, b;} stdarg_many_test_struct_type;\n"
580 "void f (int a, int b, int c, int d, int e, stdarg_many_test_struct_type l, int f, int g, ...){\n"
581 " va_list ap;\n"
582 " int *p;\n"
583 " va_start (ap, g);\n"
584 " p = va_arg(ap, int*);\n"
585 " *p = va_arg(ap, int);\n"
586 " va_end (ap);\n"
587 "}\n";
588 return run_callback(src, stdarg_many_test_callback);
589}
590
561/*591/*
562 * Test Win32 stdarg handling, since the calling convention will pass a pointer592 * Test Win32 stdarg handling, since the calling convention will pass a pointer
563 * to the struct and the stdarg pointer must point to that pointer initially.593 * to the struct and the stdarg pointer must point to that pointer initially.
@@ -654,6 +684,7 @@ int main(int argc, char **argv) { · 90 unmodified lines
654 RUN_TEST(many_struct_test_2);684 RUN_TEST(many_struct_test_2);
655 RUN_TEST(many_struct_test_3);685 RUN_TEST(many_struct_test_3);
656 RUN_TEST(stdarg_test);686 RUN_TEST(stdarg_test);
687 RUN_TEST(stdarg_many_test);
657 RUN_TEST(stdarg_struct_test);688 RUN_TEST(stdarg_struct_test);
658 RUN_TEST(arg_align_test);689 RUN_TEST(arg_align_test);
659 return retval;690 return retval;
x86_64-gen.c+6−12
@@ -1423,21 +1423,15 @@ void gfunc_prolog(CType *func_type) · 1422 unmodified lines
1423 break;1423 break;
1424 1424
1425 case x86_64_mode_integer:1425 case x86_64_mode_integer:
1426 if (seen_reg_num + reg_count <= 8) {1426 if (seen_reg_num + reg_count > REGN)
1427 seen_reg_num += reg_count;1427 goto stack_arg;
1428 } else {1428 seen_reg_num += reg_count;
1429 seen_reg_num = 8;
1430 goto stack_arg;
1431 }
1432 break;1429 break;
1433 1430
1434 case x86_64_mode_sse:1431 case x86_64_mode_sse:
1435 if (seen_sse_num + reg_count <= 8) {1432 if (seen_sse_num + reg_count > 8)
1436 seen_sse_num += reg_count;1433 goto stack_arg;
1437 } else {1434 seen_sse_num += reg_count;
1438 seen_sse_num = 8;
1439 goto stack_arg;
1440 }
1441 break;1435 break;
1442 }1436 }
1443 }1437 }

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t