summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorJason King <jason.brian.king@gmail.com>2011-11-04 09:47:33 -0500
committerJason King <jason.brian.king@gmail.com>2011-11-04 09:47:33 -0500
commit6e6df3cf62ece86f43c1a3218dc4b7797d9ce731 (patch)
tree46ba8420132b208db262c47e1104a8ab5809bba0 /usr/src
parente50226eccc6dfcba3cc6f0df38438900e3df225c (diff)
downloadillumos-joyent-6e6df3cf62ece86f43c1a3218dc4b7797d9ce731.tar.gz
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>
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/dis/dis_target.c47
-rw-r--r--usr/src/cmd/dis/dis_target.h2
2 files changed, 47 insertions, 2 deletions
diff --git a/usr/src/cmd/dis/dis_target.c b/usr/src/cmd/dis/dis_target.c
index c509157335..e47d77fe8d 100644
--- a/usr/src/cmd/dis/dis_target.c
+++ b/usr/src/cmd/dis/dis_target.c
@@ -309,6 +309,47 @@ construct_symtab(dis_tgt_t *tgt)
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 @@ dis_tgt_create(const char *file)
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 @@ dis_tgt_lookup(dis_tgt_t *tgt, uint64_t addr, off_t *offset, int cache_result,
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 @@ dis_tgt_next_symbol(dis_tgt_t *tgt, uint64_t addr)
return (0);
}
+#endif
/*
* Iterate over all sections in the target, executing the given callback for
diff --git a/usr/src/cmd/dis/dis_target.h b/usr/src/cmd/dis/dis_target.h
index fa6c14c378..c6d13ab8dc 100644
--- a/usr/src/cmd/dis/dis_target.h
+++ b/usr/src/cmd/dis/dis_target.h
@@ -54,7 +54,9 @@ const char *dis_find_section(dis_tgt_t *, uint64_t, off_t *);
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 *);
/*