From patchwork Thu May 18 08:28:41 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: stsp X-Patchwork-Id: 69572 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 239B838432D3 for ; Thu, 18 May 2023 08:30:10 +0000 (GMT) X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from forward103c.mail.yandex.net (forward103c.mail.yandex.net [178.154.239.214]) by sourceware.org (Postfix) with ESMTPS id 5FB403858401 for ; Thu, 18 May 2023 08:29:40 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 5FB403858401 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=yandex.ru Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=yandex.ru Received: from mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net (mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net [IPv6:2a02:6b8:c0c:1186:0:640:38cb:0]) by forward103c.mail.yandex.net (Yandex) with ESMTP id 5F1FB60038 for ; Thu, 18 May 2023 11:29:36 +0300 (MSK) Received: by mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net (smtp/Yandex) with ESMTPSA id XTYe39MDZ0U0-tVq8fXHb; Thu, 18 May 2023 11:29:35 +0300 X-Yandex-Fwd: 1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex.ru; s=mail; t=1684398576; bh=iHrAj+A96jpxuZEsITgfoiq2qX9luYidOz5DXAZ/4Lk=; h=Message-Id:Date:In-Reply-To:Cc:Subject:References:To:From; b=GvAz1Zz/4Fwtiaico/7YVEbD67sXOCKa8TZmFG0socDaHA5bBBcZr+bZccj5qIPR2 m33QXTqoIud3+6/quMNsOPBQfvR7zoaCdlW2H57jAtCH6XjawUZwXXjqBFloSK1wqv Q3W3z+/1bqcs35TuNt8EBWB/qkdViH+azEu8eiPE= Authentication-Results: mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net; dkim=pass header.i=@yandex.ru From: Stas Sergeev To: libc-alpha@sourceware.org Cc: Stas Sergeev Subject: [PATCH 01/14] elf: switch _dl_map_segment() to anonymous mapping Date: Thu, 18 May 2023 13:28:41 +0500 Message-Id: <20230518082854.3903342-2-stsp2@yandex.ru> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230518082854.3903342-1-stsp2@yandex.ru> References: <20230518082854.3903342-1-stsp2@yandex.ru> MIME-Version: 1.0 X-Spam-Status: No, score=-10.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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: , Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" _dl_map_segment() was mapping entire file image and then was skipping the load of the first segment. Switch _dl_map_segment() to anonymous mapping and do not skip the map of the first segment. Use PROT_READ|PROT_WRITE as a protection. _dl_map_segments() later sets the proper protection for both file-mapped and anonymous parts. The test-suite was run on x86_64/64 and showed no regressions. Signed-off-by: Stas Sergeev --- elf/dl-map-segments.h | 69 ++++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 34 deletions(-) diff --git a/elf/dl-map-segments.h b/elf/dl-map-segments.h index 504cfc0a41..ed7675cabf 100644 --- a/elf/dl-map-segments.h +++ b/elf/dl-map-segments.h @@ -22,18 +22,22 @@ /* Map a segment and align it properly. */ static __always_inline ElfW(Addr) -_dl_map_segment (const struct loadcmd *c, ElfW(Addr) mappref, - const size_t maplength, int fd) +_dl_map_segment (ElfW(Addr) mappref, size_t maplength, size_t mapalign) { - if (__glibc_likely (c->mapalign <= GLRO(dl_pagesize))) - return (ElfW(Addr)) __mmap ((void *) mappref, maplength, c->prot, - MAP_COPY|MAP_FILE, fd, c->mapoff); + int err; + /* MAP_COPY is a special flag combination for solibs. */ + unsigned int map_flags = MAP_ANONYMOUS | MAP_COPY; + unsigned int prot = PROT_READ | PROT_WRITE; + + if (__glibc_likely (mapalign <= GLRO(dl_pagesize))) + return (ElfW(Addr)) __mmap ((void *) mappref, maplength, prot, + map_flags, -1, 0); /* If the segment alignment > the page size, allocate enough space to ensure that the segment can be properly aligned. */ - ElfW(Addr) maplen = (maplength >= c->mapalign - ? (maplength + c->mapalign) - : (2 * c->mapalign)); + ElfW(Addr) maplen = (maplength >= mapalign + ? (maplength + mapalign) + : (2 * mapalign)); ElfW(Addr) map_start = (ElfW(Addr)) __mmap ((void *) mappref, maplen, PROT_NONE, MAP_ANONYMOUS|MAP_PRIVATE, @@ -41,26 +45,24 @@ _dl_map_segment (const struct loadcmd *c, ElfW(Addr) mappref, if (__glibc_unlikely ((void *) map_start == MAP_FAILED)) return map_start; - ElfW(Addr) map_start_aligned = ALIGN_UP (map_start, c->mapalign); - map_start_aligned = (ElfW(Addr)) __mmap ((void *) map_start_aligned, - maplength, c->prot, - MAP_COPY|MAP_FILE|MAP_FIXED, - fd, c->mapoff); - if (__glibc_unlikely ((void *) map_start_aligned == MAP_FAILED)) - __munmap ((void *) map_start, maplen); - else + ElfW(Addr) map_start_aligned = ALIGN_UP (map_start, mapalign); + err = __mprotect ((void *) map_start_aligned, maplength, prot); + if (__glibc_unlikely (err)) { - /* Unmap the unused regions. */ - ElfW(Addr) delta = map_start_aligned - map_start; - if (delta) - __munmap ((void *) map_start, delta); - ElfW(Addr) map_end = map_start_aligned + maplength; - map_end = ALIGN_UP (map_end, GLRO(dl_pagesize)); - delta = map_start + maplen - map_end; - if (delta) - __munmap ((void *) map_end, delta); + __munmap ((void *) map_start, maplen); + return (ElfW(Addr)) MAP_FAILED; } + /* Unmap the unused regions. */ + ElfW(Addr) delta = map_start_aligned - map_start; + if (delta) + __munmap ((void *) map_start, delta); + ElfW(Addr) map_end = map_start_aligned + maplength; + map_end = ALIGN_UP (map_end, GLRO(dl_pagesize)); + delta = map_start + maplen - map_end; + if (delta) + __munmap ((void *) map_end, delta); + return map_start_aligned; } @@ -98,7 +100,7 @@ _dl_map_segments (struct link_map *l, int fd, - MAP_BASE_ADDR (l)); /* Remember which part of the address space this object uses. */ - l->l_map_start = _dl_map_segment (c, mappref, maplength, fd); + l->l_map_start = _dl_map_segment (mappref, maplength, c->mapalign); if (__glibc_unlikely ((void *) l->l_map_start == MAP_FAILED)) return DL_MAP_SEGMENTS_ERROR_MAP_SEGMENT; @@ -123,14 +125,14 @@ _dl_map_segments (struct link_map *l, int fd, } l->l_contiguous = 1; - - goto postmap; } - - /* Remember which part of the address space this object uses. */ - l->l_map_start = c->mapstart + l->l_addr; - l->l_map_end = l->l_map_start + maplength; - l->l_contiguous = !has_holes; + else + { + /* Remember which part of the address space this object uses. */ + l->l_map_start = c->mapstart + l->l_addr; + l->l_map_end = l->l_map_start + maplength; + l->l_contiguous = !has_holes; + } while (c < &loadcmds[nloadcmds]) { @@ -143,7 +145,6 @@ _dl_map_segments (struct link_map *l, int fd, == MAP_FAILED)) return DL_MAP_SEGMENTS_ERROR_MAP_SEGMENT; - postmap: _dl_postprocess_loadcmd (l, header, c); if (c->allocend > c->dataend) From patchwork Thu May 18 08:28:42 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: stsp X-Patchwork-Id: 69575 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 3E701386D634 for ; Thu, 18 May 2023 08:31:52 +0000 (GMT) X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from forward102b.mail.yandex.net (forward102b.mail.yandex.net [IPv6:2a02:6b8:c02:900:1:45:d181:d102]) by sourceware.org (Postfix) with ESMTPS id AB2D4385770F for ; Thu, 18 May 2023 08:29:41 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org AB2D4385770F Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=yandex.ru Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=yandex.ru Received: from mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net (mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net [IPv6:2a02:6b8:c0c:1186:0:640:38cb:0]) by forward102b.mail.yandex.net (Yandex) with ESMTP id 573986002F for ; Thu, 18 May 2023 11:29:37 +0300 (MSK) Received: by mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net (smtp/Yandex) with ESMTPSA id XTYe39MDZ0U0-HPvlXc7W; Thu, 18 May 2023 11:29:36 +0300 X-Yandex-Fwd: 1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex.ru; s=mail; t=1684398577; bh=ubu1ZoxOk1wyv26aata4LmhupVgv5iNiorgC21pdxiQ=; h=Message-Id:Date:In-Reply-To:Cc:Subject:References:To:From; b=TYgpKsVKYEKhdrbSd4OS72OvUgFjPxXwPPTdiKYx7/OV17fIpgMtfe7GPmsu3InxM 77cpkZtiotb19+BaMfr57ViFdzPKTVoomnP4zpy5goKYXZGtUCho2LwrgmTCnhMgRY bHZLtY9l2B2B8p3ESCxrztQqDw9KHhw5IUyaMvyU= Authentication-Results: mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net; dkim=pass header.i=@yandex.ru From: Stas Sergeev To: libc-alpha@sourceware.org Cc: Stas Sergeev Subject: [PATCH 02/14] use initial mmap also for ET_EXEC Date: Thu, 18 May 2023 13:28:42 +0500 Message-Id: <20230518082854.3903342-3-stsp2@yandex.ru> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230518082854.3903342-1-stsp2@yandex.ru> References: <20230518082854.3903342-1-stsp2@yandex.ru> MIME-Version: 1.0 X-Spam-Status: No, score=-10.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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: , Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" This allows to replace the further anonymous mmaps with mprotect. Which, in turn, will allow to split the protection stage in the subsequent patches. The test-suite was run on x86_64/64 and showed no regressions. Signed-off-by: Stas Sergeev --- elf/dl-map-segments.h | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/elf/dl-map-segments.h b/elf/dl-map-segments.h index ed7675cabf..6a6127f773 100644 --- a/elf/dl-map-segments.h +++ b/elf/dl-map-segments.h @@ -129,7 +129,12 @@ _dl_map_segments (struct link_map *l, int fd, else { /* Remember which part of the address space this object uses. */ - l->l_map_start = c->mapstart + l->l_addr; + l->l_map_start = (ElfW(Addr)) __mmap ((caddr_t) l->l_addr + c->mapstart, + maplength, PROT_NONE, + MAP_ANON|MAP_PRIVATE|MAP_FIXED, + -1, 0); + if (__glibc_unlikely ((void *) l->l_map_start == MAP_FAILED)) + return DL_MAP_SEGMENTS_ERROR_MAP_SEGMENT; l->l_map_end = l->l_map_start + maplength; l->l_contiguous = !has_holes; } @@ -182,13 +187,11 @@ _dl_map_segments (struct link_map *l, int fd, if (zeroend > zeropage) { - /* Map the remaining zero pages in from the zero fill FD. */ - caddr_t mapat; - mapat = __mmap ((caddr_t) zeropage, zeroend - zeropage, - c->prot, MAP_ANON|MAP_PRIVATE|MAP_FIXED, - -1, 0); - if (__glibc_unlikely (mapat == MAP_FAILED)) - return DL_MAP_SEGMENTS_ERROR_MAP_ZERO_FILL; + /* Protect the remaining zero pages. */ + if (__glibc_unlikely (__mprotect ((caddr_t) zeropage, + zeroend - zeropage, + c->prot) < 0)) + return DL_MAP_SEGMENTS_ERROR_MPROTECT; } } From patchwork Thu May 18 08:28:43 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: stsp X-Patchwork-Id: 69573 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 2A44C384A4B7 for ; Thu, 18 May 2023 08:30:43 +0000 (GMT) X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from forward100b.mail.yandex.net (forward100b.mail.yandex.net [178.154.239.147]) by sourceware.org (Postfix) with ESMTPS id 4EFB93858C5F for ; Thu, 18 May 2023 08:29:40 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 4EFB93858C5F Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=yandex.ru Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=yandex.ru Received: from mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net (mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net [IPv6:2a02:6b8:c0c:1186:0:640:38cb:0]) by forward100b.mail.yandex.net (Yandex) with ESMTP id 3A97B60134 for ; Thu, 18 May 2023 11:29:38 +0300 (MSK) Received: by mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net (smtp/Yandex) with ESMTPSA id XTYe39MDZ0U0-7RPYs3dA; Thu, 18 May 2023 11:29:37 +0300 X-Yandex-Fwd: 1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex.ru; s=mail; t=1684398577; bh=4EKnfJMYKMTUXJiSasLrOjAtgw84M7fIw6aUugmmrZs=; h=Message-Id:Date:In-Reply-To:Cc:Subject:References:To:From; b=vRKDwWJLjmMfMx9VxKO8rVZmWUIbBKgQIhDdj73deT0hlzIsG9Q9gB3bSxSp5rvBW XTrL2jJrDXb7pgQjp5NqoWLLzI91c1+dHFgjcJBhF3/wXzgxyOWHKlgxnSMSHggn0N mwAn5lzyTaXr4afrpnUgRurAsgHlqnbQlOzWAmVA= Authentication-Results: mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net; dkim=pass header.i=@yandex.ru From: Stas Sergeev To: libc-alpha@sourceware.org Cc: Stas Sergeev Subject: [PATCH 03/14] rework maphole Date: Thu, 18 May 2023 13:28:43 +0500 Message-Id: <20230518082854.3903342-4-stsp2@yandex.ru> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230518082854.3903342-1-stsp2@yandex.ru> References: <20230518082854.3903342-1-stsp2@yandex.ru> MIME-Version: 1.0 X-Spam-Status: No, score=-10.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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: , Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" Remove "has_holes" argument that was used to mprotect the entire initial mapping as PROT_NONE. Instead apply PROT_NONE at each individual hole. This is needed to make it possible to split the protection stage from mmap stage. The test-suite was run on x86_64/64 and showed no regressions. Signed-off-by: Stas Sergeev --- elf/dl-load.c | 8 +++---- elf/dl-load.h | 3 +-- elf/dl-map-segments.h | 52 ++++++++++++++++++++++++++----------------- 3 files changed, 36 insertions(+), 27 deletions(-) diff --git a/elf/dl-load.c b/elf/dl-load.c index 39c63ff1b3..4007a4aae3 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -1089,7 +1089,6 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, /* Scan the program header table, collecting its load commands. */ struct loadcmd loadcmds[l->l_phnum]; size_t nloadcmds = 0; - bool has_holes = false; bool empty_dynamic = false; ElfW(Addr) p_align_max = 0; @@ -1141,6 +1140,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, if (powerof2 (ph->p_align) && ph->p_align > p_align_max) p_align_max = ph->p_align; c->mapoff = ALIGN_DOWN (ph->p_offset, GLRO(dl_pagesize)); + c->maphole = 0; DIAG_PUSH_NEEDS_COMMENT; @@ -1153,8 +1153,8 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, #endif /* Determine whether there is a gap between the last segment and this one. */ - if (nloadcmds > 1 && c[-1].mapend != c->mapstart) - has_holes = true; + if (nloadcmds > 1 && c[-1].mapend < c->mapstart) + c[-1].maphole = c->mapstart - c[-1].mapend; DIAG_POP_NEEDS_COMMENT; /* Optimize a common case. */ @@ -1256,7 +1256,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, l_map_start, l_map_end, l_addr, l_contiguous, l_text_end, l_phdr */ errstring = _dl_map_segments (l, fd, header, type, loadcmds, nloadcmds, - maplength, has_holes, loader); + maplength, loader); if (__glibc_unlikely (errstring != NULL)) { /* Mappings can be in an inconsistent state: avoid unmap. */ diff --git a/elf/dl-load.h b/elf/dl-load.h index ecf6910c68..029181e8c8 100644 --- a/elf/dl-load.h +++ b/elf/dl-load.h @@ -75,7 +75,7 @@ ELF_PREFERRED_ADDRESS_DATA; Its details have been expanded out and converted. */ struct loadcmd { - ElfW(Addr) mapstart, mapend, dataend, allocend, mapalign; + ElfW(Addr) mapstart, mapend, dataend, allocend, mapalign, maphole; ElfW(Off) mapoff; int prot; /* PROT_* bits. */ }; @@ -118,7 +118,6 @@ static const char *_dl_map_segments (struct link_map *l, int fd, const struct loadcmd loadcmds[], size_t nloadcmds, const size_t maplength, - bool has_holes, struct link_map *loader); /* All the error message strings _dl_map_segments might return are diff --git a/elf/dl-map-segments.h b/elf/dl-map-segments.h index 6a6127f773..080199b76e 100644 --- a/elf/dl-map-segments.h +++ b/elf/dl-map-segments.h @@ -77,7 +77,7 @@ static __always_inline const char * _dl_map_segments (struct link_map *l, int fd, const ElfW(Ehdr) *header, int type, const struct loadcmd loadcmds[], size_t nloadcmds, - const size_t maplength, bool has_holes, + const size_t maplength, struct link_map *loader) { const struct loadcmd *c = loadcmds; @@ -106,25 +106,6 @@ _dl_map_segments (struct link_map *l, int fd, l->l_map_end = l->l_map_start + maplength; l->l_addr = l->l_map_start - c->mapstart; - - if (has_holes) - { - /* Change protection on the excess portion to disallow all access; - the portions we do not remap later will be inaccessible as if - unallocated. Then jump into the normal segment-mapping loop to - handle the portion of the segment past the end of the file - mapping. */ - if (__glibc_unlikely (loadcmds[nloadcmds - 1].mapstart < - c->mapend)) - return N_("ELF load command address/offset not page-aligned"); - if (__glibc_unlikely - (__mprotect ((caddr_t) (l->l_addr + c->mapend), - loadcmds[nloadcmds - 1].mapstart - c->mapend, - PROT_NONE) < 0)) - return DL_MAP_SEGMENTS_ERROR_MPROTECT; - } - - l->l_contiguous = 1; } else { @@ -136,11 +117,14 @@ _dl_map_segments (struct link_map *l, int fd, if (__glibc_unlikely ((void *) l->l_map_start == MAP_FAILED)) return DL_MAP_SEGMENTS_ERROR_MAP_SEGMENT; l->l_map_end = l->l_map_start + maplength; - l->l_contiguous = !has_holes; } + /* Reset to 0 later if hole found. */ + l->l_contiguous = 1; while (c < &loadcmds[nloadcmds]) { + ElfW(Addr) hole_start, hole_size; + if (c->mapend > c->mapstart /* Map the segment contents from the file. */ && (__mmap ((void *) (l->l_addr + c->mapstart), @@ -157,11 +141,15 @@ _dl_map_segments (struct link_map *l, int fd, /* Extra zero pages should appear at the end of this segment, after the data mapped from the file. */ ElfW(Addr) zero, zeroend, zeropage; + ElfW(Off) hole_off; zero = l->l_addr + c->dataend; zeroend = l->l_addr + c->allocend; zeropage = ((zero + GLRO(dl_pagesize) - 1) & ~(GLRO(dl_pagesize) - 1)); + hole_start = ALIGN_UP (c->allocend, GLRO(dl_pagesize)); + hole_off = hole_start - c->mapend; + hole_size = c->maphole - hole_off; if (zeroend < zeropage) /* All the extra data is in the last page of the segment. @@ -194,6 +182,28 @@ _dl_map_segments (struct link_map *l, int fd, return DL_MAP_SEGMENTS_ERROR_MPROTECT; } } + else + { + hole_start = c->mapend; + hole_size = c->maphole; + } + + if (__glibc_unlikely (c->maphole)) + { + if (__glibc_likely (type == ET_DYN)) + { + if (hole_size) + { + if (__mprotect ((caddr_t) (l->l_addr + hole_start), + hole_size, PROT_NONE) < 0) + return DL_MAP_SEGMENTS_ERROR_MPROTECT; + } + } + else if (l->l_contiguous) + { + l->l_contiguous = 0; + } + } ++c; } From patchwork Thu May 18 08:28:44 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: stsp X-Patchwork-Id: 69576 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 45B633836E92 for ; Thu, 18 May 2023 08:32:22 +0000 (GMT) X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from forward102c.mail.yandex.net (forward102c.mail.yandex.net [IPv6:2a02:6b8:c03:500:1:45:d181:d102]) by sourceware.org (Postfix) with ESMTPS id 9CF463857704 for ; Thu, 18 May 2023 08:29:41 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 9CF463857704 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=yandex.ru Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=yandex.ru Received: from mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net (mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net [IPv6:2a02:6b8:c0c:1186:0:640:38cb:0]) by forward102c.mail.yandex.net (Yandex) with ESMTP id 2CADD60029 for ; Thu, 18 May 2023 11:29:39 +0300 (MSK) Received: by mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net (smtp/Yandex) with ESMTPSA id XTYe39MDZ0U0-PrLdeW2K; Thu, 18 May 2023 11:29:38 +0300 X-Yandex-Fwd: 1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex.ru; s=mail; t=1684398578; bh=y/x5+YLzl0TZEURcrnlWIsTdddbJ+HMMqlig+tZ5PVI=; h=Message-Id:Date:In-Reply-To:Cc:Subject:References:To:From; b=D7qhJhY4D28UiYJozPOmIZUmpmbLl7jNo44nYHH/6enaZ/AmE/sW9MfK5alutY3f7 4+03c8Mkb3rduD9LzGHD2+hEdwmOvEl8SIdtYw9tRwUAMTPJdUWNz0euxi5aAUzG8U N3QFOxqsGrzpanr5Cab8Slg8znREglBRCPMLpTGQ= Authentication-Results: mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net; dkim=pass header.i=@yandex.ru From: Stas Sergeev To: libc-alpha@sourceware.org Cc: Stas Sergeev Subject: [PATCH 04/14] split do_reloc_1() from dl_open_worker_begin() Date: Thu, 18 May 2023 13:28:44 +0500 Message-Id: <20230518082854.3903342-5-stsp2@yandex.ru> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230518082854.3903342-1-stsp2@yandex.ru> References: <20230518082854.3903342-1-stsp2@yandex.ru> MIME-Version: 1.0 X-Spam-Status: No, score=-10.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE, URIBL_BLACK 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: , Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" This is a mostly mechanical code split with no functional changes intended. The test-suite was run on x86_64/64 and showed no regressions. Signed-off-by: Stas Sergeev --- elf/dl-open.c | 259 +++++++++++++++++++++++++------------------------- 1 file changed, 132 insertions(+), 127 deletions(-) diff --git a/elf/dl-open.c b/elf/dl-open.c index 2d985e21d8..a77a6143e2 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -486,114 +486,8 @@ call_dl_init (void *closure) } static void -dl_open_worker_begin (void *a) +do_reloc_1 (struct link_map *new, int mode, Lmid_t nsid, bool call_ctors) { - struct dl_open_args *args = a; - const char *file = args->file; - int mode = args->mode; - struct link_map *call_map = NULL; - - /* Determine the caller's map if necessary. This is needed in case - we have a DST, when we don't know the namespace ID we have to put - the new object in, or when the file name has no path in which - case we need to look along the RUNPATH/RPATH of the caller. */ - const char *dst = strchr (file, '$'); - if (dst != NULL || args->nsid == __LM_ID_CALLER - || strchr (file, '/') == NULL) - { - const void *caller_dlopen = args->caller_dlopen; - - /* We have to find out from which object the caller is calling. - By default we assume this is the main application. */ - call_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded; - - struct link_map *l = _dl_find_dso_for_object ((ElfW(Addr)) caller_dlopen); - - if (l) - call_map = l; - - if (args->nsid == __LM_ID_CALLER) - args->nsid = call_map->l_ns; - } - - /* The namespace ID is now known. Keep track of whether libc.so was - already loaded, to determine whether it is necessary to call the - early initialization routine (or clear libc_map on error). */ - args->libc_already_loaded = GL(dl_ns)[args->nsid].libc_map != NULL; - - /* Retain the old value, so that it can be restored. */ - args->original_global_scope_pending_adds - = GL (dl_ns)[args->nsid]._ns_global_scope_pending_adds; - - /* One might be tempted to assert that we are RT_CONSISTENT at this point, but that - may not be true if this is a recursive call to dlopen. */ - _dl_debug_initialize (0, args->nsid); - - /* Load the named object. */ - struct link_map *new; - args->map = new = _dl_map_object (call_map, file, lt_loaded, 0, - mode | __RTLD_CALLMAP, args->nsid); - - /* If the pointer returned is NULL this means the RTLD_NOLOAD flag is - set and the object is not already loaded. */ - if (new == NULL) - { - assert (mode & RTLD_NOLOAD); - return; - } - - if (__glibc_unlikely (mode & __RTLD_SPROF)) - /* This happens only if we load a DSO for 'sprof'. */ - return; - - /* This object is directly loaded. */ - ++new->l_direct_opencount; - - /* It was already open. */ - if (__glibc_unlikely (new->l_searchlist.r_list != NULL)) - { - /* Let the user know about the opencount. */ - if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES)) - _dl_debug_printf ("opening file=%s [%lu]; direct_opencount=%u\n\n", - new->l_name, new->l_ns, new->l_direct_opencount); - - /* If the user requested the object to be in the global - namespace but it is not so far, prepare to add it now. This - can raise an exception to do a malloc failure. */ - if ((mode & RTLD_GLOBAL) && new->l_global == 0) - add_to_global_resize (new); - - /* Mark the object as not deletable if the RTLD_NODELETE flags - was passed. */ - if (__glibc_unlikely (mode & RTLD_NODELETE)) - { - if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_FILES) - && !new->l_nodelete_active) - _dl_debug_printf ("marking %s [%lu] as NODELETE\n", - new->l_name, new->l_ns); - new->l_nodelete_active = true; - } - - /* Finalize the addition to the global scope. */ - if ((mode & RTLD_GLOBAL) && new->l_global == 0) - add_to_global_update (new); - - const int r_state __attribute__ ((unused)) - = _dl_debug_update (args->nsid)->r_state; - assert (r_state == RT_CONSISTENT); - - return; - } - - /* Schedule NODELETE marking for the directly loaded object if - requested. */ - if (__glibc_unlikely (mode & RTLD_NODELETE)) - new->l_nodelete_pending = true; - - /* Load that object's dependencies. */ - _dl_map_object_deps (new, NULL, 0, 0, - mode & (__RTLD_DLOPEN | RTLD_DEEPBIND | __RTLD_AUDIT)); - /* So far, so good. Now check the versions. */ for (unsigned int i = 0; i < new->l_searchlist.r_nlist; ++i) if (new->l_searchlist.r_list[i]->l_real->l_versions == NULL) @@ -612,23 +506,6 @@ dl_open_worker_begin (void *a) #endif } -#ifdef SHARED - /* Auditing checkpoint: we have added all objects. */ - _dl_audit_activity_nsid (new->l_ns, LA_ACT_CONSISTENT); -#endif - - /* Notify the debugger all new objects are now ready to go. */ - struct r_debug *r = _dl_debug_update (args->nsid); - r->r_state = RT_CONSISTENT; - _dl_debug_state (); - LIBC_PROBE (map_complete, 3, args->nsid, r, new); - - _dl_open_check (new); - - /* Print scope information. */ - if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SCOPES)) - _dl_show_scope (new, 0); - /* Only do lazy relocation if `LD_BIND_NOW' is not set. */ int reloc_mode = mode & __RTLD_AUDIT; if (GLRO(dl_lazy)) @@ -753,20 +630,148 @@ dl_open_worker_begin (void *a) /* Notify the debugger all new objects have been relocated. */ if (relocation_in_progress) - LIBC_PROBE (reloc_complete, 3, args->nsid, r, new); + LIBC_PROBE (reloc_complete, 3, nsid, r, new); /* If libc.so was not there before, attempt to call its early initialization routine. Indicate to the initialization routine whether the libc being initialized is the one in the base namespace. */ - if (!args->libc_already_loaded) + if (call_ctors) { /* dlopen cannot be used to load an initial libc by design. */ - struct link_map *libc_map = GL(dl_ns)[args->nsid].libc_map; + struct link_map *libc_map = GL(dl_ns)[nsid].libc_map; _dl_call_libc_early_init (libc_map, false); } +} + +static void +dl_open_worker_begin (void *a) +{ + struct dl_open_args *args = a; + const char *file = args->file; + int mode = args->mode; + struct link_map *call_map = NULL; + + /* Determine the caller's map if necessary. This is needed in case + we have a DST, when we don't know the namespace ID we have to put + the new object in, or when the file name has no path in which + case we need to look along the RUNPATH/RPATH of the caller. */ + const char *dst = strchr (file, '$'); + if (dst != NULL || args->nsid == __LM_ID_CALLER + || strchr (file, '/') == NULL) + { + const void *caller_dlopen = args->caller_dlopen; + + /* We have to find out from which object the caller is calling. + By default we assume this is the main application. */ + call_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded; + + struct link_map *l = _dl_find_dso_for_object ((ElfW(Addr)) caller_dlopen); + + if (l) + call_map = l; + + if (args->nsid == __LM_ID_CALLER) + args->nsid = call_map->l_ns; + } + + /* The namespace ID is now known. Keep track of whether libc.so was + already loaded, to determine whether it is necessary to call the + early initialization routine (or clear libc_map on error). */ + args->libc_already_loaded = GL(dl_ns)[args->nsid].libc_map != NULL; + + /* Retain the old value, so that it can be restored. */ + args->original_global_scope_pending_adds + = GL (dl_ns)[args->nsid]._ns_global_scope_pending_adds; + + /* One might be tempted to assert that we are RT_CONSISTENT at this point, but that + may not be true if this is a recursive call to dlopen. */ + _dl_debug_initialize (0, args->nsid); + + /* Load the named object. */ + struct link_map *new; + args->map = new = _dl_map_object (call_map, file, lt_loaded, 0, + mode | __RTLD_CALLMAP, args->nsid); + + /* If the pointer returned is NULL this means the RTLD_NOLOAD flag is + set and the object is not already loaded. */ + if (new == NULL) + { + assert (mode & RTLD_NOLOAD); + return; + } + + if (__glibc_unlikely (mode & __RTLD_SPROF)) + /* This happens only if we load a DSO for 'sprof'. */ + return; + + /* This object is directly loaded. */ + ++new->l_direct_opencount; + + /* It was already open. */ + if (__glibc_unlikely (new->l_searchlist.r_list != NULL)) + { + /* Let the user know about the opencount. */ + if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES)) + _dl_debug_printf ("opening file=%s [%lu]; direct_opencount=%u\n\n", + new->l_name, new->l_ns, new->l_direct_opencount); + + /* If the user requested the object to be in the global + namespace but it is not so far, prepare to add it now. This + can raise an exception to do a malloc failure. */ + if ((mode & RTLD_GLOBAL) && new->l_global == 0) + add_to_global_resize (new); + + /* Mark the object as not deletable if the RTLD_NODELETE flags + was passed. */ + if (__glibc_unlikely (mode & RTLD_NODELETE)) + { + if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_FILES) + && !new->l_nodelete_active) + _dl_debug_printf ("marking %s [%lu] as NODELETE\n", + new->l_name, new->l_ns); + new->l_nodelete_active = true; + } + + /* Finalize the addition to the global scope. */ + if ((mode & RTLD_GLOBAL) && new->l_global == 0) + add_to_global_update (new); + + const int r_state __attribute__ ((unused)) + = _dl_debug_update (args->nsid)->r_state; + assert (r_state == RT_CONSISTENT); + + return; + } + + /* Schedule NODELETE marking for the directly loaded object if + requested. */ + if (__glibc_unlikely (mode & RTLD_NODELETE)) + new->l_nodelete_pending = true; + + /* Load that object's dependencies. */ + _dl_map_object_deps (new, NULL, 0, 0, + mode & (__RTLD_DLOPEN | RTLD_DEEPBIND | __RTLD_AUDIT)); + +#ifdef SHARED + /* Auditing checkpoint: we have added all objects. */ + _dl_audit_activity_nsid (new->l_ns, LA_ACT_CONSISTENT); +#endif + + /* Notify the debugger all new objects are now ready to go. */ + struct r_debug *r = _dl_debug_update (args->nsid); + r->r_state = RT_CONSISTENT; + _dl_debug_state (); + LIBC_PROBE (map_complete, 3, args->nsid, r, new); + + _dl_open_check (new); + + /* Print scope information. */ + if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SCOPES)) + _dl_show_scope (new, 0); args->worker_continue = true; + do_reloc_1 (new, mode, args->nsid, !args->libc_already_loaded); } static void From patchwork Thu May 18 08:28:45 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: stsp X-Patchwork-Id: 69574 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id AA04F3854160 for ; Thu, 18 May 2023 08:31:11 +0000 (GMT) X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from forward103c.mail.yandex.net (forward103c.mail.yandex.net [178.154.239.214]) by sourceware.org (Postfix) with ESMTPS id 1CA893858434 for ; Thu, 18 May 2023 08:29:41 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 1CA893858434 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=yandex.ru Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=yandex.ru Received: from mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net (mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net [IPv6:2a02:6b8:c0c:1186:0:640:38cb:0]) by forward103c.mail.yandex.net (Yandex) with ESMTP id 1565A6005E for ; Thu, 18 May 2023 11:29:40 +0300 (MSK) Received: by mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net (smtp/Yandex) with ESMTPSA id XTYe39MDZ0U0-RDOcOetF; Thu, 18 May 2023 11:29:39 +0300 X-Yandex-Fwd: 1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex.ru; s=mail; t=1684398579; bh=X8XvJSwSDSD1vS/pvM1QKokeYsRcdvwcU5EzGMZ8U24=; h=Message-Id:Date:In-Reply-To:Cc:Subject:References:To:From; b=UlTezF25SEN4VaIbMzbea/T+0ES0dlWDtIgq6aASdoyfYqPewSivEBd2H+XHQebt7 blr4GHZs+9FphmoouhzKoDSooz0RMFgtpvrZGQz7EclLYvi4yUaEK7NLBVIX9kJFkN v8IoUFA8P5lEQliEdk1TGFOrQl26QoZ7EC6L2hMk= Authentication-Results: mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net; dkim=pass header.i=@yandex.ru From: Stas Sergeev To: libc-alpha@sourceware.org Cc: Stas Sergeev Subject: [PATCH 05/14] split do_reloc_2() out of do_open_worker() Date: Thu, 18 May 2023 13:28:45 +0500 Message-Id: <20230518082854.3903342-6-stsp2@yandex.ru> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230518082854.3903342-1-stsp2@yandex.ru> References: <20230518082854.3903342-1-stsp2@yandex.ru> MIME-Version: 1.0 X-Spam-Status: No, score=-10.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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: , Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" This is mostly a mechanical split with no functional changes intended. The test-suite was run on x86_64/64 and showed no regressions. Signed-off-by: Stas Sergeev --- elf/dl-open.c | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/elf/dl-open.c b/elf/dl-open.c index a77a6143e2..687a393e0d 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -644,6 +644,28 @@ do_reloc_1 (struct link_map *new, int mode, Lmid_t nsid, bool call_ctors) } } +static void +do_reloc_2 (struct link_map *new, int mode, struct dl_open_args *args) +{ + /* Run the initializer functions of new objects. Temporarily + disable the exception handler, so that lazy binding failures are + fatal. */ + { + struct dl_init_args init_args = + { + .new = new, + .argc = args->argc, + .argv = args->argv, + .env = args->env + }; + _dl_catch_exception (NULL, call_dl_init, &init_args); + } + + /* Now we can make the new map available in the global scope. */ + if (mode & RTLD_GLOBAL) + add_to_global_update (new); +} + static void dl_open_worker_begin (void *a) { @@ -801,23 +823,7 @@ dl_open_worker (void *a) int mode = args->mode; struct link_map *new = args->map; - /* Run the initializer functions of new objects. Temporarily - disable the exception handler, so that lazy binding failures are - fatal. */ - { - struct dl_init_args init_args = - { - .new = new, - .argc = args->argc, - .argv = args->argv, - .env = args->env - }; - _dl_catch_exception (NULL, call_dl_init, &init_args); - } - - /* Now we can make the new map available in the global scope. */ - if (mode & RTLD_GLOBAL) - add_to_global_update (new); + do_reloc_2 (new, mode, args); /* Let the user know about the opencount. */ if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES)) From patchwork Thu May 18 08:28:46 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: stsp X-Patchwork-Id: 69577 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id A30003834695 for ; Thu, 18 May 2023 08:32:25 +0000 (GMT) X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from forward102b.mail.yandex.net (forward102b.mail.yandex.net [IPv6:2a02:6b8:c02:900:1:45:d181:d102]) by sourceware.org (Postfix) with ESMTPS id 383DC3857724 for ; Thu, 18 May 2023 08:29:42 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 383DC3857724 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=yandex.ru Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=yandex.ru Received: from mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net (mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net [IPv6:2a02:6b8:c0c:1186:0:640:38cb:0]) by forward102b.mail.yandex.net (Yandex) with ESMTP id 1F32460114 for ; Thu, 18 May 2023 11:29:41 +0300 (MSK) Received: by mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net (smtp/Yandex) with ESMTPSA id XTYe39MDZ0U0-bmLxqVgZ; Thu, 18 May 2023 11:29:40 +0300 X-Yandex-Fwd: 1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex.ru; s=mail; t=1684398580; bh=3e+njtjSZzf0T0qO1mowm2r+GG7fOKEeaGRZLBdMsBg=; h=Message-Id:Date:In-Reply-To:Cc:Subject:References:To:From; b=cMTAXWizK9ktq4jOxsrmK6RI0btSe0VOoFtwD6sqJHu0/swq5GCf4obV9WCNT36bq X/7JKsvS+rdAUIzoYrpj8PiqQPTqr+B7ygnyDzh4GY+JaIPi/haoA8pQjQCBOYhCkf aLfNfC9Jbsl8OvO18/sgvLe+5il+rlUriT/G/llw= Authentication-Results: mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net; dkim=pass header.i=@yandex.ru From: Stas Sergeev To: libc-alpha@sourceware.org Cc: Stas Sergeev Subject: [PATCH 06/14] move relocation into _dl_object_reloc() func Date: Thu, 18 May 2023 13:28:46 +0500 Message-Id: <20230518082854.3903342-7-stsp2@yandex.ru> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230518082854.3903342-1-stsp2@yandex.ru> References: <20230518082854.3903342-1-stsp2@yandex.ru> MIME-Version: 1.0 X-Spam-Status: No, score=-11.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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: , Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" This is a small refactoring to consolidate the relocation code in a single place. The test-suite was run on x86_64/64 and showed no regressions. Signed-off-by: Stas Sergeev --- elf/dl-close.c | 2 ++ elf/dl-open.c | 55 +++++++++++++++++++++++++++++++++++++++++++++----- include/link.h | 2 ++ 3 files changed, 54 insertions(+), 5 deletions(-) diff --git a/elf/dl-close.c b/elf/dl-close.c index b887a44888..48ac3663ec 100644 --- a/elf/dl-close.c +++ b/elf/dl-close.c @@ -690,6 +690,8 @@ _dl_close_worker (struct link_map *map, bool force) if (imap == GL(dl_initfirst)) GL(dl_initfirst) = NULL; + free (imap->l_dlopen_args); + free (imap); } } diff --git a/elf/dl-open.c b/elf/dl-open.c index 687a393e0d..e553403e8b 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -666,6 +666,31 @@ do_reloc_2 (struct link_map *new, int mode, struct dl_open_args *args) add_to_global_update (new); } +static void +dl_reloc_worker_begin (void *a) +{ + struct dl_open_args *args = a; + do_reloc_1 (args->map, args->mode, args->nsid, !args->libc_already_loaded); +} + +static void +_dl_object_reloc (struct link_map *l) +{ + struct dl_exception ex; + int err; + struct dl_open_args *args = l->l_dlopen_args; + int mode = args->mode; + + /* Protects global and module specific TLS state. */ + __rtld_lock_lock_recursive (GL(dl_load_tls_lock)); + err = _dl_catch_exception (&ex, dl_reloc_worker_begin, args); + __rtld_lock_unlock_recursive (GL(dl_load_tls_lock)); + if (__glibc_unlikely (ex.errstring != NULL)) + /* Reraise the error. */ + _dl_signal_exception (err, &ex, NULL); + do_reloc_2 (l, mode, args); +} + static void dl_open_worker_begin (void *a) { @@ -775,6 +800,27 @@ dl_open_worker_begin (void *a) _dl_map_object_deps (new, NULL, 0, 0, mode & (__RTLD_DLOPEN | RTLD_DEEPBIND | __RTLD_AUDIT)); + args->worker_continue = true; + if (!new->l_dlopen_args) + { + if (new->l_type == lt_loaded) + { + new->l_dlopen_args = (struct dl_open_args *) + malloc (sizeof (struct dl_open_args)); + if (new->l_dlopen_args == NULL) + _dl_signal_error (ENOMEM, new->l_name, NULL, + N_("cannot allocate memory buffer")); + memcpy (new->l_dlopen_args, args, sizeof (*args)); + } + else + new->l_dlopen_args = args; + } + else + { + assert (new->l_type == lt_loaded); + memcpy (new->l_dlopen_args, args, sizeof (*args)); + } + #ifdef SHARED /* Auditing checkpoint: we have added all objects. */ _dl_audit_activity_nsid (new->l_ns, LA_ACT_CONSISTENT); @@ -791,9 +837,6 @@ dl_open_worker_begin (void *a) /* Print scope information. */ if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SCOPES)) _dl_show_scope (new, 0); - - args->worker_continue = true; - do_reloc_1 (new, mode, args->nsid, !args->libc_already_loaded); } static void @@ -820,10 +863,12 @@ dl_open_worker (void *a) if (!args->worker_continue) return; - int mode = args->mode; struct link_map *new = args->map; - do_reloc_2 (new, mode, args); + _dl_object_reloc (new); + /* For !lt_loaded we do not malloc(), so needs to null out here. */ + if (new->l_type != lt_loaded) + new->l_dlopen_args = NULL; /* Let the user know about the opencount. */ if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES)) diff --git a/include/link.h b/include/link.h index 1d74feb2bd..03b9f82715 100644 --- a/include/link.h +++ b/include/link.h @@ -347,6 +347,8 @@ struct link_map size_t l_relro_size; unsigned long long int l_serial; + + void *l_dlopen_args; }; #include From patchwork Thu May 18 08:28:47 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: stsp X-Patchwork-Id: 69579 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 5BFE738432D2 for ; Thu, 18 May 2023 08:33:38 +0000 (GMT) X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from forward101c.mail.yandex.net (forward101c.mail.yandex.net [IPv6:2a02:6b8:c03:500:1:45:d181:d101]) by sourceware.org (Postfix) with ESMTPS id 386F13854143 for ; Thu, 18 May 2023 08:29:45 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 386F13854143 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=yandex.ru Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=yandex.ru Received: from mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net (mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net [IPv6:2a02:6b8:c0c:1186:0:640:38cb:0]) by forward101c.mail.yandex.net (Yandex) with ESMTP id 0B83D60140 for ; Thu, 18 May 2023 11:29:42 +0300 (MSK) Received: by mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net (smtp/Yandex) with ESMTPSA id XTYe39MDZ0U0-SQfHF3xi; Thu, 18 May 2023 11:29:41 +0300 X-Yandex-Fwd: 1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex.ru; s=mail; t=1684398581; bh=0ffDyvPXby1bKU1olIDUBEeEH86jH7UYRjSa4MWBF84=; h=Message-Id:Date:In-Reply-To:Cc:Subject:References:To:From; b=MMCUJz9gKWHtgu9iO4EQk/jzUzQiWT+rlxfwPqhW4ukDy5h0lYOnjvfyfnWvXUSx4 +wfyEoWkZJHL4f6c9lPqvnBKWudRNdtI6FnF4MNKSzdQUp9uGQY89e9LRGtNcp+sl7 YKPdWFN1cutTNkX4dHAcGbDvUZjhgaRkBhQl6NXo= Authentication-Results: mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net; dkim=pass header.i=@yandex.ru From: Stas Sergeev To: libc-alpha@sourceware.org Cc: Stas Sergeev Subject: [PATCH 07/14] split out _dl_finalize_segments() Date: Thu, 18 May 2023 13:28:47 +0500 Message-Id: <20230518082854.3903342-8-stsp2@yandex.ru> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230518082854.3903342-1-stsp2@yandex.ru> References: <20230518082854.3903342-1-stsp2@yandex.ru> MIME-Version: 1.0 X-Spam-Status: No, score=-11.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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: , Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" This is needed so that further patches can move that to the relocation code. The test-suite was run on x86_64/64 and showed no regressions. Signed-off-by: Stas Sergeev --- elf/dl-load.c | 3 +++ elf/dl-load.h | 5 +++++ elf/dl-map-segments.h | 36 +++++++++++++++++++++++++++++------- 3 files changed, 37 insertions(+), 7 deletions(-) diff --git a/elf/dl-load.c b/elf/dl-load.c index 4007a4aae3..28e582fbdf 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -1263,6 +1263,9 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, l->l_map_start = l->l_map_end = 0; goto lose; } + errstring = _dl_finalize_segments (l, type, loadcmds, nloadcmds); + if (__glibc_unlikely (errstring != NULL)) + goto lose; } if (l->l_ld != 0) diff --git a/elf/dl-load.h b/elf/dl-load.h index 029181e8c8..61f5c4fadf 100644 --- a/elf/dl-load.h +++ b/elf/dl-load.h @@ -120,6 +120,11 @@ static const char *_dl_map_segments (struct link_map *l, int fd, const size_t maplength, struct link_map *loader); +static const char *_dl_finalize_segments (struct link_map *l, + int type, + const struct loadcmd loadcmds[], + size_t nloadcmds); + /* All the error message strings _dl_map_segments might return are listed here so that different implementations in different sysdeps dl-map-segments.h files all use consistent strings that are diff --git a/elf/dl-map-segments.h b/elf/dl-map-segments.h index 080199b76e..da6b762bca 100644 --- a/elf/dl-map-segments.h +++ b/elf/dl-map-segments.h @@ -123,12 +123,10 @@ _dl_map_segments (struct link_map *l, int fd, while (c < &loadcmds[nloadcmds]) { - ElfW(Addr) hole_start, hole_size; - if (c->mapend > c->mapstart /* Map the segment contents from the file. */ && (__mmap ((void *) (l->l_addr + c->mapstart), - c->mapend - c->mapstart, c->prot, + c->mapend - c->mapstart, PROT_READ | PROT_WRITE, MAP_FIXED|MAP_COPY|MAP_FILE, fd, c->mapoff) == MAP_FAILED)) @@ -136,6 +134,34 @@ _dl_map_segments (struct link_map *l, int fd, _dl_postprocess_loadcmd (l, header, c); + ++c; + } + + /* Notify ELF_PREFERRED_ADDRESS that we have to load this one + fixed. */ + ELF_FIXED_ADDRESS (loader, c->mapstart); + + return NULL; +} + +static __always_inline const char * +_dl_finalize_segments (struct link_map *l, int type, + const struct loadcmd loadcmds[], size_t nloadcmds) +{ + const struct loadcmd *c = loadcmds; + + while (c < &loadcmds[nloadcmds]) + { + ElfW(Addr) hole_start, hole_size; + + if (c->mapend > c->mapstart) + { + if (__mprotect ((void *) (l->l_addr + c->mapstart), + c->mapend - c->mapstart, c->prot) < 0) + return DL_MAP_SEGMENTS_ERROR_MPROTECT; + + } + if (c->allocend > c->dataend) { /* Extra zero pages should appear at the end of this segment, @@ -208,9 +234,5 @@ _dl_map_segments (struct link_map *l, int fd, ++c; } - /* Notify ELF_PREFERRED_ADDRESS that we have to load this one - fixed. */ - ELF_FIXED_ADDRESS (loader, c->mapstart); - return NULL; } From patchwork Thu May 18 08:28:48 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: stsp X-Patchwork-Id: 69578 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id EF66A3853570 for ; Thu, 18 May 2023 08:33:10 +0000 (GMT) X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from forward102c.mail.yandex.net (forward102c.mail.yandex.net [178.154.239.213]) by sourceware.org (Postfix) with ESMTPS id F147A3856DF4 for ; Thu, 18 May 2023 08:29:43 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org F147A3856DF4 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=yandex.ru Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=yandex.ru Received: from mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net (mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net [IPv6:2a02:6b8:c0c:1186:0:640:38cb:0]) by forward102c.mail.yandex.net (Yandex) with ESMTP id E129360031 for ; Thu, 18 May 2023 11:29:42 +0300 (MSK) Received: by mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net (smtp/Yandex) with ESMTPSA id XTYe39MDZ0U0-vSYJP4k3; Thu, 18 May 2023 11:29:42 +0300 X-Yandex-Fwd: 1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex.ru; s=mail; t=1684398582; bh=ruq76yRdNZz4P0RtmrsIHFoJB+6LMR303Cmg+gcIE4w=; h=Message-Id:Date:In-Reply-To:Cc:Subject:References:To:From; b=VTVD5EVHsz5laRHJEzGVbnEqVX0cxwGI5lPJAGC1a4jl7HJ2JE4B889jsTzlW5jj3 7L1eBATKGzxRLROhrQsJg3EIXlkBczcCPPoUTGyLf5SdTUv0qAHQ/t5MPWpHT5jcei hU9tBHvWFFL9QEPyyFLg8Drz6dpFaEiKAEe8mP0M= Authentication-Results: mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net; dkim=pass header.i=@yandex.ru From: Stas Sergeev To: libc-alpha@sourceware.org Cc: Stas Sergeev Subject: [PATCH 08/14] finalize elf segments on a relocation step Date: Thu, 18 May 2023 13:28:48 +0500 Message-Id: <20230518082854.3903342-9-stsp2@yandex.ru> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230518082854.3903342-1-stsp2@yandex.ru> References: <20230518082854.3903342-1-stsp2@yandex.ru> MIME-Version: 1.0 X-Spam-Status: No, score=-11.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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: , Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" This is needed so that the segment finalization can be delayed, together with the relocation process. The test-suite was run on x86_64/64 and showed no regressions. Signed-off-by: Stas Sergeev --- elf/dl-close.c | 1 + elf/dl-load.c | 33 ++++++++++++++++++++++----------- elf/dl-load.h | 2 +- elf/dl-map-segments.h | 7 ++++++- elf/dl-open.c | 10 +++++++++- include/link.h | 5 ++++- 6 files changed, 43 insertions(+), 15 deletions(-) diff --git a/elf/dl-close.c b/elf/dl-close.c index 48ac3663ec..0640fc0bec 100644 --- a/elf/dl-close.c +++ b/elf/dl-close.c @@ -691,6 +691,7 @@ _dl_close_worker (struct link_map *map, bool force) GL(dl_initfirst) = NULL; free (imap->l_dlopen_args); + free (imap->l_loadcmds); free (imap); } diff --git a/elf/dl-load.c b/elf/dl-load.c index 28e582fbdf..31514fca84 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -950,6 +950,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, int type; /* Initialize to keep the compiler happy. */ const char *errstring = NULL; + struct loadcmd *loadcmds = NULL; int errval = 0; /* Get file information. To match the kernel behavior, do not fill @@ -969,6 +970,8 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, lose_errno: errval = errno; lose: + if (loadcmds) + free (loadcmds); /* The file might already be closed. */ if (fd != -1) __close_nocancel (fd); @@ -1080,18 +1083,23 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, } } - /* On most platforms presume that PT_GNU_STACK is absent and the stack is - * executable. Other platforms default to a nonexecutable stack and don't - * need PT_GNU_STACK to do so. */ - unsigned int stack_flags = DEFAULT_STACK_PERMS; + /* On most platforms presume that PT_GNU_STACK is absent and the stack is + * executable. Other platforms default to a nonexecutable stack and don't + * need PT_GNU_STACK to do so. */ + unsigned int stack_flags = DEFAULT_STACK_PERMS; { /* Scan the program header table, collecting its load commands. */ - struct loadcmd loadcmds[l->l_phnum]; - size_t nloadcmds = 0; + #define nloadcmds l->l_nloadcmds bool empty_dynamic = false; ElfW(Addr) p_align_max = 0; + loadcmds = (struct loadcmd *) malloc (sizeof (struct loadcmd) * l->l_phnum); + if (loadcmds == NULL) + goto lose; + l->l_loadcmds = loadcmds; + nloadcmds = 0; + /* The struct is initialized to zero so this is not necessary: l->l_ld = 0; l->l_phdr = 0; @@ -1225,8 +1233,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, } /* Align all PT_LOAD segments to the maximum p_align. */ - for (size_t i = 0; i < nloadcmds; i++) - loadcmds[i].mapalign = p_align_max; + l->l_map_align = p_align_max; /* dlopen of an executable is not valid because it is not possible to perform proper relocations, handle static TLS, or run the @@ -1263,9 +1270,13 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, l->l_map_start = l->l_map_end = 0; goto lose; } - errstring = _dl_finalize_segments (l, type, loadcmds, nloadcmds); - if (__glibc_unlikely (errstring != NULL)) - goto lose; + /* dlopen()ed solibs are finalized on a relocation step. */ + if (!(mode & __RTLD_DLOPEN)) + { + errstring = _dl_finalize_segments (l, type, loadcmds, nloadcmds); + if (__glibc_unlikely (errstring != NULL)) + goto lose; + } } if (l->l_ld != 0) diff --git a/elf/dl-load.h b/elf/dl-load.h index 61f5c4fadf..555eed176d 100644 --- a/elf/dl-load.h +++ b/elf/dl-load.h @@ -75,7 +75,7 @@ ELF_PREFERRED_ADDRESS_DATA; Its details have been expanded out and converted. */ struct loadcmd { - ElfW(Addr) mapstart, mapend, dataend, allocend, mapalign, maphole; + ElfW(Addr) mapstart, mapend, dataend, allocend, maphole; ElfW(Off) mapoff; int prot; /* PROT_* bits. */ }; diff --git a/elf/dl-map-segments.h b/elf/dl-map-segments.h index da6b762bca..a0078a77c8 100644 --- a/elf/dl-map-segments.h +++ b/elf/dl-map-segments.h @@ -100,7 +100,7 @@ _dl_map_segments (struct link_map *l, int fd, - MAP_BASE_ADDR (l)); /* Remember which part of the address space this object uses. */ - l->l_map_start = _dl_map_segment (mappref, maplength, c->mapalign); + l->l_map_start = _dl_map_segment (mappref, maplength, l->l_map_align); if (__glibc_unlikely ((void *) l->l_map_start == MAP_FAILED)) return DL_MAP_SEGMENTS_ERROR_MAP_SEGMENT; @@ -150,6 +150,9 @@ _dl_finalize_segments (struct link_map *l, int type, { const struct loadcmd *c = loadcmds; + if (l->l_map_completed) + return NULL; + while (c < &loadcmds[nloadcmds]) { ElfW(Addr) hole_start, hole_size; @@ -234,5 +237,7 @@ _dl_finalize_segments (struct link_map *l, int type, ++c; } + l->l_map_completed = 1; + return NULL; } diff --git a/elf/dl-open.c b/elf/dl-open.c index e553403e8b..f1f2e8d3a4 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -40,7 +40,8 @@ #include #include - +#include "dl-load.h" +#include "dl-map-segments.h" /* We must be careful not to leave us in an inconsistent state. Thus we catch any error and re-raise it after cleaning up. */ @@ -543,6 +544,8 @@ do_reloc_1 (struct link_map *new, int mode, Lmid_t nsid, bool call_ctors) for (unsigned int i = last; i-- > first; ) { + const char *errstring; + l = new->l_initfini[i]; if (l->l_real->l_relocated) @@ -555,6 +558,11 @@ do_reloc_1 (struct link_map *new, int mode, Lmid_t nsid, bool call_ctors) relocation_in_progress = 1; } + errstring = _dl_finalize_segments (l, ET_DYN, l->l_loadcmds, + l->l_nloadcmds); + if (__glibc_unlikely (errstring != NULL)) + _dl_signal_error (EINVAL, l->l_libname->name, NULL, errstring); + #ifdef SHARED if (__glibc_unlikely (GLRO(dl_profile) != NULL)) { diff --git a/include/link.h b/include/link.h index 03b9f82715..fa16dfa337 100644 --- a/include/link.h +++ b/include/link.h @@ -179,6 +179,7 @@ struct link_map } l_type:2; unsigned int l_dt_relr_ref:1; /* Nonzero if GLIBC_ABI_DT_RELR is referenced. */ + unsigned int l_map_completed:1; /* Nonzero if object fully mapped. */ unsigned int l_relocated:1; /* Nonzero if object's relocations done. */ unsigned int l_init_called:1; /* Nonzero if DT_INIT function called. */ unsigned int l_global:1; /* Nonzero if object in _dl_global_scope. */ @@ -252,7 +253,7 @@ struct link_map /* Start and finish of memory map for this object. l_map_start need not be the same as l_addr. */ - ElfW(Addr) l_map_start, l_map_end; + ElfW(Addr) l_map_start, l_map_end, l_map_align; /* End of the executable part of the mapping. */ ElfW(Addr) l_text_end; @@ -349,6 +350,8 @@ struct link_map unsigned long long int l_serial; void *l_dlopen_args; + void *l_loadcmds; + size_t l_nloadcmds; }; #include From patchwork Thu May 18 08:28:49 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: stsp X-Patchwork-Id: 69580 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 2412D388207B for ; Thu, 18 May 2023 08:33:58 +0000 (GMT) X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from forward100c.mail.yandex.net (forward100c.mail.yandex.net [178.154.239.211]) by sourceware.org (Postfix) with ESMTPS id 9BA28385354A for ; Thu, 18 May 2023 08:29:45 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 9BA28385354A Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=yandex.ru Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=yandex.ru Received: from mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net (mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net [IPv6:2a02:6b8:c0c:1186:0:640:38cb:0]) by forward100c.mail.yandex.net (Yandex) with ESMTP id CA047600B3 for ; Thu, 18 May 2023 11:29:43 +0300 (MSK) Received: by mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net (smtp/Yandex) with ESMTPSA id XTYe39MDZ0U0-pHjssSzy; Thu, 18 May 2023 11:29:43 +0300 X-Yandex-Fwd: 1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex.ru; s=mail; t=1684398583; bh=2gXTDrBcZEL/pAFT/w8FxjMaa1Y7Js1rb2/nPhhJOac=; h=Message-Id:Date:In-Reply-To:Cc:Subject:References:To:From; b=iYcPmeG+RPIIdsVi/k90VXaJSFPNliFQSwlgm73XaOiKAFwmUzdw9ybRk2b4UQolu gpqBl5m9dDeiP/g7nvJtUg2Xol3C40jwkdidDrX+1vgh7v4HzC5KTutWaL41aUURfZ OicwwjJ01GXFOxZPLlAst3SRp+jjAD+/umDnN/FQ= Authentication-Results: mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net; dkim=pass header.i=@yandex.ru From: Stas Sergeev To: libc-alpha@sourceware.org Cc: Stas Sergeev Subject: [PATCH 09/14] implement RTLD_NORELOCATE dlopen() flag Date: Thu, 18 May 2023 13:28:49 +0500 Message-Id: <20230518082854.3903342-10-stsp2@yandex.ru> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230518082854.3903342-1-stsp2@yandex.ru> References: <20230518082854.3903342-1-stsp2@yandex.ru> MIME-Version: 1.0 X-Spam-Status: No, score=-11.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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: , Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" This flag allows to delay the relocation of the dlopen()ed object. If this flag is used, then the relocation is called from _dl_lookup_symbol_x(), which is called by dlsym() among other places. The test-suite was run on x86_64/64 and showed no regressions. Signed-off-by: Stas Sergeev --- bits/dlfcn.h | 3 +++ dlfcn/dlopen.c | 2 +- elf/dl-lookup.c | 6 +++++- elf/dl-main.h | 2 ++ elf/dl-open.c | 22 +++++++++++++++++++--- include/link.h | 1 + 6 files changed, 31 insertions(+), 5 deletions(-) diff --git a/bits/dlfcn.h b/bits/dlfcn.h index d1e31cf4e0..9cf2d5fb80 100644 --- a/bits/dlfcn.h +++ b/bits/dlfcn.h @@ -41,6 +41,9 @@ #define RTLD_NODELETE 0x01000 #ifdef __USE_GNU +/* Do not relocte object on dlopen(). */ +#define RTLD_NORELOCATE 0x02000 + /* To support profiling of shared objects it is a good idea to call the function found using `dlsym' using the following macro since these calls do not use the PLT. But this would mean the dynamic diff --git a/dlfcn/dlopen.c b/dlfcn/dlopen.c index 21ed2c964d..866ccf7a4a 100644 --- a/dlfcn/dlopen.c +++ b/dlfcn/dlopen.c @@ -50,7 +50,7 @@ dlopen_doit (void *a) if (args->mode & ~(RTLD_BINDING_MASK | RTLD_NOLOAD | RTLD_DEEPBIND | RTLD_GLOBAL | RTLD_LOCAL | RTLD_NODELETE - | __RTLD_SPROF)) + | __RTLD_SPROF | RTLD_NORELOCATE)) _dl_signal_error (0, NULL, NULL, _("invalid mode parameter")); args->new = GLRO(dl_open) (args->file ?: "", args->mode | __RTLD_DLOPEN, diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c index 05f36a2507..d60481676d 100644 --- a/elf/dl-lookup.c +++ b/elf/dl-lookup.c @@ -31,7 +31,7 @@ #include #include #include - +#include #include #define VERSTAG(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (tag)) @@ -759,6 +759,10 @@ _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map, struct sym_val current_value = { NULL, NULL }; struct r_scope_elem **scope = symbol_scope; + if (undef_map && !undef_map->l_relocated && undef_map->l_reloc_deferred + && undef_map->l_type == lt_loaded) + _dl_object_reloc (undef_map); + bump_num_relocations (); /* DL_LOOKUP_RETURN_NEWEST does not make sense for versioned diff --git a/elf/dl-main.h b/elf/dl-main.h index 92766d06b4..54d139f2c4 100644 --- a/elf/dl-main.h +++ b/elf/dl-main.h @@ -127,4 +127,6 @@ _Noreturn void _dl_help (const char *argv0, struct dl_main_state *state) /* Print a diagnostics dump. */ _Noreturn void _dl_print_diagnostics (char **environ) attribute_hidden; +extern void _dl_object_reloc (struct link_map *l) attribute_hidden; + #endif /* _DL_MAIN */ diff --git a/elf/dl-open.c b/elf/dl-open.c index f1f2e8d3a4..5106c9d029 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -223,6 +223,8 @@ _dl_find_dso_for_object (const ElfW(Addr) addr) || _dl_addr_inside_object (l, (ElfW(Addr)) addr))) { assert (ns == l->l_ns); + if (!l->l_relocated) + return NULL; return l; } return NULL; @@ -681,7 +683,7 @@ dl_reloc_worker_begin (void *a) do_reloc_1 (args->map, args->mode, args->nsid, !args->libc_already_loaded); } -static void +void _dl_object_reloc (struct link_map *l) { struct dl_exception ex; @@ -689,6 +691,8 @@ _dl_object_reloc (struct link_map *l) struct dl_open_args *args = l->l_dlopen_args; int mode = args->mode; + l->l_reloc_deferred = 0; + /* Protects global and module specific TLS state. */ __rtld_lock_lock_recursive (GL(dl_load_tls_lock)); err = _dl_catch_exception (&ex, dl_reloc_worker_begin, args); @@ -760,6 +764,10 @@ dl_open_worker_begin (void *a) /* This happens only if we load a DSO for 'sprof'. */ return; + if (__glibc_unlikely ((mode & RTLD_NORELOCATE) && new->l_relocated)) + _dl_signal_error (EINVAL, new->l_name, NULL, + N_("RTLD_NORELOCATE used with already relocated object")); + /* This object is directly loaded. */ ++new->l_direct_opencount; @@ -821,7 +829,12 @@ dl_open_worker_begin (void *a) memcpy (new->l_dlopen_args, args, sizeof (*args)); } else - new->l_dlopen_args = args; + { + assert (new->l_relocated); + /* If relocated, this flag is filtered above. */ + assert (!(mode & RTLD_NORELOCATE)); + new->l_dlopen_args = args; + } } else { @@ -873,7 +886,10 @@ dl_open_worker (void *a) struct link_map *new = args->map; - _dl_object_reloc (new); + if (__glibc_likely (!(args->mode & RTLD_NORELOCATE))) + _dl_object_reloc (new); + else + new->l_reloc_deferred = 1; /* For !lt_loaded we do not malloc(), so needs to null out here. */ if (new->l_type != lt_loaded) new->l_dlopen_args = NULL; diff --git a/include/link.h b/include/link.h index fa16dfa337..6c11c33417 100644 --- a/include/link.h +++ b/include/link.h @@ -180,6 +180,7 @@ struct link_map unsigned int l_dt_relr_ref:1; /* Nonzero if GLIBC_ABI_DT_RELR is referenced. */ unsigned int l_map_completed:1; /* Nonzero if object fully mapped. */ + unsigned int l_reloc_deferred:1; /* Nonzero if relocation deferred. */ unsigned int l_relocated:1; /* Nonzero if object's relocations done. */ unsigned int l_init_called:1; /* Nonzero if DT_INIT function called. */ unsigned int l_global:1; /* Nonzero if object in _dl_global_scope. */ From patchwork Thu May 18 08:28:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: stsp X-Patchwork-Id: 69581 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 236E53882AEA for ; Thu, 18 May 2023 08:34:11 +0000 (GMT) X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from forward102b.mail.yandex.net (forward102b.mail.yandex.net [IPv6:2a02:6b8:c02:900:1:45:d181:d102]) by sourceware.org (Postfix) with ESMTPS id C95BB384B81B for ; Thu, 18 May 2023 08:29:45 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org C95BB384B81B Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=yandex.ru Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=yandex.ru Received: from mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net (mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net [IPv6:2a02:6b8:c0c:1186:0:640:38cb:0]) by forward102b.mail.yandex.net (Yandex) with ESMTP id BECBD600AD for ; Thu, 18 May 2023 11:29:44 +0300 (MSK) Received: by mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net (smtp/Yandex) with ESMTPSA id XTYe39MDZ0U0-0ksYwjs4; Thu, 18 May 2023 11:29:44 +0300 X-Yandex-Fwd: 1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex.ru; s=mail; t=1684398584; bh=lel847E5I2GPUncNHb7o9gwg6Z96ew1OLjHqi2bDGR8=; h=Message-Id:Date:In-Reply-To:Cc:Subject:References:To:From; b=itqW+W5P96Gz2Cy3F3IDBbLl8OobTNggVbAFm6mOpps9JUmPOYyGxnN3F40f3u38Q uvk0BKDSKc110CVY/3Gaf7HIGloc8NeLi0pJnuo9BbxjFf/1J5IjbyDQVXfJD7UYHM erXo3Ey4OHBxuU4dmMM1j7CEYfDPuCPftSYqnId0= Authentication-Results: mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net; dkim=pass header.i=@yandex.ru From: Stas Sergeev To: libc-alpha@sourceware.org Cc: Stas Sergeev Subject: [PATCH 10/14] add test-case for RTLD_NORELOCATE Date: Thu, 18 May 2023 13:28:50 +0500 Message-Id: <20230518082854.3903342-11-stsp2@yandex.ru> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230518082854.3903342-1-stsp2@yandex.ru> References: <20230518082854.3903342-1-stsp2@yandex.ru> MIME-Version: 1.0 X-Spam-Status: No, score=-11.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, KAM_SHORT, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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: , Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" Makes sure that things work as before. Makes sure that ctors are called upon dlsym(). The test-suite was run on x86_64/64 and showed no regressions. Signed-off-by: Stas Sergeev --- dlfcn/Makefile | 6 ++-- dlfcn/ctorlib1.c | 36 ++++++++++++++++++++++ dlfcn/tst-noreloc.c | 73 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 dlfcn/ctorlib1.c create mode 100644 dlfcn/tst-noreloc.c diff --git a/dlfcn/Makefile b/dlfcn/Makefile index 1fa7fea1ef..16b9401610 100644 --- a/dlfcn/Makefile +++ b/dlfcn/Makefile @@ -51,12 +51,12 @@ endif ifeq (yes,$(build-shared)) tests = glrefmain failtest tst-dladdr default errmsg1 tstcxaatexit \ bug-dlopen1 bug-dlsym1 tst-dlinfo bug-atexit1 bug-atexit2 \ - bug-atexit3 tstatexit bug-dl-leaf tst-rec-dlopen + bug-atexit3 tstatexit bug-dl-leaf tst-rec-dlopen tst-noreloc endif modules-names = glreflib1 glreflib2 glreflib3 failtestmod defaultmod1 \ defaultmod2 errmsg1mod modatexit modcxaatexit \ bug-dlsym1-lib1 bug-dlsym1-lib2 bug-atexit1-lib \ - bug-atexit2-lib bug-dl-leaf-lib \ + bug-atexit2-lib bug-dl-leaf-lib ctorlib1 \ bug-dl-leaf-lib-cb moddummy1 moddummy2 failtestmod.so-no-z-defs = yes @@ -102,6 +102,8 @@ $(objpfx)glrefmain.out: $(objpfx)glrefmain \ $(objpfx)failtest.out: $(objpfx)failtestmod.so $(objpfx)tst-dladdr.out: $(objpfx)glreflib1.so +$(objpfx)tst-noreloc.out: $(objpfx)ctorlib1.so +LDFLAGS-tst-noreloc = $(LDFLAGS-rdynamic) $(objpfx)tst-dlinfo.out: $(objpfx)glreflib3.so LDFLAGS-glreflib3.so = -Wl,-rpath,: diff --git a/dlfcn/ctorlib1.c b/dlfcn/ctorlib1.c new file mode 100644 index 0000000000..cf7a9096ea --- /dev/null +++ b/dlfcn/ctorlib1.c @@ -0,0 +1,36 @@ +/* Test for ctor calling. + Copyright (C) 2000-2023 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include + +extern int ref1 (void); +int +ref1 (void) +{ + return 42; +} + +void __attribute__((constructor)) +ctor (void) +{ + int *ct = (int *) dlsym (RTLD_DEFAULT, "ctor_called"); + assert (ct); + (*ct)++; +} diff --git a/dlfcn/tst-noreloc.c b/dlfcn/tst-noreloc.c new file mode 100644 index 0000000000..78f5a7fb25 --- /dev/null +++ b/dlfcn/tst-noreloc.c @@ -0,0 +1,73 @@ +/* Tests for RTLD_NORELOCATE flag. + Copyright (C) 2000-2023 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include +#include +#include +#include +#include + +int ctor_called; + +static int +do_test (void) +{ + void *handle; + int (*sym) (void); + Dl_info info; + int ret; + + handle = dlopen ("ctorlib1.so", RTLD_NOW | RTLD_NORELOCATE); + if (handle == NULL) + error (EXIT_FAILURE, 0, "cannot load: ctorlib1.so"); + + TEST_COMPARE (ctor_called, 0); + sym = dlsym (handle, "ref1"); + if (sym == NULL) + error (EXIT_FAILURE, 0, "dlsym failed"); + TEST_COMPARE (ctor_called, 1); + + memset (&info, 0, sizeof (info)); + ret = dladdr (sym, &info); + if (ret == 0) + error (EXIT_FAILURE, 0, "dladdr failed"); + + printf ("ret = %d\n", ret); + printf ("info.dli_fname = %p (\"%s\")\n", info.dli_fname, info.dli_fname); + printf ("info.dli_fbase = %p\n", info.dli_fbase); + printf ("info.dli_sname = %p (\"%s\")\n", info.dli_sname, info.dli_sname); + printf ("info.dli_saddr = %p\n", info.dli_saddr); + + if (info.dli_fname == NULL) + error (EXIT_FAILURE, 0, "dli_fname is NULL"); + if (info.dli_fbase == NULL) + error (EXIT_FAILURE, 0, "dli_fbase is NULL"); + if (info.dli_sname == NULL) + error (EXIT_FAILURE, 0, "dli_sname is NULL"); + if (info.dli_saddr == NULL) + error (EXIT_FAILURE, 0, "dli_saddr is NULL"); + + dlclose (handle); + + return 0; +} + + +#include From patchwork Thu May 18 08:28:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: stsp X-Patchwork-Id: 69583 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id A3575388202D for ; Thu, 18 May 2023 08:34:46 +0000 (GMT) X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from forward101c.mail.yandex.net (forward101c.mail.yandex.net [178.154.239.212]) by sourceware.org (Postfix) with ESMTPS id 440503855598 for ; Thu, 18 May 2023 08:29:47 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 440503855598 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=yandex.ru Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=yandex.ru Received: from mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net (mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net [IPv6:2a02:6b8:c0c:1186:0:640:38cb:0]) by forward101c.mail.yandex.net (Yandex) with ESMTP id 3102960123 for ; Thu, 18 May 2023 11:29:46 +0300 (MSK) Received: by mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net (smtp/Yandex) with ESMTPSA id XTYe39MDZ0U0-4C2fyjpT; Thu, 18 May 2023 11:29:45 +0300 X-Yandex-Fwd: 1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex.ru; s=mail; t=1684398585; bh=3UZKmt4eWKUtnQ5brAG6RmjIVqfruMXXmxciXlx7VfU=; h=Message-Id:Date:In-Reply-To:Cc:Subject:References:To:From; b=QVHrv8wNjekkrHdgbo1g+WfKSNPbFtkXCSCYoB3BizygpZoB1p+bZvvmoGOBJ27N0 qIb3j7euGmuWorra3ZMG7E9rxd/7L6HMftPtDDifxFkTK++QSAF8P5/AWGGFVe2rjK ADBNT02fylR3VzX5dC/kfE9OSLCq3fvTmJgFnSLQ= Authentication-Results: mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net; dkim=pass header.i=@yandex.ru From: Stas Sergeev To: libc-alpha@sourceware.org Cc: Stas Sergeev Subject: [PATCH 11/14] implement dlrelocate() function Date: Thu, 18 May 2023 13:28:51 +0500 Message-Id: <20230518082854.3903342-12-stsp2@yandex.ru> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230518082854.3903342-1-stsp2@yandex.ru> References: <20230518082854.3903342-1-stsp2@yandex.ru> MIME-Version: 1.0 X-Spam-Status: No, score=-11.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, KAM_SHORT, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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: , Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" This function allows to relocate the solib previously loaded with the use of RTLD_NORELOCATE flag, including all its deps. It allows to handle the relocation errors, and in case of a success, call the object's ctors. The test-suite was run on x86_64/64 and showed no regressions. Signed-off-by: Stas Sergeev --- dlfcn/Makefile | 1 + dlfcn/Versions | 3 + dlfcn/dlfcn.h | 3 + dlfcn/dlrelocate.c | 68 +++++++++++++++++++ dlfcn/tst-noreloc.c | 20 ++++++ elf/dl-open.c | 14 ++++ elf/rtld.c | 1 + include/dlfcn.h | 7 ++ sysdeps/generic/ldsodefs.h | 1 + sysdeps/mach/hurd/i386/libc.abilist | 1 + sysdeps/unix/sysv/linux/aarch64/libc.abilist | 1 + sysdeps/unix/sysv/linux/alpha/libc.abilist | 1 + sysdeps/unix/sysv/linux/arc/libc.abilist | 1 + sysdeps/unix/sysv/linux/arm/be/libc.abilist | 1 + sysdeps/unix/sysv/linux/arm/le/libc.abilist | 1 + sysdeps/unix/sysv/linux/csky/libc.abilist | 1 + sysdeps/unix/sysv/linux/hppa/libc.abilist | 1 + sysdeps/unix/sysv/linux/i386/libc.abilist | 1 + sysdeps/unix/sysv/linux/ia64/libc.abilist | 1 + .../sysv/linux/loongarch/lp64/libc.abilist | 1 + .../sysv/linux/m68k/coldfire/libc.abilist | 1 + .../unix/sysv/linux/m68k/m680x0/libc.abilist | 1 + .../sysv/linux/microblaze/be/libc.abilist | 1 + .../sysv/linux/microblaze/le/libc.abilist | 1 + .../sysv/linux/mips/mips32/fpu/libc.abilist | 1 + .../sysv/linux/mips/mips32/nofpu/libc.abilist | 1 + .../sysv/linux/mips/mips64/n32/libc.abilist | 1 + .../sysv/linux/mips/mips64/n64/libc.abilist | 1 + sysdeps/unix/sysv/linux/nios2/libc.abilist | 1 + sysdeps/unix/sysv/linux/or1k/libc.abilist | 1 + .../linux/powerpc/powerpc32/fpu/libc.abilist | 1 + .../powerpc/powerpc32/nofpu/libc.abilist | 1 + .../linux/powerpc/powerpc64/be/libc.abilist | 1 + .../linux/powerpc/powerpc64/le/libc.abilist | 1 + .../unix/sysv/linux/riscv/rv32/libc.abilist | 1 + .../unix/sysv/linux/riscv/rv64/libc.abilist | 1 + .../unix/sysv/linux/s390/s390-32/libc.abilist | 1 + .../unix/sysv/linux/s390/s390-64/libc.abilist | 1 + sysdeps/unix/sysv/linux/sh/be/libc.abilist | 1 + sysdeps/unix/sysv/linux/sh/le/libc.abilist | 1 + .../sysv/linux/sparc/sparc32/libc.abilist | 1 + .../sysv/linux/sparc/sparc64/libc.abilist | 1 + .../unix/sysv/linux/x86_64/64/libc.abilist | 1 + .../unix/sysv/linux/x86_64/x32/libc.abilist | 1 + 44 files changed, 153 insertions(+) create mode 100644 dlfcn/dlrelocate.c diff --git a/dlfcn/Makefile b/dlfcn/Makefile index 16b9401610..fb56b8aecb 100644 --- a/dlfcn/Makefile +++ b/dlfcn/Makefile @@ -26,6 +26,7 @@ routines = \ dladdr \ dladdr1 \ dlclose \ + dlrelocate \ dlerror \ dlinfo \ dlmopen \ diff --git a/dlfcn/Versions b/dlfcn/Versions index cc34eb824d..61ab01d764 100644 --- a/dlfcn/Versions +++ b/dlfcn/Versions @@ -28,6 +28,9 @@ libc { dlsym; dlvsym; } + GLIBC_2.38 { + dlrelocate; + } GLIBC_PRIVATE { __libc_dlerror_result; _dlerror_run; diff --git a/dlfcn/dlfcn.h b/dlfcn/dlfcn.h index c5d192597d..c3e228c667 100644 --- a/dlfcn/dlfcn.h +++ b/dlfcn/dlfcn.h @@ -68,6 +68,9 @@ extern void *dlsym (void *__restrict __handle, /* Like `dlopen', but request object to be allocated in a new namespace. */ extern void *dlmopen (Lmid_t __nsid, const char *__file, int __mode) __THROWNL; +/* Relocate a shared object opened by `dlopen' with `RTLD_NORELOCATE'. */ +extern int dlrelocate (void *__handle) __THROWNL __nonnull ((1)); + /* Find the run-time address in the shared object HANDLE refers to of the symbol called NAME with VERSION. */ extern void *dlvsym (void *__restrict __handle, diff --git a/dlfcn/dlrelocate.c b/dlfcn/dlrelocate.c new file mode 100644 index 0000000000..7ff0b74107 --- /dev/null +++ b/dlfcn/dlrelocate.c @@ -0,0 +1,68 @@ +/* Relocate the shared object loaded by `dlopen' with `RTLD_NORELOCATE'. + Copyright (C) 1995-2023 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include +#include + +struct dlrelocate_args +{ + /* The arguments to dlrelocate_doit. */ + void *handle; +}; + +static void +dlrelocate_doit (void *a) +{ + struct dlrelocate_args *args = (struct dlrelocate_args *) a; + + GLRO (dl_relocate) (args->handle); +} + +static int +dlrelocate_implementation (void *handle) +{ + struct dlrelocate_args args; + args.handle = handle; + + /* Protect against concurrent loads and unloads. */ + __rtld_lock_lock_recursive (GL(dl_load_lock)); + + int result = (_dlerror_run (dlrelocate_doit, &args) ? -1 : 0); + + __rtld_lock_unlock_recursive (GL(dl_load_lock)); + + return result; +} + +int +__dlrelocate (void *handle) +{ +#ifdef SHARED + if (GLRO (dl_dlfcn_hook) != NULL) + return GLRO (dl_dlfcn_hook)->dlrelocate (handle); +#endif + return dlrelocate_implementation (handle); +} +#ifdef SHARED +versioned_symbol (libc, __dlrelocate, dlrelocate, GLIBC_2_38); +#else /* !SHARED */ +/* Also used with _dlfcn_hook. */ +weak_alias (__dlrelocate, dlrelocate) +#endif /* !SHARED */ diff --git a/dlfcn/tst-noreloc.c b/dlfcn/tst-noreloc.c index 78f5a7fb25..a56e8102bb 100644 --- a/dlfcn/tst-noreloc.c +++ b/dlfcn/tst-noreloc.c @@ -44,6 +44,26 @@ do_test (void) error (EXIT_FAILURE, 0, "dlsym failed"); TEST_COMPARE (ctor_called, 1); + dlclose (handle); + ctor_called = 0; + handle = dlopen ("ctorlib1.so", RTLD_NOW | RTLD_NORELOCATE); + if (handle == NULL) + error (EXIT_FAILURE, 0, "cannot load: ctorlib1.so"); + + TEST_COMPARE (ctor_called, 0); + ret = dlrelocate (handle); + TEST_COMPARE (ret, 0); + /* dlrelocate() called ctors. */ + TEST_COMPARE (ctor_called, 1); + /* This time should fail. */ + ret = dlrelocate (handle); + TEST_COMPARE (ret, -1); + TEST_COMPARE (ctor_called, 1); + sym = dlsym (handle, "ref1"); + if (sym == NULL) + error (EXIT_FAILURE, 0, "dlsym failed"); + TEST_COMPARE (ctor_called, 1); + memset (&info, 0, sizeof (info)); ret = dladdr (sym, &info); if (ret == 0) diff --git a/elf/dl-open.c b/elf/dl-open.c index 5106c9d029..178593efe7 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -1043,3 +1043,17 @@ _dl_show_scope (struct link_map *l, int from) _dl_debug_printf (" no scope\n"); _dl_debug_printf ("\n"); } + +void +_dl_relocate (void *handle) +{ + struct link_map *map = handle; + + if (map->l_type != lt_loaded) + _dl_signal_error (EINVAL, map->l_name, NULL, + N_("invalid object for dlrelocate()")); + if (map->l_relocated || !map->l_reloc_deferred) + _dl_signal_error (EINVAL, map->l_name, NULL, + N_("object already relocated")); + _dl_object_reloc (handle); +} diff --git a/elf/rtld.c b/elf/rtld.c index c1e383b055..471509a72c 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -368,6 +368,7 @@ struct rtld_global_ro _rtld_global_ro attribute_relro = ._dl_lookup_symbol_x = _dl_lookup_symbol_x, ._dl_open = _dl_open, ._dl_close = _dl_close, + ._dl_relocate = _dl_relocate, ._dl_catch_error = _dl_catch_error, ._dl_error_free = _dl_error_free, ._dl_tls_get_addr_soft = _dl_tls_get_addr_soft, diff --git a/include/dlfcn.h b/include/dlfcn.h index ae25f05303..7bfd5b9085 100644 --- a/include/dlfcn.h +++ b/include/dlfcn.h @@ -57,6 +57,8 @@ extern void *__libc_dlvsym (void *map, const char *name, const char *version) attribute_hidden; extern int __libc_dlclose (void *__map) attribute_hidden; +extern int __libc_dlrelocate (void *__map) + attribute_hidden; /* Locate shared object containing the given address. */ #ifdef ElfW @@ -74,6 +76,9 @@ extern void _dl_close (void *map) attribute_hidden; extern void _dl_close_worker (struct link_map *map, bool force) attribute_hidden; +/* Relocate an object previously opened by _dl_open with RTLD_NORELOCATE. */ +extern void _dl_relocate (void *handle) attribute_hidden; + /* Look up NAME in shared object HANDLE (which may be RTLD_DEFAULT or RTLD_NEXT). WHO is the calling function, for RTLD_NEXT. Returns the symbol value, which may be NULL. */ @@ -101,6 +106,7 @@ struct dlfcn_hook /* Public interfaces. */ void *(*dlopen) (const char *file, int mode, void *dl_caller); int (*dlclose) (void *handle); + int (*dlrelocate) (void *handle); void *(*dlsym) (void *handle, const char *name, void *dl_caller); void *(*dlvsym) (void *handle, const char *name, const char *version, void *dl_caller); @@ -126,6 +132,7 @@ extern void *__dlopen (const char *file, int mode, void *caller); extern void *__dlmopen (Lmid_t nsid, const char *file, int mode, void *dl_caller); extern int __dlclose (void *handle); +extern int __dlrelocate (void *handle); extern void *__dlsym (void *handle, const char *name, void *dl_caller); extern void *__dlvsym (void *handle, const char *name, const char *version, void *dl_caller); diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index ba53176296..53601aa7e2 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -664,6 +664,7 @@ struct rtld_global_ro void *(*_dl_open) (const char *file, int mode, const void *caller_dlopen, Lmid_t nsid, int argc, char *argv[], char *env[]); void (*_dl_close) (void *map); + void (*_dl_relocate) (void *handle); /* libdl in a secondary namespace (after dlopen) must use _dl_catch_error from the main namespace, so it has to be exported in some way. */ diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist index 6925222ff3..53dc594256 100644 --- a/sysdeps/mach/hurd/i386/libc.abilist +++ b/sysdeps/mach/hurd/i386/libc.abilist @@ -2326,6 +2326,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlrelocate F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist index 0e2d9c3045..9571379cb9 100644 --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist @@ -2665,3 +2665,4 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlrelocate F diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist index f1bec1978d..cf34f3001c 100644 --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist @@ -2774,6 +2774,7 @@ GLIBC_2.38 __nldbl___isoc23_vsscanf F GLIBC_2.38 __nldbl___isoc23_vswscanf F GLIBC_2.38 __nldbl___isoc23_vwscanf F GLIBC_2.38 __nldbl___isoc23_wscanf F +GLIBC_2.38 dlrelocate F GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist index aa874b88d0..30ab1f6ca6 100644 --- a/sysdeps/unix/sysv/linux/arc/libc.abilist +++ b/sysdeps/unix/sysv/linux/arc/libc.abilist @@ -2426,3 +2426,4 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlrelocate F diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist index afbd57da6f..5ac9dbba3f 100644 --- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist @@ -546,6 +546,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlrelocate F GLIBC_2.4 _Exit F GLIBC_2.4 _IO_2_1_stderr_ D 0xa0 GLIBC_2.4 _IO_2_1_stdin_ D 0xa0 diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist index e7364cd3fe..3c745d1228 100644 --- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist @@ -543,6 +543,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlrelocate F GLIBC_2.4 _Exit F GLIBC_2.4 _IO_2_1_stderr_ D 0xa0 GLIBC_2.4 _IO_2_1_stdin_ D 0xa0 diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist index 913fa59215..fb7a6bd8ae 100644 --- a/sysdeps/unix/sysv/linux/csky/libc.abilist +++ b/sysdeps/unix/sysv/linux/csky/libc.abilist @@ -2702,3 +2702,4 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlrelocate F diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist index 43af3a9811..d03741e927 100644 --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist @@ -2651,6 +2651,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlrelocate F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist index af72f8fab0..a543c4e1f6 100644 --- a/sysdeps/unix/sysv/linux/i386/libc.abilist +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist @@ -2835,6 +2835,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlrelocate F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist index 48cbb0fa50..a0d098e09a 100644 --- a/sysdeps/unix/sysv/linux/ia64/libc.abilist +++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist @@ -2600,6 +2600,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlrelocate F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist index c15884bb0b..d5ccc5044b 100644 --- a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist +++ b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist @@ -2186,3 +2186,4 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlrelocate F diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist index 3738db81df..3b40a335f1 100644 --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist @@ -547,6 +547,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlrelocate F GLIBC_2.4 _Exit F GLIBC_2.4 _IO_2_1_stderr_ D 0x98 GLIBC_2.4 _IO_2_1_stdin_ D 0x98 diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist index ed13627752..5673e771f9 100644 --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist @@ -2778,6 +2778,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlrelocate F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist index 8357738621..6096f8749a 100644 --- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist @@ -2751,3 +2751,4 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlrelocate F diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist index 58c5da583d..c03f9a7681 100644 --- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist @@ -2748,3 +2748,4 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlrelocate F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist index d3741945cd..21748a22ca 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist @@ -2743,6 +2743,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlrelocate F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist index 5319fdc204..2f55942c24 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist @@ -2741,6 +2741,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlrelocate F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist index 1743ea6eb9..1e32a53947 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist @@ -2749,6 +2749,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlrelocate F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist index 9b1f53c6ac..ab272a1f23 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist @@ -2651,6 +2651,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlrelocate F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist index ae1c6ca1b5..fd9d42118e 100644 --- a/sysdeps/unix/sysv/linux/nios2/libc.abilist +++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist @@ -2790,3 +2790,4 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlrelocate F diff --git a/sysdeps/unix/sysv/linux/or1k/libc.abilist b/sysdeps/unix/sysv/linux/or1k/libc.abilist index a7c572c947..19599aa47d 100644 --- a/sysdeps/unix/sysv/linux/or1k/libc.abilist +++ b/sysdeps/unix/sysv/linux/or1k/libc.abilist @@ -2172,3 +2172,4 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlrelocate F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist index 074fa031a7..8687e97f3e 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist @@ -2817,6 +2817,7 @@ GLIBC_2.38 __nldbl___isoc23_vsscanf F GLIBC_2.38 __nldbl___isoc23_vswscanf F GLIBC_2.38 __nldbl___isoc23_vwscanf F GLIBC_2.38 __nldbl___isoc23_wscanf F +GLIBC_2.38 dlrelocate F GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist index dfcb4bd2d5..17bac95761 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist @@ -2850,6 +2850,7 @@ GLIBC_2.38 __nldbl___isoc23_vsscanf F GLIBC_2.38 __nldbl___isoc23_vswscanf F GLIBC_2.38 __nldbl___isoc23_vwscanf F GLIBC_2.38 __nldbl___isoc23_wscanf F +GLIBC_2.38 dlrelocate F GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist index 63bbccf3f9..fbf6bb0c8c 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist @@ -2571,6 +2571,7 @@ GLIBC_2.38 __nldbl___isoc23_vsscanf F GLIBC_2.38 __nldbl___isoc23_vswscanf F GLIBC_2.38 __nldbl___isoc23_vwscanf F GLIBC_2.38 __nldbl___isoc23_wscanf F +GLIBC_2.38 dlrelocate F GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist index ab85fd61ef..3fcc670919 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist @@ -2885,3 +2885,4 @@ GLIBC_2.38 __nldbl___isoc23_vsscanf F GLIBC_2.38 __nldbl___isoc23_vswscanf F GLIBC_2.38 __nldbl___isoc23_vwscanf F GLIBC_2.38 __nldbl___isoc23_wscanf F +GLIBC_2.38 dlrelocate F diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist index b716f5c763..20dea1535e 100644 --- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist +++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist @@ -2428,3 +2428,4 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlrelocate F diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist index 774e777b65..93084b7ed5 100644 --- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist @@ -2628,3 +2628,4 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlrelocate F diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist index 8625135c48..20c110ae92 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist @@ -2815,6 +2815,7 @@ GLIBC_2.38 __nldbl___isoc23_vsscanf F GLIBC_2.38 __nldbl___isoc23_vswscanf F GLIBC_2.38 __nldbl___isoc23_vwscanf F GLIBC_2.38 __nldbl___isoc23_wscanf F +GLIBC_2.38 dlrelocate F GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist index d00c7eb262..daa7300b54 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist @@ -2608,6 +2608,7 @@ GLIBC_2.38 __nldbl___isoc23_vsscanf F GLIBC_2.38 __nldbl___isoc23_vswscanf F GLIBC_2.38 __nldbl___isoc23_vwscanf F GLIBC_2.38 __nldbl___isoc23_wscanf F +GLIBC_2.38 dlrelocate F GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist index b63037241d..3bbcad60a6 100644 --- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist @@ -2658,6 +2658,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlrelocate F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist index d80055617d..d08611b8b5 100644 --- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist @@ -2655,6 +2655,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlrelocate F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist index 5be55c11d2..ce81a96967 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist @@ -2810,6 +2810,7 @@ GLIBC_2.38 __nldbl___isoc23_vsscanf F GLIBC_2.38 __nldbl___isoc23_vswscanf F GLIBC_2.38 __nldbl___isoc23_vwscanf F GLIBC_2.38 __nldbl___isoc23_wscanf F +GLIBC_2.38 dlrelocate F GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist index 475fdaae15..9cfe5dbe8c 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist @@ -2623,6 +2623,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlrelocate F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist index 6cfb928bc8..2b04d40ce5 100644 --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist @@ -2574,6 +2574,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlrelocate F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist index c735097172..e8c2ef8cb4 100644 --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist @@ -2680,3 +2680,4 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlrelocate F From patchwork Thu May 18 08:28:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: stsp X-Patchwork-Id: 69582 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 5636A382E809 for ; Thu, 18 May 2023 08:34:22 +0000 (GMT) X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from forward102c.mail.yandex.net (forward102c.mail.yandex.net [178.154.239.213]) by sourceware.org (Postfix) with ESMTPS id 0E17D3854179 for ; Thu, 18 May 2023 08:29:48 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 0E17D3854179 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=yandex.ru Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=yandex.ru Received: from mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net (mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net [IPv6:2a02:6b8:c0c:1186:0:640:38cb:0]) by forward102c.mail.yandex.net (Yandex) with ESMTP id 0E54A600A7 for ; Thu, 18 May 2023 11:29:47 +0300 (MSK) Received: by mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net (smtp/Yandex) with ESMTPSA id XTYe39MDZ0U0-Lo3BHGVk; Thu, 18 May 2023 11:29:46 +0300 X-Yandex-Fwd: 1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex.ru; s=mail; t=1684398586; bh=gTkyK+Xdn02mwlLMd9fncxkJHRYhq7rOeWqFn5VuaII=; h=Message-Id:Date:In-Reply-To:Cc:Subject:References:To:From; b=D1fw3D1/ixSoRWLumAdcqBBt0svfVjx9i7E6vcJ0R/TzEcjozoAiC1cl1yzPpEnCH WcUmFY1GvVYVu245bLlfrRg8SNaJ4toxRJ1125epD5OR+AifgDT2EVFn1chOGc+M9q 548hfioYgf8fhlS8wxBYo2fYzwVEFqvqLwVJ8h6U= Authentication-Results: mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net; dkim=pass header.i=@yandex.ru From: Stas Sergeev To: libc-alpha@sourceware.org Cc: Stas Sergeev Subject: [PATCH 12/14] implement RTLD_DI_MAPINFO dlinfo() request Date: Thu, 18 May 2023 13:28:52 +0500 Message-Id: <20230518082854.3903342-13-stsp2@yandex.ru> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230518082854.3903342-1-stsp2@yandex.ru> References: <20230518082854.3903342-1-stsp2@yandex.ru> MIME-Version: 1.0 X-Spam-Status: No, score=-11.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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: , Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" This request fills in the following structure: typedef struct { void *map_start; /* Beginning of mapping containing address. */ size_t map_length; /* Length of mapping. */ size_t map_align; /* Alignment of mapping. */ int relocated; /* Indicates whether an object was relocated. */ } Dl_mapinfo; This structure allows the user to move an unrelocated object. The test-suite was run on x86_64/64 and showed no regressions. Signed-off-by: Stas Sergeev --- dlfcn/dlfcn.h | 15 ++++++++++++++- dlfcn/dlinfo.c | 18 ++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/dlfcn/dlfcn.h b/dlfcn/dlfcn.h index c3e228c667..7671c187a3 100644 --- a/dlfcn/dlfcn.h +++ b/dlfcn/dlfcn.h @@ -170,7 +170,12 @@ enum the number of program headers in the array. */ RTLD_DI_PHDR = 11, - RTLD_DI_MAX = 11 + /* Treat ARG as Dl_mapinfo *, and store the mapping information + at that location. The dlinfo call returns 0 on success or + -1 on failure. */ + RTLD_DI_MAPINFO = 12, + + RTLD_DI_MAX = 12 }; @@ -203,6 +208,14 @@ typedef struct # endif } Dl_serinfo; +typedef struct +{ + void *map_start; /* Beginning of mapping containing address. */ + size_t map_length; /* Length of mapping. */ + size_t map_align; /* Alignment of mapping. */ + int relocated; /* Indicates whether an object was relocated. */ +} Dl_mapinfo; + struct dl_find_object { __extension__ unsigned long long int dlfo_flags; diff --git a/dlfcn/dlinfo.c b/dlfcn/dlinfo.c index 1b5dd90ae5..8d7db7dbb8 100644 --- a/dlfcn/dlinfo.c +++ b/dlfcn/dlinfo.c @@ -85,6 +85,24 @@ dlinfo_doit (void *argsblock) *(const ElfW(Phdr) **) args->arg = l->l_phdr; args->result = l->l_phnum; break; + + case RTLD_DI_MAPINFO: + { + Dl_mapinfo *info = (Dl_mapinfo *) args->arg; + __rtld_lock_lock_recursive (GL(dl_load_lock)); + if (l->l_contiguous) + { + info->map_start = (void *) l->l_map_start; + info->map_length = l->l_map_end - l->l_map_start; + info->map_align = l->l_map_align; + info->relocated = l->l_relocated; + args->result = 0; + } + else + args->result = -1; + __rtld_lock_unlock_recursive (GL(dl_load_lock)); + break; + } } } From patchwork Thu May 18 08:28:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: stsp X-Patchwork-Id: 69585 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 979C538323F1 for ; Thu, 18 May 2023 08:35:26 +0000 (GMT) X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from forward102c.mail.yandex.net (forward102c.mail.yandex.net [178.154.239.213]) by sourceware.org (Postfix) with ESMTPS id 9E5583857344 for ; Thu, 18 May 2023 08:29:49 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 9E5583857344 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=yandex.ru Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=yandex.ru Received: from mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net (mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net [IPv6:2a02:6b8:c0c:1186:0:640:38cb:0]) by forward102c.mail.yandex.net (Yandex) with ESMTP id 9FDDD6004A for ; Thu, 18 May 2023 11:29:48 +0300 (MSK) Received: by mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net (smtp/Yandex) with ESMTPSA id XTYe39MDZ0U0-CDEHeSwe; Thu, 18 May 2023 11:29:47 +0300 X-Yandex-Fwd: 1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex.ru; s=mail; t=1684398587; bh=ndI4ZOtgwpeH6JGyKgZ7XfWvQp+5A/z+Fa4GIldfbBY=; h=Message-Id:Date:In-Reply-To:Cc:Subject:References:To:From; b=VQeWyglQ7Ne+Yh5zyUX69OXfRXZ2urqK7fa0UgIREwzkTwJrkSlvtg0xOoDkpTT3u bJNNZkHzronft9SM1u9vqyt6ZjIKbZ2+WvI75N8fhI3b4/WVjPRNyMjhG6Jti/lskP 91uw0cnmy77wZ1tP2+oCMIJw9ogZ1dSiJsJOLNUg= Authentication-Results: mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net; dkim=pass header.i=@yandex.ru From: Stas Sergeev To: libc-alpha@sourceware.org Cc: Stas Sergeev Subject: [PATCH 13/14] implement dlset_object_base() function Date: Thu, 18 May 2023 13:28:53 +0500 Message-Id: <20230518082854.3903342-14-stsp2@yandex.ru> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230518082854.3903342-1-stsp2@yandex.ru> References: <20230518082854.3903342-1-stsp2@yandex.ru> MIME-Version: 1.0 X-Spam-Status: No, score=-11.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, KAM_SHORT, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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: , Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" `int dlset_object_base(void *handle, void *addr)' - new function to set the new base address of an unrelocated object, after it was moved. Returns error if the object is already relocated. The base address set by this function, will be used when relocation is performed. The test-suite was run on x86_64/64 and showed no regressions. Signed-off-by: Stas Sergeev --- dlfcn/Makefile | 1 + dlfcn/Versions | 1 + dlfcn/dlfcn.h | 4 + dlfcn/dlset_object_base.c | 124 ++++++++++++++++++ dlfcn/tst-noreloc.c | 44 +++++++ include/dlfcn.h | 4 + sysdeps/mach/hurd/i386/libc.abilist | 1 + sysdeps/unix/sysv/linux/aarch64/libc.abilist | 1 + sysdeps/unix/sysv/linux/alpha/libc.abilist | 1 + sysdeps/unix/sysv/linux/arc/libc.abilist | 1 + sysdeps/unix/sysv/linux/arm/be/libc.abilist | 1 + sysdeps/unix/sysv/linux/arm/le/libc.abilist | 1 + sysdeps/unix/sysv/linux/csky/libc.abilist | 1 + sysdeps/unix/sysv/linux/hppa/libc.abilist | 1 + sysdeps/unix/sysv/linux/i386/libc.abilist | 1 + sysdeps/unix/sysv/linux/ia64/libc.abilist | 1 + .../sysv/linux/loongarch/lp64/libc.abilist | 1 + .../sysv/linux/m68k/coldfire/libc.abilist | 1 + .../unix/sysv/linux/m68k/m680x0/libc.abilist | 1 + .../sysv/linux/microblaze/be/libc.abilist | 1 + .../sysv/linux/microblaze/le/libc.abilist | 1 + .../sysv/linux/mips/mips32/fpu/libc.abilist | 1 + .../sysv/linux/mips/mips32/nofpu/libc.abilist | 1 + .../sysv/linux/mips/mips64/n32/libc.abilist | 1 + .../sysv/linux/mips/mips64/n64/libc.abilist | 1 + sysdeps/unix/sysv/linux/nios2/libc.abilist | 1 + sysdeps/unix/sysv/linux/or1k/libc.abilist | 1 + .../linux/powerpc/powerpc32/fpu/libc.abilist | 1 + .../powerpc/powerpc32/nofpu/libc.abilist | 1 + .../linux/powerpc/powerpc64/be/libc.abilist | 1 + .../linux/powerpc/powerpc64/le/libc.abilist | 1 + .../unix/sysv/linux/riscv/rv32/libc.abilist | 1 + .../unix/sysv/linux/riscv/rv64/libc.abilist | 1 + .../unix/sysv/linux/s390/s390-32/libc.abilist | 1 + .../unix/sysv/linux/s390/s390-64/libc.abilist | 1 + sysdeps/unix/sysv/linux/sh/be/libc.abilist | 1 + sysdeps/unix/sysv/linux/sh/le/libc.abilist | 1 + .../sysv/linux/sparc/sparc32/libc.abilist | 1 + .../sysv/linux/sparc/sparc64/libc.abilist | 1 + .../unix/sysv/linux/x86_64/64/libc.abilist | 1 + .../unix/sysv/linux/x86_64/x32/libc.abilist | 1 + 41 files changed, 213 insertions(+) create mode 100644 dlfcn/dlset_object_base.c diff --git a/dlfcn/Makefile b/dlfcn/Makefile index fb56b8aecb..da486a9b01 100644 --- a/dlfcn/Makefile +++ b/dlfcn/Makefile @@ -27,6 +27,7 @@ routines = \ dladdr1 \ dlclose \ dlrelocate \ + dlset_object_base \ dlerror \ dlinfo \ dlmopen \ diff --git a/dlfcn/Versions b/dlfcn/Versions index 61ab01d764..8b1566b7c7 100644 --- a/dlfcn/Versions +++ b/dlfcn/Versions @@ -30,6 +30,7 @@ libc { } GLIBC_2.38 { dlrelocate; + dlset_object_base; } GLIBC_PRIVATE { __libc_dlerror_result; diff --git a/dlfcn/dlfcn.h b/dlfcn/dlfcn.h index 7671c187a3..eee6343833 100644 --- a/dlfcn/dlfcn.h +++ b/dlfcn/dlfcn.h @@ -71,6 +71,10 @@ extern void *dlmopen (Lmid_t __nsid, const char *__file, int __mode) __THROWNL; /* Relocate a shared object opened by `dlopen' with `RTLD_NORELOCATE'. */ extern int dlrelocate (void *__handle) __THROWNL __nonnull ((1)); +/* Set a new base address of a shared object opened by `dlopen' with + `RTLD_NORELOCATE' and then moved by user. */ +extern int dlset_object_base (void *handle, void *base); + /* Find the run-time address in the shared object HANDLE refers to of the symbol called NAME with VERSION. */ extern void *dlvsym (void *__restrict __handle, diff --git a/dlfcn/dlset_object_base.c b/dlfcn/dlset_object_base.c new file mode 100644 index 0000000000..9221a6b72e --- /dev/null +++ b/dlfcn/dlset_object_base.c @@ -0,0 +1,124 @@ +/* Set the new base address for shared object loaded by `dlopen' with + `RTLD_NORELOCATE' and moved by the user. + Copyright (C) 1995-2023 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include +#include +#include + +static void +adjust_dyn_info (ElfW(Dyn) **info, ptrdiff_t delta) +{ +# define ADJUST_DYN_INFO(tag) \ + do \ + { \ + if (info[tag] != NULL) \ + info[tag]->d_un.d_ptr += delta; \ + } \ + while (0) + + ADJUST_DYN_INFO (DT_HASH); + ADJUST_DYN_INFO (DT_PLTGOT); + ADJUST_DYN_INFO (DT_STRTAB); + ADJUST_DYN_INFO (DT_SYMTAB); + ADJUST_DYN_INFO (DT_RELR); + ADJUST_DYN_INFO (DT_JMPREL); + ADJUST_DYN_INFO (VERSYMIDX (DT_VERSYM)); + ADJUST_DYN_INFO (ADDRIDX (DT_GNU_HASH)); +# undef ADJUST_DYN_INFO + + /* DT_RELA/DT_REL are mandatory. But they may have zero value if + there is DT_RELR. Don't relocate them if they are zero. */ +# define ADJUST_DYN_INFO(tag) \ + do \ + if (info[tag] != NULL && info[tag]->d_un.d_ptr != 0) \ + info[tag]->d_un.d_ptr += delta; \ + while (0) + + ADJUST_DYN_INFO (DT_RELA); + ADJUST_DYN_INFO (DT_REL); +# undef ADJUST_DYN_INFO +} + +static int +dlset_object_base_implementation (void *handle, void *base) +{ + struct link_map *l = handle; + int result = 0; + + /* Protect against concurrent loads and unloads. */ + __rtld_lock_lock_recursive (GL(dl_load_lock)); + + if (l->l_relocated) + result = -1; + else + { + ptrdiff_t delta = (uintptr_t) base - l->l_map_start; + if (delta) + { + int i; + + l->l_map_start += delta; + l->l_map_end += delta; + l->l_addr += delta; + l->l_text_end += delta; + l->l_entry += delta; + if (!l->l_phdr_allocated) + l->l_phdr = (__typeof (l->l_phdr)) (((uintptr_t) l->l_phdr) + + delta); + l->l_ld = (__typeof (l->l_ld)) (((uintptr_t) l->l_ld) + delta); + for (i = 0; i < array_length (l->l_info); i++) + if (l->l_info[i]) + l->l_info[i] = (__typeof (l->l_info[i])) (((uintptr_t) + l->l_info[i]) + + delta); + l->l_versyms = (__typeof (l->l_versyms)) (((uintptr_t) l->l_versyms) + + delta); + l->l_gnu_bitmask = (__typeof (l->l_gnu_bitmask)) + (((uintptr_t) l->l_gnu_bitmask) + + delta); + l->l_chain = (__typeof (l->l_chain)) (((uintptr_t) l->l_chain) + + delta); + l->l_buckets = (__typeof (l->l_buckets)) (((uintptr_t) l->l_buckets) + + delta); + adjust_dyn_info (l->l_info, delta); + } + } + + __rtld_lock_unlock_recursive (GL(dl_load_lock)); + + return result; +} + +int +__dlset_object_base (void *handle, void *base) +{ +#ifdef SHARED + if (GLRO (dl_dlfcn_hook) != NULL) + return GLRO (dl_dlfcn_hook)->dlset_object_base (handle, base); +#endif + return dlset_object_base_implementation (handle, base); +} +#ifdef SHARED +versioned_symbol (libc, __dlset_object_base, dlset_object_base, GLIBC_2_38); +#else /* !SHARED */ +/* Also used with _dlfcn_hook. */ +weak_alias (__dlset_object_base, dlset_object_base) +#endif /* !SHARED */ diff --git a/dlfcn/tst-noreloc.c b/dlfcn/tst-noreloc.c index a56e8102bb..96c05a4b06 100644 --- a/dlfcn/tst-noreloc.c +++ b/dlfcn/tst-noreloc.c @@ -22,10 +22,37 @@ #include #include #include +#include +#include +#include #include int ctor_called; +static void move_object (void *handle) +{ + int ret; + Dl_mapinfo mapinfo; + void *new_addr; + + ret = dlinfo (handle, RTLD_DI_MAPINFO, &mapinfo); + TEST_COMPARE (ret, 0); + TEST_COMPARE (mapinfo.relocated, 0); + if (mapinfo.map_align != getpagesize ()) + error (EXIT_FAILURE, 0, "unsupported map alignment"); +#ifndef MAP_32BIT +#define MAP_32BIT 0 +#endif + new_addr = mmap (NULL, mapinfo.map_length, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_32BIT, -1, 0); + if (new_addr == MAP_FAILED) + error (EXIT_FAILURE, 0, "cannot mmap buffer"); + memcpy (new_addr, mapinfo.map_start, mapinfo.map_length); + ret = dlset_object_base (handle, new_addr); + TEST_COMPARE (ret, 0); + munmap (mapinfo.map_start, mapinfo.map_length); +} + static int do_test (void) { @@ -64,10 +91,27 @@ do_test (void) error (EXIT_FAILURE, 0, "dlsym failed"); TEST_COMPARE (ctor_called, 1); + dlclose (handle); + ctor_called = 0; + handle = dlopen ("ctorlib1.so", RTLD_NOW | RTLD_NORELOCATE); + if (handle == NULL) + error (EXIT_FAILURE, 0, "cannot load: ctorlib1.so"); + + move_object (handle); + + TEST_COMPARE (ctor_called, 0); + sym = dlsym (handle, "ref1"); + if (sym == NULL) + error (EXIT_FAILURE, 0, "dlsym failed"); + TEST_COMPARE (ctor_called, 1); + memset (&info, 0, sizeof (info)); ret = dladdr (sym, &info); if (ret == 0) error (EXIT_FAILURE, 0, "dladdr failed"); +#if MAP_32BIT != 0 + TEST_VERIFY ((uintptr_t) info.dli_fbase < 0x100000000); +#endif printf ("ret = %d\n", ret); printf ("info.dli_fname = %p (\"%s\")\n", info.dli_fname, info.dli_fname); diff --git a/include/dlfcn.h b/include/dlfcn.h index 7bfd5b9085..96950f72dc 100644 --- a/include/dlfcn.h +++ b/include/dlfcn.h @@ -59,6 +59,8 @@ extern int __libc_dlclose (void *__map) attribute_hidden; extern int __libc_dlrelocate (void *__map) attribute_hidden; +extern int __libc_dlset_object_base (void *__map, void *base) + attribute_hidden; /* Locate shared object containing the given address. */ #ifdef ElfW @@ -107,6 +109,7 @@ struct dlfcn_hook void *(*dlopen) (const char *file, int mode, void *dl_caller); int (*dlclose) (void *handle); int (*dlrelocate) (void *handle); + int (*dlset_object_base) (void *handle, void *base); void *(*dlsym) (void *handle, const char *name, void *dl_caller); void *(*dlvsym) (void *handle, const char *name, const char *version, void *dl_caller); @@ -133,6 +136,7 @@ extern void *__dlmopen (Lmid_t nsid, const char *file, int mode, void *dl_caller); extern int __dlclose (void *handle); extern int __dlrelocate (void *handle); +extern int __dlset_object_base (void *handle, void *base); extern void *__dlsym (void *handle, const char *name, void *dl_caller); extern void *__dlvsym (void *handle, const char *name, const char *version, void *dl_caller); diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist index 53dc594256..6d1c233f3d 100644 --- a/sysdeps/mach/hurd/i386/libc.abilist +++ b/sysdeps/mach/hurd/i386/libc.abilist @@ -2327,6 +2327,7 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 dlrelocate F +GLIBC_2.38 dlset_object_base F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist index 9571379cb9..f37e388df3 100644 --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist @@ -2666,3 +2666,4 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 dlrelocate F +GLIBC_2.38 dlset_object_base F diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist index cf34f3001c..e0074f1ead 100644 --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist @@ -2775,6 +2775,7 @@ GLIBC_2.38 __nldbl___isoc23_vswscanf F GLIBC_2.38 __nldbl___isoc23_vwscanf F GLIBC_2.38 __nldbl___isoc23_wscanf F GLIBC_2.38 dlrelocate F +GLIBC_2.38 dlset_object_base F GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist index 30ab1f6ca6..14eb175e1a 100644 --- a/sysdeps/unix/sysv/linux/arc/libc.abilist +++ b/sysdeps/unix/sysv/linux/arc/libc.abilist @@ -2427,3 +2427,4 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 dlrelocate F +GLIBC_2.38 dlset_object_base F diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist index 5ac9dbba3f..6fbe0f2c14 100644 --- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist @@ -547,6 +547,7 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 dlrelocate F +GLIBC_2.38 dlset_object_base F GLIBC_2.4 _Exit F GLIBC_2.4 _IO_2_1_stderr_ D 0xa0 GLIBC_2.4 _IO_2_1_stdin_ D 0xa0 diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist index 3c745d1228..6c3b69a3eb 100644 --- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist @@ -544,6 +544,7 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 dlrelocate F +GLIBC_2.38 dlset_object_base F GLIBC_2.4 _Exit F GLIBC_2.4 _IO_2_1_stderr_ D 0xa0 GLIBC_2.4 _IO_2_1_stdin_ D 0xa0 diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist index fb7a6bd8ae..9d7e9d2f98 100644 --- a/sysdeps/unix/sysv/linux/csky/libc.abilist +++ b/sysdeps/unix/sysv/linux/csky/libc.abilist @@ -2703,3 +2703,4 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 dlrelocate F +GLIBC_2.38 dlset_object_base F diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist index d03741e927..ba52a9d463 100644 --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist @@ -2652,6 +2652,7 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 dlrelocate F +GLIBC_2.38 dlset_object_base F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist index a543c4e1f6..3d71ddd3f4 100644 --- a/sysdeps/unix/sysv/linux/i386/libc.abilist +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist @@ -2836,6 +2836,7 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 dlrelocate F +GLIBC_2.38 dlset_object_base F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist index a0d098e09a..8ccb96eeee 100644 --- a/sysdeps/unix/sysv/linux/ia64/libc.abilist +++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist @@ -2601,6 +2601,7 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 dlrelocate F +GLIBC_2.38 dlset_object_base F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist index d5ccc5044b..08d8c210eb 100644 --- a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist +++ b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist @@ -2187,3 +2187,4 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 dlrelocate F +GLIBC_2.38 dlset_object_base F diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist index 3b40a335f1..6486192065 100644 --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist @@ -548,6 +548,7 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 dlrelocate F +GLIBC_2.38 dlset_object_base F GLIBC_2.4 _Exit F GLIBC_2.4 _IO_2_1_stderr_ D 0x98 GLIBC_2.4 _IO_2_1_stdin_ D 0x98 diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist index 5673e771f9..a0edd6aaba 100644 --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist @@ -2779,6 +2779,7 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 dlrelocate F +GLIBC_2.38 dlset_object_base F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist index 6096f8749a..3602d95f46 100644 --- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist @@ -2752,3 +2752,4 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 dlrelocate F +GLIBC_2.38 dlset_object_base F diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist index c03f9a7681..da4f93ad6f 100644 --- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist @@ -2749,3 +2749,4 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 dlrelocate F +GLIBC_2.38 dlset_object_base F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist index 21748a22ca..5c581c7d7d 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist @@ -2744,6 +2744,7 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 dlrelocate F +GLIBC_2.38 dlset_object_base F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist index 2f55942c24..b7832c343d 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist @@ -2742,6 +2742,7 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 dlrelocate F +GLIBC_2.38 dlset_object_base F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist index 1e32a53947..f0becc0684 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist @@ -2750,6 +2750,7 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 dlrelocate F +GLIBC_2.38 dlset_object_base F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist index ab272a1f23..6c70fd76d2 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist @@ -2652,6 +2652,7 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 dlrelocate F +GLIBC_2.38 dlset_object_base F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist index fd9d42118e..8c8784986c 100644 --- a/sysdeps/unix/sysv/linux/nios2/libc.abilist +++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist @@ -2791,3 +2791,4 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 dlrelocate F +GLIBC_2.38 dlset_object_base F diff --git a/sysdeps/unix/sysv/linux/or1k/libc.abilist b/sysdeps/unix/sysv/linux/or1k/libc.abilist index 19599aa47d..8dbeabbed1 100644 --- a/sysdeps/unix/sysv/linux/or1k/libc.abilist +++ b/sysdeps/unix/sysv/linux/or1k/libc.abilist @@ -2173,3 +2173,4 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 dlrelocate F +GLIBC_2.38 dlset_object_base F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist index 8687e97f3e..c6066679b1 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist @@ -2818,6 +2818,7 @@ GLIBC_2.38 __nldbl___isoc23_vswscanf F GLIBC_2.38 __nldbl___isoc23_vwscanf F GLIBC_2.38 __nldbl___isoc23_wscanf F GLIBC_2.38 dlrelocate F +GLIBC_2.38 dlset_object_base F GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist index 17bac95761..295dd909b9 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist @@ -2851,6 +2851,7 @@ GLIBC_2.38 __nldbl___isoc23_vswscanf F GLIBC_2.38 __nldbl___isoc23_vwscanf F GLIBC_2.38 __nldbl___isoc23_wscanf F GLIBC_2.38 dlrelocate F +GLIBC_2.38 dlset_object_base F GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist index fbf6bb0c8c..2cd0bce2fb 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist @@ -2572,6 +2572,7 @@ GLIBC_2.38 __nldbl___isoc23_vswscanf F GLIBC_2.38 __nldbl___isoc23_vwscanf F GLIBC_2.38 __nldbl___isoc23_wscanf F GLIBC_2.38 dlrelocate F +GLIBC_2.38 dlset_object_base F GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist index 3fcc670919..046d506558 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist @@ -2886,3 +2886,4 @@ GLIBC_2.38 __nldbl___isoc23_vswscanf F GLIBC_2.38 __nldbl___isoc23_vwscanf F GLIBC_2.38 __nldbl___isoc23_wscanf F GLIBC_2.38 dlrelocate F +GLIBC_2.38 dlset_object_base F diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist index 20dea1535e..0dc396c19d 100644 --- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist +++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist @@ -2429,3 +2429,4 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 dlrelocate F +GLIBC_2.38 dlset_object_base F diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist index 93084b7ed5..95dee89535 100644 --- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist @@ -2629,3 +2629,4 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 dlrelocate F +GLIBC_2.38 dlset_object_base F diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist index 20c110ae92..9c99e15f6d 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist @@ -2816,6 +2816,7 @@ GLIBC_2.38 __nldbl___isoc23_vswscanf F GLIBC_2.38 __nldbl___isoc23_vwscanf F GLIBC_2.38 __nldbl___isoc23_wscanf F GLIBC_2.38 dlrelocate F +GLIBC_2.38 dlset_object_base F GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist index daa7300b54..ec91d47437 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist @@ -2609,6 +2609,7 @@ GLIBC_2.38 __nldbl___isoc23_vswscanf F GLIBC_2.38 __nldbl___isoc23_vwscanf F GLIBC_2.38 __nldbl___isoc23_wscanf F GLIBC_2.38 dlrelocate F +GLIBC_2.38 dlset_object_base F GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist index 3bbcad60a6..4c91900238 100644 --- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist @@ -2659,6 +2659,7 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 dlrelocate F +GLIBC_2.38 dlset_object_base F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist index d08611b8b5..89c7a41098 100644 --- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist @@ -2656,6 +2656,7 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 dlrelocate F +GLIBC_2.38 dlset_object_base F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist index ce81a96967..0d65f5f357 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist @@ -2811,6 +2811,7 @@ GLIBC_2.38 __nldbl___isoc23_vswscanf F GLIBC_2.38 __nldbl___isoc23_vwscanf F GLIBC_2.38 __nldbl___isoc23_wscanf F GLIBC_2.38 dlrelocate F +GLIBC_2.38 dlset_object_base F GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist index 9cfe5dbe8c..c39c641445 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist @@ -2624,6 +2624,7 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 dlrelocate F +GLIBC_2.38 dlset_object_base F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist index 2b04d40ce5..2243b7a05e 100644 --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist @@ -2575,6 +2575,7 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 dlrelocate F +GLIBC_2.38 dlset_object_base F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist index e8c2ef8cb4..449991c7bd 100644 --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist @@ -2681,3 +2681,4 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 dlrelocate F +GLIBC_2.38 dlset_object_base F From patchwork Thu May 18 08:28:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: stsp X-Patchwork-Id: 69584 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 337393882050 for ; Thu, 18 May 2023 08:34:58 +0000 (GMT) X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from forward103b.mail.yandex.net (forward103b.mail.yandex.net [IPv6:2a02:6b8:c02:900:1:45:d181:d103]) by sourceware.org (Postfix) with ESMTPS id EBF943856976 for ; Thu, 18 May 2023 08:29:50 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org EBF943856976 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=yandex.ru Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=yandex.ru Received: from mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net (mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net [IPv6:2a02:6b8:c0c:1186:0:640:38cb:0]) by forward103b.mail.yandex.net (Yandex) with ESMTP id 88A7E60033 for ; Thu, 18 May 2023 11:29:49 +0300 (MSK) Received: by mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net (smtp/Yandex) with ESMTPSA id XTYe39MDZ0U0-aalOJ8Er; Thu, 18 May 2023 11:29:49 +0300 X-Yandex-Fwd: 1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex.ru; s=mail; t=1684398589; bh=A3HbRwdB0rg4zGImcm+WBWHHqE/bw5mFc4mU3tIEVEw=; h=Message-Id:Date:In-Reply-To:Cc:Subject:References:To:From; b=VB5AnxAbw66qZS651CbCyE6BO4xC161WbHQfZuv0qg915rzdd/iO/dzbpAKjgK2Mm OzNZgu+LDAOyPeEpA8ja90VnWs0omkhxkyoP72/Sv2PaMmWSX3QaklFK3jIqo6oV+o 3AL2l0TdKxqQLTvi6EjyuPJS++tufOQy5FcXJrDc= Authentication-Results: mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net; dkim=pass header.i=@yandex.ru From: Stas Sergeev To: libc-alpha@sourceware.org Cc: Stas Sergeev Subject: [PATCH 14/14] implement RTLD_DI_DEPLIST dlinfo() request Date: Thu, 18 May 2023 13:28:54 +0500 Message-Id: <20230518082854.3903342-15-stsp2@yandex.ru> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230518082854.3903342-1-stsp2@yandex.ru> References: <20230518082854.3903342-1-stsp2@yandex.ru> MIME-Version: 1.0 X-Spam-Status: No, score=-11.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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: , Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" `RTLD_DI_DEPLIST' is a new dlinfo() request that fills in this structure: typedef struct { void **deps; /* Array of handles for the deps. */ unsigned int ndeps; /* Number of entries in the list. */ } Dl_deplist; It is needed if the user wants to move also the dependencies of the loaded solib. In this case he needs to traverse the `deps' array, make RTLD_DI_MAPINFO dlinfo() request per each handle from an array, find the object he needs by inspecting the filled-in Dl_mapinfo structure, make sure this object is not relocated yet, and move it, calling dlset_object_base() at the end. The test-suite was run on x86_64/64 and showed no regressions. Signed-off-by: Stas Sergeev --- dlfcn/Makefile | 3 +++ dlfcn/ctorlib1.c | 9 ++++++--- dlfcn/dlfcn.h | 13 ++++++++++++- dlfcn/dlinfo.c | 14 ++++++++++++++ dlfcn/tst-noreloc.c | 30 +++++++++++++++++++++++++++--- 5 files changed, 62 insertions(+), 7 deletions(-) diff --git a/dlfcn/Makefile b/dlfcn/Makefile index da486a9b01..0d6b16c820 100644 --- a/dlfcn/Makefile +++ b/dlfcn/Makefile @@ -104,6 +104,9 @@ $(objpfx)glrefmain.out: $(objpfx)glrefmain \ $(objpfx)failtest.out: $(objpfx)failtestmod.so $(objpfx)tst-dladdr.out: $(objpfx)glreflib1.so + +$(objpfx)ctorlib1.so: $(objpfx)glreflib1.so +LDFLAGS-ctorlib1 = $(objpfx)glreflib1.so $(objpfx)tst-noreloc.out: $(objpfx)ctorlib1.so LDFLAGS-tst-noreloc = $(LDFLAGS-rdynamic) diff --git a/dlfcn/ctorlib1.c b/dlfcn/ctorlib1.c index cf7a9096ea..7d410f6c71 100644 --- a/dlfcn/ctorlib1.c +++ b/dlfcn/ctorlib1.c @@ -21,10 +21,12 @@ #include extern int ref1 (void); + +extern int cref1 (void); int -ref1 (void) +cref1 (void) { - return 42; + return 34; } void __attribute__((constructor)) @@ -32,5 +34,6 @@ ctor (void) { int *ct = (int *) dlsym (RTLD_DEFAULT, "ctor_called"); assert (ct); - (*ct)++; + if (ref1 () == 42) + (*ct)++; } diff --git a/dlfcn/dlfcn.h b/dlfcn/dlfcn.h index eee6343833..5b36330aa9 100644 --- a/dlfcn/dlfcn.h +++ b/dlfcn/dlfcn.h @@ -179,7 +179,12 @@ enum -1 on failure. */ RTLD_DI_MAPINFO = 12, - RTLD_DI_MAX = 12 + /* Treat ARG as Dl_deplist *, and store the dependency link-maps + at that location. The dlinfo call returns 0 on success or + -1 on failure. */ + RTLD_DI_DEPLIST = 13, + + RTLD_DI_MAX = 13 }; @@ -220,6 +225,12 @@ typedef struct int relocated; /* Indicates whether an object was relocated. */ } Dl_mapinfo; +typedef struct +{ + void **deps; /* Array of handles for the deps. */ + unsigned int ndeps; /* Number of entries in the list. */ +} Dl_deplist; + struct dl_find_object { __extension__ unsigned long long int dlfo_flags; diff --git a/dlfcn/dlinfo.c b/dlfcn/dlinfo.c index 8d7db7dbb8..4eb96bc476 100644 --- a/dlfcn/dlinfo.c +++ b/dlfcn/dlinfo.c @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -103,6 +104,19 @@ dlinfo_doit (void *argsblock) __rtld_lock_unlock_recursive (GL(dl_load_lock)); break; } + + case RTLD_DI_DEPLIST: + { + int i = 0; + Dl_deplist *list = (Dl_deplist *) args->arg; + assert (l == l->l_initfini[0]); + list->deps = (void **) &l->l_initfini[1]; /* Skip our own handle. */ + while (list->deps[i]) + i++; + list->ndeps = i; + args->result = 0; + break; + } } } diff --git a/dlfcn/tst-noreloc.c b/dlfcn/tst-noreloc.c index 96c05a4b06..846d2b9321 100644 --- a/dlfcn/tst-noreloc.c +++ b/dlfcn/tst-noreloc.c @@ -29,14 +29,17 @@ int ctor_called; -static void move_object (void *handle) +static void move_object (void *handle, int is_dep) { int ret; Dl_mapinfo mapinfo; void *new_addr; ret = dlinfo (handle, RTLD_DI_MAPINFO, &mapinfo); - TEST_COMPARE (ret, 0); + if (!is_dep) + TEST_COMPARE (ret, 0); + if (is_dep && (ret == -1 || mapinfo.relocated)) + return; TEST_COMPARE (mapinfo.relocated, 0); if (mapinfo.map_align != getpagesize ()) error (EXIT_FAILURE, 0, "unsupported map alignment"); @@ -59,7 +62,10 @@ do_test (void) void *handle; int (*sym) (void); Dl_info info; + Dl_info info2; + Dl_deplist deplist; int ret; + int i; handle = dlopen ("ctorlib1.so", RTLD_NOW | RTLD_NORELOCATE); if (handle == NULL) @@ -97,7 +103,11 @@ do_test (void) if (handle == NULL) error (EXIT_FAILURE, 0, "cannot load: ctorlib1.so"); - move_object (handle); + move_object (handle, 0); + ret = dlinfo (handle, RTLD_DI_DEPLIST, &deplist); + TEST_COMPARE (ret, 0); + for (i = 0; i < deplist.ndeps; i++) + move_object (deplist.deps[i], 1); TEST_COMPARE (ctor_called, 0); sym = dlsym (handle, "ref1"); @@ -113,6 +123,20 @@ do_test (void) TEST_VERIFY ((uintptr_t) info.dli_fbase < 0x100000000); #endif + sym = dlsym (handle, "cref1"); + if (sym == NULL) + error (EXIT_FAILURE, 0, "dlsym failed"); + TEST_COMPARE (ctor_called, 1); + + memset (&info2, 0, sizeof (info2)); + ret = dladdr (sym, &info2); + if (ret == 0) + error (EXIT_FAILURE, 0, "dladdr failed"); +#if MAP_32BIT != 0 + TEST_VERIFY ((uintptr_t) info2.dli_fbase < 0x100000000); +#endif + TEST_VERIFY (info2.dli_fbase != info.dli_fbase); + printf ("ret = %d\n", ret); printf ("info.dli_fname = %p (\"%s\")\n", info.dli_fname, info.dli_fname); printf ("info.dli_fbase = %p\n", info.dli_fbase);