This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: Behavior change, PLT entries for R_X86_64_PLT32 relocations with undefined symbol
- From: "H.J. Lu" <hjl dot tools at gmail dot com>
- To: Martin McClure <martin dot mcclure at gemtalksystems dot com>
- Cc: Binutils <binutils at sourceware dot org>
- Date: Tue, 19 Mar 2019 14:30:19 +0800
- Subject: Re: Behavior change, PLT entries for R_X86_64_PLT32 relocations with undefined symbol
- References: <6d93d4f6-40af-b73f-5c58-9bb77a55b13d@gemtalksystems.com>
On Tue, Mar 19, 2019 at 10:08 AM Martin McClure
<martin.mcclure@gemtalksystems.com> wrote:
>
> tl;dr: The linker produced PLT entries for undefined symbols with
> R_X86_64_PLT32 relocations up through Ubuntu 16.04; but produces calls
> to empty PLT entries in Ubuntu 18.04. Has this usage ever been legal,
> and if so how can it be made to work now?
>
> (very simplified) reproduction case, x86_64:
>
> ----
>
> 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;
> }
>
> ----
>
>
> Compile and link:
>
> gcc -fpic library.c -c -o library.o
> gcc -shared -o library.so library.o
>
> gcc -c -fPIC executable.c -o executable.o
> gcc executable.o -lc -ldl -Wl,--unresolved-symbols=ignore-all -o executable
>
> ---
>
> This produces a functional executable in Ubuntu versions up to and
> including 16.04 (gcc 5.4.0, ld 2.26.1) but fails in Ubuntu 18.04 (gcc
> 7.3.0, ld 2.30). Another difference is that Ubuntu 18.04 configures with
> --enable-default-pie. Full configuration info below for reference.
>
> In the success case, ld produces a PLT entry for the symbol "answer" and
> the call to answer() goes to that entry.
> In the failure case, the call to answer() goes to an offset in the PLT,
> but that offset in the PLT is empty (zeroes).
>
> THE QUESTION: Is it supported usage to expect the linker to produce a
> PLT entry from a R_X86_64_PLT32 relocation, even if the symbol is
> undefined? And if so, is the failure I'm seeing a matter of incorrect
> invocation, or a bug?
>
> Why do I want this to work? The code base I work with has been using
> this for quite a few years (long before I got involved). There are two
> shared libraries that each implement the same few hundred functions, but
> implement them differently (one locally, the other via RPC). By having
> the executable dlopen() the version it wants to use, it can choose the
> implementation at runtime rather than at link time.
Since answer is undefined, its behavior is undefined.
--
H.J.