[PATCH] IPA ICF + ASAN: do not merge vars with different alignment

Martin Liška mliska@suse.cz
Tue Feb 23 14:22:27 GMT 2021


On 2/23/21 12:56 PM, Richard Biener wrote:
> Can't we fix the asan runtime?  Does the same issue happen when merging
> two comdat with different alignment and LTO?

All right, there's a detail explanation what happens.
Let's consider the following example:

struct my_struct
{
   unsigned long volatile x;
} __attribute__((aligned(128)));

static int array[5][6] = {};
static struct my_struct variable128 = {1UL};
static struct my_struct variable32 __attribute__((aligned(64))) = {1UL};

Here we have 2 variables (variable128 and variable32) that are merged. Later on,
we decide not to protect the global variable variable128 due to:
       || DECL_ALIGN_UNIT (decl) > 2 * ASAN_RED_ZONE_SIZE

Without ICF we end up with:

	.align 64
	.type	variable32, @object
	.size	variable32, 128
variable32:
	.zero	128
	.zero	32
	.align 128
	.type	variable128, @object
	.size	variable128, 128
variable128:
	.zero	128

As seen, variable32 has .zero 128+32, where 32 is the red-zone (and alignment is increased to 64).

With ICF we end up with:

	.align 128
	.type	variable128, @object
	.size	variable128, 128
variable128:
	.zero	128
	.set	variable32,variable128

So variable32 points to variable128 (which has no prepared red zone + alignment is the same).
$ nm -n a.out
...
0000000000400b80 r variable128
0000000000400b80 r variable32
0000000000400c00 r array

0000000000400c00 - 0000000000400b80 == sizeof(variable32).

Then we tell libasan what is the variable size and size of the corresponding red zone:
$ ASAN_OPTIONS=report_globals=3 ./a.out
...
==20602==Added Global[0x000000403080]: beg=0x000000400b80 size=128/160 name=variable32 module=asan.c dyn_init=0 odr_indicator=0x000000000000

And bad thinks happen. So I really think ICF should not merge the variables.
Please provide a comdat test-case :)

Thanks,
Martin




More information about the Gcc-patches mailing list