Hi,

We use the following patch in frysk for unw_get_proc_info to get the
correct start_ip when dwarf_make_proc_info fails. In that case we need
to adjust the start_ip using unw_get_proc_name to get the right
procedure start. Since we are only interested in the offset this patch
also makes it so that a NULL bufp can be provided to unw_get_proc_name
(including a small documentation update). This way the base address
returned by unw_get_proc_info can always be reliably used in combination
with later offsets returned by unw_get_proc_name (without this patch
there is no way to know whether or not to use the offset because both
unw_get_proc_info and unw_get_proc_name seem to succeed just fine).

2006-09-16  Alexandre Oliva  <[EMAIL PROTECTED]>
        
        * src/x86/Gget_proc_info.c (unw_get_proc_info): Use
        unw_get_proc_name to build a proper proc_info_t.
        * src/x86_64/Gget_proc_info.c (unw_get_proc_info): Likewise.
        * src/hppa/Gget_proc_info.c (unw_get_proc_info): Likewise.

2006-09-27  Alexandre Oliva  <[EMAIL PROTECTED]>

    * src/elfxx.c (lookup_symbol): Cope with NULL buf and zero buf_len.
    * src/mi/Gget_proc_name.c (intern_string, get_proc_name): Likewise.
    * src/hppa/Gget_proc_info.c (unw_get_proc_info): Use it.
    * src/x86/Gget_proc_info.c (unw_get_proc_info): Likewise.
    * src/x86_64/Gget_proc_info.c (unw_get_proc_info): Likewise.
    * doc/unw_get_proc_name.tex: Document NULL buf and zero buf_len.
    * doc/unw_create_addr_space.tex (get_proc_name): Likewise.
    * doc/unw_get_proc_name.man: Rebuilt.
    * doc/unw_create_addr_space.man: Likewise.

This doesn't introduce any test suite regressions (x86).

Cheers,

Mark
diff -r 5b0998e37265 doc/unw_create_addr_space.man
--- a/doc/unw_create_addr_space.man	Mon Sep 24 13:00:13 2007 +0200
+++ b/doc/unw_create_addr_space.man	Tue Oct 02 15:27:25 2007 +0200
@@ -413,6 +413,19 @@ pointed to by offp
 (assuming the procedure is at least 0x80 
 bytes long). 
 .PP
+If bufp
+is NULL
+, buf_len
+is still verified to fit
+and offp
+is set.  Passing buf_len
+as zero to indicate no
+limits on the buffer length is only safe if buf
+is NULL
+,
+otherwise the callback is entitled and likely to scribble anywhere in
+the entire address space.
+.PP
 On successful completion, the get_proc_name()
 call\-back must 
 return zero. Otherwise, the negative value of one of the 
diff -r 5b0998e37265 doc/unw_create_addr_space.tex
--- a/doc/unw_create_addr_space.tex	Mon Sep 24 13:00:13 2007 +0200
+++ b/doc/unw_create_addr_space.tex	Tue Oct 02 15:27:25 2007 +0200
@@ -229,6 +229,12 @@ pointed to by \Var{offp} (assuming the p
 pointed to by \Var{offp} (assuming the procedure is at least 0x80
 bytes long).
 
+If \Var{bufp} is \Const{NULL}, \Var{buf\_len} is still verified to fit
+and \Var{offp} is set.  Passing \Var{buf\_len} as zero to indicate no
+limits on the buffer length is only safe if \Var{buf} is \Const{NULL},
+otherwise the callback is entitled and likely to scribble anywhere in
+the entire address space.
+
 On successful completion, the \Func{get\_proc\_name}() call-back must
 return zero.  Otherwise, the negative value of one of the
 \Type{unw\_error\_t} error-codes may be returned.
diff -r 5b0998e37265 doc/unw_get_proc_name.man
--- a/doc/unw_get_proc_name.man	Mon Sep 24 13:00:13 2007 +0200
+++ b/doc/unw_get_proc_name.man	Tue Oct 02 15:27:25 2007 +0200
@@ -53,6 +53,19 @@ return a value of 0x80 in the word point
 return a value of 0x80 in the word pointed to by offp
 (assuming 
 the procedure is at least 0x80 bytes long). 
+.PP
+If bufp
+is NULL
+, buf_len
+is still verified to fit
+and offp
+is set.  Passing buf_len
+as zero to indicate no
+limits on the buffer length is only safe if buf
+is NULL
+,
+otherwise the callback is entitled and likely to scribble anywhere in
+the entire address space.
 .PP
 Note that on some platforms there is no reliable way to distinguish 
 between procedure names and ordinary labels. Furthermore, if symbol 
diff -r 5b0998e37265 doc/unw_get_proc_name.tex
--- a/doc/unw_get_proc_name.tex	Mon Sep 24 13:00:13 2007 +0200
+++ b/doc/unw_get_proc_name.tex	Tue Oct 02 15:27:25 2007 +0200
@@ -28,6 +28,12 @@ stack frame with an instruction-pointer 
 stack frame with an instruction-pointer value of 0x40003080 would
 return a value of 0x80 in the word pointed to by \Var{offp} (assuming
 the procedure is at least 0x80 bytes long).
+
+If \Var{bufp} is \Const{NULL}, \Var{buf\_len} is still verified to fit
+and \Var{offp} is set.  Passing \Var{buf\_len} as zero to indicate no
+limits on the buffer length is only safe if \Var{buf} is \Const{NULL},
+otherwise the callback is entitled and likely to scribble anywhere in
+the entire address space.
 
 Note that on some platforms there is no reliable way to distinguish
 between procedure names and ordinary labels.  Furthermore, if symbol
diff -r 5b0998e37265 src/elfxx.c
--- a/src/elfxx.c	Mon Sep 24 13:00:13 2007 +0200
+++ b/src/elfxx.c	Tue Oct 02 15:27:25 2007 +0200
@@ -110,9 +110,13 @@ elf_w (lookup_symbol) (unw_addr_space_t 
 		  if ((Elf_W (Addr)) (ip - val) < min_dist)
 		    {
 		      min_dist = (Elf_W (Addr)) (ip - val);
-		      strncpy (buf, strtab + sym->st_name, buf_len);
-		      buf[buf_len - 1] = '\0';
-		      if (strlen (strtab + sym->st_name) >= buf_len)
+		      buf_len--;
+		      if (buf)
+			{
+			  strncpy (buf, strtab + sym->st_name, buf_len);
+			  buf[buf_len] = '\0';
+			}
+		      if (strlen (strtab + sym->st_name) > buf_len)
 			ret = -UNW_ENOMEM;
 		    }
 		}
diff -r 5b0998e37265 src/hppa/Gget_proc_info.c
--- a/src/hppa/Gget_proc_info.c	Mon Sep 24 13:00:13 2007 +0200
+++ b/src/hppa/Gget_proc_info.c	Tue Oct 02 15:27:25 2007 +0200
@@ -36,8 +36,13 @@ unw_get_proc_info (unw_cursor_t *cursor,
 	 are missing DWARF unwind info.  We don't want to fail in that
 	 case, because those frames are uninteresting and just mark
 	 the end of the frame-chain anyhow.  */
+      unw_word_t offset;
+
+      if (unw_get_proc_name (cursor, NULL, 0, &offset) < 0)
+	offset = 0;
+
       memset (pi, 0, sizeof (*pi));
-      pi->start_ip = c->dwarf.ip;
+      pi->start_ip = c->dwarf.ip - offset;
       pi->end_ip = c->dwarf.ip + 4;
       return 0;
     }
diff -r 5b0998e37265 src/mi/Gget_proc_name.c
--- a/src/mi/Gget_proc_name.c	Mon Sep 24 13:00:13 2007 +0200
+++ b/src/mi/Gget_proc_name.c	Tue Oct 02 15:27:25 2007 +0200
@@ -33,16 +33,25 @@ intern_string (unw_addr_space_t as, unw_
   size_t i;
   int ret;
 
-  for (i = 0; i < buf_len; ++i)
+  buf_len--;
+
+  for (i = 0; i <= buf_len; ++i)
     {
-      if ((ret = fetch8 (as, a, &addr, (int8_t *) buf + i, arg)) < 0)
+      int8_t c, *p = buf ? (int8_t *)buf + i : &c;
+
+      if ((ret = fetch8 (as, a, &addr, p, arg)) < 0)
 	return ret;
 
-      if (buf[i] == '\0')
+      if (*p == '\0')
 	return 0;		/* copied full string; return success */
     }
-  buf[buf_len - 1] = '\0';	/* ensure string is NUL terminated */
-  return -UNW_ENOMEM;
+  if (buf)
+    {
+      buf[buf_len] = '\0';	/* ensure string is NUL terminated */
+      return -UNW_ENOMEM;
+    }
+  else
+    return 0;
 }
 
 static inline int
@@ -53,7 +62,8 @@ get_proc_name (unw_addr_space_t as, unw_
   unw_proc_info_t pi;
   int ret;
 
-  buf[0] = '\0';	/* always return a valid string, even if it's empty */
+  if (buf)
+    buf[0] = '\0';	/* always return a valid string, even if it's empty */
 
   ret = unwi_find_dynamic_proc_info (as, ip, &pi, 1, arg);
   if (ret == 0)
diff -r 5b0998e37265 src/x86/Gget_proc_info.c
--- a/src/x86/Gget_proc_info.c	Mon Sep 24 13:00:13 2007 +0200
+++ b/src/x86/Gget_proc_info.c	Tue Oct 02 15:27:25 2007 +0200
@@ -35,8 +35,13 @@ unw_get_proc_info (unw_cursor_t *cursor,
       /* On x86, it's relatively common to be missing DWARF unwind
 	 info.  We don't want to fail in that case, because the
 	 frame-chain still would let us do a backtrace at least.  */
+      unw_word_t offset;
+
+      if (unw_get_proc_name (cursor, NULL, 0, &offset) < 0)
+	offset = 0;
+
       memset (pi, 0, sizeof (*pi));
-      pi->start_ip = c->dwarf.ip;
+      pi->start_ip = c->dwarf.ip - offset;
       pi->end_ip = c->dwarf.ip + 1;
       return 0;
     }
diff -r 5b0998e37265 src/x86_64/Gget_proc_info.c
--- a/src/x86_64/Gget_proc_info.c	Mon Sep 24 13:00:13 2007 +0200
+++ b/src/x86_64/Gget_proc_info.c	Tue Oct 02 15:39:43 2007 +0200
@@ -38,8 +38,13 @@ unw_get_proc_info (unw_cursor_t *cursor,
 	 are missing DWARF unwind info.  We don't want to fail in that
 	 case, because those frames are uninteresting and just mark
 	 the end of the frame-chain anyhow.  */
+      unw_word_t offset;
+
+      if (unw_get_proc_name (cursor, NULL, 0, &offset) < 0)
+	offset = 0;
+
       memset (pi, 0, sizeof (*pi));
-      pi->start_ip = c->dwarf.ip;
+      pi->start_ip = c->dwarf.ip - offset;
       pi->end_ip = c->dwarf.ip + 1;
       return 0;
     }
_______________________________________________
Libunwind-devel mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/libunwind-devel

Reply via email to