I used to think that x86-64 supports unaligned memory access and invalid memory access always causes segmentation fault (except, perhaps, SIMD instructions like movdqa
or movaps
). Nevertheless recently I observed bus error with normal mov
instruction. Here is a reproducer:
void test(void *a)
{
asm("mov %0, %%rbp\n\t"
"mov 0(%%rbp), %%rdx\n\t"
: : "r"(a) : "rbp", "rdx");
}
int main()
{
test((void *)0x706a2e3630332d69);
return 0;
}
(must be compiled with frame pointer omission, e.g. gcc -O test.c && ./a.out
).
mov 0(%rbp), %rdx
instruction and the address 0x706a2e3630332d69
were copied from a coredump of the buggy program. Changing it to 0 causes segfault, but just aligning to 0x706a2e3630332d60
is still bus error (my guess is that it is related to the fact that address space is 48-bit on x86-64).
The question is: which addresses cause bus error (SIGBUS)? Is it determined by architecture or configured by OS kernel (i.e. in page table, control registers or something similar)?