Serious Bug All Targets -- Please Read
Till Straumann
strauman at slac.stanford.edu
Wed Mar 4 05:20:38 UTC 2009
Ralf Corsepius wrote:
> Till Straumann wrote:
>> Ralf Corsepius wrote:
>>> Till Straumann wrote:
>>>> Ralf Corsepius wrote:
>>>>> Till Straumann wrote:
>>>>>> Ralf Corsepius wrote:
>>>>>>> Till Straumann wrote:
>>>>>>>> Hmm - AFAIK, c99 doesn't specify the exact representation
>>>>>>>> of 'bool' / '_Bool'. It only says that
>>>>>>>>
>>>>>>>> "An object declared as type _Bool is large enough to store the
>>>>>>>> values 0 and 1"
>>>>>>>>
>>>>>>>> Hence, there is no really safe way to access such
>>>>>>>> an object from assembly code.
>>>>>>> Exactly.
>>>>>>>
>>>>>>>> I wonder if it wouldn't be better to change the
>>>>>>>> type of _Context_Switch_necessary & friends
>>>>>>>> to a type of known width.
>>>>>>> IMO, no.
>>>>>>>
>>>>>>> We should change to code into something which doesn't need to
>>>>>>> know the size of a type, rsp. automatically gets it right.
>>>>>> So how would you do that given the requirement
>>>>>> that these variables need to be available to
>>>>>> assembly code, maybe w/o a stack available?
>>>>> E.g. by rewriting the code in question in C
>>>> That's what the new PPC framework does.
>>>>> w/ inline asm. This isn't always possible, but is possible on many
>>>>> occasions, even when stack is not available.
>>>> w/o stack I'm not sure...
>>> You can do something like this (Pseudo-C code):
>>>
>>> extern bool var;
>>>
>>> int _foo_stub(....)
>>> {
>>> asm( ENTRY_SYMBOL(foo) );
>>> asm( PROCESS(var) );
>>>
>>> asm( RETURN );
>>> }
>> You can't be serious.
>>
> What's your problem with this? This is all valid C and is not any
> dirtier than using asm.
Inline assembly is *much* trickier than straight assembly
in a separate compilation unit because of the interaction
with the C-compiler which doesn't 'understand' what
the inline assembly does but makes certain assumptions
for optimization purposes. We have been bitten quite
a few times by delicate inline-assembly issues in the
recent past (as gcc optimization gets more aggressive).
Just one (recently seen) example of a subtle problem:
outF()
{
char ch = 'F';
asm( <magic assembly copying memory pointed to by
'address-register' to console>
::"a"(&ch)) ;
}
doesn't work correctly because gcc doesn't know that
the inline assembly accesses/uses the value at &ch
and optimizes storing ch='F' away.
Here are some things that could happen to your proposed
hack:
1) gcc could generate prologue instructions and emit them
interspersed with the 'asm' statements. (quoting the gcc manual:
"Note that even a volatile 'asm' instruction can be moved
relative to other code,...")
Hence, in order to keep everything together you'd have
to use a single 'asm' construct.
2) The whole point of using inline assembly, I assume, was
to let gcc take care of the type promotion -- however, the
code it generates for that purpose may either not be
executed (if you use a single asm and jump to the
entry point) or it may clobber registers.
Consider (ppc)
extern char foovar;
__foo()
{
asm (" .global FOO\n"
"FOO: \n"
" mr 3, %0"::"r"(foovar):"3");
asm (" b FOORETURN");
}
which translates into
00000000 <__foo>:
0: 3d 20 00 00 lis r9,0
2: R_PPC_ADDR16_HA foovar
4: 88 09 00 00 lbz r0,0(r9)
6: R_PPC_ADDR16_LO foovar
00000008 <FOO>:
8: 7c 03 03 78 mr r3,r0
c: 48 00 00 00 b c <FOO+0x4>
c: R_PPC_REL24 FOORETURN
10: 4e 80 00 20 blr
=> if you jump to FOO 'r0' is not loaded
with 'foovar'
=> if you jump to __foo then registers 0 and 9
are clobbered (the only safe way would be
calling __foo as a regular C-subroutine
which requires a stack and also requires
observing the C ABI from the calling
assembly code).
-- Till
>
> Ralf
More information about the users
mailing list