[RFC] Fix LD_PROFILE for ia64 and hppa (any arch using function descriptors)
Carlos O'Donell
carlos@baldric.uwo.ca
Tue Jan 6 05:58:00 GMT 2004
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
More information about the Libc-alpha
mailing list