* undefined reference to `__divdi3'
@ 2018-07-22 12:18 Himanshu Jha
[not found] ` <CACnJAqP9JKzzg+dxsyLjfZ+Y5qp=APmjrqNKHbbTBjeF5U_kqQ@mail.gmail.com>
2018-07-23 17:41 ` valdis.kletnieks at vt.edu
0 siblings, 2 replies; 3+ messages in thread
From: Himanshu Jha @ 2018-07-22 12:18 UTC (permalink / raw)
To: kernelnewbies
Hi,
I am currently working on my GSoC project and while testing through
0-day test service, I hit the following error:
drivers/iio/chemical/bme680_core.o: In function `bme680_compensate_gas':
drivers/iio/chemical/bme680_core.c:450: undefined reference to `__divdi3'
vim +450 drivers/iio/chemical/bme680_core.c
417
418 /*
419 * Taken from Bosch BME680 API:
420 * https://github.com/BoschSensortec/BME680_driver/blob/63bb5336/bme680.c#L973
421 *
422 * Returns gas measurement in Ohm. Output value of "82986" represent 82986 ohms.
423 */
424 static u32 bme680_compensate_gas(struct bme680_data *data, u16 gas_res_adc,
425 u8 gas_range)
426 {
427 struct bme680_calib *calib = &data->bme680;
428 s64 var1;
429 u64 var2;
430 s64 var3;
431 u32 calc_gas_res;
432
433 /* Look up table 1 for the possible gas range values */
434 u32 lookupTable1[16] = {2147483647u, 2147483647u, 2147483647u,
435 2147483647u, 2147483647u, 2126008810u,
436 2147483647u, 2130303777u, 2147483647u,
437 2147483647u, 2143188679u, 2136746228u,
438 2147483647u, 2126008810u, 2147483647u,
439 2147483647u};
440 /* Look up table 2 for the possible gas range values */
441 u32 lookupTable2[16] = {4096000000u, 2048000000u, 1024000000u,
442 512000000u, 255744255u, 127110228u, 64000000u,
443 32258064u, 16016016u, 8000000u, 4000000u,
444 2000000u, 1000000u, 500000u, 250000u, 125000u};
445
446 var1 = ((1340 + (5 * (s64) calib->range_sw_err)) *
447 ((s64) lookupTable1[gas_range])) >> 16;
448 var2 = (((s64) ((s64) gas_res_adc << 15) - 16777216) + var1);
449 var3 = (((s64) lookupTable2[gas_range] * (s64) var1) >> 9);
> 450 calc_gas_res = (u32) ((var3 + ((s64) var2 >> 1)) / (s64) var2);
451
452 return calc_gas_res;
453 }
Now, I understood the problem of 64bit divison and how gcc places
'__divdi3()'
https://gcc.gnu.org/onlinedocs/gccint/Integer-library-routines.html
to support the "freestanding" environment and support architectures
which don't have such datatypes. And I need to use div64_s64()
or hack around do_div() to solve the issue.
Just out of curiosity, I decided to disassemble this particular function
to see __divdi3 and couldn't find it!
(gdb) disassemble bme680_compensate_gas
Dump of assembler code for function bme680_compensate_gas:
0x0000000000000000 <+0>: call 0x5 <bme680_compensate_gas+5>
0x0000000000000005 <+5>: sub rsp,0x88
0x000000000000000c <+12>: movabs rcx,0x7eb851ea7fffffff
0x0000000000000016 <+22>: movzx edx,dl
0x0000000000000019 <+25>: mov rax,QWORD PTR gs:0x28
0x0000000000000022 <+34>: mov QWORD PTR [rsp+0x80],rax
0x000000000000002a <+42>: xor eax,eax
0x000000000000002c <+44>: movabs rax,0x7fffffff7fffffff
0x0000000000000036 <+54>: movabs r8,0x7ef9db217fffffff
0x0000000000000040 <+64>: movabs r9,0x7f5c28f47fbe76c7
0x000000000000004a <+74>: mov QWORD PTR [rsp],rax
0x000000000000004e <+78>: mov QWORD PTR [rsp+0x8],rax
0x0000000000000053 <+83>: movzx esi,si
0x0000000000000056 <+86>: mov QWORD PTR [rsp+0x20],rax
0x000000000000005b <+91>: mov QWORD PTR [rsp+0x38],rax
0x0000000000000060 <+96>: movabs rax,0x7a120000f4240000
0x000000000000006a <+106>: mov QWORD PTR [rsp+0x40],rax
0x000000000000006f <+111>: movabs rax,0x1e8480003d090000
0x0000000000000079 <+121>: mov QWORD PTR [rsp+0x10],rcx
0x000000000000007e <+126>: mov QWORD PTR [rsp+0x48],rax
0x0000000000000083 <+131>: movabs rax,0x7938c540f3e58ff
0x000000000000008d <+141>: mov QWORD PTR [rsp+0x18],r8
0x0000000000000092 <+146>: mov QWORD PTR [rsp+0x50],rax
0x0000000000000097 <+151>: movabs rax,0x1ec381003d09000
0x00000000000000a1 <+161>: mov QWORD PTR [rsp+0x28],r9
0x00000000000000a6 <+166>: mov QWORD PTR [rsp+0x58],rax
0x00000000000000ab <+171>: movabs rax,0x7a120000f46290
0x00000000000000b5 <+181>: mov QWORD PTR [rsp+0x30],rcx
0x00000000000000ba <+186>: mov QWORD PTR [rsp+0x60],rax
0x00000000000000bf <+191>: movabs rax,0x1e8480003d0900
0x00000000000000c9 <+201>: mov ecx,DWORD PTR [rsp+rdx*4]
0x00000000000000cc <+204>: mov QWORD PTR [rsp+0x68],rax
0x00000000000000d1 <+209>: movabs rax,0x7a120000f4240
0x00000000000000db <+219>: shl rsi,0xf
0x00000000000000df <+223>: mov QWORD PTR [rsp+0x70],rax
0x00000000000000e4 <+228>: movabs rax,0x1e8480003d090
0x00000000000000ee <+238>: mov QWORD PTR [rsp+0x78],rax
0x00000000000000f3 <+243>: movsx rax,BYTE PTR [rdi+0x2f]
0x00000000000000f8 <+248>: lea rax,[rax+rax*4+0x53c]
0x0000000000000100 <+256>: imul rax,rcx
0x0000000000000104 <+260>: sar rax,0x10
0x0000000000000108 <+264>: lea rsi,[rax+rsi*1-0x1000000]
0x0000000000000110 <+272>: mov rcx,rax
0x0000000000000113 <+275>: mov eax,DWORD PTR [rsp+rdx*4+0x40]
0x0000000000000117 <+279>: mov rdx,rsi
0x000000000000011a <+282>: sar rdx,1
0x000000000000011d <+285>: imul rax,rcx
0x0000000000000121 <+289>: sar rax,0x9
0x0000000000000125 <+293>: add rax,rdx
0x0000000000000128 <+296>: cqo
0x000000000000012a <+298>: idiv rsi
0x000000000000012d <+301>: mov rdi,QWORD PTR [rsp+0x80]
0x0000000000000135 <+309>: xor rdi,QWORD PTR gs:0x28
0x000000000000013e <+318>: jne 0x148 <bme680_compensate_gas+328>
0x0000000000000140 <+320>: add rsp,0x88
0x0000000000000147 <+327>: ret
0x0000000000000148 <+328>: call 0x14d
End of assembler dump.
So, we have here:
0x000000000000012a <+298>: idiv rsi
Now, my question is, will __divdi3() be generated when I compile using
-m32 gcc flag or make ARCH=i386 ?
My machine is x86_64 and therefore idiv instruction is used instead of referencing
__divdi3(). Isn't it ?
Thanks.
--
Himanshu Jha
Undergraduate Student
Department of Electronics & Communication
Guru Tegh Bahadur Institute of Technology
^ permalink raw reply [flat|nested] 3+ messages in thread
* undefined reference to `__divdi3'
[not found] ` <CACnJAqP9JKzzg+dxsyLjfZ+Y5qp=APmjrqNKHbbTBjeF5U_kqQ@mail.gmail.com>
@ 2018-07-22 19:27 ` Himanshu Jha
0 siblings, 0 replies; 3+ messages in thread
From: Himanshu Jha @ 2018-07-22 19:27 UTC (permalink / raw)
To: kernelnewbies
Hi Alan,
On Sun, Jul 22, 2018 at 09:01:59PM +0200, Alan Keane wrote:
> Hi Himanshu,
>
> >>
> Hi,
>
>
> I am currently working on my GSoC project and while testing through
> 0-day test service, I hit the following error:
>
> drivers/iio/chemical/bme680_core.o: In function `bme680_compensate_gas':
> drivers/iio/chemical/bme680_core.c:450: undefined reference to `__divdi3'
>
> <<
>
> Are these errors that stop compilation or the compiler "just" giving
> warnings?
https://lists.01.org/pipermail/kbuild-all/2018-July/050481.html
> I'm guessing they are warnings because you have an object file that you can
> disassemble to find the idiv instruction?
Not sure to understand the question!?
> Are you building this code within the linux build system, I ask because I
> work a lot on bare metal systems and see a lot of these kind of warnings,
> on bare metal systems sometimes you have to implement __divdi3 (and
> friends) yourself, if your code does build (with warnings) does it link and
> most importantly does it (at least appear to) work?
Yes, I'm building within my linux machine.
The thing is when you do 64bit arithmetic operations in the code for an
architecture where there is no support for such operations(i386)
For instance in my code: 64 bit division
calc_gas_res = (u32) ((var3 + ((s64) var2 >> 1)) / (s64) var2);
In such situations, gcc provides its own runtime library(libgcc.a or
libgcc_s.so.1) to perform those operations:
Runtime Function: long __divdi3 (long a, long b)
But the linker in the kernel compilation doesn't link libgcc and
therefore, we get this error.
To solve the problem we can do:
1. Use do_div() (look math64.h for more functions) to prevent build
error on 32bit environments.
2. Link statically libgcc using flags:
-static-libgcc -lgcc
I have not cross-compiled for i386 and checked, but looking at kbuild
report it likely that build terminates and no linking takes place.
So, I need to use option 1. and test.
I'm sure div64_s64() would solve my problem.
Also, please avoid top-posting :)
--
Himanshu Jha
Undergraduate Student
Department of Electronics & Communication
Guru Tegh Bahadur Institute of Technology
^ permalink raw reply [flat|nested] 3+ messages in thread
* undefined reference to `__divdi3'
2018-07-22 12:18 undefined reference to `__divdi3' Himanshu Jha
[not found] ` <CACnJAqP9JKzzg+dxsyLjfZ+Y5qp=APmjrqNKHbbTBjeF5U_kqQ@mail.gmail.com>
@ 2018-07-23 17:41 ` valdis.kletnieks at vt.edu
1 sibling, 0 replies; 3+ messages in thread
From: valdis.kletnieks at vt.edu @ 2018-07-23 17:41 UTC (permalink / raw)
To: kernelnewbies
On Sun, 22 Jul 2018 17:48:21 +0530, Himanshu Jha said:
> I am currently working on my GSoC project and while testing through
> 0-day test service, I hit the following error:
> 424 static u32 bme680_compensate_gas(struct bme680_data *data, u16 gas_res_adc,
> 425 u8 gas_range)
> 426 {
> 427 struct bme680_calib *calib = &data->bme680;
> 428 s64 var1;
> 429 u64 var2;
> 430 s64 var3;
> 431 u32 calc_gas_res;
> 432
> 433 /* Look up table 1 for the possible gas range values */
> 434 u32 lookupTable1[16] = {2147483647u, 2147483647u, 2147483647u,
> 435 2147483647u, 2147483647u, 2126008810u,
> 436 2147483647u, 2130303777u, 2147483647u,
> 437 2147483647u, 2143188679u, 2136746228u,
> 438 2147483647u, 2126008810u, 2147483647u,
> 439 2147483647u};
As an aside, making this a 'static u32' will get rid of the mess of mov and movabs
instructions each time. 'static const u32' would be even better, as then the
compiler knows it can optimize assuming it never changes any of the values...
(In addition, with all that initialization out of the picture, figuring out
which assembler code does what should be easier...
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 486 bytes
Desc: not available
URL: <http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20180723/27536e06/attachment.sig>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2018-07-23 17:41 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-07-22 12:18 undefined reference to `__divdi3' Himanshu Jha
[not found] ` <CACnJAqP9JKzzg+dxsyLjfZ+Y5qp=APmjrqNKHbbTBjeF5U_kqQ@mail.gmail.com>
2018-07-22 19:27 ` Himanshu Jha
2018-07-23 17:41 ` valdis.kletnieks at vt.edu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).