From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 43436 invoked by alias); 13 Jun 2016 15:28:07 -0000 Mailing-List: contact gnu-gabi-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Post: List-Help: List-Subscribe: Sender: gnu-gabi-owner@sourceware.org Received: (qmail 42534 invoked by uid 89); 13 Jun 2016 15:28:05 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Checked: by ClamAV 0.99.1 on sourceware.org X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.4 required=5.0 tests=AWL,BAYES_00,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=ham version=3.3.2 spammy=anti, fno-plt, fnoplt, Deferred X-Spam-Status: No, score=-2.4 required=5.0 tests=AWL,BAYES_00,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=ham version=3.3.2 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on sourceware.org X-Spam-Level: X-HELO: mail-io0-f179.google.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:subject:reply-to:references:organization:to:cc:message-id:date :user-agent:mime-version:in-reply-to:content-transfer-encoding; bh=sJ3dsEBj1vLknUoZFhYw/VrVyyCSpLPWQzwNMqJtAMg=; b=ZZR2JtND9RtaSjfMCdpzp8LTEe66QpYXyWLVFVXCWnH9Ad0PrKsljmSWtO9Px6blIc /ZNbMxKMrmSsrRNqt6muZPfuPxB1ESys9rrQfhW0dwG5DKxlb2JkuqsaThzd4hLVerNF 6Yxyu2PwV6lVLdhjofdSX70UiUEkoXvkNtEhYSSBK4lVLscM4F3MmFqlfXeau0XE0STr kWHq1nXNgjZR0g/x4qYyKSyT6Hu9BL6eS6k2Ygy6dD1eI9Qryzkx/rWq0sBI2t9TIWXV NGpEYkVawfr77sCkRiPUpaqVSmOgvgKiWRE8hHOHp6peeFKOGQz1GNlBRKa9+qCerNea WkcQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:subject:reply-to:references:organization:to :cc:message-id:date:user-agent:mime-version:in-reply-to :content-transfer-encoding; bh=sJ3dsEBj1vLknUoZFhYw/VrVyyCSpLPWQzwNMqJtAMg=; b=gErERJEyFBS7Xa17NWsEVuOeK/FSXcVtADy21MaiisjgSHZeGkKxRSUMGLazeCm1uX lAnIS2t4zg6GlXeLR9plwbWBMI4ftPpMBLaKTFo8aNAzdf+0Nm1GpgzlUjqks+o2NSlv 1ve/Aon8CXV5G+rmvWCJ7KA7wvuMmtQy5XRkKI1NNpdhkBzmfI1L8TzFsFAmKkakWoSZ 3tKib/pESRVPLAc/Z6nEu1/ZoqlSIum8J9GwoLxfq3Lku+AyHwm0O7zB2WjpxUL+ySbt jmdTglOlB6Relc7jQiFsFP4v9Jnw88IQQrwPUc63wdekaTe+cR+qBypXTmEPYjdmgaHD e4uQ== X-Gm-Message-State: ALyK8tIxxPTV9Q1aOdzQd/D9i+DLRUfCwvGNZ/tcAspcuT+89hIORxGI0t7My9j6HwLlyg== X-Received: by 10.107.174.5 with SMTP id x5mr23815040ioe.76.1465831671746; Mon, 13 Jun 2016 08:27:51 -0700 (PDT) From: Suprateeka R Hegde Subject: Re: Deferred Binding of Function Pointers in SHLIB Reply-To: hegdesmailbox@gmail.com References: <36cd44e9-9f62-6784-17d8-22dd3c41e9f6@gmail.com> <20160610213649.D8A7B2C39F7@topped-with-meat.com> Organization: HEGDESASPECT To: Roland McGrath Cc: gnu-gabi@sourceware.org Message-ID: Date: Fri, 01 Jan 2016 00:00:00 -0000 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Thunderbird/45.1.1 MIME-Version: 1.0 In-Reply-To: <20160610213649.D8A7B2C39F7@topped-with-meat.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Antivirus: avast! (VPS 160613-0, 13-06-2016), Outbound message X-Antivirus-Status: Clean X-SW-Source: 2016-q2/txt/msg00017.txt.bz2 Thanks for the response. You are right that my observation is incorrect. However something else is the story here. And my requirement/proposal is still valid. Read more inline. On 11-Jun-2016 03:06 AM, Roland McGrath wrote: > I think you are confused about what you're observing. Lazy binding > happens only for PLT entries, i.e. for direct function calls. There > is never lazy binding for data initializers like your example uses. Yes, I got confused. Coming after a decade of work on a platform where PIC is default, I missed adding -fpic while creating the executable. And I thought -fpic is default. That is the difference that confused me. In addition I was lazy enough not to debug, but to rely on messages of the dynamic linker. This is what happened: In executable, --- $ cat exe.c #include extern void foo(void); void (*func_p)(void) = NULL; int main() { printf("printf()\n"); func_p = foo; (*func_p)(); return 0; } $ cc exe.c -Wl,--unresolved-symbol=ignore-all $ ./a.out printf() Segmentation fault (core dumped) --- printf() is called and then SEGV. Observe there is no message from dynamic linker at startup regarding UNDEF foo. In contrast, in the shlib case, --- $ cat main.c extern void libmain(void); int main() { libmain(); return 0; } $ cat libmain.c #include extern void foo(void); void (*func_p)(void) = NULL; int libmain() { printf("printf()\n"); func_p = foo; (*func_p)(); return 0; } $ cc -fpic -shared libmain.c -Wl,--unresolved-symbol=ignore-all $ cc main.c -L. -lmain -Wl,--unresolved-symbol=ignore-all $ LD_LIBRARY_PATH=. ./a.out ./a.out: symbol lookup error: ./libmain.so: undefined symbol: foo --- Observe that there is an error message from the dynamic linker at startup even before printf is called. This missing startup message made me think that, in case of executable, there is lazy bind happening. (Sorry I should have debugged it and not relied on the message) Just because of the non-PIC mode for exe, the dynamic linker is deprived of the capability to give out a neat error message and exit gracefully. Had the same executable been built with -fpic, the result would have been same -- error message from the dynamic linker: --- $ cc exe.c -Wl,--unresolved-symbol=ignore-all $ ./a.out ./a.out: symbol lookup error: ./a.out: undefined symbol: foo --- However, the story does not end here. I make a minor change to exe.c: --- $ cat exe.c #include extern void foo(void); void (*func_p)(void) = foo; /* func_p initialized before main */ int main() { printf("printf()\n"); (*func_p)(); return 0; } $ cat libfoo.c #include void foo(void) { printf("In Foo\n"); } $ cc -fpic -shared libfoo.c -o libfoo.so $ cc exe.c -L. -lfoo --- After the exe build, change libfoo.c and make foo() as bar(), but keep the name of shlib same -- libfoo.so. What I did is, provide a well defined foo() during link edit time. But remove foo() at runtime. Then I see: --- $ LD_LIBRARY_PATH=. ./a.out printf() ./a.out: symbol lookup error: ./a.out: undefined symbol: foo LD_BIND_NOW=1 LD_LIBRARY_PATH=. ./a.out ./a.out: symbol lookup error: ./a.out: undefined symbol: foo --- Observe that without LD_BIND_NOW, lazy bind is happening. With LD_BIND_NOW, its all at startup and hence printf() is not even called. Now, convert this modified exe.c into a shlib as before, and again remove foo at runtime. Then, there is no lazy bind at all. I see: --- $ LD_LIBRARY_PATH=. ./a.out ./a.out: symbol lookup error: ./libmain.so: undefined symbol: foo --- So, observing all these, it is all about whether foo gets a JUMP_SLOT reloc or not. In other words, foo gets a PLT or not (?). What I want to propose is that the behavior should be consistent across exe and shlib. However, It is not the case as seen above. Is there any anti option to -fno-plt of GCC6 :-) > Your use of -Wl,--unresolved-symbols=ignore-all means that the > non-shared case (libmain.c as executable) is simply mis-linked. (If > you remove that switch, then the link will fail to complete and you > can never get a binary to run.) Not really. One can get the symbols at runtime too. Not everything need to be resolved at link-edit time. For instance, using LD_PRELOAD, dlopen-with-RTLD_GLOBAL, etc. (See my thread on GNU dlopen vs POSIX/IEEE on the mailing list: https://sourceware.org/ml/gnu-gabi/2016-q2/msg00015.html) My real case is as follows: I have an executable with hundreds of function pointers as an array. Functions are called using array index which depends on the arguments passed to the executable. This executable is short lived and in each invocation calls only one function. Without lazy bind, all these function pointers are being resolved at startup. This increases startup time which becomes significant given the fact that the executable is very short lived. -- Supra