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