Behavior change, PLT entries for R_X86_64_PLT32 relocations with undefined symbol

Martin McClure martin.mcclure@gemtalksystems.com
Mon Mar 25 21:14:00 GMT 2019


On 3/25/19 12:32 PM, Martin McClure wrote:
> On 3/25/19 12:28 PM, Michael Matz wrote:
>> Hi,
>>
>> On Tue, 19 Mar 2019, H.J. Lu wrote:
>>
>>>> library.c
>>>>
>>>> int answer() {
>>>>       return 42;
>>>> }
>>>>
>>>> ----
>>>>
>>>> executable.c
>>>>
>>>> #include <dlfcn.h>
>>>>
>>>> int answer();
>>>>
>>>> int main()
>>>> {
>>>>       void *lib = dlopen("./library.so", RTLD_LAZY | RTLD_GLOBAL);
>>>>       if (!lib) {
>>>>           printf("dlopen failed");
>>>>       }
>>>>       printf("The answer is %d\n", answer());
>>>>       return 0;
>>>> }
>>>
>>> Since answer is undefined, its behavior is undefined.
>>
>> You're making this sound more clear-cut than it is, and I disagree with
>> it.  Clearly, at runtime, the symbol 'answer' is resolvable just fine, 
>> the
>> loaded library contains a global definition.  So with lazy resolution 
>> it'd
>> work.  Note that the user explicitely requested the acceptance of
>> unresolved symbols with --unresolved-symbols=ignore-all (and did not
>> request non-lazy loading), so I would fully expect that unresolved global
>> symbols will be made dynamic symbols even for executables.
>>
>> Martin: there is a work around for you for now: declare the functions in
>> question as weak in the objects making use of them:
>>
>> ------
>> int answer() __attribute__((weak));
>> ...
>>       printf("The answer is %d\n", answer());
>> ...
>> ------
>>
>> You might or might not have to use the '-z dynamic-undefined-weak' link
>> editor option for this to work.
>>
> 
> Thanks, Michael. I believe I tried making the symbol weak, and it failed 
> to work, but I may have done it wrong, and I probably did not use '-z 
> dynamic-undefined-weak', so I'll try again.

Using the weak symbol worked nicely -- thanks again! The '-z 
dynamic-undefined-weak' option was not required. I like this better than 
our previous use of --unresolved-symbols=ignore-all since that did not 
detect misspelled function names until runtime.

Is there any drawback to using weak symbols? I don't expect any strong 
symbols with these names to be defined anywhere outside of the 
dynamically loaded library.

Is there any better way to implement this kind of pattern? I looked for 
an option something like -l to link a dynamic library, but that unlike 
-l did not add a DT_NEEDED entry for the library, so the specific 
library could be specified at runtime. However, if there is such an 
option I did not find it.

Regards,
-Martin



More information about the Binutils mailing list