From patchwork Thu Jul 9 08:26:18 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vincent Chen X-Patchwork-Id: 39990 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 11080384B0C0; Thu, 9 Jul 2020 08:26:40 +0000 (GMT) X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pl1-x642.google.com (mail-pl1-x642.google.com [IPv6:2607:f8b0:4864:20::642]) by sourceware.org (Postfix) with ESMTPS id 8A939384B0C0 for ; Thu, 9 Jul 2020 08:26:36 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 8A939384B0C0 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=sifive.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=vincent.chen@sifive.com Received: by mail-pl1-x642.google.com with SMTP id w17so534600ply.11 for ; Thu, 09 Jul 2020 01:26:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; h=from:to:cc:subject:date:message-id; bh=Dey2pfOpEeWUDLNVNgzWTIpHtVy9N+iTrJaeD0EqjBE=; b=VsDTeYmQRPs4psIqK+BhxyVbEKGeniCC7QLcQrbdSErd4xlACx65Jx/sHPIAFwEiv5 KDtc2FlPclCLplF+3ADK7ViXn+0wKMUG+HqufQXBVbuzkSDrd+mSQ1+eGUAURkqCPsE+ fp7CVRCgA7Mu/NfuE7UKylHo4Gdn3pRj5QVx+0fjdE17ExQup2R3KWazvappfsRWBm43 jo0v/rsvF30ZxJx6b3RwuzjndkVeYGUtFcz65zMV1yp7rS3XpQWlxS3aCYO2uMh5UV3p OFeDnf4DO9e8hAQiem6AN1pMmwRTzQQxVer8Gb5/u9TDqevQIsSd+KW9n22sEhuisSAv Wqzg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=Dey2pfOpEeWUDLNVNgzWTIpHtVy9N+iTrJaeD0EqjBE=; b=toYJABxf3an00Att9OEOpo/Qu008mRj6+KJn7VZpkJDT3QmtPGtohHeOpX5CG3UXmt hzy3F0JTi0+yDL4t6wTHKSWFoHLqdK8GFYBz/yO+uCyayxbwf83N8TJ5dWRZ1PobX1ZD kCryRfk5lHKE7/KgwEPp9yhbETgK5QEghkYJTu/08T75Jxrfoz35FypgUgZSVWVGLpri e/UCRYmiuKhnFfMg7YjtZgeVOiHdU2FLdCDvW0NuSRCNRzKh+Sh98W/pNOm7ItV+ufKQ Y2jezdao/JHlGbOHZUnmzEATXf5J972Y9OyAWB3iCCsOqGjYGY3eDrpEaXAKehTK95o0 yAzA== X-Gm-Message-State: AOAM5308zC/OsH/fOf4J16e+5ko7FHxZisX+5L9ommV1lSOGdLJECt3m Cmse7hqENSnIvfU0emkjOHNVCNB1GKw= X-Google-Smtp-Source: ABdhPJzyNWGE+2MC5FpiZxnZqvAaSzZMg3TAuIjh0LYhyNEb+k9/AxRN1bRMHDz/UZ7NGqAVlUjxvQ== X-Received: by 2002:a17:90a:72c7:: with SMTP id l7mr14559852pjk.34.1594283195354; Thu, 09 Jul 2020 01:26:35 -0700 (PDT) Received: from VincentChen-ThinkPad-T480s.internal.sifive.com (114-34-229-221.HINET-IP.hinet.net. [114.34.229.221]) by smtp.gmail.com with ESMTPSA id y65sm1979602pfb.75.2020.07.09.01.26.33 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 09 Jul 2020 01:26:34 -0700 (PDT) From: Vincent Chen To: libc-alpha@sourceware.org, palmer@dabbelt.com, darius@bluespec.com, dj@redhat.com Subject: [RFC PATCH] riscv: Add support for STT_GNU_IFUNC symbols Date: Thu, 9 Jul 2020 16:26:18 +0800 Message-Id: <1594283178-9047-1-git-send-email-vincent.chen@sifive.com> X-Mailer: git-send-email 2.7.4 X-Spam-Status: No, score=-11.4 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.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: vincent.chen@sifive.com Errors-To: libc-alpha-bounces@sourceware.org Sender: "Libc-alpha" This patch adds the support for STT_GNU_IFUNC symbols to riscv ports. The Binutils' IFUNC patches are under reviewing and can be found in https://sourceware.org/pipermail/binutils/2020-July/112186.html. Any suggestions and feedback are welcome. --- sysdeps/riscv/dl-irel.h | 53 ++++++++++++++++++++++++++++++++++++++++++++++ sysdeps/riscv/dl-machine.h | 22 ++++++++++++++++++- 2 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 sysdeps/riscv/dl-irel.h diff --git a/sysdeps/riscv/dl-irel.h b/sysdeps/riscv/dl-irel.h new file mode 100644 index 0000000..9dd8de9 --- /dev/null +++ b/sysdeps/riscv/dl-irel.h @@ -0,0 +1,53 @@ +/* Machine-dependent ELF indirect relocation inline functions. + RISC-V version. + Copyright (C) 2012-2020 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_IREL_H +#define _DL_IREL_H + +#include +#include +#include +#include + +#define ELF_MACHINE_IRELA 1 + +static inline ElfW(Addr) +__attribute ((always_inline)) +elf_ifunc_invoke (ElfW(Addr) addr) +{ + return ((ElfW(Addr) (*) (uint64_t)) (addr)) (GLRO(dl_hwcap)); +} + +static inline void +__attribute ((always_inline)) +elf_irela (const ElfW(Rela) *reloc) +{ + ElfW(Addr) *const reloc_addr = (void *) reloc->r_offset; + const unsigned long int r_type = ELFW(R_TYPE) (reloc->r_info); + + if (__glibc_likely (r_type == R_RISCV_IRELATIVE)) + { + ElfW(Addr) value = elf_ifunc_invoke (reloc->r_addend); + *reloc_addr = value; + } + else + __libc_fatal ("Unexpected reloc type in static binary.\n"); +} + +#endif diff --git a/sysdeps/riscv/dl-machine.h b/sysdeps/riscv/dl-machine.h index 03db94a..728e6d3 100644 --- a/sysdeps/riscv/dl-machine.h +++ b/sysdeps/riscv/dl-machine.h @@ -25,6 +25,7 @@ #include #include #include +#include #ifndef _RTLD_PROLOGUE # define _RTLD_PROLOGUE(entry) \ @@ -174,6 +175,13 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc, if (sym_map != NULL) value = SYMBOL_ADDRESS (sym_map, sym, true) + reloc->r_addend; + if (sym != NULL + && __glibc_unlikely (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC) + && __glibc_likely (sym->st_shndx != SHN_UNDEF) + && __glibc_likely (!skip_ifunc)) + value = elf_ifunc_invoke (value); + + switch (r_type) { #ifndef RTLD_BOOTSTRAP @@ -248,7 +256,12 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc, break; } #endif - + case R_RISCV_IRELATIVE: + value = map->l_addr + reloc->r_addend; + if (__glibc_likely (!skip_ifunc)) + value = elf_ifunc_invoke (value); + *addr_field = value; + break; case R_RISCV_JUMP_SLOT: case __WORDSIZE == 64 ? R_RISCV_64 : R_RISCV_32: *addr_field = value; @@ -290,6 +303,13 @@ elf_machine_lazy_rel (struct link_map *map, ElfW(Addr) l_addr, else *reloc_addr = map->l_mach.plt; } + else if (__glibc_unlikely (r_type == R_RISCV_IRELATIVE)) + { + ElfW(Addr) value = map->l_addr + reloc->r_addend; + if (__glibc_likely (!skip_ifunc)) + value = elf_ifunc_invoke (value); + *reloc_addr = value; + } else _dl_reloc_bad_type (map, r_type, 1); }