diff mbox series

SquashFS not compiling due to missing __udivdi3 and __umoddi3

Message ID 23111307-751a-27cc-1551-0594eb65c0d5@mclink.it
State Superseded
Delegated to: Tom Rini
Headers show
Series SquashFS not compiling due to missing __udivdi3 and __umoddi3 | expand

Commit Message

Mauro Condarelli Sept. 3, 2020, 8:41 a.m. UTC
Hi,
enabling squashfs on my target (vocore2) result in multiple errors:

> /home/mcon/vocore/__V2__/Buildroot-2/recov/per-package/uboot/host/bin/mipsel-linux-ld.bfd: fs/built-in.o: in function `sqfs_calc_n_blks':
> fs/squashfs/sqfs.c:(.text.sqfs_calc_n_blks+0x44): undefined reference to `__umoddi3'
> /home/mcon/vocore/__V2__/Buildroot-2/recov/per-package/uboot/host/bin/mipsel-linux-ld.bfd: fs/squashfs/sqfs.c:(.text.sqfs_calc_n_blks+0x98): undefined reference to `__udivdi3'
> /home/mcon/vocore/__V2__/Buildroot-2/recov/per-package/uboot/host/bin/mipsel-linux-ld.bfd: fs/built-in.o: in function `sqfs_frag_lookup':
> fs/squashfs/sqfs.c:(.text.sqfs_frag_lookup+0x74): undefined reference to `__udivdi3'
> /home/mcon/vocore/__V2__/Buildroot-2/recov/per-package/uboot/host/bin/mipsel-linux-ld.bfd: fs/squashfs/sqfs.c:(.text.sqfs_frag_lookup+0x1b0): undefined reference to `__udivdi3'
> /home/mcon/vocore/__V2__/Buildroot-2/recov/per-package/uboot/host/bin/mipsel-linux-ld.bfd: fs/built-in.o: in function `sqfs_opendir':
> (.text.sqfs_opendir+0xbc): undefined reference to `__udivdi3'
> /home/mcon/vocore/__V2__/Buildroot-2/recov/per-package/uboot/host/bin/mipsel-linux-ld.bfd: (.text.sqfs_opendir+0x178): undefined reference to `__udivdi3'
> /home/mcon/vocore/__V2__/Buildroot-2/recov/per-package/uboot/host/bin/mipsel-linux-ld.bfd: fs/built-in.o:(.text.sqfs_read+0x324): more undefined references to `__udivdi3' follow
> /home/mcon/vocore/__V2__/Buildroot-2/recov/per-package/uboot/host/bin/mipsel-linux-ld.bfd: fs/built-in.o: in function `sqfs_read':
> (.text.sqfs_read+0x348): undefined reference to `__umoddi3'
> /home/mcon/vocore/__V2__/Buildroot-2/recov/per-package/uboot/host/bin/mipsel-linux-ld.bfd: (.text.sqfs_read+0x388): undefined reference to `__udivdi3'
> /home/mcon/vocore/__V2__/Buildroot-2/recov/per-package/uboot/host/bin/mipsel-linux-ld.bfd: (.text.sqfs_read+0x5bc): undefined reference to `__umoddi3'
> /home/mcon/vocore/__V2__/Buildroot-2/recov/per-package/uboot/host/bin/mipsel-linux-ld.bfd: (.text.sqfs_read+0x600): undefined reference to `__udivdi3'
> /home/mcon/vocore/__V2__/Buildroot-2/recov/per-package/uboot/host/bin/mipsel-linux-ld.bfd: (.text.sqfs_read+0x64c): undefined reference to `__udivdi3'
> /home/mcon/vocore/__V2__/Buildroot-2/recov/per-package/uboot/host/bin/mipsel-linux-ld.bfd: fs/built-in.o: in function `sqfs_inode_size':
> (.text.sqfs_inode_size+0x140): undefined reference to `__udivdi3'
> make[2]: *** [Makefile:1753: u-boot] Error 1
> make[1]: *** [package/pkg-generic.mk:269: /home/mcon/vocore/__V2__/Buildroot-2/recov/build/uboot-v2020.10-rc3/.stamp_built] Error 2
> make: *** [Makefile:23: _all] Error 2

Following some advice on IRC (I can be contacted there as "mcon")
I tried to fix issue by explicit calling `lldiv()` (full patch below).
Fix allows full compilation, and is also somewhat working:
Directory list works, file load does not :(

> => ls mmc 0:6 /boot    
>         0   not_mounted
>   2512916   uImage
>
> 2 file(s), 0 dir(s)
>
> => load mmc 0:6 85000000 /boot/uImage
> Failed to load '/boot/uImage'

Here I have two questions:
1) can someone check my patch end tell me where I goofed?
2) is this supposedly the right way to fix? One other suggestion I had
on IRC is to simply implement __udivdi3/__umoddi3 in my architecture
(i.e.: u-boot/arch/mips/lib), but that doesn't seem like what has been
done in other places. I would like to provide an upstreamable patch.


==8<--- Here comes the (tentative) patch==================================
From cfd07aac0aa00345df1a0f2fac04ee549c78f87a Mon Sep 17 00:00:00 2001
From: Mauro Condarelli <mc5686@mclink.it>
Date: Thu, 3 Sep 2020 08:37:58 +0200
Subject: [PATCH 4/4] Fix missing __udivdi3 in SquashFS implementation.

Signed-off-by: Mauro Condarelli <mc5686@mclink.it>
---
 fs/squashfs/sqfs.c       | 27 ++++++++++++++++-----------
 fs/squashfs/sqfs_inode.c | 11 +++++++++--
 2 files changed, 25 insertions(+), 13 deletions(-)

Comments

Mauro Condarelli Sept. 3, 2020, 10:24 a.m. UTC | #1
Small update, see below.

On 9/3/20 10:41 AM, Mauro Condarelli wrote:
> Hi,
> enabling squashfs on my target (vocore2) result in multiple errors:
>
>> /home/mcon/vocore/__V2__/Buildroot-2/recov/per-package/uboot/host/bin/mipsel-linux-ld.bfd: fs/built-in.o: in function `sqfs_calc_n_blks':
>> fs/squashfs/sqfs.c:(.text.sqfs_calc_n_blks+0x44): undefined reference to `__umoddi3'
>> /home/mcon/vocore/__V2__/Buildroot-2/recov/per-package/uboot/host/bin/mipsel-linux-ld.bfd: fs/squashfs/sqfs.c:(.text.sqfs_calc_n_blks+0x98): undefined reference to `__udivdi3'
>> /home/mcon/vocore/__V2__/Buildroot-2/recov/per-package/uboot/host/bin/mipsel-linux-ld.bfd: fs/built-in.o: in function `sqfs_frag_lookup':
>> fs/squashfs/sqfs.c:(.text.sqfs_frag_lookup+0x74): undefined reference to `__udivdi3'
>> /home/mcon/vocore/__V2__/Buildroot-2/recov/per-package/uboot/host/bin/mipsel-linux-ld.bfd: fs/squashfs/sqfs.c:(.text.sqfs_frag_lookup+0x1b0): undefined reference to `__udivdi3'
>> /home/mcon/vocore/__V2__/Buildroot-2/recov/per-package/uboot/host/bin/mipsel-linux-ld.bfd: fs/built-in.o: in function `sqfs_opendir':
>> (.text.sqfs_opendir+0xbc): undefined reference to `__udivdi3'
>> /home/mcon/vocore/__V2__/Buildroot-2/recov/per-package/uboot/host/bin/mipsel-linux-ld.bfd: (.text.sqfs_opendir+0x178): undefined reference to `__udivdi3'
>> /home/mcon/vocore/__V2__/Buildroot-2/recov/per-package/uboot/host/bin/mipsel-linux-ld.bfd: fs/built-in.o:(.text.sqfs_read+0x324): more undefined references to `__udivdi3' follow
>> /home/mcon/vocore/__V2__/Buildroot-2/recov/per-package/uboot/host/bin/mipsel-linux-ld.bfd: fs/built-in.o: in function `sqfs_read':
>> (.text.sqfs_read+0x348): undefined reference to `__umoddi3'
>> /home/mcon/vocore/__V2__/Buildroot-2/recov/per-package/uboot/host/bin/mipsel-linux-ld.bfd: (.text.sqfs_read+0x388): undefined reference to `__udivdi3'
>> /home/mcon/vocore/__V2__/Buildroot-2/recov/per-package/uboot/host/bin/mipsel-linux-ld.bfd: (.text.sqfs_read+0x5bc): undefined reference to `__umoddi3'
>> /home/mcon/vocore/__V2__/Buildroot-2/recov/per-package/uboot/host/bin/mipsel-linux-ld.bfd: (.text.sqfs_read+0x600): undefined reference to `__udivdi3'
>> /home/mcon/vocore/__V2__/Buildroot-2/recov/per-package/uboot/host/bin/mipsel-linux-ld.bfd: (.text.sqfs_read+0x64c): undefined reference to `__udivdi3'
>> /home/mcon/vocore/__V2__/Buildroot-2/recov/per-package/uboot/host/bin/mipsel-linux-ld.bfd: fs/built-in.o: in function `sqfs_inode_size':
>> (.text.sqfs_inode_size+0x140): undefined reference to `__udivdi3'
>> make[2]: *** [Makefile:1753: u-boot] Error 1
>> make[1]: *** [package/pkg-generic.mk:269: /home/mcon/vocore/__V2__/Buildroot-2/recov/build/uboot-v2020.10-rc3/.stamp_built] Error 2
>> make: *** [Makefile:23: _all] Error 2
> Following some advice on IRC (I can be contacted there as "mcon")
> I tried to fix issue by explicit calling `lldiv()` (full patch below).
> Fix allows full compilation, and is also somewhat working:
> Directory list works, file load does not :(
>
>> => ls mmc 0:6 /boot    
>>         0   not_mounted
>>   2512916   uImage
>>
>> 2 file(s), 0 dir(s)
>>
>> => load mmc 0:6 85000000 /boot/uImage
>> Failed to load '/boot/uImage'
After load failure also dir listing becomes non-functional.
I didn't find any way to cure problem without full reboot.
I have no idea how to debug this.

=> ls mmc 0:6 /boot
        0   not_mounted
  2512916   uImage

2 file(s), 0 dir(s)

=> ls mmc 0:6 /root
       26   .profile
            .ssh/
      673   is_ssh3
     1251   kmsgd
    65536   master.bin
       77   persist_data.lst
      451   public.pem
     1186   termsize
     1675   update
     2853   verkey
     2336   wifi.py

10 file(s), 1 dir(s)

=> load mmc 0:6 85000000 /root/persist_data.lst
Failed to load '/root/persist_data.lst'
=> ls mmc 0:6 /root                           
=>

> Here I have two questions:
> 1) can someone check my patch end tell me where I goofed?
> 2) is this supposedly the right way to fix? One other suggestion I had
> on IRC is to simply implement __udivdi3/__umoddi3 in my architecture
> (i.e.: u-boot/arch/mips/lib), but that doesn't seem like what has been
> done in other places. I would like to provide an upstreamable patch.
>
>
> ==8<--- Here comes the (tentative) patch==================================
> From cfd07aac0aa00345df1a0f2fac04ee549c78f87a Mon Sep 17 00:00:00 2001
> From: Mauro Condarelli <mc5686@mclink.it>
> Date: Thu, 3 Sep 2020 08:37:58 +0200
> Subject: [PATCH 4/4] Fix missing __udivdi3 in SquashFS implementation.
>
> Signed-off-by: Mauro Condarelli <mc5686@mclink.it>
> ---
>  fs/squashfs/sqfs.c       | 27 ++++++++++++++++-----------
>  fs/squashfs/sqfs_inode.c | 11 +++++++++--
>  2 files changed, 25 insertions(+), 13 deletions(-)
>
> diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c
> index f67f7c4a40..12115b6baa 100644
> --- a/fs/squashfs/sqfs.c
> +++ b/fs/squashfs/sqfs.c
> @@ -23,6 +23,12 @@
>  #include "sqfs_filesystem.h"
>  #include "sqfs_utils.h"
>  
> +#include <div64.h>
> +#ifdef DIV_ROUND_UP
> +#undef DIV_ROUND_UP
> +#endif
> +#define DIV_ROUND_UP(n,d) (lldiv(((n) + (d) - 1), (d)))
> +
>  static struct squashfs_ctxt ctxt;
>  
>  static int sqfs_disk_read(__u32 block, __u32 nr_blocks, void *buf)
> @@ -85,7 +91,7 @@ static int sqfs_calc_n_blks(__le64 start, __le64 end, u64 *offset)
>      u64 start_, table_size;
>  
>      table_size = le64_to_cpu(end) - le64_to_cpu(start);
> -    start_ = le64_to_cpu(start) / ctxt.cur_dev->blksz;
> +    start_ = lldiv(le64_to_cpu(start), ctxt.cur_dev->blksz);
>      *offset = le64_to_cpu(start) - (start_ * ctxt.cur_dev->blksz);
>  
>      return DIV_ROUND_UP(table_size + *offset, ctxt.cur_dev->blksz);
> @@ -109,8 +115,8 @@ static int sqfs_frag_lookup(u32 inode_fragment_index,
>      if (inode_fragment_index >= get_unaligned_le32(&sblk->fragments))
>          return -EINVAL;
>  
> -    start = get_unaligned_le64(&sblk->fragment_table_start) /
> -        ctxt.cur_dev->blksz;
> +    start = lldiv(get_unaligned_le64(&sblk->fragment_table_start),
> +        ctxt.cur_dev->blksz);
>      n_blks = sqfs_calc_n_blks(sblk->fragment_table_start,
>                    sblk->export_table_start,
>                    &table_offset);
> @@ -135,7 +141,7 @@ static int sqfs_frag_lookup(u32 inode_fragment_index,
>      start_block = get_unaligned_le64(table + table_offset + block *
>                       sizeof(u64));
>  
> -    start = start_block / ctxt.cur_dev->blksz;
> +    start = lldiv(start_block, ctxt.cur_dev->blksz);
>      n_blks = sqfs_calc_n_blks(cpu_to_le64(start_block),
>                    sblk->fragment_table_start, &table_offset);
>  
> @@ -641,8 +647,8 @@ static int sqfs_read_inode_table(unsigned char **inode_table)
>  
>      table_size = get_unaligned_le64(&sblk->directory_table_start) -
>          get_unaligned_le64(&sblk->inode_table_start);
> -    start = get_unaligned_le64(&sblk->inode_table_start) /
> -        ctxt.cur_dev->blksz;
> +    start = lldiv(get_unaligned_le64(&sblk->inode_table_start),
> +        ctxt.cur_dev->blksz);
>      n_blks = sqfs_calc_n_blks(sblk->inode_table_start,
>                    sblk->directory_table_start, &table_offset);
>  
> @@ -725,8 +731,8 @@ static int sqfs_read_directory_table(unsigned char **dir_table, u32 **pos_list)
>      /* DIRECTORY TABLE */
>      table_size = get_unaligned_le64(&sblk->fragment_table_start) -
>          get_unaligned_le64(&sblk->directory_table_start);
> -    start = get_unaligned_le64(&sblk->directory_table_start) /
> -        ctxt.cur_dev->blksz;
> +    start = lldiv(get_unaligned_le64(&sblk->directory_table_start),
> +        ctxt.cur_dev->blksz);
>      n_blks = sqfs_calc_n_blks(sblk->directory_table_start,
>                    sblk->fragment_table_start, &table_offset);
>  
> @@ -1328,7 +1333,7 @@ int sqfs_read(const char *filename, void *buf, loff_t offset, loff_t len,
>      }
>  
>      for (j = 0; j < datablk_count; j++) {
> -        start = data_offset / ctxt.cur_dev->blksz;
> +        start = lldiv(data_offset, ctxt.cur_dev->blksz);
>          table_size = SQFS_BLOCK_SIZE(finfo.blk_sizes[j]);
>          table_offset = data_offset - (start * ctxt.cur_dev->blksz);
>          n_blks = DIV_ROUND_UP(table_size + table_offset,
> @@ -1382,7 +1387,7 @@ int sqfs_read(const char *filename, void *buf, loff_t offset, loff_t len,
>          goto free_buffer;
>      }
>  
> -    start = frag_entry.start / ctxt.cur_dev->blksz;
> +    start = lldiv(frag_entry.start, ctxt.cur_dev->blksz);
>      table_size = SQFS_BLOCK_SIZE(frag_entry.size);
>      table_offset = frag_entry.start - (start * ctxt.cur_dev->blksz);
>      n_blks = DIV_ROUND_UP(table_size + table_offset, ctxt.cur_dev->blksz);
> diff --git a/fs/squashfs/sqfs_inode.c b/fs/squashfs/sqfs_inode.c
> index 1387779a85..cfb2b8374c 100644
> --- a/fs/squashfs/sqfs_inode.c
> +++ b/fs/squashfs/sqfs_inode.c
> @@ -16,6 +16,13 @@
>  #include "sqfs_filesystem.h"
>  #include "sqfs_utils.h"
>  
> +#include <div64.h>
> +#ifdef DIV_ROUND_UP
> +#undef DIV_ROUND_UP
> +#endif
> +#define DIV_ROUND_UP(n,d) (lldiv(((n) + (d) - 1), (d)))
> +
> +
>  int sqfs_inode_size(struct squashfs_base_inode *inode, u32 blk_size)
>  {
>      switch (get_unaligned_le16(&inode->inode_type)) {
> @@ -30,7 +37,7 @@ int sqfs_inode_size(struct squashfs_base_inode *inode, u32 blk_size)
>          unsigned int blk_list_size;
>  
>          if (SQFS_IS_FRAGMENTED(fragment))
> -            blk_list_size = file_size / blk_size;
> +            blk_list_size = lldiv(file_size, blk_size);
>          else
>              blk_list_size = DIV_ROUND_UP(file_size, blk_size);
>  
> @@ -70,7 +77,7 @@ int sqfs_inode_size(struct squashfs_base_inode *inode, u32 blk_size)
>          if (fragment == 0xFFFFFFFF)
>              blk_list_size = DIV_ROUND_UP(file_size, blk_size);
>          else
> -            blk_list_size = file_size / blk_size;
> +            blk_list_size = lldiv(file_size, blk_size);
>  
>          return sizeof(*lreg) + blk_list_size * sizeof(u32);
>      }
diff mbox series

Patch

diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c
index f67f7c4a40..12115b6baa 100644
--- a/fs/squashfs/sqfs.c
+++ b/fs/squashfs/sqfs.c
@@ -23,6 +23,12 @@ 
 #include "sqfs_filesystem.h"
 #include "sqfs_utils.h"
 
+#include <div64.h>
+#ifdef DIV_ROUND_UP
+#undef DIV_ROUND_UP
+#endif
+#define DIV_ROUND_UP(n,d) (lldiv(((n) + (d) - 1), (d)))
+
 static struct squashfs_ctxt ctxt;
 
 static int sqfs_disk_read(__u32 block, __u32 nr_blocks, void *buf)
@@ -85,7 +91,7 @@  static int sqfs_calc_n_blks(__le64 start, __le64 end, u64 *offset)
     u64 start_, table_size;
 
     table_size = le64_to_cpu(end) - le64_to_cpu(start);
-    start_ = le64_to_cpu(start) / ctxt.cur_dev->blksz;
+    start_ = lldiv(le64_to_cpu(start), ctxt.cur_dev->blksz);
     *offset = le64_to_cpu(start) - (start_ * ctxt.cur_dev->blksz);
 
     return DIV_ROUND_UP(table_size + *offset, ctxt.cur_dev->blksz);
@@ -109,8 +115,8 @@  static int sqfs_frag_lookup(u32 inode_fragment_index,
     if (inode_fragment_index >= get_unaligned_le32(&sblk->fragments))
         return -EINVAL;
 
-    start = get_unaligned_le64(&sblk->fragment_table_start) /
-        ctxt.cur_dev->blksz;
+    start = lldiv(get_unaligned_le64(&sblk->fragment_table_start),
+        ctxt.cur_dev->blksz);
     n_blks = sqfs_calc_n_blks(sblk->fragment_table_start,
                   sblk->export_table_start,
                   &table_offset);
@@ -135,7 +141,7 @@  static int sqfs_frag_lookup(u32 inode_fragment_index,
     start_block = get_unaligned_le64(table + table_offset + block *
                      sizeof(u64));
 
-    start = start_block / ctxt.cur_dev->blksz;
+    start = lldiv(start_block, ctxt.cur_dev->blksz);
     n_blks = sqfs_calc_n_blks(cpu_to_le64(start_block),
                   sblk->fragment_table_start, &table_offset);
 
@@ -641,8 +647,8 @@  static int sqfs_read_inode_table(unsigned char **inode_table)
 
     table_size = get_unaligned_le64(&sblk->directory_table_start) -
         get_unaligned_le64(&sblk->inode_table_start);
-    start = get_unaligned_le64(&sblk->inode_table_start) /
-        ctxt.cur_dev->blksz;
+    start = lldiv(get_unaligned_le64(&sblk->inode_table_start),
+        ctxt.cur_dev->blksz);
     n_blks = sqfs_calc_n_blks(sblk->inode_table_start,
                   sblk->directory_table_start, &table_offset);
 
@@ -725,8 +731,8 @@  static int sqfs_read_directory_table(unsigned char **dir_table, u32 **pos_list)
     /* DIRECTORY TABLE */
     table_size = get_unaligned_le64(&sblk->fragment_table_start) -
         get_unaligned_le64(&sblk->directory_table_start);
-    start = get_unaligned_le64(&sblk->directory_table_start) /
-        ctxt.cur_dev->blksz;
+    start = lldiv(get_unaligned_le64(&sblk->directory_table_start),
+        ctxt.cur_dev->blksz);
     n_blks = sqfs_calc_n_blks(sblk->directory_table_start,
                   sblk->fragment_table_start, &table_offset);
 
@@ -1328,7 +1333,7 @@  int sqfs_read(const char *filename, void *buf, loff_t offset, loff_t len,
     }
 
     for (j = 0; j < datablk_count; j++) {
-        start = data_offset / ctxt.cur_dev->blksz;
+        start = lldiv(data_offset, ctxt.cur_dev->blksz);
         table_size = SQFS_BLOCK_SIZE(finfo.blk_sizes[j]);
         table_offset = data_offset - (start * ctxt.cur_dev->blksz);
         n_blks = DIV_ROUND_UP(table_size + table_offset,
@@ -1382,7 +1387,7 @@  int sqfs_read(const char *filename, void *buf, loff_t offset, loff_t len,
         goto free_buffer;
     }
 
-    start = frag_entry.start / ctxt.cur_dev->blksz;
+    start = lldiv(frag_entry.start, ctxt.cur_dev->blksz);
     table_size = SQFS_BLOCK_SIZE(frag_entry.size);
     table_offset = frag_entry.start - (start * ctxt.cur_dev->blksz);
     n_blks = DIV_ROUND_UP(table_size + table_offset, ctxt.cur_dev->blksz);
diff --git a/fs/squashfs/sqfs_inode.c b/fs/squashfs/sqfs_inode.c
index 1387779a85..cfb2b8374c 100644
--- a/fs/squashfs/sqfs_inode.c
+++ b/fs/squashfs/sqfs_inode.c
@@ -16,6 +16,13 @@ 
 #include "sqfs_filesystem.h"
 #include "sqfs_utils.h"
 
+#include <div64.h>
+#ifdef DIV_ROUND_UP
+#undef DIV_ROUND_UP
+#endif
+#define DIV_ROUND_UP(n,d) (lldiv(((n) + (d) - 1), (d)))
+
+
 int sqfs_inode_size(struct squashfs_base_inode *inode, u32 blk_size)
 {
     switch (get_unaligned_le16(&inode->inode_type)) {
@@ -30,7 +37,7 @@  int sqfs_inode_size(struct squashfs_base_inode *inode, u32 blk_size)
         unsigned int blk_list_size;
 
         if (SQFS_IS_FRAGMENTED(fragment))
-            blk_list_size = file_size / blk_size;
+            blk_list_size = lldiv(file_size, blk_size);
         else
             blk_list_size = DIV_ROUND_UP(file_size, blk_size);
 
@@ -70,7 +77,7 @@  int sqfs_inode_size(struct squashfs_base_inode *inode, u32 blk_size)
         if (fragment == 0xFFFFFFFF)
             blk_list_size = DIV_ROUND_UP(file_size, blk_size);
         else
-            blk_list_size = file_size / blk_size;
+            blk_list_size = lldiv(file_size, blk_size);
 
         return sizeof(*lreg) + blk_list_size * sizeof(u32);
     }