Skip to contentSkip to conversation

unresolved symbol: __udivdi3

DISCUSSION Ben Greear 8 participants 13 messages Apr 19, 2002 – Apr 25, 2002

lore
Share & tools
lore

Ben Greear

author
#0 lore raw

I would like to be able to devide 64bit numbers in a kernel module, but I get unresolved symbols when trying to insmod.

Does anyone have any ideas how to get around this little issue (without the obvious of casting the hell out of all my __u64s when doing division and throwing away precision.)?

Thanks,
Ben

Signature · 3 lines
Ben Greear <[email protected]>       <Ben_Greear AT excite.com>
President of Candela Technologies Inc      http://www.candelatech.com
ScryMUD:  http://scry.wanfear.com     http://scry.wanfear.com/~greear
#1 lore raw

On Fri, 19 Apr 2002, Ben Greear wrote:

| I would like to be able to devide 64bit numbers in a kernel module,
| but I get unresolved symbols when trying to insmod.
|
| Does anyone have any ideas how to get around this little issue
| (without the obvious of casting the hell out of all my __u64s
| when doing division and throwing away precision.)?

Did you look at linux/include/asm*/div64.h ?

Signature · 1 line
~Randy
#11 lore raw
In reply to Ben Greear
Quoted 6 lines · Ben Greear

I would like to be able to devide 64bit numbers in a kernel module, but I get unresolved symbols when trying to insmod.

Does anyone have any ideas how to get around this little issue (without the obvious of casting the hell out of all my __u64s when doing division and throwing away precision.)?

When you talk about precision, it makes me think you want to have a floating-point divide. In fact, no floating-point math can be done in the kernel.

Cheers, Andreas
--
Andreas Dilger
http://www-mddsp.enel.ucalgary.ca/People/adilger/
http://sourceforge.net/projects/ext2resize/

author
#2 lore raw
In reply to Randy.Dunlap
Quoted 10 lines · Randy.Dunlap

On Fri, 19 Apr 2002, Ben Greear wrote:

| I would like to be able to devide 64bit numbers in a kernel module,
| but I get unresolved symbols when trying to insmod.
|
| Does anyone have any ideas how to get around this little issue
| (without the obvious of casting the hell out of all my __u64s
| when doing division and throwing away precision.)?

Did you look at linux/include/asm*/div64.h ?

I changed my code to look like this:

		char *p = info->pg_result;
                __u64 mbps = 0;
                __u64 t1 = (info->pg_sofar*1000);
                __u64 t2 = do_div(total, 1000);
                __u64 pps = 0; /* do_div(t1, t2); */
                t1 = (info->pg_sofar * 1000);
                mbps = 0;/* do_div(t1, t2); */
                /* mbps *= info->pkt_size; */

This code will load w/out problems. However, if I uncomment the do_div on the line: __u64 pps = 0; /* do_div(t1, t2); */
then I get another unresolved symbol:
__umodi3

I'm guessing that there is some optimization the compiler is doing that is using the mod operator somehow, but I am unsure about how to work around this.

Thanks,
Ben

Quoted 2 lines
Signature · 3 lines
Ben Greear <[email protected]>       <Ben_Greear AT excite.com>
President of Candela Technologies Inc      http://www.candelatech.com
ScryMUD:  http://scry.wanfear.com     http://scry.wanfear.com/~greear
#3 lore raw

From: Ben Greear <[email protected]>
Date: Fri, 19 Apr 2002 14:58:10 -0700

then I get another unresolved symbol:
__umodi3

Someone needs to add this routine under arch/sparc/lib/

I'm guessing that there is some optimization the compiler is doing that is using the mod operator somehow, but I am unsure about how to work around this.

"guessing"? Have a look the definition of do_div in asm-sparc/div64.h it explicitly does a mod operation :-)

author
#4 lore raw
In reply to Randy.Dunlap
Quoted 6 lines · David S. Miller

From: Ben Greear <[email protected]>
Date: Fri, 19 Apr 2002 14:58:10 -0700

then I get another unresolved symbol:

   __umodi3
Quoted 8 lines

Someone needs to add this routine under arch/sparc/lib/

I'm guessing that there is some optimization the compiler is doing that is using the mod operator somehow, but I am unsure about how to work around this.

"guessing"? Have a look the definition of do_div in asm-sparc/div64.h it explicitly does a mod operation :-)

Yeah, I just noticed that. What good is do_div if it calls % which is also not resolved??? I can see why you had all the hi/lo crap in the pktgen.c now :)

(I'm looking in asm-i386/div64.h, btw, since I'm running on x86 right now.)

Signature · 3 lines
Ben Greear <[email protected]>       <Ben_Greear AT excite.com>
President of Candela Technologies Inc      http://www.candelatech.com
ScryMUD:  http://scry.wanfear.com     http://scry.wanfear.com/~greear
author
#5 lore raw
In reply to Randy.Dunlap

Also, for what it's worth, do_div on x86 seems to corrupt arguments given to it, and may do other screwy things. I'm just going to go back to casting and let user-space do any precise division.

Quoted 16 lines · David S. Miller

From: Ben Greear <[email protected]>
Date: Fri, 19 Apr 2002 14:58:10 -0700

then I get another unresolved symbol:

   __umodi3

Someone needs to add this routine under arch/sparc/lib/

I'm guessing that there is some optimization the compiler is doing that is using the mod operator somehow, but I am unsure about how to work around this.

"guessing"? Have a look the definition of do_div in asm-sparc/div64.h it explicitly does a mod operation :-)

Signature · 3 lines
Ben Greear <[email protected]>       <Ben_Greear AT excite.com>
President of Candela Technologies Inc      http://www.candelatech.com
ScryMUD:  http://scry.wanfear.com     http://scry.wanfear.com/~greear
#6 lore raw

do_div(n, base) is defined (in some versions of the div64.h files) to be:

n = n / base; return rem;

so the first arg is modified.

~Randy

On Fri, 19 Apr 2002, Ben Greear wrote:

| Also, for what it's worth, do_div on x86 seems to corrupt arguments
| given to it, and may do other screwy things.  I'm just going to
| go back to casting and let user-space do any precise division.
|
| David S. Miller wrote:
|
| >    From: Ben Greear <[email protected]>
| >    Date: Fri, 19 Apr 2002 14:58:10 -0700
| >
| >    then I get another unresolved symbol:
| >    __umodi3
| >
| > Someone needs to add this routine under arch/sparc/lib/
| >
| >    I'm guessing that there is some optimization the compiler is doing that
| >    is using the mod operator somehow, but I am unsure about how to work around
| >    this.
| >
| > "guessing"?  Have a look the definition of do_div in asm-sparc/div64.h
| > it explicitly does a mod operation :-)
#12 lore raw
In reply to Ben Greear

At Fri, 19 Apr 2002 14:03:46 -0700,

Quoted 6 lines · Ben Greear

I would like to be able to devide 64bit numbers in a kernel module, but I get unresolved symbols when trying to insmod.

Does anyone have any ideas how to get around this little issue (without the obvious of casting the hell out of all my __u64s when doing division and throwing away precision.)?

Your architecture is i386? *Ad-hoc* solution is linking libgcc, thus you designate the following parameter during linking time:

gcc -print-libgcc-file-name

In addition, some architecture (sh, parisc) links libgcc.a. Look at arch/{sh,parisc}/Makefile. (I heard such architecture's gcc need libgcc for the basic calculation.)

-- gotom

#7 lore raw
In reply to Ben Greear
Quoted 3 lines · Ben Greear

Also, for what it's worth, do_div on x86 seems to corrupt arguments given to it, and may do other screwy things. I'm just going to go back to casting and let user-space do any precise division.

Or consider the code from:

http://nemesis.sourceforge.net/browse/lib/static/intmath/ix86/intmath.c.html

Adapted as follows...

Chris

---

#define DIV 0
#define REM 1

// Function copied/adapted/optimized from:
//
// nemesis.sourceforge.net/browse/lib/static/intmath/ix86/intmath.c.html //
// Copyright 1994, University of Cambridge Computer Laboratory // All Rights Reserved.
//
// TODO: When running on a 64-bit CPU platform, this should no longer be // TODO: necessary.
//
s64 divremdi3(s64 x,

              s64 y,
              int type)

{
u64 a = (x < 0) ? -x : x;
u64 b = (y < 0) ? -y : y;
u64 res = 0, d = 1;

  if (b > 0) while (b < a) b <<= 1, d <<= 1;

  do
    {
      if ( a >= b ) a -= b, res += d;
      b >>= 1;
      d >>= 1;
    }
  while (d);

if (DIV == type)

    {
      return (((x ^ y) & (1ll<<63)) == 0) ? res : -(s64)res;
    }
  else
    {
      return ((x & (1ll<<63)) == 0) ? a : -(s64)a;
    }
}
#8 lore raw

Hi,

I threw that function into a little procfs test module that I have and it worked nicely. Thanks.

~Randy

On Sat, 20 Apr 2002, Chris Caputo wrote:

| On Fri, 19 Apr 2002, Ben Greear wrote:
| > Also, for what it's worth, do_div on x86 seems to corrupt arguments
| > given to it, and may do other screwy things.  I'm just going to
| > go back to casting and let user-space do any precise division.
|
| Or consider the code from:
|
|  http://nemesis.sourceforge.net/browse/lib/static/intmath/ix86/intmath.c.html
|
| Adapted as follows...
|
| Chris
|
| ---
|
| // Function copied/adapted/optimized from:
| //
| //  nemesis.sourceforge.net/browse/lib/static/intmath/ix86/intmath.c.html
| //
| // Copyright 1994, University of Cambridge Computer Laboratory
| // All Rights Reserved.
| //
| // TODO: When running on a 64-bit CPU platform, this should no longer be
| // TODO: necessary.
| -
#9 lore raw

swap_free: Bad swap offset entry

I run a 2.4.17 system with high filesystem load and experience the following problem:

after running some hours with ext2 I got a lot of these messages:

Apr 24 22:19:00 linux kernel: swap_free: Bad swap offset entry 04000000

if I do a swapoff (swap is at /dev/hda6) they turn to:

Apr 24 22:20:29 linux kernel: swap_free: Unused swap file entry 04000000

..and get back to "Bad swap offset entry" if I do the swapon again

Before that I run the machine with ext3 where even worse things happened. I got a lot of these messages before the machine hangs some hours later:

Apr 22 04:01:04 linux kernel: Unable to handle kernel paging request at
virtual address e71d6478
Apr 22 04:01:04 linux kernel:  printing eip:
Apr 22 04:01:04 linux kernel: c013ede8
Apr 22 04:01:04 linux kernel: *pde = 00000000
Apr 22 04:01:04 linux kernel: Oops: 0002
Apr 22 04:01:04 linux kernel: CPU:    0
Apr 22 04:01:04 linux kernel: EIP:    0010:[prune_dcache+24/296]    Not
tainted
Apr 22 04:01:04 linux kernel: EFLAGS: 00210212
Apr 22 04:01:04 linux kernel: eax: c027c93c   ebx: c71d63f8   ecx: c71d6040
edx: e71d6478
Apr 22 04:01:04 linux kernel: esi: c71d62e0   edi: 00000000   ebp: 00007e35
esp: c3771e04
Apr 22 04:01:04 linux kernel: ds: 0018   es: 0018   ss: 0018
Apr 22 04:01:04 linux kernel: Process mogrify (pid: 913, stackpage=c3771000)
Apr 22 04:01:04 linux kernel: Stack: 00000004 000001d2 00000020 00000006
c013f14b 0000a4d0 c01290e0 00000006
Apr 22 04:01:05 linux kernel:        000001d2 00000006 000001d2 c027bc48
c027bc48 c027bc48 c012913c 00000020
Apr 22 04:01:05 linux kernel:        c3770000 00000100 00000000 c0129942
c027bdc4 00000100 00000010 00000000
Apr 22 04:01:05 linux kernel: Call Trace: [shrink_dcache_memory+27/52]
[shrink_caches+108/140] [try_to_free_pages+60/92] [balance_classzone+78/360]
[__alloc_pages+262/356]
Apr 22 04:01:05 linux kernel:    [_alloc_pages+22/24]
[do_anonymous_page+52/228] [do_no_page+51/400] [handle_mm_fault+82/176]
[do_page_fault+352/1176] [do_page_fault+0/1176]
Apr 22 04:01:05 linux kernel:    [update_wall_time+11/52] [timer_bh+36/604]
[do_timer+63/108] [timer_interrupt+95/264] [bh_action+26/64]
[tasklet_hi_action+68/100]
Apr 22 04:01:05 linux kernel:    [do_softirq+90/164] [error_code+52/60]
Apr 22 04:01:05 linux kernel:
Apr 22 04:01:05 linux kernel: Code: 89 02 89 1b 89 5b 04 8d 73 e8 8b 46 54

a8 08 74 27 24 f7 89

Any ideas/help??

Thanks in advance
Robert

#10 lore raw

Re: swap_free: Bad swap offset entry

Quoted 9 lines · Robert Schelander
Apr 24 22:19:00 linux kernel: swap_free: Bad swap offset entry 04000000
Apr 24 22:20:29 linux kernel: swap_free: Unused swap file entry 04000000
Apr 22 04:01:04 linux kernel: Unable to handle kernel paging request at
virtual address e71d6478
Apr 22 04:01:04 linux kernel: EIP:    0010:[prune_dcache+24/296]    Not
tainted
Apr 22 04:01:04 linux kernel: eax: c027c93c   ebx: c71d63f8   ecx: c71d6040
edx: e71d6478
Apr 22 04:01:04 linux kernel: esi: c71d62e0   edi: 00000000   ebp: 00007e35

These look _very_ much like single bit memory errors.
Please run memtest86 overnight, it will probably show your memory is bad.

Hugh