This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [GOLD] [PATCH] Casting plugin onload entry point


Ralf Wildenhues <Ralf.Wildenhues@gmx.de> writes:

> Hello,
>
> * Ian Lance Taylor wrote on Thu, Dec 10, 2009 at 08:46:08AM CET:
>> Viktor Kutuzov writes:
>> 
>> > Depending on the version of the compiler, the way how plugin onload
>> > entry point is casted may give a compilation error: "ISO C++ forbids
>> > casting between pointer-to-function and pointer-to-object".
>> >
>> > The attached patch fixes this issue by using the workaround introduced by the POSIX.1-2003.
>> 
>> >   *(void **)(&onload) = dlsym(this->handle_, "onload");
>> 
>> Thanks for pointing that out.  I hope that POSIX doesn't really
>> recommend your approach, though, as it is an aliasing violation.  I
>> committed this patch to fix the problem in a way that should be
>> standard compliant.
>
> This is what POSIX recommends, though.  There is a rationale:
>
> |   The ISO C standard does not require that pointers to functions can
> |   be cast back and forth to pointers to data. However,
> |   POSIX-conforming implementations are required to support this, as
> |   noted in Pointer Types . The result of converting a pointer to a
> |   function into a pointer to another data type (except void *) is
> |   still undefined, however.
> |
> |   Note that compilers conforming to the ISO C standard are required to
> |   generate a warning if a conversion from a void * pointer to a
> |   function pointer is attempted as in:
> |
> |      fptr = (int (*)(int))dlsym(handle, "my_function");
>
> and the reference "Pointer Types" refers to this text:
>
> |     2.12.3 Pointer Types
> |
> |  All function pointer types shall have the same representation as the
> |  type pointer to void. Conversion of a function pointer to void *
> |  shall not alter the representation. A void * value resulting from
> |  such a conversion can be converted back to the original function
> |  pointer type, using an explicit cast, without loss of information.
> |
> |  Note:
> |          The ISO C standard does not require this, but it is required
> |          for POSIX conformance.
>
> So do I understand correctly that this is not an aliasing violation, and
> the memcpy change was not really needed?

The aliasing violation is taking the address of onload, which has type
ld_plugin_onload (== enum ld_plugin_status (*)(struct ld_plugin_tv*)),
casting that address to void**, and then dereferencing the pointer.
That means that the code was assigning to memory using type void* and
then later accessing it as type ld_plugin_onload.  The aliasing
violation is using one type to store the value and a different type to
read it.  That is entirely independent of the quoted text above.

Ian


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]