summary refs log tree commit diff
path: root/elf/dl-runtime.c
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2012-11-14 15:44:40 -0800
committerH.J. Lu <hjl.tools@gmail.com>2012-11-14 15:44:40 -0800
commit2e64d2659d3edaebc792ac596a9863f1626e5c25 (patch)
tree4d551713145a5b3e0ff1351c0de7f8cab70a7fc4 /elf/dl-runtime.c
parentf507f7d598aec75a51689abf5863122b49ca6954 (diff)
downloadglibc-2e64d2659d3edaebc792ac596a9863f1626e5c25.tar.gz
glibc-2e64d2659d3edaebc792ac596a9863f1626e5c25.tar.xz
glibc-2e64d2659d3edaebc792ac596a9863f1626e5c25.zip
Skip audit if l_reloc_result is NULL
Diffstat (limited to 'elf/dl-runtime.c')
-rw-r--r--elf/dl-runtime.c22
1 files changed, 21 insertions, 1 deletions
diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
index 2e02a218e6..7a3bc9ed9d 100644
--- a/elf/dl-runtime.c
+++ b/elf/dl-runtime.c
@@ -1,5 +1,5 @@
 /* On-demand PLT fixup for shared objects.
-   Copyright (C) 1995-2009, 2010, 2011 Free Software Foundation, Inc.
+   Copyright (C) 1995-2012 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
@@ -164,6 +164,26 @@ _dl_profile_fixup (
 {
   void (*mcount_fct) (ElfW(Addr), ElfW(Addr)) = INTUSE(_dl_mcount);
 
+  if (l->l_reloc_result == NULL)
+    {
+      /* BZ #14843: ELF_DYNAMIC_RELOCATE is called before l_reloc_result
+	 is allocated.  We will get here if ELF_DYNAMIC_RELOCATE calls a
+	 resolver function to resolve an IRELATIVE relocation and that
+	 resolver calls a function that is not yet resolved (lazy).  For
+	 example, the resolver in x86-64 libm.so calls __get_cpu_features
+	 defined in libc.so.  Skip audit and resolve the external function
+	 in this case.  */
+      *framesizep = -1;
+      return _dl_fixup (
+# ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS
+#  ifndef ELF_MACHINE_RUNTIME_FIXUP_PARAMS
+#   error Please define ELF_MACHINE_RUNTIME_FIXUP_PARAMS.
+#  endif
+			ELF_MACHINE_RUNTIME_FIXUP_PARAMS,
+# endif
+			l, reloc_arg);
+    }
+
   /* This is the address in the array where we store the result of previous
      relocations.  */
   struct reloc_result *reloc_result = &l->l_reloc_result[reloc_index];