[RFC,4/5] MIPS: Locally export the ABI flags cache maintenance routines

Message ID alpine.DEB.2.00.1511200640490.6915@tp.orcam.me.uk
State New, archived
Headers

Commit Message

Maciej W. Rozycki Nov. 20, 2015, 7:30 a.m. UTC
  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
  

Patch

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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <elf.h>
+#include <ldsodefs.h>
+#include <link.h>
+#include <stdbool.h>
+
+#include <dl-abiflags-cache.h>
+
+/* 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
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _DL_FPABI_CACHE
+#define _DL_FPABI_CACHE 1
+
+#include <elf.h>
+#include <link.h>
+#include <stdbool.h>
+
+/* 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 <unistd.h>
 #include <sys/prctl.h>
 
+#include <dl-abiflags-cache.h>
+
 #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