From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: AS22989 209.51.188.0/24 X-Spam-Status: No, score=-4.0 required=3.0 tests=AWL,BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, RCVD_IN_DNSWL_LOW,SPF_HELO_NONE,SPF_PASS shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dcvr.yhbt.net (Postfix) with ESMTPS id C25371F619 for ; Mon, 24 Feb 2020 02:27:55 +0000 (UTC) Received: from localhost ([::1]:58844 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j63TO-0001zi-IE for normalperson@yhbt.net; Sun, 23 Feb 2020 21:27:54 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:52626) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j63TK-0001zb-Ce for bug-gnulib@gnu.org; Sun, 23 Feb 2020 21:27:51 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1j63TJ-0003zO-7O for bug-gnulib@gnu.org; Sun, 23 Feb 2020 21:27:50 -0500 Received: from mo6-p00-ob.smtp.rzone.de ([2a01:238:20a:202:5300::2]:24134) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1j63TI-0003yK-Iq for bug-gnulib@gnu.org; Sun, 23 Feb 2020 21:27:49 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1582511265; s=strato-dkim-0002; d=clisp.org; h=References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: X-RZG-CLASS-ID:X-RZG-AUTH:From:Subject:Sender; bh=u7P8kBYPD+9AAx5PMy6td6OIs5gTr4sPAd4pGtWvZ6I=; b=OeSZQmmbYG6ZvPQN0QHq/dSaM8r8ly18olncXH+j3dSrXf+3YBmMyHfmfawMUiiVMF /2octGEZpshC/cFu/40MdC1U6cIoojQfZ6mFtlmFF1rEkNh9d2XbqXHHJ1eZgEoaKihq 13eRJcO9nR8Xy3q8TTwCcpwBJ8RlmZBKWMzpHmQrA6sn0kJpMRG1zXdufyuAl/2jGKU2 q4z54+8su12sSSH/lo06Rig6uvkV3cbb7Zy3aS5gS/3XDwX1os5+pAOQXJ7CMekQPX/I eaT8Da6R8+PyCHK7fkg4UZwwFg4iPd8AkeiMRSFCjYg1fKCP8g7oq3mBfWZVzraGYUfQ mFkw== X-RZG-AUTH: ":Ln4Re0+Ic/6oZXR1YgKryK8brlshOcZlIWs+iCP5vnk6shH+AHjwLuWOH6fzxfs=" X-RZG-CLASS-ID: mo00 Received: from bruno.haible.de by smtp.strato.de (RZmta 46.1.12 DYNA|AUTH) with ESMTPSA id g00701w1O2Rhiqs (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (curve X9_62_prime256v1 with 256 ECDH bits, eq. 3072 bits RSA)) (Client did not present a certificate); Mon, 24 Feb 2020 03:27:43 +0100 (CET) From: Bruno Haible To: Paul Eggert Subject: Re: overriding glibc stub functions Date: Mon, 24 Feb 2020 03:27:43 +0100 Message-ID: <2067295.439v2BxDju@omega> User-Agent: KMail/5.1.3 (Linux/4.4.0-171-generic; KDE/5.18.0; x86_64; ; ) In-Reply-To: <3d21d85b-975d-f67c-d555-e41abf44743b@cs.ucla.edu> References: <20200213184209.34020-1-eggert@cs.ucla.edu> <2690728.gVUGnRkd8D@omega> <3d21d85b-975d-f67c-d555-e41abf44743b@cs.ucla.edu> MIME-Version: 1.0 Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="us-ascii" X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2a01:238:20a:202:5300::2 X-BeenThere: bug-gnulib@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Gnulib discussion list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: bug-gnulib@gnu.org Errors-To: bug-gnulib-bounces+normalperson=yhbt.net@gnu.org Sender: "bug-gnulib" Paul Eggert wrote: > On 2/23/20 2:58 AM, Bruno Haible wrote: > > the file doc/glibc-functions/lchmod.texi still says > > > > ... > > This function always fails with @code{errno} set to @code{ENOSYS}, > > even when the file is not a symbolic link: > > GNU/Linux with glibc 2.31. > > > > Overriding the system's lchmod function requires the case REPLACE_LCHMOD=1. > > Hmm, why? 'configure' says that GNU/Linux functions that always fail with > errno==ENOSYS do not exist, i.e., 'configure' sets HAVE_LCHMOD=0 on GNU/Linux. > This convention is used often by Autoconf and Gnulib. And if HAVE_LCHMOD=0 why > would we want REPLACE_LCHMOD=1? Ouch. I had completely forgotten about this. Yes, lchmod is defined as a stub in glibc/Linux: $ nm --dynamic /lib/x86_64-linux-gnu/libc.so.6 | grep lchmod 00000000000f6f40 T lchmod $ grep lchmod /usr/include/x86_64-linux-gnu/gnu/stubs-64.h #define __stub_lchmod And, as you say, this leads to HAVE_LCHMOD=0. But why do we to distinguish 'lchmod' and 'rpl_lchmod' when we are overriding lchmod? For three reasons: 1) So that there is no conflict when linking statically. 2) So that the behaviour is reliable, and does not break when '-lc' occurs in the link command line (or as dependency of other shared libraries on the link command line). 3) So that when debugging with gdb, you know where you are. Test case for 1): $ gcc -Wall -O2 -c main.c $ gcc -Wall -O2 -c lib.c $ gcc -static main.c lib.c -o main1 $ gcc -static main.c lib.c -lc -o main2 $ gcc -static main.c -lc lib.c -o main3 /tmp/ccPmrK5B.o: In function `main': main.c:(.text+0x1a): warning: lchmod is not implemented and will always fail /tmp/ccJXO5KR.o: In function `lchmod': lib.c:(.text+0x0): multiple definition of `lchmod' /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libc.a(lchmod.o):(.text+0x0): first defined here collect2: error: ld returned 1 exit status Test case for 2): $ gcc -Wall -O2 -c main.c $ gcc -Wall -O2 -fPIC -c lib.c $ gcc -shared -o libfoo.so lib.o $ gcc main.c -o main1 $ gcc main.c -L. -lfoo -o main2 $ gcc main.c -L. -lc -lfoo -o main3 $ touch foo $ ./main1 => lchmod -> -1 $ LD_LIBRARY_PATH=. ./main2 => lchmod -> 0 $ LD_LIBRARY_PATH=. ./main3 => lchmod -> -1 (main.c and lib.c are attached below.) 3) is relatively unimportant, but * 1) is important if we don't want to receive bug reports from people who do embedded systems (OpenWRT and such), and * 2) is important for projects that use gnulib in shared libraries (from gettext to guile) and don't use the [expensive] renaming of symbols in the shared library. (For example, in libunistring, lchmod would be renamed to libunistring_lchmod, thus eliminating the conflict. But not all libraries do this.) Therefore I think we need to do two things: * For those functions that may be stubs in glibc, define HAVE_FUNC to 1 instead of 0 if glibc implements it as a stub. * Reinstall (at least partially) the code for REPLACE_LCHMOD=1. Bruno =================================== main.c =================================== #include #include int main (int argc, char *argv[]) { int ret = lchmod ("foo", 0444); printf ("lchmod -> %d\n", ret); } =================================== lib.c =================================== #include /* This function is intended to override the libc function. */ int lchmod (const char *file, mode_t mode) { return chmod (file, mode); }