File crash-Fix-for-the-dis-command-on-architectures-with-variab.patch of Package crash.4081
From 2e3d3f20d3b5ec6c17ceaeaa9c868f9d8794db4a Mon Sep 17 00:00:00 2001
From: Dave Anderson <anderson@redhat.com>
Date: Fri, 14 Aug 2015 10:19:56 -0400
Subject: [PATCH] Fix for the "dis" command on architectures with
variable-length instructions. Without the patch, "dis [-f] <function>" may
continue beyond the end of a function, disassembling the memory that is in
between the target function and the next function. (anderson@redhat.com)
---
defs.h | 2 ++
gdb-7.6.patch | 15 +++++++++++++++
gdb_interface.c | 7 +++++--
kernel.c | 7 ++++++-
symbols.c | 31 +++++++++++++++++++++++++++++++
5 files changed, 59 insertions(+), 3 deletions(-)
Index: crash-7.0.5/defs.h
===================================================================
--- crash-7.0.5.orig/defs.h
+++ crash-7.0.5/defs.h
@@ -3948,6 +3948,7 @@ struct gnu_request {
#define GNU_GET_SYMBOL_TYPE (15)
#define GNU_USER_PRINT_OPTION (16)
#define GNU_SET_CRASH_BLOCK (17)
+#define GNU_GET_FUNCTION_RANGE (18)
#define GNU_DEBUG_COMMAND (100)
/*
* GNU flags
@@ -4369,6 +4370,7 @@ int is_kernel_data(ulong);
int is_init_data(ulong value);
int is_kernel_text_offset(ulong);
int is_rodata(ulong, struct syment **);
+int get_text_function_range(ulong, ulong *, ulong *);
void datatype_init(void);
struct syment *symbol_search(char *);
struct syment *value_search(ulong, ulong *);
Index: crash-7.0.5/gdb-7.6.patch
===================================================================
--- crash-7.0.5.orig/gdb-7.6.patch
+++ crash-7.0.5/gdb-7.6.patch
@@ -1571,3 +1571,18 @@
if (build_address_symbolic (gdbarch, addr, do_demangle, &name, &offset,
&filename, &line, &unmapped))
{
+--- gdb-7.6/gdb/symtab.c.orig
++++ gdb-7.6/gdb/symtab.c
+@@ -5236,6 +5236,12 @@ gdb_command_funnel(struct gnu_request *r
+ gdb_set_crash_block(req);
+ break;
+
++ case GNU_GET_FUNCTION_RANGE:
++ sym = lookup_symbol(req->name, 0, VAR_DOMAIN, 0);
++ if (!find_pc_partial_function(req->pc, NULL, &req->addr, &req->addr2))
++ req->flags |= GNU_COMMAND_FAILED;
++ break;
++
+ default:
+ req->flags |= GNU_COMMAND_FAILED;
+ break;
Index: crash-7.0.5/gdb_interface.c
===================================================================
--- crash-7.0.5.orig/gdb_interface.c
+++ crash-7.0.5/gdb_interface.c
@@ -1,8 +1,8 @@
/* gdb_interface.c - core analysis suite
*
* Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc.
- * Copyright (C) 2002-2013 David Anderson
- * Copyright (C) 2002-2013 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2002-2015 David Anderson
+ * Copyright (C) 2002-2015 Red Hat, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -592,6 +592,9 @@ gdb_command_string(int cmd, char *buf, i
case GNU_SET_CRASH_BLOCK:
sprintf(buf, "GNU_SET_CRASH_BLOCK");
break;
+ case GNU_GET_FUNCTION_RANGE:
+ sprintf(buf, "GNU_GET_FUNCTION_RANGE");
+ break;
case 0:
buf[0] = NULLCHAR;
break;
Index: crash-7.0.5/kernel.c
===================================================================
--- crash-7.0.5.orig/kernel.c
+++ crash-7.0.5/kernel.c
@@ -1339,6 +1339,7 @@ cmd_dis(void)
ulong target;
ulong count;
ulong offset;
+ ulong low, high;
struct syment *sp;
struct gnu_request *req;
char *savename;
@@ -1495,8 +1496,12 @@ cmd_dis(void)
req->command = GNU_RESOLVE_TEXT_ADDR;
gdb_interface(req);
req->flags &= ~GNU_COMMAND_FAILED;
+
if (reverse || forward || req->flags & GNU_FUNCTION_ONLY) {
- if (sp) {
+ if (get_text_function_range(sp ? sp->value : req->addr,
+ &low, &high))
+ req->addr2 = high;
+ else if (sp) {
savename = sp->name;
if ((sp = next_symbol(NULL, sp)))
req->addr2 = sp->value;
Index: crash-7.0.5/symbols.c
===================================================================
--- crash-7.0.5.orig/symbols.c
+++ crash-7.0.5/symbols.c
@@ -2653,6 +2653,37 @@ is_rodata(ulong value, struct syment **s
}
/*
+ * For a given kernel virtual address, request that gdb return
+ * the address range of the containing function. For module
+ * text addresses, its debuginfo data must be loaded.
+ */
+int
+get_text_function_range(ulong vaddr, ulong *low, ulong *high)
+{
+ struct syment *sp;
+ struct gnu_request gnu_request, *req = &gnu_request;
+
+ if (!(sp = value_search(vaddr, NULL)))
+ return FALSE;
+
+ BZERO(req, sizeof(struct gnu_request));
+ req->command = GNU_GET_FUNCTION_RANGE;
+ req->pc = sp->value;
+ req->name = sp->name;
+ gdb_interface(req);
+ if (req->flags & GNU_COMMAND_FAILED)
+ return FALSE;
+
+ if ((vaddr < req->addr) || (vaddr >= req->addr2))
+ return FALSE;
+
+ *low = req->addr;
+ *high = req->addr2;
+
+ return TRUE;
+}
+
+/*
* "help -s" output
*/
void