Skip to content

[clang / ASan] ASan doesn't respect preserve_none calling convention on ARMv8 #177519

@csjh

Description

@csjh

Reproduced on MacOS with llvm clang++ 21.1.8 installed w/ homebrew, but reproduces on compiler explorer on every clang version I try (line 86 in the provided link for the offending x19 read):

https://godbolt.org/z/qrh1EEab9

#include <vector>

__attribute__((preserve_none)) void preserved() {
    asm volatile("mov x19, #0" ::: "x19");
}

int main() {
    std::vector<char> vec;

    preserved();
}

Compiled with clang++ repro.cpp -g3 -fsanitize=address -o crasher

AddressSanitizer:DEADLYSIGNAL
=================================================================
==52059==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000010 (pc 0x0001007e07b4 bp 0x00016f61e370 sp 0x00016f61e200 T0)
==52059==The signal is caused by a READ memory access.
==52059==Hint: address points to the zero page.
    #0 0x0001007e07b4 in main repro.cpp:10
    #1 0x000194061d50  (<unknown module>)

==52059==Register values:
 x[0] = 0x000000016f61e220   x[1] = 0x000000016f61e9f8   x[2] = 0x000000016f61ea08   x[3] = 0x000000016f61ec10  
 x[4] = 0x0000000000000001   x[5] = 0x0000000000000010   x[6] = 0x0000000000000041   x[7] = 0x0000000000000000  
 x[8] = 0x000000016f61e220   x[9] = 0x000000016f61e230  x[10] = 0x000000702dee3c48  x[11] = 0x000000016f61e210  
x[12] = 0x000000016f61e208  x[13] = 0x000000016f61e200  x[14] = 0x0000000000000002  x[15] = 0x0000000000000000  
x[16] = 0x0000000194430884  x[17] = 0x000000020290ac20  x[18] = 0x0000000000000000  x[19] = 0x0000000000000000  
x[20] = 0x0000000201348e08  x[21] = 0x000000020109cdc0  x[22] = 0xfffffffffffffff0  x[23] = 0x000000020134c520  
x[24] = 0x0000000000000001  x[25] = 0x000000016f61e570  x[26] = 0x000000020134c530  x[27] = 0x0000000000000000  
x[28] = 0x0000000000000000     fp = 0x000000016f61e370     lr = 0x00000001007e07b4     sp = 0x000000016f61e200  
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV repro.cpp:10 in main
==52059==ABORTING
zsh: abort      ./crasher

Seems to only reproduce with ASan enabled. Very fickle, this example is -O0, but it happens on -Og for my main project, so I'm not fully convinced it wouldn't happen on other optimization levels under certain scenarios. The inline assembly isn't necessary, just tedious to write some contrived code that writes to x19.

Alternate version w/o vector complexity:

__attribute__((preserve_none, noinline)) void preserved() {
    asm volatile("mov x19, #0" ::: "x19");
}

struct A {
    ~A() {}
};

int main() {
    A a;

    preserved();
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions