This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [GOLD] [PATCH] Casting plugin onload entry point
- From: Ian Lance Taylor <iant at google dot com>
- To: Ralf Wildenhues <Ralf dot Wildenhues at gmx dot de>
- Cc: Viktor Kutuzov <vkutuzov at accesssoftek dot com>, binutils at sourceware dot org
- Date: Mon, 14 Dec 2009 14:17:51 -0800
- Subject: Re: [GOLD] [PATCH] Casting plugin onload entry point
- References: <6AE1604EE3EC5F4296C096518C6B77EEE56FBF79@mail.accesssoftek.com> <6AE1604EE3EC5F4296C096518C6B77EEE56FBF7F@mail.accesssoftek.com> <6AE1604EE3EC5F4296C096518C6B77EEED7DBE12@mail.accesssoftek.com> <6AE1604EE3EC5F4296C096518C6B77EEED7DBE18@mail.accesssoftek.com> <71D42A22F6FB467FA698FE3D4193E555@andreic6e7fe55> <mcrd42nff0f.fsf@dhcp-172-17-9-151.mtv.corp.google.com> <20091214184048.GB7087@gmx.de>
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