[patch/idea,v2] Add register scrambling to testsuite

Message ID xnwndhll2e.fsf@greed.delorie.com
State Changes Requested, archived
Headers
Series [patch/idea,v2] Add register scrambling to testsuite |

Checks

Context Check Description
dj/TryBot-apply_patch success Patch applied to master at the time it was sent
dj/TryBot-32bit success Build for i686

Commit Message

DJ Delorie June 15, 2022, 8:37 p.m. UTC
  [added register clobbers, filled out ppc/x86 lists, added riscv]

Allow for target-specific register "scrambling" - loading arbitrary
values into all registers that need not be call-saved.  These values
should be non-zero and invalid addresses, to help catch inadvertent
uses of otherwise uninitialized registers.

Intended to help prevent bugs such as those fixed by
0218463dd8265ed937622f88ac68c7d984fe0cfc
  

Comments

Carlos O'Donell Nov. 22, 2023, 1:34 p.m. UTC | #1
On 6/15/22 16:37, DJ Delorie via Libc-alpha wrote:
> [added register clobbers, filled out ppc/x86 lists, added riscv]

I was reviewing your patch queue and this was the last item.

Changes requested.
 
> Allow for target-specific register "scrambling" - loading arbitrary
> values into all registers that need not be call-saved.  These values
> should be non-zero and invalid addresses, to help catch inadvertent
> uses of otherwise uninitialized registers.

Suggest adding:

The goal with this change is to add a minimal amount of register scrambling that
perturbs system state.  The goal is not to cover all call paths, or to correctly
fuzz all assembly implementations (which we should have fewer of), or to insert
per-PLT call register fuzzing.  This change is the smallest possible change that
adds the largest amount of state change to simulate an application having modified
the register states.  If the compiler uses the registers between scrambling and
the assembly then that's fine too because they will then have non-zero values.
The machine implementations should not zero registers but use large values that
are not valid pointers.

> 
> Intended to help prevent bugs such as those fixed by
> 0218463dd8265ed937622f88ac68c7d984fe0cfc
> 
> diff --git a/support/Makefile b/support/Makefile
> index 9b50eac117..91b940c379 100644
> --- a/support/Makefile
> +++ b/support/Makefile
> @@ -76,6 +76,7 @@ libsupport-routines = \
>    support_quote_string \
>    support_record_failure \
>    support_run_diff \
> +  support_scramble_registers \

OK. Looks correctly sorted (lint-makefiles will fail if it isn't).

>    support_select_modifies_timeout \
>    support_select_normalizes_timeout \
>    support_set_small_thread_stack_size \
> diff --git a/support/support.h b/support/support.h
> index d20051da4d..3d049575d0 100644
> --- a/support/support.h
> +++ b/support/support.h
> @@ -233,6 +233,11 @@ void support_stack_free (struct support_stack *stack);
>     The returned value is the lowest file descriptor number.  */
>  int support_open_dev_null_range (int num, int flags, mode_t mode);
>  
> +/* Write arbitrary values to all registers that can be written do, to
> +   avoid assumptions about initial register contents in test
> +   cases.  */
> +void support_scramble_registers (void);

OK.


> +
>  __END_DECLS
>  
>  #endif /* SUPPORT_H */
> diff --git a/support/support_scramble_registers.c b/support/support_scramble_registers.c
> new file mode 100644
> index 0000000000..d5e2d3fd6d
> --- /dev/null
> +++ b/support/support_scramble_registers.c
> @@ -0,0 +1,29 @@
> +/* scramble any call-not-preserved registers
> +   Copyright (C) 2022 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#include <support/support.h>
> +
> +#include "scramble-regs.h"
> +
> +void
> +support_scramble_registers(void)
> +{
> +#ifdef SCRAMBLE_REGS

Typo-prone interface.

Please either remove the macro e.g. provide a concrete inline function implementation.

Or make it typo-safe with a centralized default that is typo-safe.

See: https://sourceware.org/glibc/wiki/Wundef

> +  SCRAMBLE_REGS;
> +#endif
> +}



> diff --git a/support/support_test_main.c b/support/support_test_main.c
> index 60307fd68e..0ccb182791 100644
> --- a/support/support_test_main.c
> +++ b/support/support_test_main.c
> @@ -269,6 +269,8 @@ adjust_exit_status (int status)
>  int
>  support_test_main (int argc, char **argv, const struct test_config *config)
>  {
> +  support_scramble_registers();

OK.

> +
>    if (test_main_called)
>      {
>        printf ("error: test_main called for a second time\n");
> diff --git a/sysdeps/generic/scramble-regs.h b/sysdeps/generic/scramble-regs.h
> new file mode 100644
> index 0000000000..e3c158d475
> --- /dev/null
> +++ b/sysdeps/generic/scramble-regs.h
> @@ -0,0 +1,36 @@
> +/* scramble any call-not-preserved registers, target portion.
> +   Copyright (C) 2022 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <https://www.gnu.org/licenses/>.  */
> +
> +/* Example target-specific usage:
> +
> +   #define SCRAMBLE_REGS \
> +     asm volatile ("movl %0, %%eax" :: "i" (1235) : "%eax"); \
> +     asm volatile ("movl %0, %%edx" :: "i" (3579) : "%edx");
> +
> +   Targets are encouraged to create their own target-specific sub-definitions, like
> +   
> +   #ifndef SCRAMBLE_REGS_FPU
> +   #define SCRAMBLE_REGS_FPU
> +   #endif
> +   #define SCRAMBLE_REGS \
> +     SCRAMBLE_REGS_FPU \
> +     asm volatile ("..."); \
> +
> +*/
> +

Could be a header that provides the function.

> +/* #define SCRAMBLE_REGS */
> diff --git a/sysdeps/powerpc/scramble-regs.h b/sysdeps/powerpc/scramble-regs.h
> new file mode 100644
> index 0000000000..8480ac0da3
> --- /dev/null
> +++ b/sysdeps/powerpc/scramble-regs.h
> @@ -0,0 +1,30 @@
> +/* scramble any call-not-preserved registers, powerpc version
> +   Copyright (C) 2022 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#define SCRAMBLE_REGS		       \
> +  asm volatile ("li 0, %0" :: "i" (0x1235) : "0"); \
> +  asm volatile ("li 3, %0" :: "i" (0x1235) : "3"); \
> +  asm volatile ("li 4, %0" :: "i" (0x1235) : "4"); \
> +  asm volatile ("li 5, %0" :: "i" (0x1235) : "5"); \
> +  asm volatile ("li 6, %0" :: "i" (0x1235) : "6"); \
> +  asm volatile ("li 7, %0" :: "i" (0x1235) : "7"); \
> +  asm volatile ("li 8, %0" :: "i" (0x1235) : "8"); \
> +  asm volatile ("li 9, %0" :: "i" (0x1235) : "9"); \
> +  asm volatile ("li 10, %0" :: "i" (0x1235) : "10"); \
> +  asm volatile ("li 11, %0" :: "i" (0x1235) : "11"); \
> +  asm volatile ("li 12, %0" :: "i" (0x1235) : "12");

Likewise.

Prefer header name to be something clearly support related: support-scramble-regs.h.

> diff --git a/sysdeps/riscv/scramble-regs.h b/sysdeps/riscv/scramble-regs.h
> new file mode 100644
> index 0000000000..85bc1d501c
> --- /dev/null
> +++ b/sysdeps/riscv/scramble-regs.h
> @@ -0,0 +1,34 @@
> +/* scramble any call-not-preserved registers, powerpc version
> +   Copyright (C) 2022 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#define SCRAMBLE_REGS		       \
> +  asm volatile ("li t0, %0" :: "i" (0x13579bdf) : "t0"); \
> +  asm volatile ("li t1, %0" :: "i" (0x13579bdf) : "t1"); \
> +  asm volatile ("li t2, %0" :: "i" (0x13579bdf) : "t2"); \
> +  asm volatile ("li t3, %0" :: "i" (0x13579bdf) : "t3"); \
> +  asm volatile ("li t4, %0" :: "i" (0x13579bdf) : "t4"); \
> +  asm volatile ("li t5, %0" :: "i" (0x13579bdf) : "t5"); \
> +  asm volatile ("li t6, %0" :: "i" (0x13579bdf) : "t6"); \
> +  asm volatile ("li a0, %0" :: "i" (0x13579bdf) : "a0"); \
> +  asm volatile ("li a1, %0" :: "i" (0x13579bdf) : "a1"); \
> +  asm volatile ("li a2, %0" :: "i" (0x13579bdf) : "a2"); \
> +  asm volatile ("li a3, %0" :: "i" (0x13579bdf) : "a3"); \
> +  asm volatile ("li a4, %0" :: "i" (0x13579bdf) : "a4"); \
> +  asm volatile ("li a5, %0" :: "i" (0x13579bdf) : "a5"); \
> +  asm volatile ("li a6, %0" :: "i" (0x13579bdf) : "a6"); \
> +  asm volatile ("li a7, %0" :: "i" (0x13579bdf) : "a7");
> diff --git a/sysdeps/x86_64/scramble-regs.h b/sysdeps/x86_64/scramble-regs.h
> new file mode 100644
> index 0000000000..3993c3b843
> --- /dev/null
> +++ b/sysdeps/x86_64/scramble-regs.h
> @@ -0,0 +1,31 @@
> +/* scramble any call-not-preserved registers, x86_64 version
> +   Copyright (C) 2022 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <https://www.gnu.org/licenses/>.  */
> +
> +/* SysV ABI: preserve EBX, ESP, EBP and R12-R15.  */
> +
> +#define SCRAMBLE_REGS		       \
> +  asm volatile ("movl %0, %%eax" :: "i" (0x12345679) : "%eax");	\
> +  asm volatile ("movl %0, %%ecx" :: "i" (0x12345679) : "%ecx");	\
> +  asm volatile ("movl %0, %%edx" :: "i" (0x12345679) : "%edx");	\
> +  asm volatile ("movl %0, %%esi" :: "i" (0x12345679) : "%esi");	\
> +  asm volatile ("movl %0, %%edi" :: "i" (0x12345679) : "%edi");	\
> +  asm volatile ("mov %0, %%r8"  :: "i" (0x12345679) : "%r8");	\
> +  asm volatile ("mov %0, %%r9"  :: "i" (0x12345679) : "%r9");	\
> +  asm volatile ("mov %0, %%r10" :: "i" (0x12345679) : "%r10");	\
> +  asm volatile ("mov %0, %%r11" :: "i" (0x12345679) : "%r11");	\
> +
>
  
Adhemerval Zanella Nov. 22, 2023, 2:16 p.m. UTC | #2
On 22/11/23 10:34, Carlos O'Donell wrote:
> On 6/15/22 16:37, DJ Delorie via Libc-alpha wrote:
>> [added register clobbers, filled out ppc/x86 lists, added riscv]
> 
> I was reviewing your patch queue and this was the last item.
> 
> Changes requested.
>  
>> Allow for target-specific register "scrambling" - loading arbitrary
>> values into all registers that need not be call-saved.  These values
>> should be non-zero and invalid addresses, to help catch inadvertent
>> uses of otherwise uninitialized registers.
> 
> Suggest adding:
> 
> The goal with this change is to add a minimal amount of register scrambling that
> perturbs system state.  The goal is not to cover all call paths, or to correctly
> fuzz all assembly implementations (which we should have fewer of), or to insert
> per-PLT call register fuzzing.  This change is the smallest possible change that
> adds the largest amount of state change to simulate an application having modified
> the register states.  If the compiler uses the registers between scrambling and
> the assembly then that's fine too because they will then have non-zero values.
> The machine implementations should not zero registers but use large values that
> are not valid pointers.

Maybe also add some state perturbation for ISA extensions, like AVX, VSX, NEON,
etc?  The original issue 0218463dd8265ed937622f88ac68c7d984fe0cfc that motivate
this patch was originally for the powerpc vector extension.

> 
>>
>> Intended to help prevent bugs such as those fixed by
>> 0218463dd8265ed937622f88ac68c7d984fe0cfc
>>
>> diff --git a/support/Makefile b/support/Makefile
>> index 9b50eac117..91b940c379 100644
>> --- a/support/Makefile
>> +++ b/support/Makefile
>> @@ -76,6 +76,7 @@ libsupport-routines = \
>>    support_quote_string \
>>    support_record_failure \
>>    support_run_diff \
>> +  support_scramble_registers \
> 
> OK. Looks correctly sorted (lint-makefiles will fail if it isn't).
> 
>>    support_select_modifies_timeout \
>>    support_select_normalizes_timeout \
>>    support_set_small_thread_stack_size \
>> diff --git a/support/support.h b/support/support.h
>> index d20051da4d..3d049575d0 100644
>> --- a/support/support.h
>> +++ b/support/support.h
>> @@ -233,6 +233,11 @@ void support_stack_free (struct support_stack *stack);
>>     The returned value is the lowest file descriptor number.  */
>>  int support_open_dev_null_range (int num, int flags, mode_t mode);
>>  
>> +/* Write arbitrary values to all registers that can be written do, to
>> +   avoid assumptions about initial register contents in test
>> +   cases.  */
>> +void support_scramble_registers (void);
> 
> OK.
> 
> 
>> +
>>  __END_DECLS
>>  
>>  #endif /* SUPPORT_H */
>> diff --git a/support/support_scramble_registers.c b/support/support_scramble_registers.c
>> new file mode 100644
>> index 0000000000..d5e2d3fd6d
>> --- /dev/null
>> +++ b/support/support_scramble_registers.c
>> @@ -0,0 +1,29 @@
>> +/* scramble any call-not-preserved registers
>> +   Copyright (C) 2022 Free Software Foundation, Inc.
>> +   This file is part of the GNU C Library.
>> +
>> +   The GNU C Library is free software; you can redistribute it and/or
>> +   modify it under the terms of the GNU Lesser General Public
>> +   License as published by the Free Software Foundation; either
>> +   version 2.1 of the License, or (at your option) any later version.
>> +
>> +   The GNU C Library is distributed in the hope that it will be useful,
>> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
>> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>> +   Lesser General Public License for more details.
>> +
>> +   You should have received a copy of the GNU Lesser General Public
>> +   License along with the GNU C Library; if not, see
>> +   <https://www.gnu.org/licenses/>.  */
>> +
>> +#include <support/support.h>
>> +
>> +#include "scramble-regs.h"
>> +
>> +void
>> +support_scramble_registers(void)
>> +{
>> +#ifdef SCRAMBLE_REGS
> 
> Typo-prone interface.
> 
> Please either remove the macro e.g. provide a concrete inline function implementation.
> 
> Or make it typo-safe with a centralized default that is typo-safe.
> 
> See: https://sourceware.org/glibc/wiki/Wundef
> 
>> +  SCRAMBLE_REGS;
>> +#endif
>> +}
> 
> 
> 
>> diff --git a/support/support_test_main.c b/support/support_test_main.c
>> index 60307fd68e..0ccb182791 100644
>> --- a/support/support_test_main.c
>> +++ b/support/support_test_main.c
>> @@ -269,6 +269,8 @@ adjust_exit_status (int status)
>>  int
>>  support_test_main (int argc, char **argv, const struct test_config *config)
>>  {
>> +  support_scramble_registers();
> 
> OK.
> 
>> +
>>    if (test_main_called)
>>      {
>>        printf ("error: test_main called for a second time\n");
>> diff --git a/sysdeps/generic/scramble-regs.h b/sysdeps/generic/scramble-regs.h
>> new file mode 100644
>> index 0000000000..e3c158d475
>> --- /dev/null
>> +++ b/sysdeps/generic/scramble-regs.h
>> @@ -0,0 +1,36 @@
>> +/* scramble any call-not-preserved registers, target portion.
>> +   Copyright (C) 2022 Free Software Foundation, Inc.
>> +   This file is part of the GNU C Library.
>> +
>> +   The GNU C Library is free software; you can redistribute it and/or
>> +   modify it under the terms of the GNU Lesser General Public
>> +   License as published by the Free Software Foundation; either
>> +   version 2.1 of the License, or (at your option) any later version.
>> +
>> +   The GNU C Library is distributed in the hope that it will be useful,
>> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
>> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>> +   Lesser General Public License for more details.
>> +
>> +   You should have received a copy of the GNU Lesser General Public
>> +   License along with the GNU C Library; if not, see
>> +   <https://www.gnu.org/licenses/>.  */
>> +
>> +/* Example target-specific usage:
>> +
>> +   #define SCRAMBLE_REGS \
>> +     asm volatile ("movl %0, %%eax" :: "i" (1235) : "%eax"); \
>> +     asm volatile ("movl %0, %%edx" :: "i" (3579) : "%edx");
>> +
>> +   Targets are encouraged to create their own target-specific sub-definitions, like
>> +   
>> +   #ifndef SCRAMBLE_REGS_FPU
>> +   #define SCRAMBLE_REGS_FPU
>> +   #endif
>> +   #define SCRAMBLE_REGS \
>> +     SCRAMBLE_REGS_FPU \
>> +     asm volatile ("..."); \
>> +
>> +*/
>> +
> 
> Could be a header that provides the function.
> 
>> +/* #define SCRAMBLE_REGS */
>> diff --git a/sysdeps/powerpc/scramble-regs.h b/sysdeps/powerpc/scramble-regs.h
>> new file mode 100644
>> index 0000000000..8480ac0da3
>> --- /dev/null
>> +++ b/sysdeps/powerpc/scramble-regs.h
>> @@ -0,0 +1,30 @@
>> +/* scramble any call-not-preserved registers, powerpc version
>> +   Copyright (C) 2022 Free Software Foundation, Inc.
>> +   This file is part of the GNU C Library.
>> +
>> +   The GNU C Library is free software; you can redistribute it and/or
>> +   modify it under the terms of the GNU Lesser General Public
>> +   License as published by the Free Software Foundation; either
>> +   version 2.1 of the License, or (at your option) any later version.
>> +
>> +   The GNU C Library is distributed in the hope that it will be useful,
>> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
>> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>> +   Lesser General Public License for more details.
>> +
>> +   You should have received a copy of the GNU Lesser General Public
>> +   License along with the GNU C Library; if not, see
>> +   <https://www.gnu.org/licenses/>.  */
>> +
>> +#define SCRAMBLE_REGS		       \
>> +  asm volatile ("li 0, %0" :: "i" (0x1235) : "0"); \
>> +  asm volatile ("li 3, %0" :: "i" (0x1235) : "3"); \
>> +  asm volatile ("li 4, %0" :: "i" (0x1235) : "4"); \
>> +  asm volatile ("li 5, %0" :: "i" (0x1235) : "5"); \
>> +  asm volatile ("li 6, %0" :: "i" (0x1235) : "6"); \
>> +  asm volatile ("li 7, %0" :: "i" (0x1235) : "7"); \
>> +  asm volatile ("li 8, %0" :: "i" (0x1235) : "8"); \
>> +  asm volatile ("li 9, %0" :: "i" (0x1235) : "9"); \
>> +  asm volatile ("li 10, %0" :: "i" (0x1235) : "10"); \
>> +  asm volatile ("li 11, %0" :: "i" (0x1235) : "11"); \
>> +  asm volatile ("li 12, %0" :: "i" (0x1235) : "12");
> 
> Likewise.
> 
> Prefer header name to be something clearly support related: support-scramble-regs.h.
> 
>> diff --git a/sysdeps/riscv/scramble-regs.h b/sysdeps/riscv/scramble-regs.h
>> new file mode 100644
>> index 0000000000..85bc1d501c
>> --- /dev/null
>> +++ b/sysdeps/riscv/scramble-regs.h
>> @@ -0,0 +1,34 @@
>> +/* scramble any call-not-preserved registers, powerpc version
>> +   Copyright (C) 2022 Free Software Foundation, Inc.
>> +   This file is part of the GNU C Library.
>> +
>> +   The GNU C Library is free software; you can redistribute it and/or
>> +   modify it under the terms of the GNU Lesser General Public
>> +   License as published by the Free Software Foundation; either
>> +   version 2.1 of the License, or (at your option) any later version.
>> +
>> +   The GNU C Library is distributed in the hope that it will be useful,
>> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
>> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>> +   Lesser General Public License for more details.
>> +
>> +   You should have received a copy of the GNU Lesser General Public
>> +   License along with the GNU C Library; if not, see
>> +   <https://www.gnu.org/licenses/>.  */
>> +
>> +#define SCRAMBLE_REGS		       \
>> +  asm volatile ("li t0, %0" :: "i" (0x13579bdf) : "t0"); \
>> +  asm volatile ("li t1, %0" :: "i" (0x13579bdf) : "t1"); \
>> +  asm volatile ("li t2, %0" :: "i" (0x13579bdf) : "t2"); \
>> +  asm volatile ("li t3, %0" :: "i" (0x13579bdf) : "t3"); \
>> +  asm volatile ("li t4, %0" :: "i" (0x13579bdf) : "t4"); \
>> +  asm volatile ("li t5, %0" :: "i" (0x13579bdf) : "t5"); \
>> +  asm volatile ("li t6, %0" :: "i" (0x13579bdf) : "t6"); \
>> +  asm volatile ("li a0, %0" :: "i" (0x13579bdf) : "a0"); \
>> +  asm volatile ("li a1, %0" :: "i" (0x13579bdf) : "a1"); \
>> +  asm volatile ("li a2, %0" :: "i" (0x13579bdf) : "a2"); \
>> +  asm volatile ("li a3, %0" :: "i" (0x13579bdf) : "a3"); \
>> +  asm volatile ("li a4, %0" :: "i" (0x13579bdf) : "a4"); \
>> +  asm volatile ("li a5, %0" :: "i" (0x13579bdf) : "a5"); \
>> +  asm volatile ("li a6, %0" :: "i" (0x13579bdf) : "a6"); \
>> +  asm volatile ("li a7, %0" :: "i" (0x13579bdf) : "a7");
>> diff --git a/sysdeps/x86_64/scramble-regs.h b/sysdeps/x86_64/scramble-regs.h
>> new file mode 100644
>> index 0000000000..3993c3b843
>> --- /dev/null
>> +++ b/sysdeps/x86_64/scramble-regs.h
>> @@ -0,0 +1,31 @@
>> +/* scramble any call-not-preserved registers, x86_64 version
>> +   Copyright (C) 2022 Free Software Foundation, Inc.
>> +   This file is part of the GNU C Library.
>> +
>> +   The GNU C Library is free software; you can redistribute it and/or
>> +   modify it under the terms of the GNU Lesser General Public
>> +   License as published by the Free Software Foundation; either
>> +   version 2.1 of the License, or (at your option) any later version.
>> +
>> +   The GNU C Library is distributed in the hope that it will be useful,
>> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
>> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>> +   Lesser General Public License for more details.
>> +
>> +   You should have received a copy of the GNU Lesser General Public
>> +   License along with the GNU C Library; if not, see
>> +   <https://www.gnu.org/licenses/>.  */
>> +
>> +/* SysV ABI: preserve EBX, ESP, EBP and R12-R15.  */
>> +
>> +#define SCRAMBLE_REGS		       \
>> +  asm volatile ("movl %0, %%eax" :: "i" (0x12345679) : "%eax");	\
>> +  asm volatile ("movl %0, %%ecx" :: "i" (0x12345679) : "%ecx");	\
>> +  asm volatile ("movl %0, %%edx" :: "i" (0x12345679) : "%edx");	\
>> +  asm volatile ("movl %0, %%esi" :: "i" (0x12345679) : "%esi");	\
>> +  asm volatile ("movl %0, %%edi" :: "i" (0x12345679) : "%edi");	\
>> +  asm volatile ("mov %0, %%r8"  :: "i" (0x12345679) : "%r8");	\
>> +  asm volatile ("mov %0, %%r9"  :: "i" (0x12345679) : "%r9");	\
>> +  asm volatile ("mov %0, %%r10" :: "i" (0x12345679) : "%r10");	\
>> +  asm volatile ("mov %0, %%r11" :: "i" (0x12345679) : "%r11");	\
>> +
>>
>
  
DJ Delorie Nov. 22, 2023, 9:04 p.m. UTC | #3
Adhemerval Zanella Netto <adhemerval.zanella@linaro.org> writes:
> Maybe also add some state perturbation for ISA extensions, like AVX, VSX, NEON,
> etc?  The original issue 0218463dd8265ed937622f88ac68c7d984fe0cfc that motivate
> this patch was originally for the powerpc vector extension.

In my original posting long ago, I proposed that the ISA maintainers
provide ISA-specific macros to scramble the appopriate registers if
present.  I don't have the knowledge to implement that accurately for
all (or any) ISAs.  My patch is for the framework.
  

Patch

diff --git a/support/Makefile b/support/Makefile
index 9b50eac117..91b940c379 100644
--- a/support/Makefile
+++ b/support/Makefile
@@ -76,6 +76,7 @@  libsupport-routines = \
   support_quote_string \
   support_record_failure \
   support_run_diff \
+  support_scramble_registers \
   support_select_modifies_timeout \
   support_select_normalizes_timeout \
   support_set_small_thread_stack_size \
diff --git a/support/support.h b/support/support.h
index d20051da4d..3d049575d0 100644
--- a/support/support.h
+++ b/support/support.h
@@ -233,6 +233,11 @@  void support_stack_free (struct support_stack *stack);
    The returned value is the lowest file descriptor number.  */
 int support_open_dev_null_range (int num, int flags, mode_t mode);
 
+/* Write arbitrary values to all registers that can be written do, to
+   avoid assumptions about initial register contents in test
+   cases.  */
+void support_scramble_registers (void);
+
 __END_DECLS
 
 #endif /* SUPPORT_H */
diff --git a/support/support_scramble_registers.c b/support/support_scramble_registers.c
new file mode 100644
index 0000000000..d5e2d3fd6d
--- /dev/null
+++ b/support/support_scramble_registers.c
@@ -0,0 +1,29 @@ 
+/* scramble any call-not-preserved registers
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <support/support.h>
+
+#include "scramble-regs.h"
+
+void
+support_scramble_registers(void)
+{
+#ifdef SCRAMBLE_REGS
+  SCRAMBLE_REGS;
+#endif
+}
diff --git a/support/support_test_main.c b/support/support_test_main.c
index 60307fd68e..0ccb182791 100644
--- a/support/support_test_main.c
+++ b/support/support_test_main.c
@@ -269,6 +269,8 @@  adjust_exit_status (int status)
 int
 support_test_main (int argc, char **argv, const struct test_config *config)
 {
+  support_scramble_registers();
+
   if (test_main_called)
     {
       printf ("error: test_main called for a second time\n");
diff --git a/sysdeps/generic/scramble-regs.h b/sysdeps/generic/scramble-regs.h
new file mode 100644
index 0000000000..e3c158d475
--- /dev/null
+++ b/sysdeps/generic/scramble-regs.h
@@ -0,0 +1,36 @@ 
+/* scramble any call-not-preserved registers, target portion.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+/* Example target-specific usage:
+
+   #define SCRAMBLE_REGS \
+     asm volatile ("movl %0, %%eax" :: "i" (1235) : "%eax"); \
+     asm volatile ("movl %0, %%edx" :: "i" (3579) : "%edx");
+
+   Targets are encouraged to create their own target-specific sub-definitions, like
+   
+   #ifndef SCRAMBLE_REGS_FPU
+   #define SCRAMBLE_REGS_FPU
+   #endif
+   #define SCRAMBLE_REGS \
+     SCRAMBLE_REGS_FPU \
+     asm volatile ("..."); \
+
+*/
+
+/* #define SCRAMBLE_REGS */
diff --git a/sysdeps/powerpc/scramble-regs.h b/sysdeps/powerpc/scramble-regs.h
new file mode 100644
index 0000000000..8480ac0da3
--- /dev/null
+++ b/sysdeps/powerpc/scramble-regs.h
@@ -0,0 +1,30 @@ 
+/* scramble any call-not-preserved registers, powerpc version
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#define SCRAMBLE_REGS		       \
+  asm volatile ("li 0, %0" :: "i" (0x1235) : "0"); \
+  asm volatile ("li 3, %0" :: "i" (0x1235) : "3"); \
+  asm volatile ("li 4, %0" :: "i" (0x1235) : "4"); \
+  asm volatile ("li 5, %0" :: "i" (0x1235) : "5"); \
+  asm volatile ("li 6, %0" :: "i" (0x1235) : "6"); \
+  asm volatile ("li 7, %0" :: "i" (0x1235) : "7"); \
+  asm volatile ("li 8, %0" :: "i" (0x1235) : "8"); \
+  asm volatile ("li 9, %0" :: "i" (0x1235) : "9"); \
+  asm volatile ("li 10, %0" :: "i" (0x1235) : "10"); \
+  asm volatile ("li 11, %0" :: "i" (0x1235) : "11"); \
+  asm volatile ("li 12, %0" :: "i" (0x1235) : "12");
diff --git a/sysdeps/riscv/scramble-regs.h b/sysdeps/riscv/scramble-regs.h
new file mode 100644
index 0000000000..85bc1d501c
--- /dev/null
+++ b/sysdeps/riscv/scramble-regs.h
@@ -0,0 +1,34 @@ 
+/* scramble any call-not-preserved registers, powerpc version
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#define SCRAMBLE_REGS		       \
+  asm volatile ("li t0, %0" :: "i" (0x13579bdf) : "t0"); \
+  asm volatile ("li t1, %0" :: "i" (0x13579bdf) : "t1"); \
+  asm volatile ("li t2, %0" :: "i" (0x13579bdf) : "t2"); \
+  asm volatile ("li t3, %0" :: "i" (0x13579bdf) : "t3"); \
+  asm volatile ("li t4, %0" :: "i" (0x13579bdf) : "t4"); \
+  asm volatile ("li t5, %0" :: "i" (0x13579bdf) : "t5"); \
+  asm volatile ("li t6, %0" :: "i" (0x13579bdf) : "t6"); \
+  asm volatile ("li a0, %0" :: "i" (0x13579bdf) : "a0"); \
+  asm volatile ("li a1, %0" :: "i" (0x13579bdf) : "a1"); \
+  asm volatile ("li a2, %0" :: "i" (0x13579bdf) : "a2"); \
+  asm volatile ("li a3, %0" :: "i" (0x13579bdf) : "a3"); \
+  asm volatile ("li a4, %0" :: "i" (0x13579bdf) : "a4"); \
+  asm volatile ("li a5, %0" :: "i" (0x13579bdf) : "a5"); \
+  asm volatile ("li a6, %0" :: "i" (0x13579bdf) : "a6"); \
+  asm volatile ("li a7, %0" :: "i" (0x13579bdf) : "a7");
diff --git a/sysdeps/x86_64/scramble-regs.h b/sysdeps/x86_64/scramble-regs.h
new file mode 100644
index 0000000000..3993c3b843
--- /dev/null
+++ b/sysdeps/x86_64/scramble-regs.h
@@ -0,0 +1,31 @@ 
+/* scramble any call-not-preserved registers, x86_64 version
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+/* SysV ABI: preserve EBX, ESP, EBP and R12-R15.  */
+
+#define SCRAMBLE_REGS		       \
+  asm volatile ("movl %0, %%eax" :: "i" (0x12345679) : "%eax");	\
+  asm volatile ("movl %0, %%ecx" :: "i" (0x12345679) : "%ecx");	\
+  asm volatile ("movl %0, %%edx" :: "i" (0x12345679) : "%edx");	\
+  asm volatile ("movl %0, %%esi" :: "i" (0x12345679) : "%esi");	\
+  asm volatile ("movl %0, %%edi" :: "i" (0x12345679) : "%edi");	\
+  asm volatile ("mov %0, %%r8"  :: "i" (0x12345679) : "%r8");	\
+  asm volatile ("mov %0, %%r9"  :: "i" (0x12345679) : "%r9");	\
+  asm volatile ("mov %0, %%r10" :: "i" (0x12345679) : "%r10");	\
+  asm volatile ("mov %0, %%r11" :: "i" (0x12345679) : "%r11");	\
+