[RFC PATCH 10/15] Support "sym -p" option

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Signed-off-by: Kazuhito Hagio <k-hagio-ab@xxxxxxx>
---
 symbols.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 69 insertions(+)

diff --git a/symbols.c b/symbols.c
index a432909ff28e..62092ba7d723 100644
--- a/symbols.c
+++ b/symbols.c
@@ -111,6 +111,7 @@ static ulong module_mem_end(ulong, struct load_module *);
 static int _in_module_range(ulong, struct load_module *, int, int);
 struct syment *value_search_module_v2(ulong, ulong *);
 struct syment *next_module_symbol(char *, struct syment *, ulong);
+struct syment *prev_module_symbol(struct syment *, ulong);
 
 static const char *module_start_tags[];
 static const char *module_start_strs[];
@@ -6073,6 +6074,71 @@ next_symbol(char *symbol, struct syment *sp_in)
         return NULL;
 }
 
+/* Only for 6.4 and later */
+struct syment *
+prev_module_symbol(struct syment *sp_in, ulong val_in)
+{
+	int i, j, k;
+	struct load_module *lm;
+	struct syment *sp, *sp_end;
+
+	if (val_in)
+		goto value_search;
+
+	for (i = 0; i < st->mods_installed; i++) {
+		lm = &st->load_modules[i];
+
+		/* quick check: sp_in is not in the module range. */
+		if (sp_in < lm->symtable[lm->address_order[0]] ||
+		    sp_in > lm->symend[lm->address_order[lm->nr_mems-1]])
+			continue;
+
+		for (j = 0; j < lm->nr_mems; j++) {
+			k = lm->address_order[j];
+			if (sp_in < lm->symtable[k] || sp_in > lm->symend[k])
+				continue;
+
+			if (sp_in == lm->symtable[k])
+				return prev_module_symbol(NULL, sp_in->value);
+
+			sp = sp_in - 1;
+			if (MODULE_PSEUDO_SYMBOL(sp))
+				return prev_module_symbol(NULL, sp->value);
+
+			return sp;
+		}
+	}
+	return NULL;
+
+value_search:
+	sp = sp_end = NULL;
+	for (i = 0; i < st->mods_installed; i++) {
+		lm = &st->load_modules[i];
+
+		/* quick check: val_in is lower than the lowest in the module. */
+		if (val_in < lm->symtable[lm->address_order[0]]->value)
+			continue;
+
+		for (j = lm->nr_mems - 1; j >= 0 ; j--) {
+			k = lm->address_order[j];
+			if (val_in > lm->symend[k]->value &&
+			    (sp == NULL || lm->symend[k]->value > sp->value)) {
+				sp = lm->symtable[k];
+				sp_end = lm->symend[k];
+				break;
+			}
+		}
+	}
+	for ( ; sp_end > sp; sp_end--) {
+		if (MODULE_PSEUDO_SYMBOL(sp_end))
+			continue;
+		if (sp_end->value > val_in)
+			return sp_end;
+	}
+
+	return NULL;
+}
+
 /*
  * For a given symbol, return a pointer to the previous (lower) symbol's syment.
  * Either a symbol name or syment pointer may be passed as an argument.
@@ -6096,6 +6162,9 @@ prev_symbol(char *symbol, struct syment *sp_in)
 			sp_prev = sp;
                 }
 
+		if (MODULE_MEMORY())
+			return prev_module_symbol(sp_in, 0);
+
 		search_init = FALSE;
 
                 for (i = 0; i < st->mods_installed; i++) {
-- 
2.31.1

--
Crash-utility mailing list
Crash-utility@xxxxxxxxxx
https://listman.redhat.com/mailman/listinfo/crash-utility
Contribution Guidelines: https://github.com/crash-utility/crash/wiki




[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux