mtd-utils: improve compatibility with klibc
Subsystems (2)
cover mtd-utils: improve compatibility with klibc
Klibc does not support floating point calculations.
Here some fixes needed to build the ubi-utils against klibc for aarch64, without FPU.
These lines end up compiled with soft float for other arm targets w/out FPU thus this was discovered only cross-building for qemuarm64 using the flag
'-mgeneral-regs-only'.
Changes tested on armv5, same output is printed.
Andrea Adami (2):
mtd-utils: common.c: convert to integer arithmetic
ubi-utils: ubiformat.c: convert to integer arithmetic.
lib/common.c | 15 +++++++++------ ubi-utils/ubiformat.c | 2 +- 2 files changed, 10 insertions(+), 7 deletions(-)
Signature · 1 line
2.7.4
PATCH 1/2 mtd-utils: common.c: convert to integer arithmetic
We use floating point just to print out KiB, MiB, GiB. Avoid that to be klibc friendly.
Fixes compilation for aarch64 against klibc:
error: '-mgeneral-regs-only' is incompatible with floating-point argument
| printf("%s%.1f GiB", p, (double)bytes / (1024 * 1024 * 1024));
etc.
Note:
* In the KiB case, we could apparently multiply by 100 before dividing without risking overflow. This code simply avoids multiplications.
--- lib/common.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
lib/common.c +9 -6
@@ -107,6 +107,9 @@ long long util_get_bytes(const char *str)void util_print_bytes (long long bytes,int bracket) {const char *p; +int GiB =1024 *1024 *1024 ; +int MiB =1024 *1024 ; +int KiB =1024 ;if (bracket) p =" (" ;
@@ -115,12 +118,12 @@ void util_print_bytes(long long bytes, int bracket)printf ("%lld bytes" , bytes); -if (bytes >1024 *1024 *1024 ) -printf ("%s%.1f GiB" , p, (double )bytes / (1024 *1024 *1024 )); -else if (bytes >1024 *1024 ) -printf ("%s%.1f MiB" , p, (double )bytes / (1024 *1024 )); -else if (bytes >1024 && bytes !=0 ) -printf ("%s%.1f KiB" , p, (double )bytes /1024 ); +if (bytes > GiB) +printf ("%s%d.%d GiB" , p, bytes / GiB, bytes % GiB / (GiB /10 )); +else if (bytes > MiB) +printf ("%s%d.%d MiB" , p, bytes / MiB, bytes % MiB / (MiB /10 )); +else if (bytes > KiB && bytes !=0 ) +printf ("%s%d.%d KiB" , p, bytes / KiB, bytes % KiB / (KiB /10 ));else return ;
Signature · 1 line
2.7.4
Re: [PATCH 1/2] mtd-utils: common.c: convert to integer arithmetic
Quoted 52 lines · Andrea Adami
We use floating point just to print out KiB, MiB, GiB. Avoid that to be klibc friendly.
Fixes compilation for aarch64 against klibc:
error: '-mgeneral-regs-only' is incompatible with floating-point argument
|printf("%s%.1f GiB", p, (double)bytes / (1024 * 1024 * 1024));
etc.Note:
* In the KiB case, we could apparently multiply by 100 before dividing without risking overflow. This code simply avoids multiplications.Signed-off-by Andrea Adami <[email protected]>--- lib/common.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)lib/common.c +9
-7@@ -107,6 +107,9 @@ long long util_get_bytes(const char *str)void util_print_bytes (long long bytes,int bracket) {const char *p; +int GiB =1024 *1024 *1024 ; +int MiB =1024 *1024 ; +int KiB =1024 ;if (bracket) p =" (" ;@@ -115,12 +118,12 @@ void util_print_bytes(long long bytes, int bracket)printf ("%lld bytes" , bytes); -if (bytes >1024 *1024 *1024 ) -printf ("%s%.1f GiB" , p, (double )bytes / (1024 *1024 *1024 )); -else if (bytes >1024 *1024 ) -printf ("%s%.1f MiB" , p, (double )bytes / (1024 *1024 )); -else if (bytes >1024 && bytes !=0 ) -printf ("%s%.1f KiB" , p, (double )bytes /1024 ); +if (bytes > GiB) +printf ("%s%d.%d GiB" , p, bytes / GiB, bytes % GiB / (GiB /10 )); +else if (bytes > MiB) +printf ("%s%d.%d MiB" , p, bytes / MiB, bytes % MiB / (MiB /10 )); +else if (bytes > KiB && bytes !=0 ) +printf ("%s%d.%d KiB" , p, bytes / KiB, bytes % KiB / (KiB /10 ));else return ; --
Quoted 2 lines
2.7.4
Missing cast to integer, the right specifier here would be %lld and not %d. Building 1.5.2-klibc I had no warnings but now I see them with 2.0.1. I'll send a v2.
Regards
Andrea
PATCH 2/2 ubi-utils: ubiformat.c: convert to integer arithmetic
In reply to Andrea AdamiDo not cast percent to double, it is just used as upper limit. Avoid floating point to fix compilation for aarch64 against klibc:
error: '-mgeneral-regs-only' is incompatible with floating-point code
| int percent = ((double)si->ok_cnt)/si->good_cnt * 100;
| ^~~~~~~
Notes:
* The checks in the code above this line ensure that si->good_cnt is not 0.
* The code assumes si->good_cnt * 100 will not overflow, then we can use (si->ok_cnt * 100) safely because the former is bigger.
* The truncated result does not affect the logic:
i.e. a value of 49.9 is truncated to 49 and is still <50.
--- ubi-utils/ubiformat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
ubi-utils/ubiformat.c +1 -1
@@ -844,7 +844,7 @@ int main(int argc, char * const argv[]) }if (!args.override_ec && si->empty_cnt < si->good_cnt) { -int percent = ((double )si->ok_cnt)/si->good_cnt *100 ; +int percent = (si->ok_cnt *100 ) / si->good_cnt;/* * Make sure the majority of eraseblocks have valid
Signature · 1 line
2.7.4