public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* Question on volatile functions and GCC
@ 2013-03-04 23:40 Jeffrey Walton
  2013-03-04 23:46 ` Jonathan Wakely
                   ` (2 more replies)
  0 siblings, 3 replies; 12+ messages in thread
From: Jeffrey Walton @ 2013-03-04 23:40 UTC (permalink / raw)
  To: gcc-help

Hi All,

I was looking at some slides on OpenSSL and secure memory wiping using
volatile (Slide 36 at
http://www.slideshare.net/guanzhi/crypto-with-openssl).

I believe GCC's interpretation of the use for 'volatile' is memory
mapped hardware. I think Ian stated it for me some time ago when I was
trying to understand different interpretations among compilers. If
volatile is for memory mapped hardware, why does GCC compile the
following:

volatile void clean_memory(volatile void* dest, size_t len)
{
  volatile unsigned char* p;
  for(p = (volatile unsigned char*)dest; len; dest[--len] = 0)
    ;;
}

How does a function become a 'volatile' memory mapped object related
to hardware?

Jeff

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Question on volatile functions and GCC
  2013-03-04 23:40 Question on volatile functions and GCC Jeffrey Walton
@ 2013-03-04 23:46 ` Jonathan Wakely
  2013-03-05 19:00   ` Jeffrey Walton
  2013-03-05  9:28 ` David Paterson
  2013-03-05  9:46 ` Georg-Johann Lay
  2 siblings, 1 reply; 12+ messages in thread
From: Jonathan Wakely @ 2013-03-04 23:46 UTC (permalink / raw)
  To: noloader; +Cc: gcc-help

On 4 March 2013 23:40, Jeffrey Walton wrote:
> Hi All,
>
> I was looking at some slides on OpenSSL and secure memory wiping using
> volatile (Slide 36 at
> http://www.slideshare.net/guanzhi/crypto-with-openssl).
>
> I believe GCC's interpretation of the use for 'volatile' is memory
> mapped hardware. I think Ian stated it for me some time ago when I was
> trying to understand different interpretations among compilers. If
> volatile is for memory mapped hardware, why does GCC compile the
> following:
>
> volatile void clean_memory(volatile void* dest, size_t len)
> {
>   volatile unsigned char* p;
>   for(p = (volatile unsigned char*)dest; len; dest[--len] = 0)
>     ;;
> }

This doesn't compile, it dereferences void.  Did you mean p[--len] ?

> How does a function become a 'volatile' memory mapped object related
> to hardware?

The function isn't volatile, the return type is. Qualifying void as
volatile is meaningless, but allowed by the C grammar.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Question on volatile functions and GCC
  2013-03-04 23:40 Question on volatile functions and GCC Jeffrey Walton
  2013-03-04 23:46 ` Jonathan Wakely
@ 2013-03-05  9:28 ` David Paterson
  2013-03-05  9:40   ` Jonathan Wakely
  2013-03-05 18:39   ` Jeffrey Walton
  2013-03-05  9:46 ` Georg-Johann Lay
  2 siblings, 2 replies; 12+ messages in thread
From: David Paterson @ 2013-03-05  9:28 UTC (permalink / raw)
  To: noloader; +Cc: gcc-help

On 4 March 2013 23:40, Jeffrey Walton <noloader@gmail.com> wrote:
> Hi All,
>
> I was looking at some slides on OpenSSL and secure memory wiping using
> volatile (Slide 36 at
> http://www.slideshare.net/guanzhi/crypto-with-openssl).
>
> I believe GCC's interpretation of the use for 'volatile' is memory
> mapped hardware.

In addition to Jonathan's answer on the use of "volatile", it's worth adding
that it's not only used for memory mapped hardware. There are many other
uses, such as inter-thread communication, or indeed the example you
show below.

> I think Ian stated it for me some time ago when I was
> trying to understand different interpretations among compilers. If
> volatile is for memory mapped hardware, why does GCC compile the
> following:
>
> volatile void clean_memory(volatile void* dest, size_t len)
> {
>   volatile unsigned char* p;
>   for(p = (volatile unsigned char*)dest; len; dest[--len] = 0)
>     ;;
> }

In this case, the use of "volatile" prevents an over-eager optimiser from
discarding this function completely, since it could assume that it does
nothing useful.

Regards,

David P.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Question on volatile functions and GCC
  2013-03-05  9:28 ` David Paterson
@ 2013-03-05  9:40   ` Jonathan Wakely
  2013-03-05  9:58     ` David Paterson
  2013-03-05 10:14     ` Tobias Burnus
  2013-03-05 18:39   ` Jeffrey Walton
  1 sibling, 2 replies; 12+ messages in thread
From: Jonathan Wakely @ 2013-03-05  9:40 UTC (permalink / raw)
  To: David Paterson; +Cc: noloader, gcc-help

On 5 March 2013 09:27, David Paterson wrote:
>
> In addition to Jonathan's answer on the use of "volatile", it's worth adding
> that it's not only used for memory mapped hardware. There are many other
> uses, such as inter-thread communication, or indeed the example you
> show below.

Only in broken code.

volatile is not for multithreading, you need proper synchronization
for interthread communication.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Question on volatile functions and GCC
  2013-03-04 23:40 Question on volatile functions and GCC Jeffrey Walton
  2013-03-04 23:46 ` Jonathan Wakely
  2013-03-05  9:28 ` David Paterson
@ 2013-03-05  9:46 ` Georg-Johann Lay
  2 siblings, 0 replies; 12+ messages in thread
From: Georg-Johann Lay @ 2013-03-05  9:46 UTC (permalink / raw)
  To: noloader; +Cc: gcc-help

Jeffrey Walton schrieb:
> Hi All,
> 
> I was looking at some slides on OpenSSL and secure memory wiping using
> volatile (Slide 36 at
> http://www.slideshare.net/guanzhi/crypto-with-openssl).
> 
> I believe GCC's interpretation of the use for 'volatile' is memory
> mapped hardware. I think Ian stated it for me some time ago when I was
> trying to understand different interpretations among compilers. If
> volatile is for memory mapped hardware, why does GCC compile the
> following:
> 
> volatile void clean_memory(volatile void* dest, size_t len)
> {
>   volatile unsigned char* p;
>   for(p = (volatile unsigned char*)dest; len; dest[--len] = 0)
>     ;;
> }
> 
> How does a function become a 'volatile' memory mapped object related
> to hardware?

volatile can be used to express that a function is noreturn like in the 
following example where only one call of f() is issued:

typedef void ft (void);
volatile ft f;

void foo (void)
{
     f();
     f();
}

or this example that throws
<stdin>: In function 'f':
<stdin>:4:1: warning: 'noreturn' function does return [enabled by default]

typedef void ft (void);
volatile ft f;

void f (void) {}

In your example, the volatile looks meaningless and like a typo.

Johann

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Question on volatile functions and GCC
  2013-03-05  9:40   ` Jonathan Wakely
@ 2013-03-05  9:58     ` David Paterson
  2013-03-05 10:19       ` David Brown
  2013-03-05 14:35       ` Ian Lance Taylor
  2013-03-05 10:14     ` Tobias Burnus
  1 sibling, 2 replies; 12+ messages in thread
From: David Paterson @ 2013-03-05  9:58 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: noloader, gcc-help

On 5 March 2013 09:40, Jonathan Wakely <jwakely.gcc@gmail.com> wrote:
> On 5 March 2013 09:27, David Paterson wrote:
>>
>> In addition to Jonathan's answer on the use of "volatile", it's worth adding
>> that it's not only used for memory mapped hardware. There are many other
>> uses, such as inter-thread communication, or indeed the example you
>> show below.
>
> Only in broken code.

LOL - well, it depends on your definition of "broken"...

> volatile is not for multithreading, you need proper synchronization
> for interthread communication.

Not always.  For very simple, non-critical uses you can just use a
volatile flag-type variable.  Cheap and nasty, I agree, but useable.

Regards,

David P.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Question on volatile functions and GCC
  2013-03-05  9:40   ` Jonathan Wakely
  2013-03-05  9:58     ` David Paterson
@ 2013-03-05 10:14     ` Tobias Burnus
  1 sibling, 0 replies; 12+ messages in thread
From: Tobias Burnus @ 2013-03-05 10:14 UTC (permalink / raw)
  To: gcc-help

Jonathan Wakely wrote:
> On 5 March 2013 09:27, David Paterson wrote:
>>
>> In addition to Jonathan's answer on the use of "volatile", it's worth adding
>> that it's not only used for memory mapped hardware. There are many other
>> uses, such as inter-thread communication, or indeed the example you
>> show below.
>
> Only in broken code.
>
> volatile is not for multithreading, you need proper synchronization
> for interthread communication.

Maybe he meant something like using volatile to prevent code moves with 
asynchronous communication (be it I/O or communication with libraries 
like MPI, or also call to some functions, which internally invoke some 
kind of synchronization.)

However, if I understand it correctly, GCC doesn't do such code moves* 
and C/C++ also does not allow them – even not without "volatile". That's 
different to Fortran, which allows for some code moves across procedure 
calls; hence, Fortran has – additionally to "volatile" – the 
"asynchronous" attribute to prevent those.

Tobias

* Side note: See PR49733 which tracks a case, where for Fortran code the 
lack of the asynchronous attribute is not used for optimizations.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Question on volatile functions and GCC
  2013-03-05  9:58     ` David Paterson
@ 2013-03-05 10:19       ` David Brown
  2013-03-05 14:35       ` Ian Lance Taylor
  1 sibling, 0 replies; 12+ messages in thread
From: David Brown @ 2013-03-05 10:19 UTC (permalink / raw)
  To: David Paterson; +Cc: Jonathan Wakely, noloader, gcc-help

On 05/03/13 10:58, David Paterson wrote:
> On 5 March 2013 09:40, Jonathan Wakely <jwakely.gcc@gmail.com> wrote:
>> On 5 March 2013 09:27, David Paterson wrote:
>>>
>>> In addition to Jonathan's answer on the use of "volatile", it's worth adding
>>> that it's not only used for memory mapped hardware. There are many other
>>> uses, such as inter-thread communication, or indeed the example you
>>> show below.
>>
>> Only in broken code.
> 
> LOL - well, it depends on your definition of "broken"...
> 
>> volatile is not for multithreading, you need proper synchronization
>> for interthread communication.

"volatile" is often part of the synchronisation, but it is seldom
sufficient on its own.  So it is "used in inter-thread communication" in
a sense.

> 
> Not always.  For very simple, non-critical uses you can just use a
> volatile flag-type variable.  Cheap and nasty, I agree, but useable.
> 

In some cases that is true - particularly on small processors and
embedded systems that don't have complications like caches, write
buffers, superscaler cpus, etc.

> Regards,
> 
> David P.
> 

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Question on volatile functions and GCC
  2013-03-05  9:58     ` David Paterson
  2013-03-05 10:19       ` David Brown
@ 2013-03-05 14:35       ` Ian Lance Taylor
  1 sibling, 0 replies; 12+ messages in thread
From: Ian Lance Taylor @ 2013-03-05 14:35 UTC (permalink / raw)
  To: David Paterson; +Cc: Jonathan Wakely, noloader, gcc-help

On Tue, Mar 5, 2013 at 1:58 AM, David Paterson <dnpaterson@gmail.com> wrote:
> On 5 March 2013 09:40, Jonathan Wakely <jwakely.gcc@gmail.com> wrote:
>
>> volatile is not for multithreading, you need proper synchronization
>> for interthread communication.
>
> Not always.  For very simple, non-critical uses you can just use a
> volatile flag-type variable.  Cheap and nasty, I agree, but useable.

If your code has a race condition before you add a volatile qualifier,
it will still have a race condition after you add the qualifier.

If you want a simple flag variable, don't use volatile; use
__atomic_load and __atomic_store.

Ian

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Question on volatile functions and GCC
  2013-03-05  9:28 ` David Paterson
  2013-03-05  9:40   ` Jonathan Wakely
@ 2013-03-05 18:39   ` Jeffrey Walton
  2013-03-06 10:22     ` Andrew Haley
  1 sibling, 1 reply; 12+ messages in thread
From: Jeffrey Walton @ 2013-03-05 18:39 UTC (permalink / raw)
  To: David Paterson; +Cc: gcc-help

On Tue, Mar 5, 2013 at 4:27 AM, David Paterson <dnpaterson@gmail.com> wrote:
> On 4 March 2013 23:40, Jeffrey Walton <noloader@gmail.com> wrote:
>>
>> ...
>> I believe GCC's interpretation of the use for 'volatile' is memory
>> mapped hardware.
>
> In addition to Jonathan's answer on the use of "volatile", it's worth adding
> that it's not only used for memory mapped hardware. There are many other
> uses, such as inter-thread communication, or indeed the example you
> show below.
A good discussion on the subject can be found at
http://gcc.gnu.org/ml/gcc-help/2012-03/msg00239.html.

The thread includes a discussion of Microsoft's and GCC's
interpretation of the keyword. The interpretations were so different I
wondered if it was 'implementation defined' in the standard.

> ...
> In this case, the use of "volatile" prevents an over-eager optimizer from
> discarding this function completely, since it could assume that it does
> nothing useful.
I think the only way to do it properly with GCC is to put the function
in its own source file and compile with -O0. Otherwise, I think you're
playing with fire under GCC.

OpenSSL uses other tricks to ensure the optimizer is tamed. Check out
their  OPENSSL_cleanse() function.

Microsoft is a different story: you can use volatile, or even their
SecureZeroMemory function [0], which is guaranteed to execute.

I have not seen a problem (yet) with Clang/Clang++ or Intel ICC/ICPC.
But I don't know their interpretation of the keyword.

In the end, I think the C/C++ committee needs to supply another
keyword to ensure program statements are never removed and executed
in-situ with no side effects (perhaps 'pin'). They gave the compiler
writer's 'restrict' so they could optimize. The security minded folks
should get something too to ensure program correctness even when the
optimizer is aggressive.

Jeff

[0] http://msdn.microsoft.com/en-us/library/windows/desktop/aa366877%28v=vs.85%29.aspx

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Question on volatile functions and GCC
  2013-03-04 23:46 ` Jonathan Wakely
@ 2013-03-05 19:00   ` Jeffrey Walton
  0 siblings, 0 replies; 12+ messages in thread
From: Jeffrey Walton @ 2013-03-05 19:00 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: gcc-help

On Mon, Mar 4, 2013 at 6:46 PM, Jonathan Wakely <jwakely.gcc@gmail.com> wrote:
> On 4 March 2013 23:40, Jeffrey Walton wrote:
>> Hi All,
>>
>> I was looking at some slides on OpenSSL and secure memory wiping using
>> volatile (Slide 36 at
>> http://www.slideshare.net/guanzhi/crypto-with-openssl).
>>
>> I believe GCC's interpretation of the use for 'volatile' is memory
>> mapped hardware. I think Ian stated it for me some time ago when I was
>> trying to understand different interpretations among compilers. If
>> volatile is for memory mapped hardware, why does GCC compile the
>> following:
>>
>> volatile void clean_memory(volatile void* dest, size_t len)
>> {
>>   volatile unsigned char* p;
>>   for(p = (volatile unsigned char*)dest; len; dest[--len] = 0)
>>     ;;
>> }
>
> This doesn't compile, it dereferences void.  Did you mean p[--len] ?
Yes, my bad. Sorry - copy[paste was not available because the slide
was an umage.

>> How does a function become a 'volatile' memory mapped object related
>> to hardware?
>
> The function isn't volatile, the return type is. Qualifying void as
> volatile is meaningless, but allowed by the C grammar.
:)

Jeff

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Question on volatile functions and GCC
  2013-03-05 18:39   ` Jeffrey Walton
@ 2013-03-06 10:22     ` Andrew Haley
  0 siblings, 0 replies; 12+ messages in thread
From: Andrew Haley @ 2013-03-06 10:22 UTC (permalink / raw)
  To: noloader; +Cc: David Paterson, gcc-help

On 03/05/2013 06:39 PM, Jeffrey Walton wrote:
> On Tue, Mar 5, 2013 at 4:27 AM, David Paterson <dnpaterson@gmail.com> wrote:
>> On 4 March 2013 23:40, Jeffrey Walton <noloader@gmail.com> wrote:
>>>
>>> ...
>>> I believe GCC's interpretation of the use for 'volatile' is memory
>>> mapped hardware.
>>
>> In addition to Jonathan's answer on the use of "volatile", it's worth adding
>> that it's not only used for memory mapped hardware. There are many other
>> uses, such as inter-thread communication, or indeed the example you
>> show below.
>
> A good discussion on the subject can be found at
> http://gcc.gnu.org/ml/gcc-help/2012-03/msg00239.html.
> 
> The thread includes a discussion of Microsoft's and GCC's
> interpretation of the keyword. The interpretations were so different I
> wondered if it was 'implementation defined' in the standard.

Yes: 6.7.3 Type qualifiers, "What constitutes an access to an object
that has volatile-qualified type is implementation-defined."

> In the end, I think the C/C++ committee needs to supply another
> keyword to ensure program statements are never removed and executed
> in-situ with no side effects (perhaps 'pin'). They gave the compiler
> writer's 'restrict' so they could optimize. The security minded folks
> should get something too to ensure program correctness even when the
> optimizer is aggressive.

But that'd still be impossible to define in terms of the abstract
machine, so it wouldn't help.

We now have the C++11 memory model.  Are you really saying that you
can't figure out how to use atomic_store() to write a secure memory
erase function?

Andrew.

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2013-03-06 10:22 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-03-04 23:40 Question on volatile functions and GCC Jeffrey Walton
2013-03-04 23:46 ` Jonathan Wakely
2013-03-05 19:00   ` Jeffrey Walton
2013-03-05  9:28 ` David Paterson
2013-03-05  9:40   ` Jonathan Wakely
2013-03-05  9:58     ` David Paterson
2013-03-05 10:19       ` David Brown
2013-03-05 14:35       ` Ian Lance Taylor
2013-03-05 10:14     ` Tobias Burnus
2013-03-05 18:39   ` Jeffrey Walton
2013-03-06 10:22     ` Andrew Haley
2013-03-05  9:46 ` Georg-Johann Lay

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).