From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 103472 invoked by alias); 10 Jun 2016 21:36:53 -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 103378 invoked by uid 89); 10 Jun 2016 21:36:52 -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=0.5 required=5.0 tests=BAYES_05,KAM_LAZY_DOMAIN_SECURITY autolearn=no version=3.3.2 spammy=H*F:U*roland, HX-Envelope-From:sk:roland@, Hx-languages-length:1434, Deferred X-Spam-Status: No, score=0.5 required=5.0 tests=BAYES_05,KAM_LAZY_DOMAIN_SECURITY autolearn=no version=3.3.2 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on sourceware.org X-Spam-Level: X-HELO: topped-with-meat.com MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit From: Roland McGrath To: hegdesmailbox@gmail.com Cc: gnu-gabi@sourceware.org Subject: Re: Deferred Binding of Function Pointers in SHLIB In-Reply-To: Suprateeka R Hegde's message of Sunday, 5 June 2016 12:58:34 +0530 <36cd44e9-9f62-6784-17d8-22dd3c41e9f6@gmail.com> References: <36cd44e9-9f62-6784-17d8-22dd3c41e9f6@gmail.com> X-Zippy-Says: Yow! I'm out of work...I could go into shock absorbers...or SCUBA GEAR!! Message-Id: <20160610213649.D8A7B2C39F7@topped-with-meat.com> Date: Fri, 01 Jan 2016 00:00:00 -0000 X-CMAE-Score: 0 X-CMAE-Analysis: v=2.1 cv=Tvt12lnh c=1 sm=1 tr=0 a=WkljmVdYkabdwxfqvArNOQ==:117 a=L9H7d07YOLsA:10 a=9cW_t1CCXrUA:10 a=s5jvgZ67dGcA:10 a=kj9zAlcOel0A:10 a=vo4HKTR7EiA1G9iPUJwA:9 a=CjuIK1q_8ugA:10 X-SW-Source: 2016-q2/txt/msg00013.txt.bz2 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. 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.) After linking it's as if you'd instead had "void (*func_p)(void) = 0;" in the source. No kind of binding at all happens at runtime. The reason you saw the output from printf is because there was no kind of symbol resolution happening at all, and so nothing to fail at startup--your program starts up fine, does what it does, and only crashes when it tries to call the function pointer with value 0. In the shared library case, foo is left undefined in the DSO. The same would happen without --unresolved-symbols=ignore-all. (To see link-time checking for apparent definedness of referenced symbols, use -Wl,-z,defs.) Because the reference to foo is in a data initializer rather than a PLT entry (i.e., what you'd get if main had the line "foo();"), it has to be resolved at startup time by the dynamic linker before any of your code runs at all. Since that resolution fails, the dynamic linker bails out before even trying to start your program.