From patchwork Fri Nov 20 07:30:41 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Maciej W. Rozycki" X-Patchwork-Id: 9754 Received: (qmail 35962 invoked by alias); 20 Nov 2015 07:30:49 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 35940 invoked by uid 89); 20 Nov 2015 07:30:48 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.3 required=5.0 tests=AWL, BAYES_00, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_LOW, RP_MATCHES_RCVD, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mailapp01.imgtec.com Date: Fri, 20 Nov 2015 07:30:41 +0000 From: "Maciej W. Rozycki" To: CC: Matthew Fortune , Daniel Sanders , Leonid Yegoshin Subject: [RFC PATCH 4/5] MIPS: Locally export the ABI flags cache maintenance routines In-Reply-To: Message-ID: References: User-Agent: Alpine 2.00 (DEB 1167 2008-08-23) MIME-Version: 1.0 Rename `cached_abiflags_reject_phdr_p' to `__mips_abiflags_cache', to reflect its role of a cache accessor function, which by itself has nothing to do with ELF program header rejection. Move it along `find_mips_abiflags' to a separate file and export both for local use within the run-time loader or static libc as required. Reuse code from the REJECT macro in dl-machine-reject-phdr.h to implement the FAIL macro in dl-abiflags-cache.h, replacing calls from `__mips_abiflags_cache'. Correct formatting in code moved to follow the GNU Coding Standard. No functional change otherwise. * sysdeps/mips/dl-abiflags-cache.h: New file. * sysdeps/mips/dl-abiflags-cache.c: New file. * sysdeps/mips/dl-machine-reject-phdr.h (find_mips_abiflags): Move to sysdeps/mips/dl-abiflags-cache.h. (cached_fpabi_reject_phdr_p): Rename to `__mips_abiflags_cache' and move to sysdeps/mips/dl-abiflags-cache.c. (elf_machine_reject_phdr_p): Update call to `cached_fpabi_reject_phdr_p' accordingly. * sysdeps/mips/Makefile (sysdep-dl-routines) [($(subdir),elf)]: Add `dl-abiflags-cache'. --- I am a bit concerned about ABI flags check code duplication between `__mips_abiflags_cache' (nee `cached_fpabi_reject_phdr_p') and `elf_machine_reject_phdr_p', however let's defer it to a separate cleanup. glibc-mips-abiflags-cache.diff Index: glibc/sysdeps/mips/Makefile =================================================================== --- glibc.orig/sysdeps/mips/Makefile 2015-11-10 00:12:02.128733539 +0000 +++ glibc/sysdeps/mips/Makefile 2015-11-10 00:32:08.522430954 +0000 @@ -28,6 +28,9 @@ endif ASFLAGS-.os += $(pic-ccflag) ifeq ($(subdir),elf) +# Extra shared linker files to link into dl-allobjs.so and libc. +sysdep-dl-routines += dl-abiflags-cache + ifneq ($(o32-fpabi),) tests += tst-abi-interlink Index: glibc/sysdeps/mips/dl-abiflags-cache.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ glibc/sysdeps/mips/dl-abiflags-cache.c 2015-11-10 00:32:08.635963017 +0000 @@ -0,0 +1,68 @@ +/* MIPS FP ABI cache maintenance. + Copyright (C) 2015 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 + +/* Return failure with a debug message. */ +#define FAIL(str, args...) \ + { \ + if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_LIBS)) \ + _dl_debug_printf (str, ##args); \ + return false; \ + } + +/* Cache the FP ABI value from the PT_MIPS_ABIFLAGS program header. */ + +bool +internal_function +__mips_abiflags_cache (struct link_map *l) +{ + if (l->l_mach.fpabi == 0) + { + const ElfW (Phdr) *ph = find_mips_abiflags (l->l_phdr, l->l_phnum); + + if (ph) + { + Elf_MIPS_ABIFlags_v0 *mips_abiflags; + if (ph->p_filesz < sizeof (Elf_MIPS_ABIFlags_v0)) + FAIL (" %s: malformed PT_MIPS_ABIFLAGS found\n", l->l_name); + + mips_abiflags = (Elf_MIPS_ABIFlags_v0 *) (l->l_addr + ph->p_vaddr); + + if (__glibc_unlikely (mips_abiflags->flags2 != 0)) + FAIL (" %s: unknown MIPS.abiflags flags2: %u\n", l->l_name, + mips_abiflags->flags2); + + l->l_mach.fpabi = mips_abiflags->fp_abi; + l->l_mach.odd_spreg = (mips_abiflags->flags1 + & MIPS_AFL_FLAGS1_ODDSPREG) != 0; + } + else + { + l->l_mach.fpabi = -1; + l->l_mach.odd_spreg = true; + } + } + return true; +} +libc_hidden_def (__mips_abiflags_cache) Index: glibc/sysdeps/mips/dl-abiflags-cache.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ glibc/sysdeps/mips/dl-abiflags-cache.h 2015-11-10 00:32:08.907394930 +0000 @@ -0,0 +1,44 @@ +/* MIPS FP ABI cache maintenance. + Copyright (C) 2015 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_FPABI_CACHE +#define _DL_FPABI_CACHE 1 + +#include +#include +#include + +/* Search the program headers for the ABI Flags. */ + +static inline const ElfW (Phdr) * +find_mips_abiflags (const ElfW (Phdr) *phdr, ElfW (Half) phnum) +{ + const ElfW (Phdr) *ph; + + for (ph = phdr; ph < &phdr[phnum]; ++ph) + if (ph->p_type == PT_MIPS_ABIFLAGS) + return ph; + return NULL; +} + +/* Cache the FP ABI value from the PT_MIPS_ABIFLAGS program header. */ + +extern bool __mips_abiflags_cache (struct link_map *l); +libc_hidden_proto (__mips_abiflags_cache) + +#endif /* dl-abiflags-cache.h */ Index: glibc/sysdeps/mips/dl-machine-reject-phdr.h =================================================================== --- glibc.orig/sysdeps/mips/dl-machine-reject-phdr.h 2015-11-10 00:12:02.149056932 +0000 +++ glibc/sysdeps/mips/dl-machine-reject-phdr.h 2015-11-10 00:32:09.041975883 +0000 @@ -22,6 +22,8 @@ #include #include +#include + #if defined PR_GET_FP_MODE && defined PR_SET_FP_MODE # define HAVE_PRCTL_FP_MODE 1 #else @@ -36,53 +38,6 @@ return true; \ } -/* Search the program headers for the ABI Flags. */ - -static inline const ElfW(Phdr) * -find_mips_abiflags (const ElfW(Phdr) *phdr, ElfW(Half) phnum) -{ - const ElfW(Phdr) *ph; - - for (ph = phdr; ph < &phdr[phnum]; ++ph) - if (ph->p_type == PT_MIPS_ABIFLAGS) - return ph; - return NULL; -} - -/* Cache the FP ABI value from the PT_MIPS_ABIFLAGS program header. */ - -static bool -cached_fpabi_reject_phdr_p (struct link_map *l) -{ - if (l->l_mach.fpabi == 0) - { - const ElfW(Phdr) *ph = find_mips_abiflags (l->l_phdr, l->l_phnum); - - if (ph) - { - Elf_MIPS_ABIFlags_v0 * mips_abiflags; - if (ph->p_filesz < sizeof (Elf_MIPS_ABIFlags_v0)) - REJECT (" %s: malformed PT_MIPS_ABIFLAGS found\n", l->l_name); - - mips_abiflags = (Elf_MIPS_ABIFlags_v0 *) (l->l_addr + ph->p_vaddr); - - if (__glibc_unlikely (mips_abiflags->flags2 != 0)) - REJECT (" %s: unknown MIPS.abiflags flags2: %u\n", l->l_name, - mips_abiflags->flags2); - - l->l_mach.fpabi = mips_abiflags->fp_abi; - l->l_mach.odd_spreg = (mips_abiflags->flags1 - & MIPS_AFL_FLAGS1_ODDSPREG) != 0; - } - else - { - l->l_mach.fpabi = -1; - l->l_mach.odd_spreg = true; - } - } - return false; -} - /* Return a description of the specified floating-point ABI. */ static const char * @@ -214,7 +169,7 @@ elf_machine_reject_phdr_p (const ElfW(Ph { struct abi_req existing_req; - if (cached_fpabi_reject_phdr_p (l)) + if (!__mips_abiflags_cache (l)) return true; #if _MIPS_SIM == _ABIO32