[GOLD] [PATCH] Casting plugin onload entry point
Ian Lance Taylor
iant@google.com
Mon Dec 14 22:18:00 GMT 2009
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
More information about the Binutils
mailing list