From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pf1-x443.google.com (mail-pf1-x443.google.com [IPv6:2607:f8b0:4864:20::443]) by sourceware.org (Postfix) with ESMTPS id AD6603877011 for ; Mon, 16 Mar 2020 15:47:11 +0000 (GMT) Received: by mail-pf1-x443.google.com with SMTP id z65so10150253pfz.8 for ; Mon, 16 Mar 2020 08:47:11 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=+V3t/GrP1yhEvHLBgrtOsuBDKhXDXmZf1c9x4fIm1O8=; b=og3rto1UDH5GYNfzv+EN+KPTVUfrZ9suDGGaYVT6p08FuuGiAMWijHOeykIEHnr5z2 P84pjZRh8kCKwoNlgrKv+avTcEiQQ3jKUL1yQm9RmPPrCs8VjQNp3HSOqEW3QQTO8d5r QSY25BjAdR8Z5m3D5ZC4O2tiT4PjEsGTfUybK2rYGu7v2l8eQ+1RX1SWb89pm8RIXEFH pHy8qtEjvydD5Ir5Qw4M9+co526P+h/Wr3XtpOSN+OA0r0kElBbUsb4TVo6Fs3ofIsEp OLh/0656/0Oral2IvQJOOJS2juxthFfnI+C+rfHfNROxC1V+O2hdnzxm0Dl68VPrU+2v 07FQ== X-Gm-Message-State: ANhLgQ0zXqe88ak8z4AeBbkfrd9EJDd+jQ8KVU/d8Kmtzo+ph7ZLdcuY 5m9IjEjHn99DgXFXWr/XyXSWDQ== X-Google-Smtp-Source: ADFU+vvftE/q5dp5mXVkerkwIxLd50pmln2Sj6+yIQZWXEoxr4S3trQUU5YaFoXQJ8ryhGptcHHmrQ== X-Received: by 2002:a62:aa19:: with SMTP id e25mr262066pff.302.1584373630488; Mon, 16 Mar 2020 08:47:10 -0700 (PDT) Received: from google.com ([2620:15c:2ce:0:9efe:9f1:9267:2b27]) by smtp.gmail.com with ESMTPSA id c190sm33212pga.35.2020.03.16.08.47.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 16 Mar 2020 08:47:09 -0700 (PDT) Date: Mon, 16 Mar 2020 08:47:06 -0700 From: Fangrui Song To: "H.J. Lu" Cc: Binutils , GNU C Library , Florian Weimer Subject: Re: Suppress the fetch of an archive member via --defsym (glibc/elf/librtld.map.o) Message-ID: <20200316154706.fblgnhpezjggiugx@google.com> References: <20200316045859.hq76yfsdqiupjgiy@google.com> <20200316050202.pql3syb2imduinf7@google.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Disposition: inline In-Reply-To: X-Spam-Status: No, score=-15.5 required=5.0 tests=DKIMWL_WL_MED, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, ENV_AND_HDR_SPF_MATCH, FSL_HELO_FAKE, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, USER_IN_DEF_DKIM_WL, USER_IN_DEF_SPF_WL autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 16 Mar 2020 15:47:13 -0000 On 2020-03-16, H.J. Lu wrote: >On Sun, Mar 15, 2020 at 10:02 PM Fangrui Song via Libc-alpha > wrote: >> >> On 2020-03-15, Fangrui Song wrote: >> >cd /tmp/p >> >git clone git://sourceware.org/git/glibc.git; cd glibc >> >mkdir Release; ../configure --prefix=/tmp/opt >> >make -j >> > >> >When linking elf/librtld.map.o >> > >> >% gcc -nostdlib -nostartfiles -r -o /tmp/p/glibc/Release/elf/librtld.map.o -Wl,--defsym=calloc=0 -Wl,--defsym=free=0 -Wl,--defsym=malloc=0 -Wl,--defsym=realloc=0 -Wl,--defsym=__stack_chk_fail=0 -Wl,--defsym=__stack_chk_fail_local=0 '-Wl,-(' /tmp/p/glibc/Release/elf/dl-allobjs.os /tmp/p/glibc/Release/libc_pic.a -lgcc '-Wl,-)' -Wl,-Map,/tmp/p/glibc/Release/elf/librtld.mapT >> > >> >Without -Wl,defsym: >> > >> >dl-allobjs.os has an undefined __libc_scratch_buffer_set_array_size >> >__libc_scratch_buffer_set_array_size fetches libc_pic.a(scratch_buffer_set_array_size.os) >> >libc_pic.a(scratch_buffer_set_array_size.os) has an undefined free >> >free fetches libc_pic.a(malloc.os) >> >libc_pic.a(malloc.os) has an undefined __libc_message >> >__libc_message fetches libc_pic.a(libc_fatal.os) >> > >> >libc_fatal.os will cause a multiple definition error (__GI___libc_fatal) >> >>>>defined at dl-fxstatat64.c >> >>>> /tmp/p/glibc/Release/elf/dl-allobjs.os:(__GI___libc_fatal) >> >>>>defined at libc_fatal.c >> >>>> libc_fatal.os:(.text+0x240) in archive /tmp/p/glibc/Release/libc_pic.a >> > >> >glibc/elf/Makefile uses -Wl,--defsym= (rtld-stubbed-symbols) to suppress libc_pic.a(malloc.os): >> > >> >% readelf -s elf/librtld.map.o | grep ABS | grep -v LOCAL >> > 712: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS __stack_chk_fail_local >> > 826: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS malloc >> > 876: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS __stack_chk_fail >> > 905: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS calloc >> > 975: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS realloc >> > 1174: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS free >> > >> >My question is: does the suppression via --defsym work reliably? >> > >> ># a.o >> >call foo >> > >> ># b.a(b.o) >> >.globl foo, free >> >foo: >> >free: >> > >> > >> ># GNU ld --defsym is order dependent. >> >ld.bfd a.o b.a --defsym foo=0 # b.a(b.o) is fetched. free is present >> >ld.bfd --defsym foo=0 a.o b.a # b.a(b.o) is not fetched. free is absent >> > >> ># gold --defsym is order independent. For the more complex glibc elf/librtld.map.o case, it happens to match GNU ld. >> >gold a.o b.a --defsym foo=0 # b.a(b.o) is not fetched. free is absent >> >gold --defsym foo=0 a.o b.a # b.a(b.o) is not fetched. free is absent >> > >> ># lld --defsym is order independent. --defsym is processed the last. For elf/librtld.map.o it will report a multiple definition error. >> ># https://sourceware.org/pipermail/libc-alpha/2020-March/111899.html is required to bypass a configure check >> >ld.lld a.o b.a --defsym foo=0 # b.a(b.o) is not fetched. free is absent >> >ld.lld --defsym=0 a.o b.a # b.a(b.o) is not fetched. free is absent >> >> Sorry, clarify the behavior of lld. >> >> # lld --defsym is order independent. --defsym is processed the last. For elf/librtld.map.o it will report a multiple definition error. >> ld.lld a.o b.a --defsym foo=0 # b.a(b.o) is fetched. free is present >> ld.lld --defsym=0 a.o b.a # b.a(b.o) is fetched. free is present > >Glibc build requires a linker compatible with ld. Can you provide an lld >option to make lld compatible with ld for cases like this? As a contributor of lld, I would be cooperative and be happy to adapt lld if the proposed semantic is reasonable. I am concerned that the --defsym's order dependence with archive files is not so obvious, given -u's behavior: # -u inserts an undefined which fetches b.a(b.o) ld.bfd -u foo b.a # b.a(b.o) is fetched. free is present # This can't be order dependent because b.a (not in a group) should have been dropped when we saw -u ld.bfd b.a -u foo # b.a(b.o) is fetched. free is present Some observations: # GNU ld --defsym interacts with an archive ld.bfd a.o b.a --defsym foo=0 # b.a(b.o) is fetched. free is present ld.bfd --defsym foo=0 a.o b.a # b.a(b.o) is not fetched. free is absent # a.x contains one line `foo = 0;` # -T a.x is similar to --defsym ld.bfd a.o b.a -T a.x -o a # b.a(b.o) is fetched. free is present ld.bfd -T a.x a.o b.a -o a # b.a(b.o) is not fetched. free is absent # -u is usually order independent # The second can't be order dependent because b.a should have been dropped when we see -u ld.bfd -u foo b.a # b.a(b.o) is fetched. free is present ld.bfd b.a -u foo # b.a(b.o) is fetched. free is present # gold --defsym is order independent. For the more complex glibc elf/librtld.map.o case, it happens to make it work gold a.o b.a --defsym foo=0 # b.a(b.o) is not fetched. free is absent gold --defsym foo=0 a.o b.a # b.a(b.o) is not fetched. free is absent # gold --export-dynamic-symbol (not in GNU ld) implies -u gold --export-dynamic-symbol foo b.a # b.a(b.o) is fetched. free is present gold b.a --export-dynamic-symbol foo # b.a(b.o) is fetched. free is present # lld --defsym is order independent. --defsym is processed the last. For elf/librtld.map.o it will report a multiple definition error. ld.lld a.o b.a --defsym foo=0 # b.a(b.o) is fetched. free is present ld.lld --defsym=0 a.o b.a # b.a(b.o) is fetched. free is present If we aim for robustness and make the librtld.map.o trick supported (I will add a note that gold happens to work), I will hope both the following can suppress b.a(b.o): ld.bfd a.o b.a --defsym foo=0 ld.bfd --defsym foo=0 a.o b.a (a) Given --defsym's similarity to a symbol assignment specified by a -T, we will hope -T does not behave too differently. (b) Note that in a linker script, at least input files should be order dependent w.r.t. input files on the command line. (a)+(b) => symbol assignments specified by -T need to be declared early but input files specified -T are ordered w.r.t. input files on the command line. For linker portability, projects using this trick (currently glibc is the only one) should place --defsym first to work with existing releases of GNU ld. The added librtld.map.o code is related to https://sourceware.org/bugzilla/show_bug.cgi?id=25486