about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--debug/backtracesyms.c81
-rw-r--r--debug/backtracesymsfd.c86
-rw-r--r--sysdeps/generic/backtracesyms.c122
-rw-r--r--sysdeps/generic/backtracesymsfd.c125
4 files changed, 147 insertions, 267 deletions
diff --git a/debug/backtracesyms.c b/debug/backtracesyms.c
index a0106647f1..d75ce0a321 100644
--- a/debug/backtracesyms.c
+++ b/debug/backtracesyms.c
@@ -1,5 +1,5 @@
 /* Return list with names for address in backtrace.
-   Copyright (C) 1998, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1998,1999,2000,2001,2003,2009 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
@@ -17,13 +17,20 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#include <assert.h>
 #include <execinfo.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
+#include <ldsodefs.h>
 
-/* Assume the worst for the width of an address.  */
-#define WORD_WIDTH 16
+#if __ELF_NATIVE_CLASS == 32
+# define WORD_WIDTH 8
+#else
+/* We assyme 64bits.  */
+# define WORD_WIDTH 16
+#endif
 
 
 char **
@@ -31,16 +38,37 @@ __backtrace_symbols (array, size)
      void *const *array;
      int size;
 {
+  Dl_info info[size];
+  int status[size];
   int cnt;
   size_t total = 0;
   char **result;
 
-  /* We can compute the text size needed for the symbols since we print
-     them all as "[+0x<addr>]".  */
-  total = size * (WORD_WIDTH + 6);
+  /* Fill in the information we can get from `dladdr'.  */
+  for (cnt = 0; cnt < size; ++cnt)
+    {
+      struct link_map *map;
+      status[cnt] = _dl_addr (array[cnt], &info[cnt], &map, NULL);
+      if (status[cnt] && info[cnt].dli_fname && info[cnt].dli_fname[0] != '\0')
+	{
+	  /* We have some info, compute the length of the string which will be
+	     "<file-name>(<sym-name>+offset) [address].  */
+	  total += (strlen (info[cnt].dli_fname ?: "")
+		    + strlen (info[cnt].dli_sname ?: "")
+		    + 3 + WORD_WIDTH + 3 + WORD_WIDTH + 5);
+
+	  /* The load bias is more useful to the user than the load
+	     address.  The use of these addresses is to calculate an
+	     address in the ELF file, so its prelinked bias is not
+	     something we want to subtract out.  */
+	  info[cnt].dli_fbase = (void *) map->l_addr;
+	}
+      else
+	total += 5 + WORD_WIDTH;
+    }
 
   /* Allocate memory for the result.  */
-  result = malloc (size * sizeof (char *) + total);
+  result = (char **) malloc (size * sizeof (char *) + total);
   if (result != NULL)
     {
       char *last = (char *) (result + size);
@@ -48,8 +76,45 @@ __backtrace_symbols (array, size)
       for (cnt = 0; cnt < size; ++cnt)
 	{
 	  result[cnt] = last;
-	  last += 1 + sprintf (last, "[+%p]", array[cnt]);
+
+	  if (status[cnt]
+	      && info[cnt].dli_fname != NULL && info[cnt].dli_fname[0] != '\0')
+	    {
+	      if (info[cnt].dli_sname == NULL)
+		/* We found no symbol name to use, so describe it as
+		   relative to the file.  */
+		info[cnt].dli_saddr = info[cnt].dli_fbase;
+
+	      if (info[cnt].dli_sname == NULL && info[cnt].dli_saddr == 0)
+		last += 1 + sprintf (last, "%s(%s) [%p]",
+				     info[cnt].dli_fname ?: "",
+				     info[cnt].dli_sname ?: "",
+				     array[cnt]);
+	      else
+		{
+		  char sign;
+		  ptrdiff_t offset;
+		  if (array[cnt] >= (void *) info[cnt].dli_saddr)
+		    {
+		      sign = '+';
+		      offset = array[cnt] - info[cnt].dli_saddr;
+		    }
+		  else
+		    {
+		      sign = '-';
+		      offset = info[cnt].dli_saddr - array[cnt];
+		    }
+
+		  last += 1 + sprintf (last, "%s(%s%c%#tx) [%p]",
+				       info[cnt].dli_fname ?: "",
+				       info[cnt].dli_sname ?: "",
+				       sign, offset, array[cnt]);
+		}
+	    }
+	  else
+	    last += 1 + sprintf (last, "[%p]", array[cnt]);
 	}
+      assert (last <= (char *) result + size * sizeof (char *) + total);
     }
 
   return result;
diff --git a/debug/backtracesymsfd.c b/debug/backtracesymsfd.c
index fe247d8cc8..8b4a836ce9 100644
--- a/debug/backtracesymsfd.c
+++ b/debug/backtracesymsfd.c
@@ -1,5 +1,5 @@
 /* Write formatted list with names for addresses in backtrace to a file.
-   Copyright (C) 1998, 2003, 2005 Free Software Foundation, Inc.
+   Copyright (C) 1998,2000,2003,2005,2009,2011 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
@@ -22,7 +22,7 @@
 #include <sys/uio.h>
 
 #include <stdio-common/_itoa.h>
-#include <not-cancel.h>
+#include <ldsodefs.h>
 
 #if __ELF_NATIVE_CLASS == 32
 # define WORD_WIDTH 8
@@ -38,25 +38,87 @@ __backtrace_symbols_fd (array, size, fd)
      int size;
      int fd;
 {
-  struct iovec iov[3];
+  struct iovec iov[9];
   int cnt;
 
   for (cnt = 0; cnt < size; ++cnt)
     {
       char buf[WORD_WIDTH];
+      char buf2[WORD_WIDTH];
+      Dl_info info;
+      struct link_map *map;
+      size_t last = 0;
 
-      iov[0].iov_base = (void *) "[0x";
-      iov[0].iov_len = 3;
+      if (_dl_addr (array[cnt], &info, &map, NULL)
+	  && info.dli_fname != NULL && info.dli_fname[0] != '\0')
+	{
+	  /* Name of the file.  */
+	  iov[0].iov_base = (void *) info.dli_fname;
+	  iov[0].iov_len = strlen (info.dli_fname);
+	  last = 1;
 
-      iov[1].iov_base = _itoa_word ((unsigned long int) array[cnt],
-				    &buf[WORD_WIDTH], 16, 0);
-      iov[1].iov_len = &buf[WORD_WIDTH] - (char *) iov[1].iov_base;
+	  if (info.dli_sname != NULL || map->l_addr != 0)
+	    {
+	      size_t diff;
 
-      iov[2].iov_base = (void *) "]\n";
-      iov[2].iov_len = 2;
+	      iov[last].iov_base = (void *) "(";
+	      iov[last].iov_len = 1;
+	      ++last;
 
-      /* We prefer to use the non-cancelable interface if it is available.  */
-      writev_not_cancel_no_status (fd, iov, 3);
+	      if (info.dli_sname != NULL)
+		{
+		  /* We have a symbol name.  */
+		  iov[last].iov_base = (void *) info.dli_sname;
+		  iov[last].iov_len = strlen (info.dli_sname);
+		  ++last;
+		}
+	      else
+		/* We have no symbol, so describe it as relative to the file.
+		   The load bias is more useful to the user than the load
+		   address.  The use of these addresses is to calculate an
+		   address in the ELF file, so its prelinked bias is not
+		   something we want to subtract out.  */
+		info.dli_saddr = (void *) map->l_addr;
+
+	      if (array[cnt] >= (void *) info.dli_saddr)
+		{
+		  iov[last].iov_base = (void *) "+0x";
+		  diff = array[cnt] - info.dli_saddr;
+		}
+	      else
+		{
+		  iov[last].iov_base = (void *) "-0x";
+		  diff = info.dli_saddr - array[cnt];
+		}
+	      iov[last].iov_len = 3;
+	      ++last;
+
+	      iov[last].iov_base = _itoa_word ((unsigned long int) diff,
+					       &buf2[WORD_WIDTH], 16, 0);
+	      iov[last].iov_len = (&buf2[WORD_WIDTH]
+				   - (char *) iov[last].iov_base);
+	      ++last;
+
+	      iov[last].iov_base = (void *) ")";
+	      iov[last].iov_len = 1;
+	      ++last;
+	    }
+	}
+
+      iov[last].iov_base = (void *) "[0x";
+      iov[last].iov_len = 3;
+      ++last;
+
+      iov[last].iov_base = _itoa_word ((unsigned long int) array[cnt],
+				       &buf[WORD_WIDTH], 16, 0);
+      iov[last].iov_len = &buf[WORD_WIDTH] - (char *) iov[last].iov_base;
+      ++last;
+
+      iov[last].iov_base = (void *) "]\n";
+      iov[last].iov_len = 2;
+      ++last;
+
+      __writev (fd, iov, last);
     }
 }
 weak_alias (__backtrace_symbols_fd, backtrace_symbols_fd)
diff --git a/sysdeps/generic/backtracesyms.c b/sysdeps/generic/backtracesyms.c
deleted file mode 100644
index d75ce0a321..0000000000
--- a/sysdeps/generic/backtracesyms.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/* Return list with names for address in backtrace.
-   Copyright (C) 1998,1999,2000,2001,2003,2009 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
-
-   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 <assert.h>
-#include <execinfo.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <ldsodefs.h>
-
-#if __ELF_NATIVE_CLASS == 32
-# define WORD_WIDTH 8
-#else
-/* We assyme 64bits.  */
-# define WORD_WIDTH 16
-#endif
-
-
-char **
-__backtrace_symbols (array, size)
-     void *const *array;
-     int size;
-{
-  Dl_info info[size];
-  int status[size];
-  int cnt;
-  size_t total = 0;
-  char **result;
-
-  /* Fill in the information we can get from `dladdr'.  */
-  for (cnt = 0; cnt < size; ++cnt)
-    {
-      struct link_map *map;
-      status[cnt] = _dl_addr (array[cnt], &info[cnt], &map, NULL);
-      if (status[cnt] && info[cnt].dli_fname && info[cnt].dli_fname[0] != '\0')
-	{
-	  /* We have some info, compute the length of the string which will be
-	     "<file-name>(<sym-name>+offset) [address].  */
-	  total += (strlen (info[cnt].dli_fname ?: "")
-		    + strlen (info[cnt].dli_sname ?: "")
-		    + 3 + WORD_WIDTH + 3 + WORD_WIDTH + 5);
-
-	  /* The load bias is more useful to the user than the load
-	     address.  The use of these addresses is to calculate an
-	     address in the ELF file, so its prelinked bias is not
-	     something we want to subtract out.  */
-	  info[cnt].dli_fbase = (void *) map->l_addr;
-	}
-      else
-	total += 5 + WORD_WIDTH;
-    }
-
-  /* Allocate memory for the result.  */
-  result = (char **) malloc (size * sizeof (char *) + total);
-  if (result != NULL)
-    {
-      char *last = (char *) (result + size);
-
-      for (cnt = 0; cnt < size; ++cnt)
-	{
-	  result[cnt] = last;
-
-	  if (status[cnt]
-	      && info[cnt].dli_fname != NULL && info[cnt].dli_fname[0] != '\0')
-	    {
-	      if (info[cnt].dli_sname == NULL)
-		/* We found no symbol name to use, so describe it as
-		   relative to the file.  */
-		info[cnt].dli_saddr = info[cnt].dli_fbase;
-
-	      if (info[cnt].dli_sname == NULL && info[cnt].dli_saddr == 0)
-		last += 1 + sprintf (last, "%s(%s) [%p]",
-				     info[cnt].dli_fname ?: "",
-				     info[cnt].dli_sname ?: "",
-				     array[cnt]);
-	      else
-		{
-		  char sign;
-		  ptrdiff_t offset;
-		  if (array[cnt] >= (void *) info[cnt].dli_saddr)
-		    {
-		      sign = '+';
-		      offset = array[cnt] - info[cnt].dli_saddr;
-		    }
-		  else
-		    {
-		      sign = '-';
-		      offset = info[cnt].dli_saddr - array[cnt];
-		    }
-
-		  last += 1 + sprintf (last, "%s(%s%c%#tx) [%p]",
-				       info[cnt].dli_fname ?: "",
-				       info[cnt].dli_sname ?: "",
-				       sign, offset, array[cnt]);
-		}
-	    }
-	  else
-	    last += 1 + sprintf (last, "[%p]", array[cnt]);
-	}
-      assert (last <= (char *) result + size * sizeof (char *) + total);
-    }
-
-  return result;
-}
-weak_alias (__backtrace_symbols, backtrace_symbols)
diff --git a/sysdeps/generic/backtracesymsfd.c b/sysdeps/generic/backtracesymsfd.c
deleted file mode 100644
index 8b4a836ce9..0000000000
--- a/sysdeps/generic/backtracesymsfd.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/* Write formatted list with names for addresses in backtrace to a file.
-   Copyright (C) 1998,2000,2003,2005,2009,2011 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
-
-   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 <execinfo.h>
-#include <string.h>
-#include <sys/uio.h>
-
-#include <stdio-common/_itoa.h>
-#include <ldsodefs.h>
-
-#if __ELF_NATIVE_CLASS == 32
-# define WORD_WIDTH 8
-#else
-/* We assume 64bits.  */
-# define WORD_WIDTH 16
-#endif
-
-
-void
-__backtrace_symbols_fd (array, size, fd)
-     void *const *array;
-     int size;
-     int fd;
-{
-  struct iovec iov[9];
-  int cnt;
-
-  for (cnt = 0; cnt < size; ++cnt)
-    {
-      char buf[WORD_WIDTH];
-      char buf2[WORD_WIDTH];
-      Dl_info info;
-      struct link_map *map;
-      size_t last = 0;
-
-      if (_dl_addr (array[cnt], &info, &map, NULL)
-	  && info.dli_fname != NULL && info.dli_fname[0] != '\0')
-	{
-	  /* Name of the file.  */
-	  iov[0].iov_base = (void *) info.dli_fname;
-	  iov[0].iov_len = strlen (info.dli_fname);
-	  last = 1;
-
-	  if (info.dli_sname != NULL || map->l_addr != 0)
-	    {
-	      size_t diff;
-
-	      iov[last].iov_base = (void *) "(";
-	      iov[last].iov_len = 1;
-	      ++last;
-
-	      if (info.dli_sname != NULL)
-		{
-		  /* We have a symbol name.  */
-		  iov[last].iov_base = (void *) info.dli_sname;
-		  iov[last].iov_len = strlen (info.dli_sname);
-		  ++last;
-		}
-	      else
-		/* We have no symbol, so describe it as relative to the file.
-		   The load bias is more useful to the user than the load
-		   address.  The use of these addresses is to calculate an
-		   address in the ELF file, so its prelinked bias is not
-		   something we want to subtract out.  */
-		info.dli_saddr = (void *) map->l_addr;
-
-	      if (array[cnt] >= (void *) info.dli_saddr)
-		{
-		  iov[last].iov_base = (void *) "+0x";
-		  diff = array[cnt] - info.dli_saddr;
-		}
-	      else
-		{
-		  iov[last].iov_base = (void *) "-0x";
-		  diff = info.dli_saddr - array[cnt];
-		}
-	      iov[last].iov_len = 3;
-	      ++last;
-
-	      iov[last].iov_base = _itoa_word ((unsigned long int) diff,
-					       &buf2[WORD_WIDTH], 16, 0);
-	      iov[last].iov_len = (&buf2[WORD_WIDTH]
-				   - (char *) iov[last].iov_base);
-	      ++last;
-
-	      iov[last].iov_base = (void *) ")";
-	      iov[last].iov_len = 1;
-	      ++last;
-	    }
-	}
-
-      iov[last].iov_base = (void *) "[0x";
-      iov[last].iov_len = 3;
-      ++last;
-
-      iov[last].iov_base = _itoa_word ((unsigned long int) array[cnt],
-				       &buf[WORD_WIDTH], 16, 0);
-      iov[last].iov_len = &buf[WORD_WIDTH] - (char *) iov[last].iov_base;
-      ++last;
-
-      iov[last].iov_base = (void *) "]\n";
-      iov[last].iov_len = 2;
-      ++last;
-
-      __writev (fd, iov, last);
-    }
-}
-weak_alias (__backtrace_symbols_fd, backtrace_symbols_fd)
-libc_hidden_def (__backtrace_symbols_fd)