summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorJason King <jason@ansipunx.net>2008-12-21 19:46:57 -0800
committerJason King <jason@ansipunx.net>2008-12-21 19:46:57 -0800
commitb8ef3d63f88370c11b7163620bbc1206301d39d5 (patch)
tree5a161c3d7b1ecb3ada4fca01152ef8dd7fd9035c /usr/src
parent2691240c021e7fd636dd0e4b884a2f76b0cb94d9 (diff)
downloadillumos-joyent-b8ef3d63f88370c11b7163620bbc1206301d39d5.tar.gz
6782322 libdisasm format output has bad printf string
6762256 sparc disassembler (dis/mdb) could display symbolic ASI names 6781870 dis doesn't disassemble sir instruction
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/lib/libdisasm/sparc/dis_sparc_fmt.c301
1 files changed, 298 insertions, 3 deletions
diff --git a/usr/src/lib/libdisasm/sparc/dis_sparc_fmt.c b/usr/src/lib/libdisasm/sparc/dis_sparc_fmt.c
index f2e6ee51af..5107c5d8bc 100644
--- a/usr/src/lib/libdisasm/sparc/dis_sparc_fmt.c
+++ b/usr/src/lib/libdisasm/sparc/dis_sparc_fmt.c
@@ -25,7 +25,7 @@
*/
/*
- * Copyright 2007 Jason King. All rights reserved.
+ * Copyright 2008 Jason King. All rights reserved.
* Use is subject to license terms.
*/
@@ -615,7 +615,7 @@ static const char *v9_privreg_names[32] = {
NULL, NULL, NULL, "%ver"
};
-/* hyper privledged register names on v9 */
+/* hyper privileged register names on v9 */
static const char *v9_hprivreg_names[32] = {
"%hpstate", "%htstate", "%hrstba", "%hintp",
NULL, "%htba", "%hver", NULL,
@@ -657,6 +657,7 @@ static void prt_name(dis_handle_t *, const char *, int);
static void prt_imm(dis_handle_t *, uint32_t, int);
static void prt_asi(dis_handle_t *, uint32_t);
+static const char *get_asi_name(uint8_t);
static void prt_address(dis_handle_t *, uint32_t, int);
static void prt_aluargs(dis_handle_t *, uint32_t, uint32_t);
static void bprintf(dis_handle_t *, const char *, ...);
@@ -935,8 +936,11 @@ static int
fmt_cas(dis_handle_t *dhp, uint32_t instr, const char *name)
{
ifmt_t *f = (ifmt_t *)&instr;
+ const char *asistr = NULL;
int noasi = 0;
+ asistr = get_asi_name(f->f3.asi);
+
if ((dhp->dh_debug & (DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT)) != 0) {
if (f->f3.op3 == 0x3c && f->f3.i == 0) {
if (f->f3.asi == 0x80) {
@@ -974,6 +978,9 @@ fmt_cas(dis_handle_t *dhp, uint32_t instr, const char *name)
bprintf(dhp, ", %s, %s", reg_names[f->f3.rs2], reg_names[f->f3.rd]);
+ if (noasi == 0 && asistr != NULL)
+ bprintf(dhp, "\t<%s>", asistr);
+
return (0);
}
@@ -1014,6 +1021,7 @@ fmt_ls(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
{
ifmt_t *f = (ifmt_t *)&instr;
const char *regstr = NULL;
+ const char *asistr = NULL;
const char *iname = inp->in_data.in_def.in_name;
uint32_t flags = inp->in_data.in_def.in_flags;
@@ -1054,6 +1062,12 @@ fmt_ls(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
else
prt_imm(dhp, f->f3.rd, 0);
+ if (idx == 0x3d && f->f3.i == 0) {
+ asistr = get_asi_name(f->f3.asi);
+ if (asistr != NULL)
+ bprintf(dhp, "\t<%s>", asistr);
+ }
+
return (0);
}
@@ -1197,6 +1211,10 @@ fmt_ls(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
get_regname(dhp, REG_FPD, f->f3.rs2),
get_regname(dhp, REG_FPD, f->f3.rs1));
prt_asi(dhp, instr);
+ asistr = get_asi_name(f->f3.asi);
+ if (asistr != NULL)
+ bprintf(dhp, "\t<%s>", asistr);
+
return (0);
default:
@@ -1207,6 +1225,9 @@ fmt_ls(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
regstr = get_regname(dhp, FLG_RD_VAL(flags), f->f3.rd);
+ if (f->f3.i == 0)
+ asistr = get_asi_name(f->f3.asi);
+
prt_name(dhp, iname, 1);
if ((flags & FLG_STORE) != 0) {
@@ -1233,6 +1254,9 @@ fmt_ls(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
}
}
+ if ((flags & FLG_ASI) != 0 && asistr != NULL)
+ bprintf(dhp, "\t<%s>", asistr);
+
return (0);
}
@@ -1374,6 +1398,19 @@ dis_fmt_rdwr(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
mask = asr_wrmask;
}
+ /*
+ * sir is shoehorned in here, per Ultrasparc 2007
+ * hyperprivileged edition, section 7.88, all of
+ * these must be true to distinguish from WRasr
+ */
+ if (v9 != 0 && f->f3.rd == 15 && f->f3.rs1 == 0 &&
+ f->f3.i == 1) {
+ prt_name(dhp, "sir", 1);
+ prt_imm(dhp, sign_extend(f->f3a.simm13, 13),
+ IMM_SIGNED);
+ return (0);
+ }
+
/* synth: mov */
if ((dhp->dh_debug & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL))
== 0)
@@ -2183,7 +2220,7 @@ prt_field(const char *field, uint32_t val, int len)
static void
prt_field(const char *field, uint32_t val, int len)
{
- (void) fprintf(stderr, "DISASM: %8s = 0x%-8ulx (", field, val);
+ (void) fprintf(stderr, "DISASM: %8s = 0x%-8x (", field, val);
prt_binary(val, len);
(void) fprintf(stderr, ")\n");
}
@@ -2478,6 +2515,264 @@ prt_aluargs(dis_handle_t *dhp, uint32_t instr, uint32_t flags)
(void) strlcat(dhp->dh_buf, r3, dhp->dh_buflen);
}
+static const char *
+get_asi_name(uint8_t asi)
+{
+ switch (asi) {
+ case 0x04:
+ return ("ASI_N");
+
+ case 0x0c:
+ return ("ASI_NL");
+
+ case 0x10:
+ return ("ASI_AIUP");
+
+ case 0x11:
+ return ("ASI_AIUS");
+
+ case 0x14:
+ return ("ASI_REAL");
+
+ case 0x15:
+ return ("ASI_REAL_IO");
+
+ case 0x16:
+ return ("ASI_BLK_AIUP");
+
+ case 0x17:
+ return ("ASI_BLK_AIUS");
+
+ case 0x18:
+ return ("ASI_AIUPL");
+
+ case 0x19:
+ return ("ASI_AIUSL");
+
+ case 0x1c:
+ return ("ASI_REAL_L");
+
+ case 0x1d:
+ return ("ASI_REAL_IO_L");
+
+ case 0x1e:
+ return ("ASI_BLK_AIUPL");
+
+ case 0x1f:
+ return ("ASI_BLK_AIUS_L");
+
+ case 0x20:
+ return ("ASI_SCRATCHPAD");
+
+ case 0x21:
+ return ("ASI_MMU_CONTEXTID");
+
+ case 0x22:
+ return ("ASI_TWINX_AIUP");
+
+ case 0x23:
+ return ("ASI_TWINX_AIUS");
+
+ case 0x25:
+ return ("ASI_QUEUE");
+
+ case 0x26:
+ return ("ASI_TWINX_R");
+
+ case 0x27:
+ return ("ASI_TWINX_N");
+
+ case 0x2a:
+ return ("ASI_LDTX_AIUPL");
+
+ case 0x2b:
+ return ("ASI_TWINX_AIUS_L");
+
+ case 0x2e:
+ return ("ASI_TWINX_REAL_L");
+
+ case 0x2f:
+ return ("ASI_TWINX_NL");
+
+ case 0x30:
+ return ("ASI_AIPP");
+
+ case 0x31:
+ return ("ASI_AIPS");
+
+ case 0x36:
+ return ("ASI_AIPN");
+
+ case 0x38:
+ return ("ASI_AIPP_L");
+
+ case 0x39:
+ return ("ASI_AIPS_L");
+
+ case 0x3e:
+ return ("ASI_AIPN_L");
+
+ case 0x41:
+ return ("ASI_CMT_SHARED");
+
+ case 0x4f:
+ return ("ASI_HYP_SCRATCHPAD");
+
+ case 0x50:
+ return ("ASI_IMMU");
+
+ case 0x52:
+ return ("ASI_MMU_REAL");
+
+ case 0x54:
+ return ("ASI_MMU");
+
+ case 0x55:
+ return ("ASI_ITLB_DATA_ACCESS_REG");
+
+ case 0x56:
+ return ("ASI_ITLB_TAG_READ_REG");
+
+ case 0x57:
+ return ("ASI_IMMU_DEMAP");
+
+ case 0x58:
+ return ("ASI_DMMU / ASI_UMMU");
+
+ case 0x5c:
+ return ("ASI_DTLB_DATA_IN_REG");
+
+ case 0x5d:
+ return ("ASI_DTLB_DATA_ACCESS_REG");
+
+ case 0x5e:
+ return ("ASI_DTLB_TAG_READ_REG");
+
+ case 0x5f:
+ return ("ASI_DMMU_DEMAP");
+
+ case 0x63:
+ return ("ASI_CMT_PER_STRAND / ASI_CMT_PER_CORE");
+
+ case 0x80:
+ return ("ASI_P");
+
+ case 0x81:
+ return ("ASI_S");
+
+ case 0x82:
+ return ("ASI_PNF");
+
+ case 0x83:
+ return ("ASI_SNF");
+
+ case 0x88:
+ return ("ASI_PL");
+
+ case 0x89:
+ return ("ASI_SL");
+
+ case 0x8a:
+ return ("ASI_PNFL");
+
+ case 0x8b:
+ return ("ASI_SNFL");
+
+ case 0xc0:
+ return ("ASI_PST8_P");
+
+ case 0xc1:
+ return ("ASI_PST8_S");
+
+ case 0xc2:
+ return ("ASI_PST16_P");
+
+ case 0xc3:
+ return ("ASI_PST16_S");
+
+ case 0xc4:
+ return ("ASI_PST32_P");
+
+ case 0xc5:
+ return ("ASI_PST32_S");
+
+ case 0xc8:
+ return ("ASI_PST8_PL");
+
+ case 0xc9:
+ return ("ASI_PST8_SL");
+
+ case 0xca:
+ return ("ASI_PST16_PL");
+
+ case 0xcb:
+ return ("ASI_PST16_SL");
+
+ case 0xcc:
+ return ("ASI_PST32_PL");
+
+ case 0xcd:
+ return ("ASI_PST32_SL");
+
+ case 0xd0:
+ return ("ASI_FL8_P");
+
+ case 0xd1:
+ return ("ASI_FL8_S");
+
+ case 0xd2:
+ return ("ASI_FL16_P");
+
+ case 0xd3:
+ return ("ASI_FL16_S");
+
+ case 0xd8:
+ return ("ASI_FL8_PL");
+
+ case 0xd9:
+ return ("ASI_FL8_SL");
+
+ case 0xda:
+ return ("ASI_FL16_PL");
+
+ case 0xdb:
+ return ("ASI_FL16_SL");
+
+ case 0xe0:
+ return ("ASI_BLK_COMMIT_P");
+
+ case 0xe1:
+ return ("ASI_BLK_SOMMIT_S");
+
+ case 0xe2:
+ return ("ASI_TWINX_P");
+
+ case 0xe3:
+ return ("ASI_TWINX_S");
+
+ case 0xea:
+ return ("ASI_TWINX_PL");
+
+ case 0xeb:
+ return ("ASI_TWINX_SL");
+
+ case 0xf0:
+ return ("ASI_BLK_P");
+
+ case 0xf1:
+ return ("ASI_BLK_S");
+
+ case 0xf8:
+ return ("ASI_BLK_PL");
+
+ case 0xf9:
+ return ("ASI_BLK_SL");
+
+ default:
+ return (NULL);
+ }
+}
+
/*
* just a handy function that takes care of managing the buffer length
* w/ printf