[coreboot] [PATCH] cld before call

Segher Boessenkool segher at kernel.crashing.org
Thu Jul 30 03:58:33 CEST 2009


Okay, I understand the question now, I hope.

>>> my understanding of all this is:
>>> 1. if you want it set a certain way, you have to set it

Yes.

>>> 2. don't ever assume it has any particular value.

For inline asm?  Yes.

The ABI says that DF=0 whenever a function is called.  For GCC, this
means that it will make sure it is like that whenever it calls some
(external) function; and (in newer GCC versions) it assumes all  
functions
are called with DF=0, so it doesn't have to use the cld insn that often,
which is a good thing because it is quite expensive.

Now, _within_ a function GCC can do as it bloody well pleases.  This
includes functions that are inlined etc.; the ABI only applies to
externally visible functions.

>> "GCC relies on the ABI mandate that the direction flag is cleared  
>> before
>> entry to a function"
>>
>> That means if you call the payload via a pointer, gcc will make  
>> sure the
>> direction flag is cleared (either by clearing it directly before the
>> call or by never changing it after the start of the program).

Yes.

>> AFAIK calling a function via inline asm is not something gcc can see,

Indeed.  It usually isn't such a great thing to do either; you will have
to take care of saving all regs etc. yourself, keeping the stack  
balanced,
all that.  Often you get much nicer code if you write this in actual
(not inline) asm, that you call with the usual calling conventions.

>> so
>> this special case might be an exception. Then again, it's pretty
>> unlikely that gcc sets the direction flag for some operations and  
>> defers
>> clearing to the last possible moment.

You do not want to rely on what GCC does if it doesn't guarantee that
behaviour.

> Turns out gcc developers disagreed with each other about direction  
> flag
> guarantees for inline asm.

Not really.  There are two things: what GCC does right now, and what
should be the guaranteed behaviour (if any).

> Michael Matz said there are no guarantees for inline asm, but he also
> said that std is not emitted lazily, so having cld inside inline asm
> will not break any code afterwards, i.e. code after an inline asm does
> never depend on the DF being set.
> Chris Lattner said it's reasonable for inline asm to expect the DF  
> to be
> cleared.
> Richard Guenther said inline asm shouldn't make assumptions about DF.
> Jan Hubicka said gcc does not emit std at the moment.

The safest way to write inline asm that changes the direction flag is
to push eflags, change the flag, do your thing, and finally pop eflags.
This should work no matter what, and you are crazy if you care about
the performance or tiny code size of this ;-)

Or, write an assembler stub for this, and all your problems magically
go away.


Segher





More information about the coreboot mailing list