2004-01-10 15:40:33

by Mario Vanoni

[permalink] [raw]
Subject: 2.6.1-mm2: compiler warning

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.




2004-01-10 15:56:46

by Tim Cambrant

[permalink] [raw]
Subject: Re: 2.6.1-mm2: compiler warning

On Sat, Jan 10, 2004 at 04:40:30PM +0100, Mario Vanoni wrote:
> 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

2004-01-10 17:29:13

by Bart Samwel

[permalink] [raw]
Subject: [PATCH][TRIVIAL] Remove bogus "value 0x37ffffff truncated to 0x37ffffff" warning.

Tim Cambrant wrote:
> On Sat, Jan 10, 2004 at 04:40:30PM +0100, Mario Vanoni wrote:
>
>>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.

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.orig 2004-01-10 18:15:17.000000000 +0100
+++ page.h 2004-01-10 18:15:47.000000000 +0100
@@ -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)


2004-01-10 17:35:17

by Hans Ulrich Niedermann

[permalink] [raw]
Subject: Re: 2.6.1-mm2: compiler warning

Tim Cambrant <[email protected]> writes:

> On Sat, Jan 10, 2004 at 04:40:30PM +0100, Mario Vanoni wrote:
>> 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

--- linux-2.6.1/include/asm-i386/page.h.orig Sat Jan 10 18:01:31 2004
+++ linux-2.6.1/include/asm-i386/page.h Sat Jan 10 18:03:48 2004
@@ -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)

2004-01-10 17:39:39

by Davide Libenzi

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

On Sat, 10 Jan 2004, Bart Samwel wrote:

> Tim Cambrant wrote:
> > On Sat, Jan 10, 2004 at 04:40:30PM +0100, Mario Vanoni wrote:
> >
> >>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.
>
> 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.orig 2004-01-10 18:15:17.000000000 +0100
> +++ page.h 2004-01-10 18:15:47.000000000 +0100
> @@ -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


2004-01-10 18:42:57

by Gene Heskett

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

On Saturday 10 January 2004 12:28, Bart Samwel wrote:
>Tim Cambrant wrote:
>> On Sat, Jan 10, 2004 at 04:40:30PM +0100, Mario Vanoni wrote:
>>>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.
>
>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.orig 2004-01-10 18:15:17.000000000 +0100
>+++ page.h 2004-01-10 18:15:47.000000000 +0100
>@@ -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?

--
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.

2004-01-10 20:15:05

by Bart Samwel

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

Gene Heskett wrote:
> On Saturday 10 January 2004 12:28, Bart Samwel wrote:
>
>>Tim Cambrant wrote:
>>
>>>On Sat, Jan 10, 2004 at 04:40:30PM +0100, Mario Vanoni wrote:
>>>
>>>>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.
>>
>>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.orig 2004-01-10 18:15:17.000000000 +0100
>>+++ page.h 2004-01-10 18:15:47.000000000 +0100
>>@@ -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?

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

2004-01-10 20:21:57

by Bart Samwel

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



Davide Libenzi wrote:
> On Sat, 10 Jan 2004, Bart Samwel wrote:
>
>
>>Tim Cambrant wrote:
>>
>>>On Sat, Jan 10, 2004 at 04:40:30PM +0100, Mario Vanoni wrote:
>>>
>>>
>>>>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.
>>
>>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.orig 2004-01-10 18:15:17.000000000 +0100
>>+++ page.h 2004-01-10 18:15:47.000000000 +0100
>>@@ -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)

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

2004-01-10 20:50:47

by Gene Heskett

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

On Saturday 10 January 2004 15:14, Bart Samwel wrote:
>Gene Heskett wrote:
[...]
>> 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.

--
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.

2004-01-10 21:04:52

by Davide Libenzi

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

On Sat, 10 Jan 2004, Bart Samwel wrote:

> >>--- page.h.orig 2004-01-10 18:15:17.000000000 +0100
> >>+++ page.h 2004-01-10 18:15:47.000000000 +0100
> >>@@ -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)
>
> 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



2004-01-10 23:40:32

by Petri T. Koistinen

[permalink] [raw]
Subject: Re: 2.6.1-mm2: compiler warning

Hi!

On Sat, 10 Jan 2004, Hans Ulrich Niedermann wrote:

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

It boots and seems to be working, don't have expertise to say anything
else. Perhaps you should queue it via Rusty to expert review, see:
http://www.kernel.org/pub/linux/kernel/people/rusty/trivial/

Petri

2004-01-11 00:25:26

by Bart Samwel

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

Davide Libenzi wrote:
>>>#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.

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

2004-01-11 14:00:19

by Bart Samwel

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

Bart Samwel wrote:
> Davide Libenzi wrote:
>
>>>> #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.
>
>
> 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

2004-01-11 16:54:24

by Davide Libenzi

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

On Sun, 11 Jan 2004, Bart Samwel wrote:

> 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


2004-01-11 17:41:41

by Martin Schlemmer

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

On Sun, 2004-01-11 at 18:53, Davide Libenzi wrote:
> On Sun, 11 Jan 2004, Bart Samwel wrote:
>
> > 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 #
--


--
Martin Schlemmer


Attachments:
signature.asc (189.00 B)
This is a digitally signed message part

2004-01-11 17:53:15

by Davide Libenzi

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

On Sun, 11 Jan 2004, Martin Schlemmer wrote:

> On Sun, 2004-01-11 at 18:53, Davide Libenzi wrote:
> > On Sun, 11 Jan 2004, Bart Samwel wrote:
> >
> > > 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 #

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


2004-01-11 18:35:52

by Martin Schlemmer

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

On Sun, 2004-01-11 at 19:53, Davide Libenzi wrote:
> On Sun, 11 Jan 2004, Martin Schlemmer wrote:
>
> > On Sun, 2004-01-11 at 18:53, Davide Libenzi wrote:
> > > On Sun, 11 Jan 2004, Bart Samwel wrote:
> > >
> > > > 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 #
>
> 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
>
>

--
azarah@nosferatu tar $ as << EOF > 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 $
--



--
Martin Schlemmer


Attachments:
signature.asc (189.00 B)
This is a digitally signed message part

2004-01-11 18:43:29

by Davide Libenzi

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

On Sun, 11 Jan 2004, Martin Schlemmer wrote:

> azarah@nosferatu tar $ as << EOF
> > 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 $

This is weird. I also verified the above with:

GNU assembler 2.13.90.0.18 20030206

and it works fine too.




- Davide


2004-01-11 18:44:41

by Martin Schlemmer

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

On Sun, 2004-01-11 at 20:42, Davide Libenzi wrote:
> On Sun, 11 Jan 2004, Martin Schlemmer wrote:
>
> > azarah@nosferatu tar $ as << EOF
> > > 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 $
>
> 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 ...


--
Martin Schlemmer


Attachments:
signature.asc (189.00 B)
This is a digitally signed message part

2004-01-11 20:48:07

by Davide Libenzi

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

On Sun, 11 Jan 2004, Martin Schlemmer wrote:

> On Sun, 2004-01-11 at 20:42, Davide Libenzi wrote:
> > On Sun, 11 Jan 2004, Martin Schlemmer wrote:
> >
> > > azarah@nosferatu tar $ as << EOF
> > > > 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 $
> >
> > 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


2004-01-11 21:26:44

by Martin Schlemmer

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

On Sun, 2004-01-11 at 22:47, Davide Libenzi wrote:
> On Sun, 11 Jan 2004, Martin Schlemmer wrote:
>
> > On Sun, 2004-01-11 at 20:42, Davide Libenzi wrote:
> > > On Sun, 11 Jan 2004, Martin Schlemmer wrote:
> > >
> > > > azarah@nosferatu tar $ as << EOF
> > > > > 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 $
> > >
> > > 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.
>

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


--
Martin Schlemmer


Attachments:
signature.asc (189.00 B)
This is a digitally signed message part

2004-01-12 00:53:19

by Davide Libenzi

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

On Mon, 12 Jan 2004, Bart Samwel wrote:

> Davide Libenzi wrote:
> >>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
> 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


2004-01-12 00:48:40

by Bart Samwel

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

Davide Libenzi wrote:
>>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

2004-01-12 01:10:41

by Bart Samwel

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

Davide Libenzi wrote:
> 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

2004-01-12 01:16:04

by Bart Samwel

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

Martin Schlemmer wrote:

> 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