Source: pixman Version: 0.46.4-1 Severity: important Tags: patch upstream User: [email protected] Usertags: sparc64 X-Debbugs-Cc: [email protected]
Hello, while running the pixman testsuite, the stress-test binary crashes on sparc64 due to unaligned access [1]: =================================== 27/35 ==================================== test: stress-test start time: 09:41:35 duration: 0.80s result: killed by signal 10 SIGBUS command: UBSAN_OPTIONS=halt_on_error=1:abort_on_error=1:print_summary=1:print_stacktrace=1 LD_LIBRARY_PATH=/build/reproducible-path/pixman-0.46.4/build/pixman MALLOC_PERTURB_=253 MSAN_OPTIONS=halt_on_error=1:abort_on_error=1:print_summary=1:print_stacktrace=1 MESON_TEST_ITERATION=1 ASAN_OPTIONS=halt_on_error=1:abort_on_error=1:print_summary=1 /build/reproducible-path/pixman-0.46.4/build/test/stress-test ============================================================================== There is an open pull request upstream which addresses this issue [2]. Please consider including this patch in the next upload. Thanks, Adrian > [1] > https://buildd.debian.org/status/fetch.php?pkg=pixman&arch=sparc64&ver=0.46.4-1&stamp=1759138947&raw=0 > [2] https://gitlab.freedesktop.org/pixman/pixman/-/merge_requests/159 -- .''`. John Paul Adrian Glaubitz : :' : Debian Developer `. `' Physicist `- GPG: 62FF 8A75 84E0 2956 9546 0006 7426 3B37 F5B5 F913
>From 26611b3ecd1de7d06d90fa7512b6efaeaee7112d Mon Sep 17 00:00:00 2001 From: Matthieu Herrb <[email protected]> Date: Fri, 1 Aug 2025 18:38:49 +0200 Subject: [PATCH 1/2] fix un-aligned uint64_t accesses on sparc64 triggered by stress-test They happen with the a16b16g16r16 format that uses uint64_t pixels. Not sure if it's the proper fix, nor why the test is triggering those. Also one cannot use image accessors there, since they are limited to 32 bits. --- pixman/pixman-access.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/pixman/pixman-access.c b/pixman/pixman-access.c index 822bef6a..f8603112 100644 --- a/pixman/pixman-access.c +++ b/pixman/pixman-access.c @@ -725,7 +725,13 @@ fetch_scanline_a16b16g16r16_float (bits_image_t * image, while (pixel < end) { +#ifdef __sparc64__ + uint64_t p; + if (((long long)pixel & 0x7LL) != 0) printf("xxxx\n"); + memcpy(&p, pixel++, sizeof(p)); +#else uint64_t p = READ (image, pixel++); +#endif uint64_t a = (p >> 48) & 0xffff; uint64_t b = (p >> 32) & 0xffff; uint64_t g = (p >> 16) & 0xffff; @@ -943,7 +949,12 @@ fetch_pixel_a16b16g16r16_float (bits_image_t *image, int line) { uint64_t *bits = (uint64_t *)(image->bits + line * image->rowstride); +#ifdef __sparc64__ + uint64_t p; + memcpy(&p, bits+offset, sizeof(p)); +#else uint64_t p = READ (image, bits + offset); +#endif uint64_t a = (p >> 48) & 0xffff; uint64_t b = (p >> 32) & 0xffff; uint64_t g = (p >> 16) & 0xffff; @@ -1193,8 +1204,13 @@ store_scanline_a16b16g16r16_float (bits_image_t * image, g = pixman_float_to_unorm (values[i].g, 16); b = pixman_float_to_unorm (values[i].b, 16); +#ifdef __sparc64__ + uint64_t p = (a << 48) | (b << 32) | (g << 16) | (r << 0) ; + memcpy(pixel++, &p, sizeof(uint64_t)); +#else WRITE (image, pixel++, (a << 48) | (b << 32) | (g << 16) | (r << 0)); +#endif } } -- GitLab >From 5bdde5517b73a419842809e1e776bd80227febf7 Mon Sep 17 00:00:00 2001 From: Matthieu Herrb <[email protected]> Date: Sun, 3 Aug 2025 10:23:31 +0200 Subject: [PATCH 2/2] Remove the __sparc64__ conditional build. On architectures with non strict alignment, the compiler will optimize the memcpy() calls away. While here also remove the debuging printf(). --- pixman/pixman-access.c | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/pixman/pixman-access.c b/pixman/pixman-access.c index f8603112..dcdf1b2b 100644 --- a/pixman/pixman-access.c +++ b/pixman/pixman-access.c @@ -725,13 +725,9 @@ fetch_scanline_a16b16g16r16_float (bits_image_t * image, while (pixel < end) { -#ifdef __sparc64__ uint64_t p; - if (((long long)pixel & 0x7LL) != 0) printf("xxxx\n"); + memcpy(&p, pixel++, sizeof(p)); -#else - uint64_t p = READ (image, pixel++); -#endif uint64_t a = (p >> 48) & 0xffff; uint64_t b = (p >> 32) & 0xffff; uint64_t g = (p >> 16) & 0xffff; @@ -949,12 +945,8 @@ fetch_pixel_a16b16g16r16_float (bits_image_t *image, int line) { uint64_t *bits = (uint64_t *)(image->bits + line * image->rowstride); -#ifdef __sparc64__ uint64_t p; memcpy(&p, bits+offset, sizeof(p)); -#else - uint64_t p = READ (image, bits + offset); -#endif uint64_t a = (p >> 48) & 0xffff; uint64_t b = (p >> 32) & 0xffff; uint64_t g = (p >> 16) & 0xffff; @@ -1204,13 +1196,8 @@ store_scanline_a16b16g16r16_float (bits_image_t * image, g = pixman_float_to_unorm (values[i].g, 16); b = pixman_float_to_unorm (values[i].b, 16); -#ifdef __sparc64__ uint64_t p = (a << 48) | (b << 32) | (g << 16) | (r << 0) ; memcpy(pixel++, &p, sizeof(uint64_t)); -#else - WRITE (image, pixel++, - (a << 48) | (b << 32) | (g << 16) | (r << 0)); -#endif } } -- GitLab

