From patchwork Wed Jul 31 16:00:50 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 1967195 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=vwlArD40; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=8.43.85.97; helo=server2.sourceware.org; envelope-from=libc-alpha-bounces~incoming=patchwork.ozlabs.org@sourceware.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WYxfh3mtRz1ybX for ; Thu, 1 Aug 2024 02:01:32 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 6FEE53858294 for ; Wed, 31 Jul 2024 16:01:29 +0000 (GMT) X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pl1-x62a.google.com (mail-pl1-x62a.google.com [IPv6:2607:f8b0:4864:20::62a]) by sourceware.org (Postfix) with ESMTPS id CF0EB3858C35 for ; Wed, 31 Jul 2024 16:01:10 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org CF0EB3858C35 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linaro.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org CF0EB3858C35 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::62a ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722441673; cv=none; b=GhdmVUgi25eHizM1z5E2bWlKqp//AHkuvdbw5uD8zXj43LOnry7GJspTKi9HW4nuZzmFEHpA+AD6vOTq14CRgaeOLWJu5O2GaAjBUsnuu1bIUNFQhIjqSDy2+R6nYkIUP6ENFojsXl9D5UGzddaccL02zjefg0H5TIn7XwtdBeg= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722441673; c=relaxed/simple; bh=7bs/6KUzWl3wmOOAmzsxQ8Qy8wKAXz0VAwUdXGyaTIc=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=PB/40I8OgjHjfA3W0e+xIb627Azjeh1yOSGo4EgE/8RH8p2bErYmHQA8O3TR/TeMGh8HVOHvKLmnHnBrWUZzH2GH8DpSOJLCRbHKqzC5RBL6TxdBwxZ5I+iDpGmeaVqubikqUwR/8XR7bVoayoX+NHziSDZv9Xe0j9PoFroGzSs= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-pl1-x62a.google.com with SMTP id d9443c01a7336-1fc692abba4so42173295ad.2 for ; Wed, 31 Jul 2024 09:01:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1722441669; x=1723046469; darn=sourceware.org; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:from:to:cc:subject:date:message-id:reply-to; bh=CnUEEjPJlRqOaRqIR8yv/YqBMSJKViR6hzC2zOtXJq4=; b=vwlArD40DYgg7q0dE7+r10OyRwZXPBgCvUS0KRn4CVuGy5SvUwI8C6wWnoCo0lCrOb j78TLX5ZTq0SC4ymljv1cozfCZAqcwixXRvSNxwVAjUI543x5JyvC/qXBoAXVzVBkDjZ 0urkoGVjjqsQNvnDRlHRix516YGTT8bnB0upw3CkZS9CroRHuCKu+DGoPYWAJlHnelvy 0H5LooF8Fb2h9whcN06rohAT6oVI7Xcrz52oOTRRCGO/VfGvo+rFE30uG570HQIskIOa weILt9/qyGQTtKpH64gEMy7ylA+5B6P4pIaaWvsJRvA6wF9cEVLQDuM5hmfKwPcY9Ez7 1iJA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1722441669; x=1723046469; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=CnUEEjPJlRqOaRqIR8yv/YqBMSJKViR6hzC2zOtXJq4=; b=bqPEUvtrh40qy6UurQPn0obNEom552o/ltcehCgtRpEwdrFCH4nb4A+cUAI1H8/LXn pqBNTFMUbJpDrH6i7Ft2Ttba7b7NDGn8cefnY7WU+F0JMKaFDp6pxlvadZrLMdyATjbk CJz74t5vRafyUeB9wpeivEv/+VcAV4ck8uqFCLeLk+kTixiiVpTMf6apYNk9D9ryTwC+ 1f6AIK5kliO+M9VelRIbNJXPbp1vbnjltSxMhSzTeefLK0rYbNRHsrJRhHWmEech1uTe +iqOF+WfM3SPukW5zs9I3OjAXkYeB4g4bpEVBkzR4nPX8vgLZeZwteUrflDRJ5PI58vd hRug== X-Gm-Message-State: AOJu0YytMrvAjY1j2uptezvKL1VVmPbcNP8whJsP1Y5oSiaWimKgGtRN xnqE3E+tO0abvaNAvtqNDgW5WG9Wx0dm8EBh0M4Lq+AIVLFRfo43a5lnTUcok42U0W6V5j7CYUB W X-Google-Smtp-Source: AGHT+IFpSrO/INiTBT67GZM4ArZGnsZN/voBg2/tmQ5Wb/nRbOcKkp6+Gz8rkYj4V3VYvbtbRpbPxw== X-Received: by 2002:a17:902:d585:b0:1fa:fc24:afa5 with SMTP id d9443c01a7336-1ff047d7cefmr126329965ad.27.1722441668865; Wed, 31 Jul 2024 09:01:08 -0700 (PDT) Received: from mandiga.. ([2804:1b3:a7c1:1944:b913:6070:fef0:3852]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1fed7ff680bsm121720245ad.298.2024.07.31.09.01.07 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 31 Jul 2024 09:01:08 -0700 (PDT) From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH] elf: Make dl-fptr and dl-symaddr hppa specific Date: Wed, 31 Jul 2024 13:00:50 -0300 Message-ID: <20240731160104.2963895-1-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.43.0 MIME-Version: 1.0 X-Spam-Status: No, score=-11.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, KAM_STOCKGEN, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP 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.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~incoming=patchwork.ozlabs.org@sourceware.org With ia64 removal, the function descriptor supports is only used by HPPA and new architectures do not seem leaning towards this design. Reviewed-by: Florian Weimer --- elf/dl-fptr.c | 322 -------------------------------------- elf/dl-symaddr.c | 33 ---- sysdeps/generic/dl-fptr.h | 45 ------ sysdeps/hppa/dl-fptr.h | 23 ++- 4 files changed, 22 insertions(+), 401 deletions(-) delete mode 100644 elf/dl-fptr.c delete mode 100644 elf/dl-symaddr.c delete mode 100644 sysdeps/generic/dl-fptr.h diff --git a/elf/dl-fptr.c b/elf/dl-fptr.c deleted file mode 100644 index 575406ae44..0000000000 --- a/elf/dl-fptr.c +++ /dev/null @@ -1,322 +0,0 @@ -/* Manage function descriptors. Generic version. - Copyright (C) 1999-2024 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 -#include -#include -#include -#include - -#ifndef ELF_MACHINE_BOOT_FPTR_TABLE_LEN -/* ELF_MACHINE_BOOT_FPTR_TABLE_LEN should be greater than the number of - dynamic symbols in ld.so. */ -# define ELF_MACHINE_BOOT_FPTR_TABLE_LEN 256 -#endif - -#ifndef ELF_MACHINE_LOAD_ADDRESS -# error "ELF_MACHINE_LOAD_ADDRESS is not defined." -#endif - -#ifndef COMPARE_AND_SWAP -# define COMPARE_AND_SWAP(ptr, old, new) \ - (catomic_compare_and_exchange_bool_acq (ptr, new, old) == 0) -#endif - -ElfW(Addr) _dl_boot_fptr_table [ELF_MACHINE_BOOT_FPTR_TABLE_LEN]; - -static struct local - { - struct fdesc_table *root; - struct fdesc *free_list; - unsigned int npages; /* # of pages to allocate */ - /* the next to members MUST be consecutive! */ - struct fdesc_table boot_table; - struct fdesc boot_fdescs[1024]; - } -local = - { - .root = &local.boot_table, - .npages = 2, - .boot_table = - { - .len = sizeof (local.boot_fdescs) / sizeof (local.boot_fdescs[0]), - .first_unused = 0 - } - }; - -/* Create a new fdesc table and return a pointer to the first fdesc - entry. The fdesc lock must have been acquired already. */ - -static struct fdesc_table * -new_fdesc_table (struct local *l, size_t *size) -{ - size_t old_npages = l->npages; - size_t new_npages = old_npages + old_npages; - struct fdesc_table *new_table; - - /* If someone has just created a new table, we return NULL to tell - the caller to use the new table. */ - if (! COMPARE_AND_SWAP (&l->npages, old_npages, new_npages)) - return (struct fdesc_table *) NULL; - - *size = old_npages * GLRO(dl_pagesize); - new_table = __mmap (NULL, *size, - PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); - if (new_table == MAP_FAILED) - _dl_signal_error (errno, NULL, NULL, - N_("cannot map pages for fdesc table")); - - new_table->len - = (*size - sizeof (*new_table)) / sizeof (struct fdesc); - new_table->first_unused = 1; - return new_table; -} - - -static ElfW(Addr) -make_fdesc (ElfW(Addr) ip, ElfW(Addr) gp) -{ - struct fdesc *fdesc = NULL; - struct fdesc_table *root; - unsigned int old; - struct local *l; - - ELF_MACHINE_LOAD_ADDRESS (l, local); - - retry: - root = l->root; - while (1) - { - old = root->first_unused; - if (old >= root->len) - break; - else if (COMPARE_AND_SWAP (&root->first_unused, old, old + 1)) - { - fdesc = &root->fdesc[old]; - goto install; - } - } - - if (l->free_list) - { - /* Get it from free-list. */ - do - { - fdesc = l->free_list; - if (fdesc == NULL) - goto retry; - } - while (! COMPARE_AND_SWAP ((ElfW(Addr) *) &l->free_list, - (ElfW(Addr)) fdesc, fdesc->ip)); - } - else - { - /* Create a new fdesc table. */ - size_t size; - struct fdesc_table *new_table = new_fdesc_table (l, &size); - - if (new_table == NULL) - goto retry; - - new_table->next = root; - if (! COMPARE_AND_SWAP ((ElfW(Addr) *) &l->root, - (ElfW(Addr)) root, - (ElfW(Addr)) new_table)) - { - /* Someone has just installed a new table. Return NULL to - tell the caller to use the new table. */ - __munmap (new_table, size); - goto retry; - } - - /* Note that the first entry was reserved while allocating the - memory for the new page. */ - fdesc = &new_table->fdesc[0]; - } - - install: - fdesc->ip = ip; - fdesc->gp = gp; - - return (ElfW(Addr)) fdesc; -} - - -static inline ElfW(Addr) * __attribute__ ((always_inline)) -make_fptr_table (struct link_map *map) -{ - const ElfW(Sym) *symtab - = (const void *) D_PTR (map, l_info[DT_SYMTAB]); - const char *strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]); - ElfW(Addr) *fptr_table; - size_t size; - size_t len; - - /* XXX Apparently the only way to find out the size of the dynamic - symbol section is to assume that the string table follows right - afterwards... */ - len = ((strtab - (char *) symtab) - / map->l_info[DT_SYMENT]->d_un.d_val); - size = ((len * sizeof (fptr_table[0]) + GLRO(dl_pagesize) - 1) - & -GLRO(dl_pagesize)); - /* XXX We don't support here in the moment systems without MAP_ANON. - There probably are none for IA-64. In case this is proven wrong - we will have to open /dev/null here and use the file descriptor - instead of the hard-coded -1. */ - fptr_table = __mmap (NULL, size, - PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, - -1, 0); - if (fptr_table == MAP_FAILED) - _dl_signal_error (errno, NULL, NULL, - N_("cannot map pages for fptr table")); - - if (COMPARE_AND_SWAP ((ElfW(Addr) *) &map->l_mach.fptr_table, - (ElfW(Addr)) NULL, (ElfW(Addr)) fptr_table)) - map->l_mach.fptr_table_len = len; - else - __munmap (fptr_table, len * sizeof (fptr_table[0])); - - return map->l_mach.fptr_table; -} - - -ElfW(Addr) -_dl_make_fptr (struct link_map *map, const ElfW(Sym) *sym, - ElfW(Addr) ip) -{ - ElfW(Addr) *ftab = map->l_mach.fptr_table; - const ElfW(Sym) *symtab; - Elf_Symndx symidx; - struct local *l; - - if (__glibc_unlikely (ftab == NULL)) - ftab = make_fptr_table (map); - - symtab = (const void *) D_PTR (map, l_info[DT_SYMTAB]); - symidx = sym - symtab; - - if (symidx >= map->l_mach.fptr_table_len) - _dl_signal_error (0, NULL, NULL, - N_("internal error: symidx out of range of fptr table")); - - while (ftab[symidx] == 0) - { - /* GOT has already been relocated in elf_get_dynamic_info - - don't try to relocate it again. */ - ElfW(Addr) fdesc - = make_fdesc (ip, map->l_info[DT_PLTGOT]->d_un.d_ptr); - - if (__builtin_expect (COMPARE_AND_SWAP (&ftab[symidx], (ElfW(Addr)) NULL, - fdesc), 1)) - { - /* No one has updated the entry and the new function - descriptor has been installed. */ -#if 0 - const char *strtab - = (const void *) D_PTR (map, l_info[DT_STRTAB]); - - ELF_MACHINE_LOAD_ADDRESS (l, local); - if (l->root != &l->boot_table - || l->boot_table.first_unused > 20) - _dl_debug_printf ("created fdesc symbol `%s' at %lx\n", - strtab + sym->st_name, ftab[symidx]); -#endif - break; - } - else - { - /* We created a duplicated function descriptor. We put it on - free-list. */ - struct fdesc *f = (struct fdesc *) fdesc; - - ELF_MACHINE_LOAD_ADDRESS (l, local); - - do - f->ip = (ElfW(Addr)) l->free_list; - while (! COMPARE_AND_SWAP ((ElfW(Addr) *) &l->free_list, - f->ip, fdesc)); - } - } - - return ftab[symidx]; -} - - -void -_dl_unmap (struct link_map *map) -{ - ElfW(Addr) *ftab = map->l_mach.fptr_table; - struct fdesc *head = NULL, *tail = NULL; - size_t i; - - _dl_unmap_segments (map); - - if (ftab == NULL) - return; - - /* String together the fdesc structures that are being freed. */ - for (i = 0; i < map->l_mach.fptr_table_len; ++i) - { - if (ftab[i]) - { - *(struct fdesc **) ftab[i] = head; - head = (struct fdesc *) ftab[i]; - if (tail == NULL) - tail = head; - } - } - - /* Prepend the new list to the free_list: */ - if (tail) - do - tail->ip = (ElfW(Addr)) local.free_list; - while (! COMPARE_AND_SWAP ((ElfW(Addr) *) &local.free_list, - tail->ip, (ElfW(Addr)) head)); - - __munmap (ftab, (map->l_mach.fptr_table_len - * sizeof (map->l_mach.fptr_table[0]))); - - map->l_mach.fptr_table = NULL; -} - - -ElfW(Addr) -_dl_lookup_address (const void *address) -{ - ElfW(Addr) addr = (ElfW(Addr)) address; - struct fdesc_table *t; - unsigned long int i; - - for (t = local.root; t != NULL; t = t->next) - { - i = (struct fdesc *) addr - &t->fdesc[0]; - if (i < t->first_unused && addr == (ElfW(Addr)) &t->fdesc[i]) - { - addr = t->fdesc[i].ip; - break; - } - } - - return addr; -} diff --git a/elf/dl-symaddr.c b/elf/dl-symaddr.c deleted file mode 100644 index b0299fdb35..0000000000 --- a/elf/dl-symaddr.c +++ /dev/null @@ -1,33 +0,0 @@ -/* Get the symbol address. Generic version. - Copyright (C) 1999-2024 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 - -void * -_dl_symbol_address (struct link_map *map, const ElfW(Sym) *ref) -{ - ElfW(Addr) value = SYMBOL_ADDRESS (map, ref, false); - - /* Return the pointer to function descriptor. */ - if (ELFW(ST_TYPE) (ref->st_info) == STT_FUNC) - return (void *) _dl_make_fptr (map, ref, value); - else - return (void *) value; -} -rtld_hidden_def (_dl_symbol_address) diff --git a/sysdeps/generic/dl-fptr.h b/sysdeps/generic/dl-fptr.h deleted file mode 100644 index 71cfb62411..0000000000 --- a/sysdeps/generic/dl-fptr.h +++ /dev/null @@ -1,45 +0,0 @@ -/* Function descriptors. Generic version. - Copyright (C) 1995-2024 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 - . */ - -#ifndef dl_fptr_h -#define dl_fptr_h 1 - -/* An FDESC is a function descriptor. */ - -struct fdesc - { - ElfW(Addr) ip; /* code entry point */ - ElfW(Addr) gp; /* global pointer */ - }; - -struct fdesc_table - { - struct fdesc_table *next; - unsigned int len; /* # of entries in fdesc table */ - volatile unsigned int first_unused; /* index of first available entry */ - struct fdesc fdesc[0]; - }; - -struct link_map; - -extern ElfW(Addr) _dl_boot_fptr_table []; - -extern ElfW(Addr) _dl_make_fptr (struct link_map *, const ElfW(Sym) *, - ElfW(Addr)); - -#endif /* !dl_fptr_h */ diff --git a/sysdeps/hppa/dl-fptr.h b/sysdeps/hppa/dl-fptr.h index 7c5eb0bd30..b7fd9cf71a 100644 --- a/sysdeps/hppa/dl-fptr.h +++ b/sysdeps/hppa/dl-fptr.h @@ -19,7 +19,28 @@ #ifndef dl_hppa_fptr_h #define dl_hppa_fptr_h 1 -#include +/* An FDESC is a function descriptor. */ + +struct fdesc + { + ElfW(Addr) ip; /* code entry point */ + ElfW(Addr) gp; /* global pointer */ + }; + +struct fdesc_table + { + struct fdesc_table *next; + unsigned int len; /* # of entries in fdesc table */ + volatile unsigned int first_unused; /* index of first available entry */ + struct fdesc fdesc[0]; + }; + +struct link_map; + +extern ElfW(Addr) _dl_boot_fptr_table []; + +extern ElfW(Addr) _dl_make_fptr (struct link_map *, const ElfW(Sym) *, + ElfW(Addr)); /* Initialize function pointer code. Call before relocation processing. */ extern void _dl_fptr_init (void);