Re: [PATCH] Fix undefined/miscompiled construct in kernel

Andi Kleen (ak@muc.de)
Sun, 15 Jun 2003 19:17:40 +0200


Linus Torvalds <torvalds@transmeta.com> writes:

> On Sun, 15 Jun 2003, Andi Kleen wrote:
>>
>> The parse_args call in init/main.c does pointer arithmetic between two
>> different external symbols. This is undefined in C (only pointer arthmetic
>> in the same symbol is defined) and gets miscompiled on AMD64 with gcc 3.2,
>
> That's silly. You're making the code less readable, with some silly
> parameters. Why does it get miscompiled on amd64, and let's just fix that
> one.

Because &arbitary_symbol_a - &arbitary_symbol_b is undefined in C and
the amd64 gcc 3.2 choses to miscompile it (it results in a very big
number because it converts the 56/40 division to an inversed multiplication
in a wrong way). I actually wrote a compiler bug report first, but the
compiler developers rightly pointed out that it is undefined.

Note this is not the first time we had such problems, it happened
with __pa(&symbol) too (amd64 has a special macro to work around that).
I don't know why it happens more often on amd64 than on i386, perhaps
it has something to do with the RIP relative addressing or the
negative kernel code model. ppc seems to have similar problems.

Passing an end pointer is not too different from passing an
max index in my opinion.

Another way would be to use the anonymous asm trick proposed by rth
some time ago for a similar problem (asm("" : "=g" (output) : "0" (input))
to hide the symbols from the compiler), but I didn't do that because
it looked more ugly to me.

If you prefer to do it with the anonymous asm I can do it, but I don't
see a big problem with passing an end pointer.

-Andi
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/