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;
}
}