Bug#1116681: pixman: FTBFS on sparc64 due to unaligned access
Source: pixman
Version: 0.46.4-1
Severity: important
Tags: patch upstream
User: debian-sparc@lists.debian.org
Usertags: sparc64
X-Debbugs-Cc: debian-sparc@lists.debian.org
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 <matthieu@herrb.eu>
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 <matthieu@herrb.eu>
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
Reply to: