This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFC] Fix LD_PROFILE for ia64 and hppa (any arch using function descriptors)


On Mon, Jan 05, 2004 at 12:16:08AM -0500, Carlos O'Donell wrote:
> I have a patch where I make l_reloc_result the size of a plt entry, as 
> defined by the arch, and then I pass the index onto elf_machine_fixup_plt. 
> Thus the call is made from the cache, and subsequent calls still go through
> the trampoline. In such a case both profile_fixup and fixup look almost 
> *identical*.
> 
> This would fix ia64 and hppa for the LD_PROFILE case.
> 
> Is there anything wrong with such a change?

Not a formal submission yet, just an RFC.

It has the benefit of making both profile_fixup and fixup very similar,
the only real difference is the check for value == 0, and the added call
to mcount. We call ELF_MACHINE_PROFILE_FIXUP_PLT at the end of
profile_fixup in order to fixup the "cached" plt slot that the profiler
has allocated.

2004-01-07  Carlos O'Donell  <carlos@baldric.uwo.ca>

	* elf/dl-reloc.c (_dl_relocate_object): Each element in
	l_reloc_result is ELF_MACHINE_SIZEOF_JMP_SLOT bytes.
	* elf/dl-runtime.c [!ELF_MACHINE_PROFILE_FIXUP_PLT]:
	ELF_MACHINE_PROFILE_FIXUP_PLT returns value.
	(profile_fixup): Calculate correct offset into l_reloc_result
	array. Call ELF_MACHINE_PROFILE_FIXUP_PLT to fixup cached plt
	slot. Don't update the cache if dl_bind_not is true.
	* elf/dynamic-link.h [!ELF_MACHINE_SIZEOF_JMP_SLOT]:
	Define ELF_MACHINE_SIZEOF_JMP_SLOT to be atleast
	sizeof ( ElfW(Addr) ).

Index: dl-reloc.c
===================================================================
RCS file: /cvs/glibc/libc/elf/dl-reloc.c,v
retrieving revision 1.91
diff -u -p -r1.91 dl-reloc.c
--- dl-reloc.c	2 Oct 2003 18:57:39 -0000	1.91
+++ dl-reloc.c	6 Jan 2004 05:47:22 -0000
@@ -282,7 +282,7 @@ _dl_relocate_object (struct link_map *l,
 	  }
 
 	l->l_reloc_result =
-	  (ElfW(Addr) *) calloc (sizeof (ElfW(Addr)),
+	  (ElfW(Addr) *) calloc (ELF_MACHINE_SIZEOF_JMP_SLOT,
 				 l->l_info[DT_PLTRELSZ]->d_un.d_val);
 	if (l->l_reloc_result == NULL)
 	  {
Index: dl-runtime.c
===================================================================
RCS file: /cvs/glibc/libc/elf/dl-runtime.c,v
retrieving revision 1.60
diff -u -p -r1.60 dl-runtime.c
--- dl-runtime.c	7 Feb 2003 19:43:36 -0000	1.60
+++ dl-runtime.c	6 Jan 2004 05:47:22 -0000
@@ -132,6 +132,10 @@ fixup (
 
 #if !defined PROF && !defined ELF_MACHINE_NO_PLT && !__BOUNDED_POINTERS__
 
+#if !defined ELF_MACHINE_PROFILE_FIXUP_PLT
+# define ELF_MACHINE_PROFILE_FIXUP_PLT (l, result, reloc, rel_addr, value) value
+#endif
+
 static ElfW(Addr) __attribute_used__
 profile_fixup (
 #ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS
@@ -141,8 +145,11 @@ profile_fixup (
 {
   void (*mcount_fct) (ElfW(Addr), ElfW(Addr)) = INTUSE(_dl_mcount);
   ElfW(Addr) *resultp;
-  lookup_t result;
+  lookup_t result = NULL;
   ElfW(Addr) value;
+  const PLTREL *const reloc
+    = (const void *) (D_PTR (l, l_info[DT_JMPREL]) + reloc_offset);
+  int reloc_result_pos = (reloc_offset / sizeof(PLTREL)) * ELF_MACHINE_SIZEOF_JMP_SLOT;
 
   /* The use of `alloca' here looks ridiculous but it helps.  The goal is
      to prevent the function from being inlined, and thus optimized out.
@@ -152,7 +159,7 @@ profile_fixup (
 
   /* This is the address in the array where we store the result of previous
      relocations.  */
-  resultp = &l->l_reloc_result[reloc_offset / sizeof (PLTREL)];
+  resultp = &l->l_reloc_result[reloc_result_pos];
 
   value = *resultp;
   if (value == 0)
@@ -162,8 +169,6 @@ profile_fixup (
 	= (const void *) D_PTR (l, l_info[DT_SYMTAB]);
       const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]);
 
-      const PLTREL *const reloc
-	= (const void *) (D_PTR (l, l_info[DT_JMPREL]) + reloc_offset);
       const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)];
 
       /* Sanity check that we're really looking at a PLT relocation.  */
@@ -217,15 +222,16 @@ profile_fixup (
 	}
       /* And now perhaps the relocation addend.  */
       value = elf_machine_plt_value (l, reloc, value);
-
-      /* Store the result for later runs.  */
-      if (__builtin_expect (! GL(dl_bind_not), 1))
-	*resultp = value;
     }
 
   (*mcount_fct) (retaddr, value);
 
-  return value;
+  if (__builtin_expect (GL(dl_bind_not), 0))
+    return value;
+  
+  /* fixup the l_reloc_result cache, not the real .got/.plt, 
+     result could be NULL */
+  return ELF_MACHINE_PROFILE_FIXUP_PLT (l, result, reloc, resultp, value);
 }
 
 #endif /* PROF && ELF_MACHINE_NO_PLT */
Index: dynamic-link.h
===================================================================
RCS file: /cvs/glibc/libc/elf/dynamic-link.h,v
retrieving revision 1.48
diff -u -p -r1.48 dynamic-link.h
--- dynamic-link.h	31 Jul 2003 06:33:50 -0000	1.48
+++ dynamic-link.h	6 Jan 2004 05:47:22 -0000
@@ -58,6 +58,10 @@ elf_machine_lazy_rel (struct link_map *m
 
 #include <dl-machine.h>
 
+#ifndef ELF_MACHINE_SIZEOF_JMP_SLOT
+# define ELF_MACHINE_SIZEOF_JMP_SLOT sizeof ( ElfW(Addr) )
+#endif
+
 #ifndef VERSYMIDX
 # define VERSYMIDX(sym)	(DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (sym))
 #endif


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]