File bigendian.patch of Package compsize

From d79eacf77abe3b799387bb8a4e07a18f1f1031e8 Mon Sep 17 00:00:00 2001
From: Goffredo Baroncelli <kreijack@inwind.it>
Date: Sat, 23 Dec 2023 22:11:35 +0100
Subject: [PATCH] bug: invalid conversion be->le

The members of the struct btrfs_ioctl_search_header are already in the
native endianess and these don't need a conversion little endian ->
native format. So drop the get_u32()/get_u64() call for these.

This is not a problem in the x86 world, which is little endian. But
in the (e.g.) ppc world, the native format is big endian so using a
get_u32()/get_u64() functions cause an incorrect conversion le -> be
when the values are already in the native format.

At the same time replace the get_u32()/get_u64() function with the
get_unaligned_[le]32/64() functions.

Signed-off-by: Goffredo Baroncelli <kreijack@libero.it>
---
 compsize.c | 33 +++++++++++----------------------
 1 file changed, 11 insertions(+), 22 deletions(-)

diff --git a/compsize.c b/compsize.c
index fff3828..42ec304 100644
--- a/compsize.c
+++ b/compsize.c
@@ -77,20 +77,6 @@ static void sigusr1(int dummy)
     sig_stats = 1;
 }
 
-static uint64_t get_u64(const void *mem)
-{
-    typedef struct __attribute__((__packed__)) { uint64_t v; } u64_unal;
-    uint64_t bad_endian = ((u64_unal*)mem)->v;
-    return htole64(bad_endian);
-}
-
-static uint32_t get_u32(const void *mem)
-{
-    typedef struct __attribute__((__packed__)) { uint32_t v; } u32_unal;
-    uint32_t bad_endian = ((u32_unal*)mem)->v;
-    return htole32(bad_endian);
-}
-
 static void init_sv2_args(ino_t st_ino, struct btrfs_sv2_args *sv2_args)
 {
         sv2_args->key.tree_id = 0;
@@ -124,7 +110,7 @@ static void parse_file_extent_item(uint8_t *bp, uint32_t hlen,
 
     ei = (struct btrfs_file_extent_item *) bp;
 
-    ram_bytes = get_u64(&ei->ram_bytes);
+    ram_bytes = get_unaligned_le64(&ei->ram_bytes);
     comp_type = ei->compression;
 
     if (ei->type == BTRFS_FILE_EXTENT_INLINE)
@@ -153,9 +139,9 @@ static void parse_file_extent_item(uint8_t *bp, uint32_t hlen,
     if (hlen != sizeof(*ei))
         die("%s: Regular extent's header not 53 bytes (%u) long?!?\n", filename, hlen);
 
-    disk_num_bytes = get_u64(&ei->disk_num_bytes);
-    disk_bytenr = get_u64(&ei->disk_bytenr);
-    num_bytes = get_u64(&ei->num_bytes);
+    disk_num_bytes = get_unaligned_le64(&ei->disk_num_bytes);
+    disk_bytenr = get_unaligned_le64(&ei->disk_bytenr);
+    num_bytes = get_unaligned_le64(&ei->num_bytes);
 
     if (is_hole(disk_bytenr))
         return;
@@ -212,10 +198,13 @@ static void do_file(int fd, ino_t st_ino, struct workspace *ws, const char *file
     for (; nr_items > 0; nr_items--, bp += hlen)
     {
         head = (struct btrfs_ioctl_search_header*)bp;
-        hlen = get_u32(&head->len);
+        hlen = get_unaligned_32(&head->len);
         DPRINTF("{ transid=%lu objectid=%lu offset=%lu type=%u len=%u }\n",
-                get_u64(&head->transid), get_u64(&head->objectid), get_u64(&head->offset),
-                get_u32(&head->type), hlen);
+		get_unaligned_64(&head->transid),
+		get_unaligned_64(&head->objectid),
+		get_unaligned_64(&head->offset),
+		get_unaligned_32(&head->type),
+		hlen);
         bp += sizeof(*head);
 
         parse_file_extent_item(bp, hlen, ws, filename);
@@ -228,7 +217,7 @@ static void do_file(int fd, ino_t st_ino, struct workspace *ws, const char *file
     if (sv2_args.key.nr_items > 512)
     {
         sv2_args.key.nr_items = -1;
-        sv2_args.key.min_offset = get_u64(&head->offset) + 1;
+        sv2_args.key.min_offset = get_unaligned_64(&head->offset) + 1;
         goto again;
     }
 }
openSUSE Build Service is sponsored by