https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119016
Tamar Christina <tnfchris at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Priority|P3 |P1
Last reconfirmed| |2025-02-26
Status|UNCONFIRMED |NEW
Ever confirmed|0 |1
--- Comment #5 from Tamar Christina <tnfchris at gcc dot gnu.org> ---
Confirmed.
Slightly easier to digest case:
---
#include <stddef.h>
#include <stdint.h>
__attribute__((noipa)) char *svn_eol__find_eol_start(char *buf, size_t len) {
for (; len > sizeof(uintptr_t);
buf += sizeof(uintptr_t), len -= sizeof(uintptr_t)) {
uintptr_t chunk = *(const uintptr_t *)buf;
uintptr_t r_test = chunk ^ 0x0a0a0a0a0a0a0a0a;
uintptr_t n_test = chunk ^ 0x0d0d0d0d0d0d0d0d;
r_test |= (r_test & 0x7f7f7f7f7f7f7f7f) + 0x7f7f7f7f7f7f7f7f;
n_test |= (n_test & 0x7f7f7f7f7f7f7f7f) + 0x7f7f7f7f7f7f7f7f;
if ((r_test & n_test & 0x8080808080808080) != 0x8080808080808080)
break;
}
#pragma GCC novector
for (; len > 0; ++buf, --len) {
if (*buf == '\n' || *buf == '\r')
return buf;
}
return ((void *)0);
}
int main() {
char p[] = {
0x2f, 0x2a, 0xa, 0x20, 0x20, 0x20, 0x62, 0x75, 0x67, 0x33, 0x33, 0x37,
0x39, 0x37, 0x32, 0x33, 0x2e, 0x63, 0xa, 0x2a, 0x2f, 0xa, 0xa, 0x23,
0x69, 0x6e, 0x63,
};
size_t len;
char *end = p + (sizeof(p) / sizeof(p[0]));
int i = 0;
do {
char *start = p + len;
const char *eol = svn_eol__find_eol_start(start, end - start);
len += (eol ? eol : end) - start;
i++;
} while (((end - p) > len + 2) && i < 100);
}#include <stddef.h>
#include <stdint.h>
__attribute__((noipa)) char *svn_eol__find_eol_start(char *buf, size_t len) {
for (; len > sizeof(uintptr_t);
buf += sizeof(uintptr_t), len -= sizeof(uintptr_t)) {
uintptr_t chunk = *(const uintptr_t *)buf;
uintptr_t r_test = chunk ^ 0x0a0a0a0a0a0a0a0a;
uintptr_t n_test = chunk ^ 0x0d0d0d0d0d0d0d0d;
r_test |= (r_test & 0x7f7f7f7f7f7f7f7f) + 0x7f7f7f7f7f7f7f7f;
n_test |= (n_test & 0x7f7f7f7f7f7f7f7f) + 0x7f7f7f7f7f7f7f7f;
if ((r_test & n_test & 0x8080808080808080) != 0x8080808080808080)
break;
}
#pragma GCC novector
for (; len > 0; ++buf, --len) {
if (*buf == '\n' || *buf == '\r')
return buf;
}
return ((void *)0);
}
int main() {
char p[] = {
0x2f, 0x2a, 0xa, 0x20, 0x20, 0x20, 0x62, 0x75, 0x67, 0x33, 0x33, 0x37,
0x39, 0x37, 0x32, 0x33, 0x2e, 0x63, 0xa, 0x2a, 0x2f, 0xa, 0xa, 0x23,
0x69, 0x6e, 0x63,
};
size_t len;
char *end = p + (sizeof(p) / sizeof(p[0]));
int i = 0;
do {
char *start = p + len;
const char *eol = svn_eol__find_eol_start(start, end - start);
len += (eol ? eol : end) - start;
i++;
} while (((end - p) > len + 2) && i < 100);
}
---
The code is peeled but the address ends up being not aligned:
Program received signal SIGSEGV, Segmentation fault.
0x000000000040135f in svn_eol__find_eol_start (buf=<optimized out>,
buf@entry=0x7fffffffe2f2 "\n bug3379723.c\n*/\n\n#inc\027", len=<optimized
out>, len@entry=25) at oel.c:8
8 uintptr_t chunk = *(const uintptr_t *)buf;
(gdb) display/i $pc
1: x/i $pc
=> 0x40135f <svn_eol__find_eol_start+351>: movdqa (%rdi,%rsi,1),%xmm10
(gdb) p/x $rdi+$rsi
$1 = 0x7fffffffe2f2
which is not 16-bytes aligned, hence the alignment fault.