PATCH: Fix ia64 audit/profile

H. J. Lu hjl@lucon.org
Sat Jan 29 18:11:00 GMT 2005


On Fri, Jan 28, 2005 at 08:10:40PM -0800, Ulrich Drepper wrote:
> I assume you tested it.  My build failed but that might be due to other
> problems.  I haven't build on that machine in a while.
> 
> Anyway, this leaves ppc as the only platform without the pltexit support.
> 

Audit works for me on ia64 with the fix for bug 677 since audit uses
profile. This patch is needed to get audit/profile to work on ia64. I
am not too happy about this patch. But I couldnt find a better way
to do it.


H.J.
-------------- next part --------------
2005-01-28  Andreas Schwab  <schwab@suse.de>
	    H.J. Lu  <hongjiu.lu@intel.com>

	[BZ #677]
	* elf/dl-runtime.c (fixup) Change return type to
	DL_FIXUP_VALUE_TYPE. Use DL_FIXUP_VALUE_TYPE,
	DL_FIXUP_MAKE_VALUE and DL_FIXUP_VALUE_CODE_ADDR for relocation
	values. Use DL_FIXUP_VALUE_ADDR and DL_FIXUP_ADDR_VALUE to
	store and retrieve relocation values.
	(profile_fixup): Likewise.

	* include/link.h (link_map): Use DL_FIXUP_VALUE_TYPE for
	l_reloc_result.

	* sysdeps/generic/dl-fptr.h (link_map): Forward declaration.

	* sysdeps/generic/dl-lookupcfg.h (DL_FIXUP_VALUE_TYPE): New.
	(DL_FIXUP_MAKE_VALUE): Likewise.
	(DL_FIXUP_VALUE_CODE_ADDR): Likewise.
	(DL_FIXUP_VALUE_ADDR): Likewise.
	(DL_FIXUP_ADDR_VALUE): Likewise.

	* sysdeps/ia64/dl-lookupcfg.h: Include <dl-fptr.h> for
	"struct fdesc".
	(DL_FIXUP_VALUE_TYPE): New.
	(DL_FIXUP_MAKE_VALUE): Likewise.
	(DL_FIXUP_VALUE_CODE_ADDR): Likewise.
	(DL_FIXUP_VALUE_ADDR): Likewise.
	(DL_FIXUP_ADDR_VALUE): Likewise.

	* sysdeps/ia64/dl-machine.h (elf_machine_profile_fixup_plt):
	Removed.
	(elf_machine_profile_plt): Removed.
	(elf_machine_fixup_plt): Change return type and type of value
	parameter to struct fdesc.
	(elf_machine_plt_value): Likewise.
	(elf_machine_rela): Use DL_FIXUP_MAKE_VALUE to construct
	argument for elf_machine_fixup_plt.

--- libc/elf/dl-runtime.c.fptr	2005-01-24 15:30:36.000000000 -0800
+++ libc/elf/dl-runtime.c	2005-01-26 16:04:46.000000000 -0800
@@ -52,7 +52,7 @@
    function.  */
 
 #ifndef ELF_MACHINE_NO_PLT
-ElfW(Addr)
+DL_FIXUP_VALUE_TYPE
 __attribute ((noinline)) ARCH_FIXUP_ATTRIBUTE
 _dl_fixup (
 # ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS
@@ -71,7 +71,7 @@ _dl_fixup (
   const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)];
   void *const rel_addr = (void *)(l->l_addr + reloc->r_offset);
   lookup_t result;
-  ElfW(Addr) value;
+  DL_FIXUP_VALUE_TYPE value;
 
   /* Sanity check that we're really looking at a PLT relocation.  */
   assert (ELFW(R_TYPE)(reloc->r_info) == ELF_MACHINE_JMP_SLOT);
@@ -99,13 +99,15 @@ _dl_fixup (
       /* Currently result contains the base load address (or link map)
 	 of the object that defines sym.  Now add in the symbol
 	 offset.  */
-      value = (sym ? LOOKUP_VALUE_ADDRESS (result) + sym->st_value : 0);
+      value = DL_FIXUP_MAKE_VALUE (result,
+				   sym ? LOOKUP_VALUE_ADDRESS (result)
+					 + sym->st_value : 0);
     }
   else
     {
       /* We already found the symbol.  The module (and therefore its load
 	 address) is also known.  */
-      value = l->l_addr + sym->st_value;
+      value = DL_FIXUP_MAKE_VALUE (l, l->l_addr + sym->st_value);
       result = l;
     }
 
@@ -122,7 +124,7 @@ _dl_fixup (
 
 #if !defined PROF && !defined ELF_MACHINE_NO_PLT && !__BOUNDED_POINTERS__
 
-ElfW(Addr)
+DL_FIXUP_VALUE_TYPE
 __attribute ((noinline)) ARCH_FIXUP_ATTRIBUTE
 _dl_profile_fixup (
 #ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS
@@ -137,10 +139,10 @@ _dl_profile_fixup (
      relocations.  */
   struct reloc_result *reloc_result
     = &l->l_reloc_result[reloc_offset / sizeof (PLTREL)];
-  ElfW(Addr) *resultp = &reloc_result->addr;
+  DL_FIXUP_VALUE_TYPE *resultp = &reloc_result->addr;
 
-  ElfW(Addr) value = *resultp;
-  if (value == 0)
+  DL_FIXUP_VALUE_TYPE value = *resultp;
+  if (DL_FIXUP_VALUE_CODE_ADDR (value) == 0)
     {
       /* This is the first time we have to relocate this object.  */
       const ElfW(Sym) *const symtab
@@ -180,14 +182,16 @@ _dl_profile_fixup (
 	  /* Currently result contains the base load address (or link map)
 	     of the object that defines sym.  Now add in the symbol
 	     offset.  */
-	  value = (defsym != NULL
-		   ? LOOKUP_VALUE_ADDRESS (result) + defsym->st_value : 0);
+	  value = DL_FIXUP_MAKE_VALUE (result,
+				       defsym != NULL
+				       ? LOOKUP_VALUE_ADDRESS (result)
+					 + defsym->st_value : 0);
 	}
       else
 	{
 	  /* We already found the symbol.  The module (and therefore its load
 	     address) is also known.  */
-	  value = l->l_addr + refsym->st_value;
+	  value = DL_FIXUP_MAKE_VALUE (l, l->l_addr + refsym->st_value);
 	  result = l;
 	}
       /* And now perhaps the relocation addend.  */
@@ -215,7 +219,7 @@ _dl_profile_fixup (
 	      /* Synthesize a symbol record where the st_value field is
 		 the result.  */
 	      ElfW(Sym) sym = *defsym;
-	      sym.st_value = value;
+	      sym.st_value = DL_FIXUP_VALUE_ADDR (value);
 
 	      /* Keep track whether there is any interest in tracing
 		 the call in the lower two bits.  */
@@ -268,7 +272,7 @@ _dl_profile_fixup (
 		}
 
 	      reloc_result->flags = altvalue;
-	      value = sym.st_value;
+	      value = DL_FIXUP_ADDR_VALUE (sym.st_value);
 	    }
 	  else
 	    /* Set all bits since this symbol binding is not interesting.  */
@@ -287,7 +291,7 @@ _dl_profile_fixup (
 #ifdef SHARED
   /* Auditing checkpoint: report the PLT entering and allow the
      auditors to change the value.  */
-  if (value != 0 && GLRO(dl_naudit) > 0
+  if (DL_FIXUP_VALUE_CODE_ADDR (value) != 0 && GLRO(dl_naudit) > 0
       /* Don't do anything if no auditor wants to intercept this call.  */
       && (reloc_result->enterexit & LA_SYMB_NOPLTENTER) == 0)
     {
@@ -297,7 +301,7 @@ _dl_profile_fixup (
 
       /* Set up the sym parameter.  */
       ElfW(Sym) sym = *defsym;
-      sym.st_value = value;
+      sym.st_value = DL_FIXUP_VALUE_ADDR (value);
 
       /* Get the symbol name.  */
       const char *strtab = (const void *) D_PTR (reloc_result->bound,
@@ -352,14 +356,14 @@ _dl_profile_fixup (
 	  afct = afct->next;
 	}
 
-      value = sym.st_value;
+      value = DL_FIXUP_ADDR_VALUE (sym.st_value);
     }
 #endif
 
   /* Store the frame size information.  */
   *framesizep = framesize;
 
-  (*mcount_fct) (retaddr, value);
+  (*mcount_fct) (retaddr, DL_FIXUP_VALUE_CODE_ADDR (value));
 
   return value;
 }
--- libc/include/link.h.fptr	2005-01-18 12:29:55.000000000 -0800
+++ libc/include/link.h	2005-01-26 16:04:46.000000000 -0800
@@ -214,7 +214,7 @@ struct link_map
     /* Collected results of relocation while profiling.  */
     struct reloc_result
     {
-      ElfW(Addr) addr;
+      DL_FIXUP_VALUE_TYPE addr;
       struct link_map *bound;
       unsigned int boundndx;
       uint32_t enterexit;
--- libc/sysdeps/generic/dl-fptr.h.fptr	2003-05-01 19:37:21.000000000 -0700
+++ libc/sysdeps/generic/dl-fptr.h	2005-01-26 16:04:46.000000000 -0800
@@ -36,6 +36,8 @@ struct fdesc_table
     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) *,
--- libc/sysdeps/generic/dl-lookupcfg.h.fptr	2005-01-07 14:13:46.000000000 -0800
+++ libc/sysdeps/generic/dl-lookupcfg.h	2005-01-26 17:05:00.545207873 -0800
@@ -17,4 +17,13 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
-/* Nothing special.  */
+/* The type of the return value of fixup/profile_fixup.  */
+#define DL_FIXUP_VALUE_TYPE ElfW(Addr)
+/* Construct a value of type DL_FIXUP_VALUE_TYPE from a code address
+   and a link map.  */
+#define DL_FIXUP_MAKE_VALUE(map, addr) (addr)
+/* Extract the code address from a value of type DL_FIXUP_MAKE_VALUE.
+ */
+#define DL_FIXUP_VALUE_CODE_ADDR(value) (value)
+#define DL_FIXUP_VALUE_ADDR(value) (value)
+#define DL_FIXUP_ADDR_VALUE(addr) (addr)
--- libc/sysdeps/ia64/dl-lookupcfg.h.fptr	2005-01-07 14:13:48.000000000 -0800
+++ libc/sysdeps/ia64/dl-lookupcfg.h	2005-01-26 16:04:46.000000000 -0800
@@ -20,6 +20,8 @@
 #define ELF_FUNCTION_PTR_IS_SPECIAL
 #define DL_UNMAP_IS_SPECIAL
 
+#include <dl-fptr.h>
+
 /* We do not support copy relocations for IA-64.  */
 #define DL_NO_COPY_RELOCS
 
@@ -56,3 +58,15 @@ extern void _dl_unmap (struct link_map *
 
 #define DL_DT_INIT_ADDRESS(map, addr) DL_AUTO_FUNCTION_ADDRESS (map, addr)
 #define DL_DT_FINI_ADDRESS(map, addr) DL_AUTO_FUNCTION_ADDRESS (map, addr)
+/* The type of the return value of fixup/profile_fixup.  */
+#define DL_FIXUP_VALUE_TYPE struct fdesc
+/* Construct a value of type DL_FIXUP_VALUE_TYPE from a code address
+   and a link map.  */
+#define DL_FIXUP_MAKE_VALUE(map, addr) \
+  ((struct fdesc) { (addr), (map)->l_info[DT_PLTGOT]->d_un.d_ptr })
+/* Extract the code address from a value of type DL_FIXUP_MAKE_VALUE.
+ */
+#define DL_FIXUP_VALUE_CODE_ADDR(value) (value).ip
+
+#define DL_FIXUP_VALUE_ADDR(value) ((uintptr_t) &(value))
+#define DL_FIXUP_ADDR_VALUE(addr) (*(struct fdesc *) (addr))
--- libc/sysdeps/ia64/dl-machine.h.fptr	2005-01-26 16:04:46.000000000 -0800
+++ libc/sysdeps/ia64/dl-machine.h	2005-01-26 16:04:46.000000000 -0800
@@ -331,34 +331,29 @@ elf_machine_runtime_setup (struct link_m
 #define ELF_MACHINE_START_ADDRESS(map, start)	\
   DL_STATIC_FUNCTION_ADDRESS (map, start)
 
-#define elf_machine_profile_fixup_plt(l, reloc, rel_addr, value) \
-  elf_machine_fixup_plt (l, reloc, rel_addr, value)
-
-#define elf_machine_profile_plt(reloc_addr) ((Elf64_Addr) (reloc_addr))
-
 /* Fixup a PLT entry to bounce directly to the function at VALUE.  */
-static inline Elf64_Addr __attribute__ ((always_inline))
+static inline struct fdesc __attribute__ ((always_inline))
 elf_machine_fixup_plt (struct link_map *l, lookup_t t,
 		       const Elf64_Rela *reloc,
-		       Elf64_Addr *reloc_addr, Elf64_Addr value)
+		       Elf64_Addr *reloc_addr, struct fdesc value)
 {
   /* l is the link_map for the caller, t is the link_map for the object
    * being called */
   /* got has already been relocated in elf_get_dynamic_info() */
-  reloc_addr[1] = t->l_info[DT_PLTGOT]->d_un.d_ptr;
+  reloc_addr[1] = value.gp;
   /* we need a "release" here to ensure that the gp is visible before
      the code entry point is updated: */
-  ((volatile Elf64_Addr *) reloc_addr)[0] = value;
-  return (Elf64_Addr) reloc_addr;
+  ((volatile Elf64_Addr *) reloc_addr)[0] = value.ip;
+  return value;
 }
 
 /* Return the final value of a plt relocation.  */
-static inline Elf64_Addr
+static inline struct fdesc
 elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc,
-		       Elf64_Addr value)
+		       struct fdesc value)
 {
   /* No need to handle rel vs rela since IA64 is rela only */
-  return value + reloc->r_addend;
+  return (struct fdesc) { value.ip + reloc->r_addend, value.gp };
 }
 
 #endif /* !dl_machine_h */
@@ -429,7 +424,8 @@ elf_machine_rela (struct link_map *map,
 	    ;/* No adjustment.  */
 	  else if (r_type == R_IA64_IPLTLSB)
 	    {
-	      elf_machine_fixup_plt (NULL, sym_map, reloc, reloc_addr, value);
+	      elf_machine_fixup_plt (NULL, NULL, reloc, reloc_addr,
+				     DL_FIXUP_MAKE_VALUE (sym_map, value));
 	      return;
 	    }
 	  else if (R_IA64_TYPE (r_type) == R_IA64_TYPE (R_IA64_FPTR64LSB))


More information about the Libc-hacker mailing list