Skip to contentSkip to conversation

2.6.1-mm2: compiler warning

PATCH In review Mario Vanoni 8 participants 25 messages Jan 10, 2004 – Jan 12, 2004

lore
Share & tools
lore
#0 lore raw

P4-3066HT with 1GB mem

Compiling the kernel under 2.6.1-mm2, gcc-3.3.2 (same messages as under 2.6.1-rc1-mm1, re-tested),

arch/i386/boot/setup.S: Assembler messages:
arch/i386/boot/setup.S:165: Warning: value 0x37ffffff truncated to 0x37ffffff

but compiles.

Rebooting with this kernel (2 times tested) then trying to recompile the kernel,
no crashes as with 2.6.1-rc2-mm1.
Every time using the last compiled bzImage.

Mario, _not_ in lkml.

#1 lore raw
Quoted 7 lines · Mario Vanoni

Compiling the kernel under 2.6.1-mm2, gcc-3.3.2 (same messages as under 2.6.1-rc1-mm1, re-tested),

arch/i386/boot/setup.S: Assembler messages:
arch/i386/boot/setup.S:165: Warning: value 0x37ffffff truncated to 0x37ffffff

This is apparently a known problem and has existed for a long time, but no-one has fixed it for some reason. I asked the exacly same question a few months ago, and someone told me that this issue has been around forever, but is noticed under 2.6, since it is less verbose during the compilation. I'll pass the message that was told to me: If you've got a fix, it would surely be included in the kernel.

Tim Cambrant

#2 lore raw

PATCH 1/1 Remove bogus "value 0x37ffffff truncated to 0x37ffffff" warning.

Quoted 8 lines · Tim Cambrant
Quoted 5 lines · Mario Vanoni

Compiling the kernel under 2.6.1-mm2, gcc-3.3.2 (same messages as under 2.6.1-rc1-mm1, re-tested),

arch/i386/boot/setup.S: Assembler messages:
arch/i386/boot/setup.S:165: Warning: value 0x37ffffff truncated to 0x37ffffff

Quoted 6 lines

This is apparently a known problem and has existed for a long time, but no-one has fixed it for some reason. I asked the exacly same question a few months ago, and someone told me that this issue has been around forever, but is noticed under 2.6, since it is less verbose during the compilation. I'll pass the message that was told to me: If you've got a fix, it would surely be included in the kernel.

The problem is in the MAXMEM macro. This macro takes the inverse of a positive number, subtracts another number, and the negative result overflows the negative range of a 32-bit integer. The assembler truncates it, but apparently it can't print overly negative numbers correctly, that's why it looks so strange.

My proposed fix is attached: change the macro to subtract the numbers from 0xFFFFFFFF, and then add 1 at the end. That yields the same result, but without going through a negative intermediate value that needs to be truncated.

-- Bart

page.h renamed from page.h.orig +1 -1
@@ -123,7 +123,7 @@
 
 #define PAGE_OFFSET		((unsigned long)__PAGE_OFFSET)
 #define VMALLOC_RESERVE		((unsigned long)__VMALLOC_RESERVE)
-#define MAXMEM			(-__PAGE_OFFSET-__VMALLOC_RESERVE)
+#define MAXMEM			(0xFFFFFFFF-__PAGE_OFFSET-__VMALLOC_RESERVE+1)
 #define __pa(x)			((unsigned long)(x)-PAGE_OFFSET)
 #define __va(x)			((void *)((unsigned long)(x)+PAGE_OFFSET))
 #define pfn_to_kaddr(pfn)      __va((pfn) << PAGE_SHIFT)
#3 lore raw

Re: [PATCH][TRIVIAL] Remove bogus "value 0x37ffffff truncated to 0x37ffffff" warning.

Quoted 35 lines · Bart Samwel
Quoted 9 lines · Tim Cambrant
Quoted 6 lines · Mario Vanoni

Compiling the kernel under 2.6.1-mm2, gcc-3.3.2 (same messages as under 2.6.1-rc1-mm1, re-tested),

arch/i386/boot/setup.S: Assembler messages:
arch/i386/boot/setup.S:165: Warning: value 0x37ffffff truncated to 0x37ffffff

Quoted 6 lines

This is apparently a known problem and has existed for a long time, but no-one has fixed it for some reason. I asked the exacly same question a few months ago, and someone told me that this issue has been around forever, but is noticed under 2.6, since it is less verbose during the compilation. I'll pass the message that was told to me: If you've got a fix, it would surely be included in the kernel.

The problem is in the MAXMEM macro. This macro takes the inverse of a positive number, subtracts another number, and the negative result overflows the negative range of a 32-bit integer. The assembler truncates it, but apparently it can't print overly negative numbers correctly, that's why it looks so strange.

My proposed fix is attached: change the macro to subtract the numbers from 0xFFFFFFFF, and then add 1 at the end. That yields the same result, but without going through a negative intermediate value that needs to be truncated.

-- Bart

page.h line 126

Quoted 5 lines
page.h renamed from page.h.orig +1 -1
@@ -123,7 +123,7 @@
 
  #define PAGE_OFFSET		((unsigned long)__PAGE_OFFSET)
  #define VMALLOC_RESERVE		((unsigned long)__VMALLOC_RESERVE)
-#define MAXMEM			(-__PAGE_OFFSET-__VMALLOC_RESERVE)
+#define MAXMEM			(0xFFFFFFFF-__PAGE_OFFSET-__VMALLOC_RESERVE+1)

Try:

#define MAXMEM (~__PAGE_OFFSET + 1 - __VMALLOC_RESERVE)

- Davide

#4 lore raw

Re: [PATCH][TRIVIAL] Remove bogus "value 0x37ffffff truncated to 0x37ffffff" warning.

Quoted 41 lines · Davide Libenzi
Quoted 29 lines · Bart Samwel
Quoted 9 lines · Tim Cambrant
Quoted 5 lines · Mario Vanoni

Compiling the kernel under 2.6.1-mm2, gcc-3.3.2 (same messages as under 2.6.1-rc1-mm1, re-tested),

arch/i386/boot/setup.S: Assembler messages:
arch/i386/boot/setup.S:165: Warning: value 0x37ffffff truncated to 0x37ffffff

Quoted 6 lines

This is apparently a known problem and has existed for a long time, but no-one has fixed it for some reason. I asked the exacly same question a few months ago, and someone told me that this issue has been around forever, but is noticed under 2.6, since it is less verbose during the compilation. I'll pass the message that was told to me: If you've got a fix, it would surely be included in the kernel.

The problem is in the MAXMEM macro. This macro takes the inverse of a positive number, subtracts another number, and the negative result overflows the negative range of a 32-bit integer. The assembler truncates it, but apparently it can't print overly negative numbers correctly, that's why it looks so strange.

My proposed fix is attached: change the macro to subtract the numbers from 0xFFFFFFFF, and then add 1 at the end. That yields the same result, but without going through a negative intermediate value that needs to be truncated.

-- Bart

page.h line 126

Quoted 5 lines
page.h renamed from page.h.orig +1 -1
@@ -123,7 +123,7 @@
 
 #define PAGE_OFFSET		((unsigned long)__PAGE_OFFSET)
 #define VMALLOC_RESERVE		((unsigned long)__VMALLOC_RESERVE)
-#define MAXMEM			(-__PAGE_OFFSET-__VMALLOC_RESERVE)
+#define MAXMEM			(0xFFFFFFFF-__PAGE_OFFSET-__VMALLOC_RESERVE+1)

Try:

Quoted 1 line

#define MAXMEM (~__PAGE_OFFSET + 1 - __VMALLOC_RESERVE)

I tried that first, before I came up with the solution in the patch, because I didn't like the dependency of 0xFFFFFFFF being 32-bit. It was a nice idea, but it didn't work. Apparently, gas interprets ~ as a one's complement negation operator, not a bitwise or. Therefore, ~__PAGE_OFFSET is just as negative as -__PAGE_OFFSET as far as gas is concerned. It gives me the same warning.

-- Bart

#5 lore raw

Re: [PATCH][TRIVIAL] Remove bogus "value 0x37ffffff truncated to 0x37ffffff" warning.

Quoted 12 lines · Bart Samwel
Quoted 12 lines

page.h line 126

Quoted 8 lines
page.h renamed from page.h.orig +1 -1
@@ -123,7 +123,7 @@
 
 #define PAGE_OFFSET		((unsigned long)__PAGE_OFFSET)
 #define VMALLOC_RESERVE		((unsigned long)__VMALLOC_RESERVE)
-#define MAXMEM			(-__PAGE_OFFSET-__VMALLOC_RESERVE)
+#define MAXMEM			(0xFFFFFFFF-__PAGE_OFFSET-__VMALLOC_RESERVE+1)

Try:

Quoted 8 lines
Quoted 1 line

#define MAXMEM (~__PAGE_OFFSET + 1 - __VMALLOC_RESERVE)

I tried that first, before I came up with the solution in the patch, because I didn't like the dependency of 0xFFFFFFFF being 32-bit. It was a nice idea, but it didn't work. Apparently, gas interprets ~ as a one's complement negation operator, not a bitwise or. Therefore, ~__PAGE_OFFSET is just as negative as -__PAGE_OFFSET as far as gas is concerned. It gives me the same warning.

That would mean a bug in as. __PAGE_OFFSET is unsigned and ~ is documented (not a surprise) as "bitwise not". The bitwise not of __PAGE_OFFSET (unsigned) is still unsigned. BTW 2.14 does not give warnings with both the original statement and the ~ one. This:

        PG=0xC0000000                                                                                                   
        VM=(128 << 20)                                                                                                  
                                                                                                                        
        mov (~PG + 1 - VM), %eax                                                                                        
        mov (-PG - VM), %eax                                                                                            

generate this:

zzzzzzzz: file format elf32-i386

Disassembly of section .text:

00000000 <.text>:

   0:   a1 00 00 00 38          mov    0x38000000,%eax
   5:   a1 00 00 00 38          mov    0x38000000,%eax

w/out any warnings. And the result is obviously 0x38000000 and not 0x37ffffff.

- Davide

#6 lore raw

Re: [PATCH][TRIVIAL] Remove bogus "value 0x37ffffff truncated to 0x37ffffff" warning.

Quoted 18 lines · Davide Libenzi
Quoted 3 lines
Quoted 1 line

#define MAXMEM (~__PAGE_OFFSET + 1 - __VMALLOC_RESERVE)

I tried that first, before I came up with the solution in the patch, because I didn't like the dependency of 0xFFFFFFFF being 32-bit. It was a nice idea, but it didn't work. Apparently, gas interprets ~ as a one's complement negation operator, not a bitwise or. Therefore, ~__PAGE_OFFSET is just as negative as -__PAGE_OFFSET as far as gas is concerned. It gives me the same warning.

That would mean a bug in as. __PAGE_OFFSET is unsigned and ~ is documented (not a surprise) as "bitwise not". The bitwise not of __PAGE_OFFSET (unsigned) is still unsigned. BTW 2.14 does not give warnings with both the original statement and the ~ one. This:

        PG=0xC0000000                                                                                                   
        VM=(128 << 20)                                                                                                  
                                                                                                                        
        mov (~PG + 1 - VM), %eax                                                                                        
        mov (-PG - VM), %eax                                                                                            

generate this:

zzzzzzzz: file format elf32-i386

Quoted 8 lines

Disassembly of section .text:

00000000 <.text>:

   0:   a1 00 00 00 38          mov    0x38000000,%eax
   5:   a1 00 00 00 38          mov    0x38000000,%eax

w/out any warnings. And the result is obviously 0x38000000 and not 0x37ffffff.

I get the same behaviour. The 0x37ffffff is from the place where MAXMEM is used (the ramdisk_max variable in setup.S); it subtracts one from the value. It turns out that the error only occurs when the value is used in a data definition. Experimentally found first value for which it gives the error is:

ramdisk_max: .long ~(0x80000000)

Interestingly, it doesn't occur for 0x7fffffff. I've taken a look at gas to see where it goes wrong, but my newly built version doesn't exhibit this behaviour -- it compiles the above statement without warnings. It might have to do with the differences between the build environment that the Debian binutils package is built in and my own machine -- I'll do some more investigating.

-- Bart

#7 lore raw

Re: [PATCH][TRIVIAL] Remove bogus "value 0x37ffffff truncated to 0x37ffffff" warning.

Quoted 32 lines · Bart Samwel
Quoted 30 lines · Davide Libenzi
Quoted 4 lines
Quoted 1 line

#define MAXMEM (~__PAGE_OFFSET + 1 - __VMALLOC_RESERVE)

I tried that first, before I came up with the solution in the patch, because I didn't like the dependency of 0xFFFFFFFF being 32-bit. It was a nice idea, but it didn't work. Apparently, gas interprets ~ as a one's complement negation operator, not a bitwise or. Therefore, ~__PAGE_OFFSET is just as negative as -__PAGE_OFFSET as far as gas is concerned. It gives me the same warning.

That would mean a bug in as. __PAGE_OFFSET is unsigned and ~ is documented (not a surprise) as "bitwise not". The bitwise not of __PAGE_OFFSET (unsigned) is still unsigned. BTW 2.14 does not give warnings with both the original statement and the ~ one. This:

PG=0xC0000000

        VM=(128 << 

20)

        mov (~PG + 1 - VM), 
%eax                                                                                        
        mov (-PG - VM), 

%eax

generate this:

zzzzzzzz: file format elf32-i386

Disassembly of section .text:

00000000 <.text>:

   0:   a1 00 00 00 38          mov    0x38000000,%eax
   5:   a1 00 00 00 38          mov    0x38000000,%eax
Quoted 8 lines
Quoted 1 line

w/out any warnings. And the result is obviously 0x38000000 and not 0x37ffffff.

I get the same behaviour. The 0x37ffffff is from the place where MAXMEM is used (the ramdisk_max variable in setup.S); it subtracts one from the value. It turns out that the error only occurs when the value is used in a data definition. Experimentally found first value for which it gives the error is:

ramdisk_max: .long ~(0x80000000)

Interestingly, it doesn't occur for 0x7fffffff. I've taken a look at gas to see where it goes wrong, but my newly built version doesn't exhibit this behaviour -- it compiles the above statement without warnings. It might have to do with the differences between the build environment that the Debian binutils package is built in and my own machine -- I'll do some more investigating.

OK, I've done a bit of investigation. It turns out that as generates this warning when the following condition is met:

      if ((get & mask) != 0
	  && ((get & mask) != mask
	      || (get & hibit) == 0))

I've modified the warning to give me some more info about the values involved:

test.S: Assembler messages:
test.S:3: Warning: value 0xffffffff7fffffff truncated to 0x7fffffff, mask = ffffffff00000000, unmask = ffffffff, (get & mask) = ffffffff00000000), sizeof(get) = 8, sizeof(mask) = 8

This could be correct if as interpreted ~ as a 64-bit binary not, not a 32-bit one. Not quite unlogical (it doesn't know the type of the input value -- it's a literal), except that it doesn't print the full value when it truncates it. I find it strange though that the warning isn't given for values under 0x80000000! This turns out to have to do with the "hibit", which turns out to be 0x80000000. Basically, their logic is that if (get & mask) == mask (all upper bits are 1) and (get & hibit) != 0 as well, then the number is fits within a 32 bits *signed* integer. However, they don't look at the unsignedness of the value. So, I've changed this to:

      if ((get & mask) != 0
	  && (exp->X_unsigned
              || (get & mask) != mask
	      || (get & hibit) == 0))

Now it seems to behave correctly: for '~' it always warns, for '-' it only warns if the negative value is below -0x80000000. I'll submit a patch to this effect (including the format extensions) to the binutils people.

What's the effect of this for the linux warning? We don't want to use ~ for this, because it's not a 32-bit binary not. So, we need to use either my solution or the one supplied by Hans.

-- Bart

#8 lore raw

Re: [PATCH][TRIVIAL] Remove bogus "value 0x37ffffff truncated to 0x37ffffff" warning.

Quoted 4 lines · Bart Samwel

Now it seems to behave correctly: for '~' it always warns, for '-' it only warns if the negative value is below -0x80000000. I'll submit a patch to this effect (including the format extensions) to the binutils people.

binutils 2.14 works fine, so I believe they already fixed it.

- Davide

#9 lore raw

Re: [PATCH][TRIVIAL] Remove bogus "value 0x37ffffff truncated to 0x37ffffff" warning.

Quoted 9 lines · Davide Libenzi
Quoted 4 lines · Bart Samwel

Now it seems to behave correctly: for '~' it always warns, for '-' it only warns if the negative value is below -0x80000000. I'll submit a patch to this effect (including the format extensions) to the binutils people.

binutils 2.14 works fine, so I believe they already fixed it.

I would beg to differ:

--
nosferatu linux # make
make[1]: `arch/i386/kernel/asm-offsets.s' is up to date.

  CHK     include/asm-i386/asm_offsets.h
  CHK     include/linux/compile.h
  AS      arch/i386/boot/setup.o

arch/i386/boot/setup.S: Assembler messages:
arch/i386/boot/setup.S:165: Warning: value 0x37ffffff truncated to 0x37ffffff
LD arch/i386/boot/setup
BUILD arch/i386/boot/bzImage
Root device is (8, 3)
Boot sector 512 bytes.
Setup is 4799 bytes.
System is 1366 kB
Kernel: arch/i386/boot/bzImage is ready
Building modules, stage 2.
MODPOST
nosferatu linux # ld --version
GNU ld version 2.14.90.0.7 20031029
Copyright 2002 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of the GNU General Public License. This program has absolutely no warranty. nosferatu linux #
--

Signature · 1 line
Martin Schlemmer
#10 lore raw

Re: [PATCH][TRIVIAL] Remove bogus "value 0x37ffffff truncated to 0x37ffffff" warning.

Quoted 28 lines · Martin Schlemmer
Quoted 9 lines · Davide Libenzi
Quoted 4 lines · Bart Samwel

Now it seems to behave correctly: for '~' it always warns, for '-' it only warns if the negative value is below -0x80000000. I'll submit a patch to this effect (including the format extensions) to the binutils people.

binutils 2.14 works fine, so I believe they already fixed it.

I would beg to differ:

--
nosferatu linux # make
make[1]: `arch/i386/kernel/asm-offsets.s' is up to date.

  CHK     include/asm-i386/asm_offsets.h
  CHK     include/linux/compile.h
  AS      arch/i386/boot/setup.o

arch/i386/boot/setup.S: Assembler messages:
arch/i386/boot/setup.S:165: Warning: value 0x37ffffff truncated to 0x37ffffff
LD arch/i386/boot/setup
BUILD arch/i386/boot/bzImage
Root device is (8, 3)
Boot sector 512 bytes.
Setup is 4799 bytes.
System is 1366 kB
Kernel: arch/i386/boot/bzImage is ready

Quoted 8 lines

Building modules, stage 2.
MODPOST
nosferatu linux # ld --version
GNU ld version 2.14.90.0.7 20031029
Copyright 2002 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of the GNU General Public License. This program has absolutely no warranty. nosferatu linux #

Ouch ! I have:

GNU assembler 2.14 20030612

and it works fine. Can you try:

$ as << EOF
	PG=0xC0000000
	VM=(128 << 20)

	.long (-PG -VM)
	.long (~PG + 1 - VM)

EOF

$ objdump -D a.out

- Davide

#11 lore raw

Re: [PATCH][TRIVIAL] Remove bogus "value 0x37ffffff truncated to 0x37ffffff" warning.

Quoted 47 lines · Davide Libenzi
Quoted 28 lines · Martin Schlemmer
Quoted 9 lines · Davide Libenzi
Quoted 4 lines · Bart Samwel

Now it seems to behave correctly: for '~' it always warns, for '-' it only warns if the negative value is below -0x80000000. I'll submit a patch to this effect (including the format extensions) to the binutils people.

binutils 2.14 works fine, so I believe they already fixed it.

I would beg to differ:

--
nosferatu linux # make
make[1]: `arch/i386/kernel/asm-offsets.s' is up to date.

  CHK     include/asm-i386/asm_offsets.h
  CHK     include/linux/compile.h
  AS      arch/i386/boot/setup.o

arch/i386/boot/setup.S: Assembler messages:
arch/i386/boot/setup.S:165: Warning: value 0x37ffffff truncated to 0x37ffffff
LD arch/i386/boot/setup
BUILD arch/i386/boot/bzImage
Root device is (8, 3)
Boot sector 512 bytes.
Setup is 4799 bytes.
System is 1366 kB
Kernel: arch/i386/boot/bzImage is ready

Quoted 8 lines

Building modules, stage 2.
MODPOST
nosferatu linux # ld --version
GNU ld version 2.14.90.0.7 20031029
Copyright 2002 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of the GNU General Public License. This program has absolutely no warranty. nosferatu linux #

Ouch ! I have:

GNU assembler 2.14 20030612

and it works fine. Can you try:

$ as << EOF
Quoted 10 lines
	PG=0xC0000000
	VM=(128 << 20)

	.long (-PG -VM)
	.long (~PG + 1 - VM)

EOF

$ objdump -D a.out

--
azarah@nosferatu tar $ as << EOF > PG=0xC0000000

Quoted 4 lines

VM=(128 << 20)
.long (-PG -VM)
.long (~PG + 1 - VM)
EOF

{standard input}: Assembler messages:
{standard input}:3: Warning: value 0x38000000 truncated to 0x38000000 {standard input}:4: Warning: value 0x38000000 truncated to 0x38000000 azarah@nosferatu tar $ objdump -D a.out

a.out: file format elf32-i386

Disassembly of section .text:

00000000 <.text>:

   0:   00 00                   add    %al,(%eax)
   2:   00 38                   add    %bh,(%eax)
   4:   00 00                   add    %al,(%eax)
   6:   00 38                   add    %bh,(%eax)

azarah@nosferatu tar $
--

Signature · 1 line
Martin Schlemmer
#12 lore raw

Re: [PATCH][TRIVIAL] Remove bogus "value 0x37ffffff truncated to 0x37ffffff" warning.

Quoted 13 lines · Martin Schlemmer

azarah@nosferatu tar $ as << EOF

Quoted 5 lines

PG=0xC0000000
VM=(128 << 20)
.long (-PG -VM)
.long (~PG + 1 - VM)
EOF

{standard input}: Assembler messages:
{standard input}:3: Warning: value 0x38000000 truncated to 0x38000000 {standard input}:4: Warning: value 0x38000000 truncated to 0x38000000 azarah@nosferatu tar $ objdump -D a.out

a.out: file format elf32-i386

Quoted 8 lines

Disassembly of section .text:

00000000 <.text>:

   0:   00 00                   add    %al,(%eax)
   2:   00 38                   add    %bh,(%eax)
   4:   00 00                   add    %al,(%eax)
   6:   00 38                   add    %bh,(%eax)

azarah@nosferatu tar $

This is weird. I also verified the above with:

GNU assembler 2.13.90.0.18 20030206

and it works fine too.

- Davide

#13 lore raw

Re: [PATCH][TRIVIAL] Remove bogus "value 0x37ffffff truncated to 0x37ffffff" warning.

Quoted 24 lines · Davide Libenzi
Quoted 13 lines · Martin Schlemmer

azarah@nosferatu tar $ as << EOF

Quoted 5 lines

PG=0xC0000000
VM=(128 << 20)
.long (-PG -VM)
.long (~PG + 1 - VM)
EOF

{standard input}: Assembler messages:
{standard input}:3: Warning: value 0x38000000 truncated to 0x38000000 {standard input}:4: Warning: value 0x38000000 truncated to 0x38000000 azarah@nosferatu tar $ objdump -D a.out

a.out: file format elf32-i386

Quoted 8 lines

Disassembly of section .text:

00000000 <.text>:

   0:   00 00                   add    %al,(%eax)
   2:   00 38                   add    %bh,(%eax)
   4:   00 00                   add    %al,(%eax)
   6:   00 38                   add    %bh,(%eax)

azarah@nosferatu tar $

Quoted 6 lines

This is weird. I also verified the above with:

GNU assembler 2.13.90.0.18 20030206

and it works fine too.

What distro? Might be an in-house patch ...

Signature · 1 line
Martin Schlemmer
#14 lore raw

Re: [PATCH][TRIVIAL] Remove bogus "value 0x37ffffff truncated to 0x37ffffff" warning.

Quoted 25 lines · Martin Schlemmer
Quoted 24 lines · Davide Libenzi
Quoted 21 lines · Martin Schlemmer

azarah@nosferatu tar $ as << EOF

Quoted 5 lines

PG=0xC0000000
VM=(128 << 20)
.long (-PG -VM)
.long (~PG + 1 - VM)
EOF

{standard input}: Assembler messages:
{standard input}:3: Warning: value 0x38000000 truncated to 0x38000000 {standard input}:4: Warning: value 0x38000000 truncated to 0x38000000 azarah@nosferatu tar $ objdump -D a.out

a.out: file format elf32-i386

Disassembly of section .text:

00000000 <.text>:

   0:   00 00                   add    %al,(%eax)
   2:   00 38                   add    %bh,(%eax)
   4:   00 00                   add    %al,(%eax)
   6:   00 38                   add    %bh,(%eax)

azarah@nosferatu tar $

Quoted 8 lines
Quoted 6 lines

This is weird. I also verified the above with:

GNU assembler 2.13.90.0.18 20030206

and it works fine too.

What distro? Might be an in-house patch ...

The 2.13.90.0.18 is std RH9, while 2.14 is self built. Tested also with FC1:

GNU assembler 2.14.90.0.6 20030820

that is fine too.

- Davide

#15 lore raw

Re: [PATCH][TRIVIAL] Remove bogus "value 0x37ffffff truncated to 0x37ffffff" warning.

Quoted 34 lines · Davide Libenzi
Quoted 32 lines · Martin Schlemmer
Quoted 30 lines · Davide Libenzi
Quoted 13 lines · Martin Schlemmer

azarah@nosferatu tar $ as << EOF

Quoted 5 lines

PG=0xC0000000
VM=(128 << 20)
.long (-PG -VM)
.long (~PG + 1 - VM)
EOF

{standard input}: Assembler messages:
{standard input}:3: Warning: value 0x38000000 truncated to 0x38000000 {standard input}:4: Warning: value 0x38000000 truncated to 0x38000000 azarah@nosferatu tar $ objdump -D a.out

a.out: file format elf32-i386

Quoted 8 lines

Disassembly of section .text:

00000000 <.text>:

   0:   00 00                   add    %al,(%eax)
   2:   00 38                   add    %bh,(%eax)
   4:   00 00                   add    %al,(%eax)
   6:   00 38                   add    %bh,(%eax)

azarah@nosferatu tar $

This is weird. I also verified the above with:

GNU assembler 2.13.90.0.18 20030206

and it works fine too.

Quoted 9 lines
Quoted 1 line

What distro? Might be an in-house patch ...

The 2.13.90.0.18 is std RH9, while 2.14 is self built. Tested also with FC1:

GNU assembler 2.14.90.0.6 20030820

that is fine too.

Hmm. Ok, ours is compiled with --enable-64-bit-bfd ... might do this? Bit late now, but I'll try to test tomorrow ...

Signature · 1 line
Martin Schlemmer
#16 lore raw

Re: [PATCH][TRIVIAL] Remove bogus "value 0x37ffffff truncated to 0x37ffffff" warning.

Quoted 3 lines · Martin Schlemmer

Hmm. Ok, ours is compiled with --enable-64-bit-bfd ... might do this? Bit late now, but I'll try to test tomorrow ...

That might definitely do it. offsetT (the type of values in gas) is defined as:

typedef bfd_signed_vma offsetT;

That DEFINITELY looks like the bit-size of bfd has an influence. In my program, offsetT is 64-bits -- looks like the default for Debian is --enable-64-bit-bfd. This explains why I didn't get a warning for my custom-built version, but I *did* get it for the version built by dpkg-buildpackage. Looks like we've got the final cause of the suddenly appearing warning.

-- Bart

#17 lore raw

Re: [PATCH][TRIVIAL] Remove bogus "value 0x37ffffff truncated to 0x37ffffff" warning.

In reply to Davide Libenzi
Quoted 3 lines · Davide Libenzi
Quoted 1 line

Now it seems to behave correctly: for '~' it always warns, for '-' it only warns if the negative value is below -0x80000000. I'll submit a patch to this effect (including the format extensions) to the binutils people.

binutils 2.14 works fine, so I believe they already fixed it.

Against your code, yes. I'm using binutils 2.14 as well. Check it when declaring a .long, like the kernel code does. Then it warns.

-- Bart

#18 lore raw

Re: [PATCH][TRIVIAL] Remove bogus "value 0x37ffffff truncated to 0x37ffffff" warning.

Quoted 10 lines · Bart Samwel
Quoted 6 lines · Davide Libenzi
Quoted 4 lines

Now it seems to behave correctly: for '~' it always warns, for '-' it only warns if the negative value is below -0x80000000. I'll submit a patch to this effect (including the format extensions) to the binutils people.

binutils 2.14 works fine, so I believe they already fixed it.

Against your code, yes. I'm using binutils 2.14 as well. Check it when declaring a .long, like the kernel code does. Then it warns.

Nope. It does not. Tested on three versions of binutils:

[davide@bigblue davide]$ as << EOF

Quoted 5 lines

PG=0xC0000000
VM=(128 << 20)
.long (-PG - VM) - 1
.long (~PG + 1 - VM) - 1
EOF

[davide@bigblue davide]$ objdump -D a.out

a.out: file format elf32-i386

Disassembly of section .text:

00000000 <.text>:

   0:   ff                      (bad)  
   1:   ff                      (bad)  
   2:   ff 37                   pushl  (%edi)
   4:   ff                      (bad)  
   5:   ff                      (bad)  
   6:   ff 37                   pushl  (%edi)

Disassembly of section .data:

Also, most important, the make bzImage does not give any warnings.

- Davide

#19 lore raw

Re: [PATCH][TRIVIAL] Remove bogus "value 0x37ffffff truncated to 0x37ffffff" warning.

Quoted 1 line · Davide Libenzi

Also, most important, the make bzImage does not give any warnings.

Hmmm. Did you get the original warning that we were talking about, before any changes were made? It still gives *me* the warnings, regardless of how it's written. What arch/compiler are you on? If you're on an arch/compiler that makes gas do 32-bit arithmetic, you're not going to get any warning -- it's going to be fine, because of gas's warning logic. I use an i386/gcc 3.3 system (debian unstable). Do you get no warnings as well on that configuration?

-- Bart

#20 lore raw

Re: [PATCH][TRIVIAL] Remove bogus "value 0x37ffffff truncated to 0x37ffffff" warning.

In reply to Bart Samwel
Quoted 35 lines · Bart Samwel
Quoted 8 lines · Tim Cambrant
Quoted 6 lines · Mario Vanoni

Compiling the kernel under 2.6.1-mm2, gcc-3.3.2 (same messages as under 2.6.1-rc1-mm1, re-tested),

arch/i386/boot/setup.S: Assembler messages:
arch/i386/boot/setup.S:165: Warning: value 0x37ffffff truncated to 0x37ffffff

Quoted 7 lines

This is apparently a known problem and has existed for a long time, but no-one has fixed it for some reason. I asked the exacly same question a few months ago, and someone told me that this issue has been around forever, but is noticed under 2.6, since it is less verbose during the compilation. I'll pass the message that was told to me: If you've got a fix, it would surely be included in the kernel.

The problem is in the MAXMEM macro. This macro takes the inverse of a positive number, subtracts another number, and the negative result overflows the negative range of a 32-bit integer. The assembler truncates it, but apparently it can't print overly negative numbers correctly, that's why it looks so strange.

My proposed fix is attached: change the macro to subtract the numbers from 0xFFFFFFFF, and then add 1 at the end. That yields the same result, but without going through a negative intermediate value that needs to be truncated.

-- Bart

page.h line 129

Quoted 8 lines
page.h renamed from page.h.orig +1 -1
@@ -123,7 +123,7 @@
 
 #define PAGE_OFFSET		((unsigned long)__PAGE_OFFSET)
 #define VMALLOC_RESERVE		((unsigned long)__VMALLOC_RESERVE)
-#define MAXMEM			(-__PAGE_OFFSET-__VMALLOC_RESERVE)
+#define MAXMEM			(0xFFFFFFFF-__PAGE_OFFSET-__VMALLOC_RESERVE+1)
 #define __pa(x)			((unsigned long)(x)-PAGE_OFFSET)
 #define __va(x)			((void *)((unsigned long)(x)+PAGE_OFFSET))
 #define pfn_to_kaddr(pfn)      __va((pfn) << PAGE_SHIFT)

This looks like a neat fix, faint praise from someone who doesn't know THAT much about it. However, the question folks like me are going to ask is which of the approximately 24 page.h's in the kernel tree (for 2.6.1-mm1 anyway) does this actually apply to?

Ahh, grep to the rescue, its include/asm/page.h

However, on checking my copy, I find a different fix there:

#define MAXMEM ((unsigned long)(-PAGE_OFFSET-VMALLOC_RESERVE))

Which I note doesn't use the PAGE_OFFSET defined a few lines up Which is correct?

Signature · 8 lines
Cheers, Gene
"There are four boxes to be used in defense of liberty: soap,
ballot, jury, and ammo. Please use in that order."
-Ed Howdershelt (Author)
99.22% setiathome rank, not too shabby for a WV hillbilly
Yahoo.com attornies please note, additions to this message
by Gene Heskett are:
Copyright 2003 by Maurice Eugene Heskett, all rights reserved.
#21 lore raw

Re: [PATCH][TRIVIAL] Remove bogus "value 0x37ffffff truncated to 0x37ffffff" warning.

Quoted 51 lines · Gene Heskett
Quoted 37 lines · Bart Samwel
Quoted 9 lines · Tim Cambrant
Quoted 6 lines · Mario Vanoni

Compiling the kernel under 2.6.1-mm2, gcc-3.3.2 (same messages as under 2.6.1-rc1-mm1, re-tested),

arch/i386/boot/setup.S: Assembler messages:
arch/i386/boot/setup.S:165: Warning: value 0x37ffffff truncated to 0x37ffffff

Quoted 7 lines

This is apparently a known problem and has existed for a long time, but no-one has fixed it for some reason. I asked the exacly same question a few months ago, and someone told me that this issue has been around forever, but is noticed under 2.6, since it is less verbose during the compilation. I'll pass the message that was told to me: If you've got a fix, it would surely be included in the kernel.

The problem is in the MAXMEM macro. This macro takes the inverse of a positive number, subtracts another number, and the negative result overflows the negative range of a 32-bit integer. The assembler truncates it, but apparently it can't print overly negative numbers correctly, that's why it looks so strange.

My proposed fix is attached: change the macro to subtract the numbers from 0xFFFFFFFF, and then add 1 at the end. That yields the same result, but without going through a negative intermediate value that needs to be truncated.

-- Bart

page.h line 129

Quoted 8 lines
page.h renamed from page.h.orig +1 -1
@@ -123,7 +123,7 @@
 
 #define PAGE_OFFSET		((unsigned long)__PAGE_OFFSET)
 #define VMALLOC_RESERVE		((unsigned long)__VMALLOC_RESERVE)
-#define MAXMEM			(-__PAGE_OFFSET-__VMALLOC_RESERVE)
+#define MAXMEM			(0xFFFFFFFF-__PAGE_OFFSET-__VMALLOC_RESERVE+1)
 #define __pa(x)			((unsigned long)(x)-PAGE_OFFSET)
 #define __va(x)			((void *)((unsigned long)(x)+PAGE_OFFSET))
 #define pfn_to_kaddr(pfn)      __va((pfn) << PAGE_SHIFT)

This looks like a neat fix, faint praise from someone who doesn't know THAT much about it. However, the question folks like me are going to ask is which of the approximately 24 page.h's in the kernel tree (for 2.6.1-mm1 anyway) does this actually apply to?

Quoted 8 lines

Ahh, grep to the rescue, its include/asm/page.h

However, on checking my copy, I find a different fix there:

#define MAXMEM ((unsigned long)(-PAGE_OFFSET-VMALLOC_RESERVE))

Which I note doesn't use the PAGE_OFFSET defined a few lines up Which is correct?

This is a C macro. Apparently in your arch it isn't used in any assembler code. The reason that i386 doesn't cast to unsigned long is that casts aren't an assembler construct, and this macro is used in arch/i386/boot/setup.S. Also, PAGE_OFFSET includes an (unsigned long) cast as well, __PAGE_OFFSET doesn't, and that explains why i386 uses __PAGE_OFFSET.

-- Bart

#22 lore raw

Re: [PATCH][TRIVIAL] Remove bogus "value 0x37ffffff truncated to 0x37ffffff" warning.

Quoted 1 line · Bart Samwel

Gene Heskett wrote:

[...]

Quoted 10 lines
Quoted 1 line

Which is correct?

This is a C macro. Apparently in your arch it isn't used in any assembler code. The reason that i386 doesn't cast to unsigned long is that casts aren't an assembler construct, and this macro is used in arch/i386/boot/setup.S. Also, PAGE_OFFSET includes an (unsigned long) cast as well, __PAGE_OFFSET doesn't, and that explains why i386 uses __PAGE_OFFSET.

-- Bart

Thanks, that clears it up to me.

Signature · 8 lines
Cheers, Gene
"There are four boxes to be used in defense of liberty: soap,
ballot, jury, and ammo. Please use in that order."
-Ed Howdershelt (Author)
99.22% setiathome rank, not too shabby for a WV hillbilly
Yahoo.com attornies please note, additions to this message
by Gene Heskett are:
Copyright 2003 by Maurice Eugene Heskett, all rights reserved.
#23 lore raw
In reply to Tim Cambrant
Quoted 10 lines · Tim Cambrant
Quoted 7 lines · Mario Vanoni

Compiling the kernel under 2.6.1-mm2, gcc-3.3.2 (same messages as under 2.6.1-rc1-mm1, re-tested),

arch/i386/boot/setup.S: Assembler messages:
arch/i386/boot/setup.S:165: Warning: value 0x37ffffff truncated to 0x37ffffff

If you've got a fix, it would surely be included in the kernel.

Hmm... let's see...

The assembler calculates in arch/i386/boot/setup.S (with the definition of MAXMEM from include/asm-i386/page.h):

- 0xC0000000 - 0x08000000 - 1

This obviously is a negative number which is what the assembler warns us about.

As there are no negative memory addresses anyway, the number we really want is the positive number

        (1 << 32) - 0xC0000000 - 0x08000000 - 1

which is the same in modulo (1 << 32) arithmetic, of course.

Original arch/i386/boot/setup.o (subtract from 0):

0000002c <ramdisk_max>:

      2c:	ff                   	(bad)  
      2d:	ff                   	(bad)  
      2e:	ff 37                	pushl  (%edi)

Patched arch/i386/boot/setup.o (subtract from (1<<32)):

0000002c <ramdisk_max>:

      2c:	ff                   	(bad)  
      2d:	ff                   	(bad)  
      2e:	ff 37                	pushl  (%edi)

This looks OK to me so far.

However, a few issues remain:

- There probably are some nasty side effects in other places which I haven't thought about.

- I didn't try to boot the patched kernel yet.

- As I don't know whether the C compiler might get confused about that, I re-used the #ifdef in include/asm-i386/page.h. Subtracting UL constants from (0UL) shouldn't make a difference, even if subtracting from 0x100000000UL might.

- __MAXMEM_ADDRSPACE_MAX should probably be defined using a constant from somewhere else. (Where from?)

Regards,

Uli

include/asm-i386/page.h renamed from include/asm-i386/page.h.orig +3 -1
@@ -116,14 +116,16 @@
 
 #ifdef __ASSEMBLY__
 #define __PAGE_OFFSET		(0xC0000000)
+#define __MAXMEM_ADDRSPACE_MAX	(1 << 32)
 #else
 #define __PAGE_OFFSET		(0xC0000000UL)
+#define __MAXMEM_ADDRSPACE_MAX	(0UL)
 #endif
 
 
 #define PAGE_OFFSET		((unsigned long)__PAGE_OFFSET)
 #define VMALLOC_RESERVE		((unsigned long)__VMALLOC_RESERVE)
-#define MAXMEM			(-__PAGE_OFFSET-__VMALLOC_RESERVE)
+#define MAXMEM			(__MAXMEM_ADDRSPACE_MAX-__PAGE_OFFSET-__VMALLOC_RESERVE)
 #define __pa(x)			((unsigned long)(x)-PAGE_OFFSET)
 #define __va(x)			((void *)((unsigned long)(x)+PAGE_OFFSET))
 #define pfn_to_kaddr(pfn)      __va((pfn) << PAGE_SHIFT)