----- Original Message -----
 Hello Dave,
 
 When using dis command on RHEL5.11, I found a weird thing. Please check the
 following execution.
 
 <cut>
 crash> dis do_wp_page | grep 591
 0xffffffff8001115c <do_wp_page+591>:	callq  0xffffffff800623d0
 <__sched_text_start>
 crash> dis schedule
 0xffffffff800623d0 <__sched_text_start>:        push   %rbp
 0xffffffff800623d1 <schedule+1>:        mov    %rsp,%rbp
 ...
 crash> dis do_wp_page | grep 591
 0xffffffff8001115c <do_wp_page+591>:	callq  0xffffffff800623d0 <schedule>
 crash> dis do_wp_page | grep 591
 0xffffffff8001115c <do_wp_page+591>:	callq  0xffffffff800623d0
 <__sched_text_start>
 <cut>
 
 schedule and __sched_text_start are always shifting.
 
 After some investigation, I found the following sentences in
 arch/x86_64/kernel/vmlinux.lds.S
 
 <cut>
 SECTIONS
 {
 ...
 SCHED_TEXT
 LOCK_TEXT
 KPROBES_TEXT
 ...
 <cut>
 
 the SCHED_TEXT is defined like below
 <cut>
 #define SCHED_TEXT                                                      \
                  ALIGN_FUNCTION();                                       \
                  VMLINUX_SYMBOL(__sched_text_start) = .;                 \
                  *(.sched.text)                                          \
                  VMLINUX_SYMBOL(__sched_text_end) = .;
 <cut>
 
 So symbol __sched_text_start may have the same address as the first function
 of *(.sched.text). And LOCK_TEXT/KPROBES_TEXT/IRQENTRY_TEXT has the same
 problems. The attached patch is used to fix this. 
 
 diff --git a/symbols.c b/symbols.c
 index cebff52..461348c 100755
 --- a/symbols.c
 +++ b/symbols.c
 @@ -4527,6 +4527,15 @@ value_search(ulong value, ulong *offset)
                           (spnext->value == value))
                               sp = spnext;
 +#define STRNVEQ(A, B)        (string_exists((char *)A) && string_exists((char
*)B) && \
 +                      strstr(A, B) && (strstr(A, B) - A) == \
 +                      (strlen((char *)(A)) - strlen((char *)(B))) )
 +
 +                     if (STRNVEQ(sp->name, "_text_start") &&
 +                         ((spnext = sp+1) < st->symend) &&
 +                         (spnext->value == value))
 +                             sp = spnext;
 +
                          return((struct syment *)sp);
                  }
                  if (sp->value > value) { 
Good catch -- thanks!  
The "shifting" is due to the caching in symval_hash_search().  But since
sp->name
is guaranteed to exist, I think the pre-existing strstr_rightmost() function makes
it a little easier to understand:
--- crash-7.0.9/symbols.c.orig
+++ crash-7.0.9/symbols.c
@@ -4527,6 +4527,11 @@ value_search(ulong value, ulong *offset)
 			    (spnext->value == value))
 				sp = spnext;
 
+			if (strstr_rightmost(sp->name, "_text_start") &&
+			    ((spnext = sp+1) < st->symend) &&
+			    (spnext->value == value))
+				sp = spnext;
+
                         return((struct syment *)sp);
                 }
                 if (sp->value > value) {
and I'll add a comment above it.
Thanks,
  Dave