709
710 if (osym == tgt->dt_symtab)
711 break;
712
713 osym = osym - 1;
714 } while ((sym->se_sym.st_value == osym->se_sym.st_value) &&
715 (addr >= osym->se_sym.st_value) &&
716 (addr < osym->se_sym.st_value + osym->se_sym.st_size));
717
718 if (cache_result)
719 tgt->dt_symcache = sym;
720
721 *offset = addr - sym->se_sym.st_value;
722 *size = sym->se_sym.st_size;
723 if (isfunc)
724 *isfunc = (GELF_ST_TYPE(sym->se_sym.st_info) == STT_FUNC);
725
726 return (sym->se_name);
727 }
728
729 #if !defined(__sparc)
730 /*
731 * Given an address, return the starting offset of the next symbol in the file.
732 * Only needed on variable length instruction architectures.
733 */
734 off_t
735 dis_tgt_next_symbol(dis_tgt_t *tgt, uint64_t addr)
736 {
737 sym_entry_t *sym;
738
739 sym = (tgt->dt_symcache != NULL) ? tgt->dt_symcache : tgt->dt_symtab;
740
741 while (sym != (tgt->dt_symtab + tgt->dt_symcount)) {
742 if (sym->se_sym.st_value >= addr)
743 return (sym->se_sym.st_value - addr);
744 sym++;
745 }
746
747 return (0);
748 }
749 #endif
750
751 /*
752 * Iterate over all sections in the target, executing the given callback for
753 * each.
754 */
755 void
756 dis_tgt_section_iter(dis_tgt_t *tgt, section_iter_f func, void *data)
757 {
758 dis_scn_t sdata;
759 Elf_Scn *scn;
760 int idx;
761
762 for (scn = elf_nextscn(tgt->dt_elf, NULL), idx = 1; scn != NULL;
763 scn = elf_nextscn(tgt->dt_elf, scn), idx++) {
764
765 if (gelf_getshdr(scn, &sdata.ds_shdr) == NULL) {
766 warn("%s: failed to get section %d header",
767 tgt->dt_filename, idx);
768 continue;
769 }
|
709
710 if (osym == tgt->dt_symtab)
711 break;
712
713 osym = osym - 1;
714 } while ((sym->se_sym.st_value == osym->se_sym.st_value) &&
715 (addr >= osym->se_sym.st_value) &&
716 (addr < osym->se_sym.st_value + osym->se_sym.st_size));
717
718 if (cache_result)
719 tgt->dt_symcache = sym;
720
721 *offset = addr - sym->se_sym.st_value;
722 *size = sym->se_sym.st_size;
723 if (isfunc)
724 *isfunc = (GELF_ST_TYPE(sym->se_sym.st_info) == STT_FUNC);
725
726 return (sym->se_name);
727 }
728
729 /*
730 * Given an address, return the starting offset of the next symbol in the file.
731 * Only needed on variable length instruction architectures.
732 */
733 off_t
734 dis_tgt_next_symbol(dis_tgt_t *tgt, uint64_t addr)
735 {
736 sym_entry_t *sym;
737
738 sym = (tgt->dt_symcache != NULL) ? tgt->dt_symcache : tgt->dt_symtab;
739
740 while (sym != (tgt->dt_symtab + tgt->dt_symcount)) {
741 if (sym->se_sym.st_value >= addr)
742 return (sym->se_sym.st_value - addr);
743 sym++;
744 }
745
746 return (0);
747 }
748
749 /*
750 * Iterate over all sections in the target, executing the given callback for
751 * each.
752 */
753 void
754 dis_tgt_section_iter(dis_tgt_t *tgt, section_iter_f func, void *data)
755 {
756 dis_scn_t sdata;
757 Elf_Scn *scn;
758 int idx;
759
760 for (scn = elf_nextscn(tgt->dt_elf, NULL), idx = 1; scn != NULL;
761 scn = elf_nextscn(tgt->dt_elf, scn), idx++) {
762
763 if (gelf_getshdr(scn, &sdata.ds_shdr) == NULL) {
764 warn("%s: failed to get section %d header",
765 tgt->dt_filename, idx);
766 continue;
767 }
|