From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pg1-x535.google.com (mail-pg1-x535.google.com [IPv6:2607:f8b0:4864:20::535]) by sourceware.org (Postfix) with ESMTPS id F2DFC383B7B4 for ; Fri, 27 May 2022 19:24:52 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org F2DFC383B7B4 Received: by mail-pg1-x535.google.com with SMTP id 129so420828pgc.2 for ; Fri, 27 May 2022 12:24:52 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=33Rv0t2ySRfRZ1F9Cv+uOAixw9yW09L+7F8eJl5hIPc=; b=4ynm1uhfDQHu8sRZ1eMSPBaZZxPpTVoAFaGQhlQU3xlx+adfuLiGuKrruS+iEk9IjV Foxzaz9tWELR6GJYvpOXyp1MMzWI+ne1NZjG6jO07I+F0KHGy/sSF8RGohOzr95Q0ZDO yPDp467U0SxpOMylJfeDHy23gI8tC3reo1mOqE1CSINEzCRIfqPv+jrIseM8zFXxTOIE n1WhQqZbJpgpfArHTGn2vAIxUg73hYb56Mwfs6KBwzmNAwlthr3f8yWEf/G1Vj2eQ7MX d6tdGZ6E32AoEJkY53j+wSyG7Tfe6669XYnt4bidncHZq+VLkIv9YlLrWUXYbCIF4UIO JHmA== X-Gm-Message-State: AOAM531yrlyqXdQ56Kevck9bIBzGpP+FSlBOf67fdjOEOsk62gmrRsGt tc54sH81yN8HTxyiOPXcMbjfoqReJtHbnQ== X-Google-Smtp-Source: ABdhPJxOXo4BLcq60dkYvJD4NOGkcKk2FPYzA28bpsFYAyF8Nw/fMumI30odBfD9du6Vwikhcbz1hQ== X-Received: by 2002:a62:e304:0:b0:4fd:ac35:6731 with SMTP id g4-20020a62e304000000b004fdac356731mr5382427pfh.71.1653679491726; Fri, 27 May 2022 12:24:51 -0700 (PDT) Received: from google.com ([2620:15c:2ce:200:781f:286a:7724:6870]) by smtp.gmail.com with ESMTPSA id t2-20020a17090340c200b001622600953bsm14316pld.80.2022.05.27.12.24.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 27 May 2022 12:24:51 -0700 (PDT) Date: Fri, 27 May 2022 12:24:48 -0700 From: Fangrui Song To: Florian Weimer Cc: libc-alpha@sourceware.org Subject: Re: [PATCH] dlsym: Make RTLD_NEXT prefer default version definition [#BZ #14932] Message-ID: <20220527192448.n7bny5g3eyxou5xo@google.com> References: <20220520083507.2368165-1-maskray@google.com> <87k0a7fd9n.fsf@oldenburg.str.redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Disposition: inline In-Reply-To: <87k0a7fd9n.fsf@oldenburg.str.redhat.com> X-Spam-Status: No, score=-27.3 required=5.0 tests=BAYES_00, DKIMWL_WL_MED, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, ENV_AND_HDR_SPF_MATCH, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE, USER_IN_DEF_DKIM_WL, USER_IN_DEF_SPF_WL autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) 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: Fri, 27 May 2022 19:24:54 -0000 On 2022-05-27, Florian Weimer wrote: >I've been looking at this for a while. > >We currently have this code in elf/dl-lookup.c: > > /* No specific version is selected. There are two ways we > can got here: > > - a binary which does not include versioning information > is loaded > > - dlsym() instead of dlvsym() is used to get a symbol which > might exist in more than one form > > If the library does not provide symbol version information > there is no problem at all: we simply use the symbol if it > is defined. > > These two lookups need to be handled differently if the > library defines versions. In the case of the old > unversioned application the oldest (default) version > should be used. In case of a dlsym() call the latest and > public interface should be returned. */ > if (verstab != NULL) > { > if ((verstab[symidx] & 0x7fff) > >= ((flags & DL_LOOKUP_RETURN_NEWEST) ? 2 : 3)) > { > /* Don't accept hidden symbols. */ > if ((verstab[symidx] & 0x8000) == 0 > && (*num_versions)++ == 0) > /* No version so far. */ > *versioned_sym = sym; > > return NULL; > } > } > >The numbers 2 and 3 look suspicious. The condition involving >num_versions ensures that we only store the first matching symbol in >*versioned_sym. But the skipped version indices are not special. >Indices are not specific to individual symbols, so it is no clear that >index 2 is special and contains the oldest possible version for that >particular symbol, and the next index will have the latest version. > >Aligning dlvsym with dlsym still makes sense, so I suggest to proceed >with this patch. But I think there are more bugs in this area. > >> diff --git a/elf/nextmod3.c b/elf/nextmod3.c >> new file mode 100644 >> index 0000000000..96608a65c0 >> --- /dev/null >> +++ b/elf/nextmod3.c >> @@ -0,0 +1,19 @@ >> +int >> +foo_v1 (int a) >> +{ >> + return 1; >> +} >> +asm (".symver foo_v1, foo@v1"); >> + >> +int >> +foo_v2 (int a) >> +{ >> + return 2; >> +} >> +asm (".symver foo_v2, foo@v2"); >> + >> +int >> +foo (int a) >> +{ >> + return 3; >> +} > >Please set foo@@v3 explicitly. Ack. Having asm (".symver foo, foo@@@v3") is clearer, though it is redundant since the version script specifies foo in the v3 version node. >> diff --git a/elf/nextmod3.map b/elf/nextmod3.map >> new file mode 100644 >> index 0000000000..0a8e4e4ee3 >> --- /dev/null >> +++ b/elf/nextmod3.map >> @@ -0,0 +1,3 @@ >> +v1 { }; >> +v2 { }; >> +v3 { foo; }; > >These versions are not ordered. Maybe use this instead? > >v1 { }; >v2 { } v1; >v3 { foo; } v2; The dependencies are a no-op in lld but tracks version definition dependencies in GNU ld and gold (see readelf -V output: `Parent 1`). The vd_cnt member is ignored in glibc and FreeBSD rtld, so omitting it should be fine. That said, I'll add it...