changeset 13508:bf0e4028ac3a

1548 dis crashes disassembling anything kernel-ish Reviewed by: Richard Lowe <richlowe@richlowe.net> Reviewed by: Eric Schrock <eric.schrock@delphix.com> Approved by: Gordon Ross <gwr@nexenta.com>
author Jason King <jason.brian.king@gmail.com>
date Fri, 04 Nov 2011 09:47:33 -0500
parents aaf06453aff9
children 04570f5cbeca
files usr/src/cmd/dis/dis_target.c usr/src/cmd/dis/dis_target.h
diffstat 2 files changed, 47 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/dis/dis_target.c	Fri Nov 04 12:59:45 2011 +0400
+++ b/usr/src/cmd/dis/dis_target.c	Fri Nov 04 09:47:33 2011 -0500
@@ -309,6 +309,47 @@
 			sym->se_shndx = sym->se_sym.st_shndx;
 		}
 
+		/* Deal with symbols with special section indicies */
+		if (sym->se_shndx == SHN_ABS) {
+			/*
+			 * If st_value == 0, references to these
+			 * symbols in code are modified in situ
+			 * thus we will never attempt to look
+			 * them up.
+			 */
+			if (sym->se_sym.st_value == 0) {
+				/*
+				 * References to these symbols in code
+				 * are modified in situ by the runtime
+				 * linker and no code on disk will ever
+				 * attempt to look them up.
+				 */
+				nsym++;
+				continue;
+			} else {
+				/*
+				 * If st_value != 0, (such as examining
+				 * something in /system/object/.../object)
+				 * the values should resolve to a value
+				 * within an existing section (such as
+				 * .data).  This also means it never needs
+				 * to have st_value mapped.
+				 */
+				sym++;
+				continue;
+			}
+		}
+
+		/*
+		 * Ignore the symbol if it has some other special
+		 * section index
+		 */
+		if (sym->se_shndx == SHN_UNDEF ||
+		    sym->se_shndx >= SHN_LORESERVE) {
+			nsym++;
+			continue;
+		}
+
 		if ((sym->se_name = elf_strptr(tgt->dt_elf, shdr.sh_link,
 		    (size_t)sym->se_sym.st_name)) == NULL) {
 			warn("%s: failed to lookup symbol %d name",
@@ -466,13 +507,12 @@
 
 		idx = 0;
 		dis_tgt_section_iter(current, tgt_scn_init, &idx);
+		current->dt_filename = file;
 
 		create_addrmap(current);
 		if (current->dt_symidx != 0)
 			construct_symtab(current);
 
-		current->dt_filename = file;
-
 		cmd = elf_next(elf);
 	}
 
@@ -669,8 +709,10 @@
 	return (sym->se_name);
 }
 
+#if !defined(__sparc)
 /*
  * Given an address, return the starting offset of the next symbol in the file.
+ * Only needed on variable length instruction architectures.
  */
 off_t
 dis_tgt_next_symbol(dis_tgt_t *tgt, uint64_t addr)
@@ -686,6 +728,7 @@
 
 	return (0);
 }
+#endif
 
 /*
  * Iterate over all sections in the target, executing the given callback for
--- a/usr/src/cmd/dis/dis_target.h	Fri Nov 04 12:59:45 2011 +0400
+++ b/usr/src/cmd/dis/dis_target.h	Fri Nov 04 09:47:33 2011 -0500
@@ -54,7 +54,9 @@
 const char *dis_tgt_name(dis_tgt_t *);
 const char *dis_tgt_member(dis_tgt_t *);
 void dis_tgt_ehdr(dis_tgt_t *, GElf_Ehdr *);
+#if !defined(__sparc)
 off_t dis_tgt_next_symbol(dis_tgt_t *, uint64_t);
+#endif
 dis_tgt_t *dis_tgt_next(dis_tgt_t *);
 
 /*