From: Ulrich Drepper Date: Fri, 11 Jan 2008 05:10:32 +0000 (+0000) Subject: merge of '3bc1b3a545049c99f3627ae7f0cbd7cf256e3806' X-Git-Tag: elfutils-0.132~26 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d117ed89d2a215d17a8b750b535fc25f1ba2da48;p=platform%2Fupstream%2Felfutils.git Merge ... '3bc1b3a545049c99f3627ae7f0cbd7cf256e3806' and '944c821e8ff593d1d87d48b73871f5ffa8c88515' --- diff --git a/libcpu/ChangeLog b/libcpu/ChangeLog index 9bb8175..8cf6be0 100644 --- a/libcpu/ChangeLog +++ b/libcpu/ChangeLog @@ -1,3 +1,9 @@ +2008-01-10 Ulrich Drepper + + * i386_disasm.c: Rewrite interface to callback functions for operands + to take a single pointer to a structure. + * i386_data.h: Adjust all functions. + 2008-01-08 Ulrich Drepper * Makefile.am: Enable x86-64 again. diff --git a/libcpu/i386_data.h b/libcpu/i386_data.h index 398c672..94bb84b 100644 --- a/libcpu/i386_data.h +++ b/libcpu/i386_data.h @@ -78,56 +78,53 @@ struct instr_enc }; -typedef int (*opfct_t) (GElf_Addr, int *, const char *, size_t, size_t, size_t, - char *, size_t *, size_t, const uint8_t *data, - const uint8_t **param_start, const uint8_t *end, - DisasmGetSymCB_t, void *); +typedef int (*opfct_t) (struct output_data *); static int -data_prefix (int *prefixes, char *bufp, size_t *bufcntp, size_t bufsize) +data_prefix (struct output_data *d) { char ch = '\0'; - if (*prefixes & has_cs) + if (*d->prefixes & has_cs) { ch = 'c'; - *prefixes &= ~has_cs; + *d->prefixes &= ~has_cs; } - else if (*prefixes & has_ds) + else if (*d->prefixes & has_ds) { ch = 'd'; - *prefixes &= ~has_ds; + *d->prefixes &= ~has_ds; } - else if (*prefixes & has_es) + else if (*d->prefixes & has_es) { ch = 'e'; - *prefixes &= ~has_es; + *d->prefixes &= ~has_es; } - else if (*prefixes & has_fs) + else if (*d->prefixes & has_fs) { ch = 'f'; - *prefixes &= ~has_fs; + *d->prefixes &= ~has_fs; } - else if (*prefixes & has_gs) + else if (*d->prefixes & has_gs) { ch = 'g'; - *prefixes &= ~has_gs; + *d->prefixes &= ~has_gs; } - else if (*prefixes & has_ss) + else if (*d->prefixes & has_ss) { ch = 's'; - *prefixes &= ~has_ss; + *d->prefixes &= ~has_ss; } else return 0; - if (*bufcntp + 4 > bufsize) - return *bufcntp + 4 - bufsize; + if (*d->bufcntp + 4 > d->bufsize) + return *d->bufcntp + 4 - d->bufsize; - bufp[(*bufcntp)++] = '%'; - bufp[(*bufcntp)++] = ch; - bufp[(*bufcntp)++] = 's'; - bufp[(*bufcntp)++] = ':'; + d->bufp[(*d->bufcntp)++] = '%'; + d->bufp[(*d->bufcntp)++] = ch; + d->bufp[(*d->bufcntp)++] = 's'; + d->bufp[(*d->bufcntp)++] = ':'; return 0; } @@ -154,38 +151,31 @@ static const char aregs[8][4] = #endif static int -general_mod$r_m (GElf_Addr addr __attribute__ ((unused)), - int *prefixes __attribute__ ((unused)), - const char *op1str __attribute__ ((unused)), - size_t opoff1 __attribute__ ((unused)), - size_t opoff2 __attribute__ ((unused)), - size_t opoff3 __attribute__ ((unused)), - char *bufp __attribute__ ((unused)), - size_t *bufcntp __attribute__ ((unused)), - size_t bufsize __attribute__ ((unused)), - const uint8_t *data __attribute__ ((unused)), - const uint8_t **param_start __attribute__ ((unused)), - const uint8_t *end __attribute__ ((unused)), - DisasmGetSymCB_t symcb __attribute__ ((unused)), - void *symcbarg __attribute__ ((unused))) +general_mod$r_m (struct output_data *d) { - int r = data_prefix (prefixes, bufp, bufcntp, bufsize); + int r = data_prefix (d); if (r != 0) return r; - uint_fast8_t modrm = data[opoff1 / 8]; + int prefixes = *d->prefixes; + const uint8_t *data = &d->data[d->opoff1 / 8]; + char *bufp = d->bufp; + size_t *bufcntp = d->bufcntp; + size_t bufsize = d->bufsize; + + uint_fast8_t modrm = data[0]; #ifndef X86_64 - if (unlikely ((*prefixes & has_addr16) != 0)) + if (unlikely ((prefixes & has_addr16) != 0)) { int16_t disp = 0; bool nodisp = false; if ((modrm & 0xc7) == 6 || (modrm & 0xc0) == 0x80) /* 16 bit displacement. */ - disp = read_2sbyte_unaligned (&data[opoff1 / 8 + 1]); + disp = read_2sbyte_unaligned (&data[1]); else if ((modrm & 0xc0) == 0x40) /* 8 bit displacement. */ - disp = *(const int8_t *) &data[opoff1 / 8 + 1]; + disp = *(const int8_t *) &data[1]; else if ((modrm & 0xc0) == 0) nodisp = true; @@ -224,10 +214,10 @@ general_mod$r_m (GElf_Addr addr __attribute__ ((unused)), if ((modrm & 0xc7) == 5 || (modrm & 0xc0) == 0x80) /* 32 bit displacement. */ - disp = read_4sbyte_unaligned (&data[opoff1 / 8 + 1]); + disp = read_4sbyte_unaligned (&data[1]); else if ((modrm & 0xc0) == 0x40) /* 8 bit displacement. */ - disp = *(const int8_t *) &data[opoff1 / 8 + 1]; + disp = *(const int8_t *) &data[1]; else if ((modrm & 0xc0) == 0) nodisp = true; @@ -237,13 +227,13 @@ general_mod$r_m (GElf_Addr addr __attribute__ ((unused)), { n = snprintf (tmpbuf, sizeof (tmpbuf), "(%%%s)", #ifdef X86_64 - (*prefixes & has_rex_b) ? hiregs[modrm & 7] : + (prefixes & has_rex_b) ? hiregs[modrm & 7] : #endif aregs[modrm & 7]); #ifdef X86_64 - if (*prefixes & has_addr16) + if (prefixes & has_addr16) { - if (*prefixes & has_rex_b) + if (prefixes & has_rex_b) tmpbuf[n++] = 'd'; else tmpbuf[2] = 'e'; @@ -256,13 +246,13 @@ general_mod$r_m (GElf_Addr addr __attribute__ ((unused)), n = snprintf (tmpbuf, sizeof (tmpbuf), "%s0x%" PRIx32 "(%%%n%s)", disp < 0 ? "-" : "", disp < 0 ? -disp : disp, &p, #ifdef X86_64 - (*prefixes & has_rex_b) ? hiregs[modrm & 7] : + (prefixes & has_rex_b) ? hiregs[modrm & 7] : #endif aregs[modrm & 7]); #ifdef X86_64 - if (*prefixes & has_addr16) + if (prefixes & has_addr16) { - if (*prefixes & has_rex_b) + if (prefixes & has_rex_b) tmpbuf[n++] = 'd'; else tmpbuf[p] = 'e'; @@ -288,17 +278,17 @@ general_mod$r_m (GElf_Addr addr __attribute__ ((unused)), else { /* SIB */ - uint_fast8_t sib = data[opoff1 / 8 + 1]; + uint_fast8_t sib = data[1]; int32_t disp = 0; bool nodisp = false; if ((modrm & 0xc7) == 5 || (modrm & 0xc0) == 0x80 || ((modrm & 0xc7) == 0x4 && (sib & 0x7) == 0x5)) /* 32 bit displacement. */ - disp = read_4sbyte_unaligned (&data[opoff1 / 8 + 2]); + disp = read_4sbyte_unaligned (&data[2]); else if ((modrm & 0xc0) == 0x40) /* 8 bit displacement. */ - disp = *(const int8_t *) &data[opoff1 / 8 + 2]; + disp = *(const int8_t *) &data[2]; else nodisp = true; @@ -307,7 +297,7 @@ general_mod$r_m (GElf_Addr addr __attribute__ ((unused)), int n; if ((modrm & 0xc0) != 0 || (sib & 0x3f) != 0x25 #ifdef X86_64 - || (*prefixes & has_rex_x) != 0 + || (prefixes & has_rex_x) != 0 #endif ) { @@ -325,12 +315,12 @@ general_mod$r_m (GElf_Addr addr __attribute__ ((unused)), *cp++ = '%'; cp = stpcpy (cp, #ifdef X86_64 - (*prefixes & has_rex_b) ? hiregs[sib & 7] : - (*prefixes & has_addr16) ? dregs[sib & 7] : + (prefixes & has_rex_b) ? hiregs[sib & 7] : + (prefixes & has_addr16) ? dregs[sib & 7] : #endif aregs[sib & 7]); #ifdef X86_64 - if ((*prefixes & (has_rex_b | has_addr16)) + if ((prefixes & (has_rex_b | has_addr16)) == (has_rex_b | has_addr16)) *cp++ = 'd'; #endif @@ -338,7 +328,7 @@ general_mod$r_m (GElf_Addr addr __attribute__ ((unused)), if ((sib & 0x38) != 0x20 #ifdef X86_64 - || (*prefixes & has_rex_x) != 0 + || (prefixes & has_rex_x) != 0 #endif ) { @@ -346,14 +336,14 @@ general_mod$r_m (GElf_Addr addr __attribute__ ((unused)), *cp++ = '%'; cp = stpcpy (cp, #ifdef X86_64 - (*prefixes & has_rex_x) + (prefixes & has_rex_x) ? hiregs[(sib >> 3) & 7] : - (*prefixes & has_addr16) + (prefixes & has_addr16) ? dregs[(sib >> 3) & 7] : #endif aregs[(sib >> 3) & 7]); #ifdef X86_64 - if ((*prefixes & (has_rex_b | has_addr16)) + if ((prefixes & (has_rex_b | has_addr16)) == (has_rex_b | has_addr16)) *cp++ = 'd'; #endif @@ -368,7 +358,7 @@ general_mod$r_m (GElf_Addr addr __attribute__ ((unused)), { assert (! nodisp); #ifdef X86_64 - if ((*prefixes & has_addr16) == 0) + if ((prefixes & has_addr16) == 0) n = snprintf (cp, sizeof (tmpbuf), "0x%" PRIx64, (int64_t) disp); else @@ -389,92 +379,62 @@ general_mod$r_m (GElf_Addr addr __attribute__ ((unused)), static int -FCT_MOD$R_M (GElf_Addr addr __attribute__ ((unused)), - int *prefixes __attribute__ ((unused)), - const char *op1str __attribute__ ((unused)), - size_t opoff1 __attribute__ ((unused)), - size_t opoff2 __attribute__ ((unused)), - size_t opoff3 __attribute__ ((unused)), - char *bufp __attribute__ ((unused)), - size_t *bufcntp __attribute__ ((unused)), - size_t bufsize __attribute__ ((unused)), - const uint8_t *data __attribute__ ((unused)), - const uint8_t **param_start __attribute__ ((unused)), - const uint8_t *end __attribute__ ((unused)), - DisasmGetSymCB_t symcb __attribute__ ((unused)), - void *symcbarg __attribute__ ((unused))) +FCT_MOD$R_M (struct output_data *d) { - assert (opoff1 % 8 == 0); - uint_fast8_t modrm = data[opoff1 / 8]; + assert (d->opoff1 % 8 == 0); + uint_fast8_t modrm = d->data[d->opoff1 / 8]; if ((modrm & 0xc0) == 0xc0) { - uint_fast8_t byte = data[opoff2 / 8] & 7; - assert (opoff2 % 8 == 5); - size_t avail = bufsize - *bufcntp; + assert (d->opoff1 / 8 == d->opoff2 / 8); + assert (d->opoff2 % 8 == 5); + //uint_fast8_t byte = d->data[d->opoff2 / 8] & 7; + uint_fast8_t byte = modrm & 7; + + size_t *bufcntp = d->bufcntp; + char *buf = d->bufp + *bufcntp; + size_t avail = d->bufsize - *bufcntp; int needed; - if (*prefixes & (has_rep | has_repne)) - needed = snprintf (&bufp[*bufcntp], avail, "%%%s", dregs[byte]); + if (*d->prefixes & (has_rep | has_repne)) + needed = snprintf (buf, avail, "%%%s", dregs[byte]); else - needed = snprintf (&bufp[*bufcntp], avail, "%%mm%" PRIxFAST8, byte); + needed = snprintf (buf, avail, "%%mm%" PRIxFAST8, byte); if ((size_t) needed > avail) return needed - avail; *bufcntp += needed; return 0; } - return general_mod$r_m (addr, prefixes, op1str, opoff1, opoff2, opoff3, bufp, - bufcntp, bufsize, data, param_start, end, - symcb, symcbarg); + return general_mod$r_m (d); } static int -FCT_Mod$R_m (GElf_Addr addr __attribute__ ((unused)), - int *prefixes __attribute__ ((unused)), - const char *op1str __attribute__ ((unused)), - size_t opoff1 __attribute__ ((unused)), - size_t opoff2 __attribute__ ((unused)), - size_t opoff3 __attribute__ ((unused)), - char *bufp __attribute__ ((unused)), - size_t *bufcntp __attribute__ ((unused)), - size_t bufsize __attribute__ ((unused)), - const uint8_t *data __attribute__ ((unused)), - const uint8_t **param_start __attribute__ ((unused)), - const uint8_t *end __attribute__ ((unused)), - DisasmGetSymCB_t symcb __attribute__ ((unused)), - void *symcbarg __attribute__ ((unused))) +FCT_Mod$R_m (struct output_data *d) { - assert (opoff1 % 8 == 0); - uint_fast8_t modrm = data[opoff1 / 8]; + assert (d->opoff1 % 8 == 0); + uint_fast8_t modrm = d->data[d->opoff1 / 8]; if ((modrm & 0xc0) == 0xc0) { - uint_fast8_t byte = data[opoff2 / 8] & 7; - assert (opoff2 % 8 == 5); - size_t avail = bufsize - *bufcntp; - int needed = snprintf (&bufp[*bufcntp], avail, "%%xmm%" PRIxFAST8, byte); + assert (d->opoff1 / 8 == d->opoff2 / 8); + assert (d->opoff2 % 8 == 5); + //uint_fast8_t byte = data[opoff2 / 8] & 7; + uint_fast8_t byte = modrm & 7; + + size_t *bufcntp = d->bufcntp; + size_t avail = d->bufsize - *bufcntp; + int needed = snprintf (&d->bufp[*bufcntp], avail, "%%xmm%" PRIxFAST8, + byte); if ((size_t) needed > avail) return needed - avail; - *bufcntp += needed; + *d->bufcntp += needed; return 0; } - return general_mod$r_m (addr, prefixes, op1str, opoff1, opoff2, opoff3, bufp, - bufcntp, bufsize, data, param_start, end, - symcb, symcbarg); + return general_mod$r_m (d); } static int -generic_abs (int *prefixes __attribute__ ((unused)), - size_t opoff1 __attribute__ ((unused)), - char *bufp __attribute__ ((unused)), - size_t *bufcntp __attribute__ ((unused)), - size_t bufsize __attribute__ ((unused)), - const uint8_t *data __attribute__ ((unused)), - const uint8_t **param_start __attribute__ ((unused)), - const uint8_t *end __attribute__ ((unused)), - DisasmGetSymCB_t symcb __attribute__ ((unused)), - void *symcbarg __attribute__ ((unused)), - const char *absstring +generic_abs (struct output_data *d, const char *absstring #ifdef X86_64 , int abslen #else @@ -482,15 +442,15 @@ generic_abs (int *prefixes __attribute__ ((unused)), #endif ) { - int r = data_prefix (prefixes, bufp, bufcntp, bufsize); + int r = data_prefix (d); if (r != 0) return r; - assert (opoff1 % 8 == 0); - assert (opoff1 / 8 == 1); - if (*param_start + abslen > end) + assert (d->opoff1 % 8 == 0); + assert (d->opoff1 / 8 == 1); + if (*d->param_start + abslen > d->end) return -1; - *param_start += abslen; + *d->param_start += abslen; #ifndef X86_64 uint32_t absval; # define ABSPRIFMT PRIx32 @@ -498,12 +458,13 @@ generic_abs (int *prefixes __attribute__ ((unused)), uint64_t absval; # define ABSPRIFMT PRIx64 if (abslen == 8) - absval = read_8ubyte_unaligned (&data[1]); + absval = read_8ubyte_unaligned (&d->data[1]); else #endif - absval = read_4ubyte_unaligned (&data[1]); - size_t avail = bufsize - *bufcntp; - int needed = snprintf (&bufp[*bufcntp], avail, "%s0x%" ABSPRIFMT, + absval = read_4ubyte_unaligned (&d->data[1]); + size_t *bufcntp = d->bufcntp; + size_t avail = d->bufsize - *bufcntp; + int needed = snprintf (&d->bufp[*bufcntp], avail, "%s0x%" ABSPRIFMT, absstring, absval); if ((size_t) needed > avail) return needed - avail; @@ -511,25 +472,11 @@ generic_abs (int *prefixes __attribute__ ((unused)), return 0; } + static int -FCT_absval (GElf_Addr addr __attribute__ ((unused)), - int *prefixes __attribute__ ((unused)), - const char *op1str __attribute__ ((unused)), - size_t opoff1 __attribute__ ((unused)), - size_t opoff2 __attribute__ ((unused)), - size_t opoff3 __attribute__ ((unused)), - char *bufp __attribute__ ((unused)), - size_t *bufcntp __attribute__ ((unused)), - size_t bufsize __attribute__ ((unused)), - const uint8_t *data __attribute__ ((unused)), - const uint8_t **param_start __attribute__ ((unused)), - const uint8_t *end __attribute__ ((unused)), - DisasmGetSymCB_t symcb __attribute__ ((unused)), - void *symcbarg __attribute__ ((unused))) +FCT_absval (struct output_data *d) { - return generic_abs (prefixes, opoff1, bufp, - bufcntp, bufsize, data, param_start, end, symcb, - symcbarg, "$" + return generic_abs (d, "$" #ifdef X86_64 , 4 #endif @@ -537,24 +484,9 @@ FCT_absval (GElf_Addr addr __attribute__ ((unused)), } static int -FCT_abs (GElf_Addr addr __attribute__ ((unused)), - int *prefixes __attribute__ ((unused)), - const char *op1str __attribute__ ((unused)), - size_t opoff1 __attribute__ ((unused)), - size_t opoff2 __attribute__ ((unused)), - size_t opoff3 __attribute__ ((unused)), - char *bufp __attribute__ ((unused)), - size_t *bufcntp __attribute__ ((unused)), - size_t bufsize __attribute__ ((unused)), - const uint8_t *data __attribute__ ((unused)), - const uint8_t **param_start __attribute__ ((unused)), - const uint8_t *end __attribute__ ((unused)), - DisasmGetSymCB_t symcb __attribute__ ((unused)), - void *symcbarg __attribute__ ((unused))) +FCT_abs (struct output_data *d) { - return generic_abs (prefixes, opoff1, bufp, - bufcntp, bufsize, data, param_start, end, symcb, - symcbarg, "" + return generic_abs (d, "" #ifdef X86_64 , 8 #endif @@ -562,22 +494,13 @@ FCT_abs (GElf_Addr addr __attribute__ ((unused)), } static int -FCT_ax (GElf_Addr addr __attribute__ ((unused)), - int *prefixes __attribute__ ((unused)), - const char *op1str __attribute__ ((unused)), - size_t opoff1 __attribute__ ((unused)), - size_t opoff2 __attribute__ ((unused)), - size_t opoff3 __attribute__ ((unused)), - char *bufp __attribute__ ((unused)), - size_t *bufcntp __attribute__ ((unused)), - size_t bufsize __attribute__ ((unused)), - const uint8_t *data __attribute__ ((unused)), - const uint8_t **param_start __attribute__ ((unused)), - const uint8_t *end __attribute__ ((unused)), - DisasmGetSymCB_t symcb __attribute__ ((unused)), - void *symcbarg __attribute__ ((unused))) +FCT_ax (struct output_data *d) { - int is_16bit = (*prefixes & has_data16) != 0; + int is_16bit = (*d->prefixes & has_data16) != 0; + + size_t *bufcntp = d->bufcntp; + char *bufp = d->bufp; + size_t bufsize = d->bufsize; if (*bufcntp + 4 - is_16bit > bufsize) return *bufcntp + 4 - is_16bit - bufsize; @@ -591,25 +514,16 @@ FCT_ax (GElf_Addr addr __attribute__ ((unused)), return 0; } + static int -FCT_ax$w (GElf_Addr addr __attribute__ ((unused)), - int *prefixes __attribute__ ((unused)), - const char *op1str __attribute__ ((unused)), - size_t opoff1 __attribute__ ((unused)), - size_t opoff2 __attribute__ ((unused)), - size_t opoff3 __attribute__ ((unused)), - char *bufp __attribute__ ((unused)), - size_t *bufcntp __attribute__ ((unused)), - size_t bufsize __attribute__ ((unused)), - const uint8_t *data __attribute__ ((unused)), - const uint8_t **param_start __attribute__ ((unused)), - const uint8_t *end __attribute__ ((unused)), - DisasmGetSymCB_t symcb __attribute__ ((unused)), - void *symcbarg __attribute__ ((unused))) +FCT_ax$w (struct output_data *d) { - if ((data[opoff2 / 8] & (1 << (7 - (opoff2 & 7)))) != 0) - return FCT_ax (addr, prefixes, op1str, opoff1, opoff2, opoff3, bufp, - bufcntp, bufsize, data, param_start, end, symcb, symcbarg); + if ((d->data[d->opoff2 / 8] & (1 << (7 - (d->opoff2 & 7)))) != 0) + return FCT_ax (d); + + size_t *bufcntp = d->bufcntp; + char *bufp = d->bufp; + size_t bufsize = d->bufsize; if (*bufcntp + 3 > bufsize) return *bufcntp + 3 - bufsize; @@ -621,119 +535,95 @@ FCT_ax$w (GElf_Addr addr __attribute__ ((unused)), return 0; } + static int -FCT_ccc (GElf_Addr addr __attribute__ ((unused)), - int *prefixes __attribute__ ((unused)), - const char *op1str __attribute__ ((unused)), - size_t opoff1 __attribute__ ((unused)), - size_t opoff2 __attribute__ ((unused)), - size_t opoff3 __attribute__ ((unused)), - char *bufp __attribute__ ((unused)), - size_t *bufcntp __attribute__ ((unused)), - size_t bufsize __attribute__ ((unused)), - const uint8_t *data __attribute__ ((unused)), - const uint8_t **param_start __attribute__ ((unused)), - const uint8_t *end __attribute__ ((unused)), - DisasmGetSymCB_t symcb __attribute__ ((unused)), - void *symcbarg __attribute__ ((unused))) +FCT_ccc (struct output_data *d) { - if (*prefixes & has_data16) + if (*d->prefixes & has_data16) return -1; - assert (opoff1 % 8 == 2); - size_t avail = bufsize - *bufcntp; - int needed = snprintf (&bufp[*bufcntp], avail, "%%cr%" PRIx32, - (uint32_t) (data[opoff1 / 8] >> 3) & 7); + size_t *bufcntp = d->bufcntp; + + // XXX If this assert is true, use absolute offset below + assert (d->opoff1 / 8 == 2); + assert (d->opoff1 % 8 == 2); + size_t avail = d->bufsize - *bufcntp; + int needed = snprintf (&d->bufp[*bufcntp], avail, "%%cr%" PRIx32, + (uint32_t) (d->data[d->opoff1 / 8] >> 3) & 7); if ((size_t) needed > avail) return needed - avail; *bufcntp += needed; return 0; } + static int -FCT_ddd (GElf_Addr addr __attribute__ ((unused)), - int *prefixes __attribute__ ((unused)), - const char *op1str __attribute__ ((unused)), - size_t opoff1 __attribute__ ((unused)), - size_t opoff2 __attribute__ ((unused)), - size_t opoff3 __attribute__ ((unused)), - char *bufp __attribute__ ((unused)), - size_t *bufcntp __attribute__ ((unused)), - size_t bufsize __attribute__ ((unused)), - const uint8_t *data __attribute__ ((unused)), - const uint8_t **param_start __attribute__ ((unused)), - const uint8_t *end __attribute__ ((unused)), - DisasmGetSymCB_t symcb __attribute__ ((unused)), - void *symcbarg __attribute__ ((unused))) +FCT_ddd (struct output_data *d) { - if (*prefixes & has_data16) + if (*d->prefixes & has_data16) return -1; - assert (opoff1 % 8 == 2); - size_t avail = bufsize - *bufcntp; - int needed = snprintf (&bufp[*bufcntp], avail, "%%db%" PRIx32, - (uint32_t) (data[opoff1 / 8] >> 3) & 7); + size_t *bufcntp = d->bufcntp; + + // XXX If this assert is true, use absolute offset below + assert (d->opoff1 / 8 == 2); + assert (d->opoff1 % 8 == 2); + size_t avail = d->bufsize - *bufcntp; + int needed = snprintf (&d->bufp[*bufcntp], avail, "%%db%" PRIx32, + (uint32_t) (d->data[d->opoff1 / 8] >> 3) & 7); if ((size_t) needed > avail) return needed - avail; *bufcntp += needed; return 0; } + static int -FCT_disp8 (GElf_Addr addr __attribute__ ((unused)), - int *prefixes __attribute__ ((unused)), - const char *op1str __attribute__ ((unused)), - size_t opoff1 __attribute__ ((unused)), - size_t opoff2 __attribute__ ((unused)), - size_t opoff3 __attribute__ ((unused)), - char *bufp __attribute__ ((unused)), - size_t *bufcntp __attribute__ ((unused)), - size_t bufsize __attribute__ ((unused)), - const uint8_t *data __attribute__ ((unused)), - const uint8_t **param_start __attribute__ ((unused)), - const uint8_t *end __attribute__ ((unused)), - DisasmGetSymCB_t symcb __attribute__ ((unused)), - void *symcbarg __attribute__ ((unused))) +FCT_disp8 (struct output_data *d) { - assert (opoff1 % 8 == 0); - int32_t offset = *(const int8_t *) (*param_start)++; - size_t avail = bufsize - *bufcntp; - int needed = snprintf (&bufp[*bufcntp], avail, "0x%" PRIx32, - (uint32_t) (addr + (*param_start - data) + offset)); + assert (d->opoff1 % 8 == 0); + if (*d->param_start >= d->end) + return -1; + int32_t offset = *(const int8_t *) (*d->param_start)++; + + size_t *bufcntp = d->bufcntp; + size_t avail = d->bufsize - *bufcntp; + int needed = snprintf (&d->bufp[*bufcntp], avail, "0x%" PRIx32, + (uint32_t) (d->addr + (*d->param_start - d->data) + + offset)); if ((size_t) needed > avail) return needed - avail; *bufcntp += needed; return 0; } + static int __attribute__ ((noinline)) -FCT_ds_xx (const char *reg, - int *prefixes __attribute__ ((unused)), - char *bufp __attribute__ ((unused)), - size_t *bufcntp __attribute__ ((unused)), - size_t bufsize __attribute__ ((unused))) +FCT_ds_xx (struct output_data *d, const char *reg) { - int prefix = *prefixes & SEGMENT_PREFIXES; + int prefix = *d->prefixes & SEGMENT_PREFIXES; if (prefix == 0) - prefix = has_ds; + *d->prefixes |= prefix = has_ds; /* Make sure only one bit is set. */ else if ((prefix - 1) & prefix) return -1; - else - *prefixes ^= prefix; - int r = data_prefix (&prefix, bufp, bufcntp, bufsize); + int r = data_prefix (d); + + assert ((*d->prefixes & prefix) == 0); + if (r != 0) return r; - size_t avail = bufsize - *bufcntp; - int needed = snprintf (&bufp[*bufcntp], avail, "(%%%s%s)", + size_t *bufcntp = d->bufcntp; + size_t avail = d->bufsize - *bufcntp; + int needed = snprintf (&d->bufp[*bufcntp], avail, "(%%%s%s)", #ifdef X86_64 - *prefixes & idx_addr16 ? "e" : "r", + *d->prefixes & idx_addr16 ? "e" : "r", #else - *prefixes & idx_addr16 ? "" : "e", + *d->prefixes & idx_addr16 ? "" : "e", #endif reg); if ((size_t) needed > avail) @@ -743,91 +633,46 @@ FCT_ds_xx (const char *reg, return 0; } + static int -FCT_ds_bx (GElf_Addr addr __attribute__ ((unused)), - int *prefixes __attribute__ ((unused)), - const char *op1str __attribute__ ((unused)), - size_t opoff1 __attribute__ ((unused)), - size_t opoff2 __attribute__ ((unused)), - size_t opoff3 __attribute__ ((unused)), - char *bufp __attribute__ ((unused)), - size_t *bufcntp __attribute__ ((unused)), - size_t bufsize __attribute__ ((unused)), - const uint8_t *data __attribute__ ((unused)), - const uint8_t **param_start __attribute__ ((unused)), - const uint8_t *end __attribute__ ((unused)), - DisasmGetSymCB_t symcb __attribute__ ((unused)), - void *symcbarg __attribute__ ((unused))) +FCT_ds_bx (struct output_data *d) { - return FCT_ds_xx ("bx", prefixes, bufp, bufcntp, bufsize); + return FCT_ds_xx (d, "bx"); } + static int -FCT_ds_si (GElf_Addr addr __attribute__ ((unused)), - int *prefixes __attribute__ ((unused)), - const char *op1str __attribute__ ((unused)), - size_t opoff1 __attribute__ ((unused)), - size_t opoff2 __attribute__ ((unused)), - size_t opoff3 __attribute__ ((unused)), - char *bufp __attribute__ ((unused)), - size_t *bufcntp __attribute__ ((unused)), - size_t bufsize __attribute__ ((unused)), - const uint8_t *data __attribute__ ((unused)), - const uint8_t **param_start __attribute__ ((unused)), - const uint8_t *end __attribute__ ((unused)), - DisasmGetSymCB_t symcb __attribute__ ((unused)), - void *symcbarg __attribute__ ((unused))) +FCT_ds_si (struct output_data *d) { - return FCT_ds_xx ("si", prefixes, bufp, bufcntp, bufsize); + return FCT_ds_xx (d, "si"); } + static int -FCT_dx (GElf_Addr addr __attribute__ ((unused)), - int *prefixes __attribute__ ((unused)), - const char *op1str __attribute__ ((unused)), - size_t opoff1 __attribute__ ((unused)), - size_t opoff2 __attribute__ ((unused)), - size_t opoff3 __attribute__ ((unused)), - char *bufp __attribute__ ((unused)), - size_t *bufcntp __attribute__ ((unused)), - size_t bufsize __attribute__ ((unused)), - const uint8_t *data __attribute__ ((unused)), - const uint8_t **param_start __attribute__ ((unused)), - const uint8_t *end __attribute__ ((unused)), - DisasmGetSymCB_t symcb __attribute__ ((unused)), - void *symcbarg __attribute__ ((unused))) +FCT_dx (struct output_data *d) { - if (*bufcntp + 7 > bufsize) - return *bufcntp + 7 - bufsize; + size_t *bufcntp = d->bufcntp; + + if (*bufcntp + 7 > d->bufsize) + return *bufcntp + 7 - d->bufsize; - memcpy (&bufp[*bufcntp], "(%dx)", 5); + memcpy (&d->bufp[*bufcntp], "(%dx)", 5); *bufcntp += 5; return 0; } + static int -FCT_es_di (GElf_Addr addr __attribute__ ((unused)), - int *prefixes __attribute__ ((unused)), - const char *op1str __attribute__ ((unused)), - size_t opoff1 __attribute__ ((unused)), - size_t opoff2 __attribute__ ((unused)), - size_t opoff3 __attribute__ ((unused)), - char *bufp __attribute__ ((unused)), - size_t *bufcntp __attribute__ ((unused)), - size_t bufsize __attribute__ ((unused)), - const uint8_t *data __attribute__ ((unused)), - const uint8_t **param_start __attribute__ ((unused)), - const uint8_t *end __attribute__ ((unused)), - DisasmGetSymCB_t symcb __attribute__ ((unused)), - void *symcbarg __attribute__ ((unused))) +FCT_es_di (struct output_data *d) { - size_t avail = bufsize - *bufcntp; - int needed = snprintf (&bufp[*bufcntp], avail, "%%es:(%%%sdi)", + size_t *bufcntp = d->bufcntp; + size_t avail = d->bufsize - *bufcntp; + int needed = snprintf (&d->bufp[*bufcntp], avail, "%%es:(%%%sdi)", #ifdef X86_64 - *prefixes & idx_addr16 ? "e" : "r" + *d->prefixes & idx_addr16 ? "e" : "r" #else - *prefixes & idx_addr16 ? "" : "e" + *d->prefixes & idx_addr16 ? "" : "e" #endif ); if ((size_t) needed > avail) @@ -837,37 +682,26 @@ FCT_es_di (GElf_Addr addr __attribute__ ((unused)), return 0; } + static int -FCT_imm (GElf_Addr addr __attribute__ ((unused)), - int *prefixes __attribute__ ((unused)), - const char *op1str __attribute__ ((unused)), - size_t opoff1 __attribute__ ((unused)), - size_t opoff2 __attribute__ ((unused)), - size_t opoff3 __attribute__ ((unused)), - char *bufp __attribute__ ((unused)), - size_t *bufcntp __attribute__ ((unused)), - size_t bufsize __attribute__ ((unused)), - const uint8_t *data __attribute__ ((unused)), - const uint8_t **param_start __attribute__ ((unused)), - const uint8_t *end __attribute__ ((unused)), - DisasmGetSymCB_t symcb __attribute__ ((unused)), - void *symcbarg __attribute__ ((unused))) +FCT_imm (struct output_data *d) { - size_t avail = bufsize - *bufcntp; + size_t *bufcntp = d->bufcntp; + size_t avail = d->bufsize - *bufcntp; int needed; - if (*prefixes & has_data16) + if (*d->prefixes & has_data16) { - if (*param_start + 2 > end) + if (*d->param_start + 2 > d->end) return -1; - uint16_t word = read_2ubyte_unaligned_inc (*param_start); - needed = snprintf (&bufp[*bufcntp], avail, "$0x%" PRIx16, word); + uint16_t word = read_2ubyte_unaligned_inc (*d->param_start); + needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx16, word); } else { - if (*param_start + 4 > end) + if (*d->param_start + 4 > d->end) return -1; - uint32_t word = read_4ubyte_unaligned_inc (*param_start); - needed = snprintf (&bufp[*bufcntp], avail, "$0x%" PRIx32, word); + uint32_t word = read_4ubyte_unaligned_inc (*d->param_start); + needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx32, word); } if ((size_t) needed > avail) return (size_t) needed - avail; @@ -875,58 +709,39 @@ FCT_imm (GElf_Addr addr __attribute__ ((unused)), return 0; } + static int -FCT_imm$w (GElf_Addr addr __attribute__ ((unused)), - int *prefixes __attribute__ ((unused)), - const char *op1str __attribute__ ((unused)), - size_t opoff1 __attribute__ ((unused)), - size_t opoff2 __attribute__ ((unused)), - size_t opoff3 __attribute__ ((unused)), - char *bufp __attribute__ ((unused)), - size_t *bufcntp __attribute__ ((unused)), - size_t bufsize __attribute__ ((unused)), - const uint8_t *data __attribute__ ((unused)), - const uint8_t **param_start __attribute__ ((unused)), - const uint8_t *end __attribute__ ((unused)), - DisasmGetSymCB_t symcb __attribute__ ((unused)), - void *symcbarg __attribute__ ((unused))) +FCT_imm$w (struct output_data *d) { - if ((data[opoff2 / 8] & (1 << (7 - (opoff2 & 7)))) != 0) - return FCT_imm (addr, prefixes, op1str, opoff1, opoff2, opoff3, bufp, - bufcntp, bufsize, data, param_start, end, symcb, symcbarg); + if ((d->data[d->opoff2 / 8] & (1 << (7 - (d->opoff2 & 7)))) != 0) + return FCT_imm (d); - size_t avail = bufsize - *bufcntp; - uint_fast8_t word = *(*param_start)++; - int needed = snprintf (&bufp[*bufcntp], avail, "$0x%" PRIxFAST8, word); + size_t *bufcntp = d->bufcntp; + size_t avail = d->bufsize - *bufcntp; + if (*d->param_start>= d->end) + return -1; + uint_fast8_t word = *(*d->param_start)++; + int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIxFAST8, word); if ((size_t) needed > avail) return (size_t) needed - avail; *bufcntp += needed; return 0; } + static int -FCT_imms (GElf_Addr addr __attribute__ ((unused)), - int *prefixes __attribute__ ((unused)), - const char *op1str __attribute__ ((unused)), - size_t opoff1 __attribute__ ((unused)), - size_t opoff2 __attribute__ ((unused)), - size_t opoff3 __attribute__ ((unused)), - char *bufp __attribute__ ((unused)), - size_t *bufcntp __attribute__ ((unused)), - size_t bufsize __attribute__ ((unused)), - const uint8_t *data __attribute__ ((unused)), - const uint8_t **param_start __attribute__ ((unused)), - const uint8_t *end __attribute__ ((unused)), - DisasmGetSymCB_t symcb __attribute__ ((unused)), - void *symcbarg __attribute__ ((unused))) +FCT_imms (struct output_data *d) { - size_t avail = bufsize - *bufcntp; - int8_t byte = *(*param_start)++; + size_t *bufcntp = d->bufcntp; + size_t avail = d->bufsize - *bufcntp; + if (*d->param_start>= d->end) + return -1; + int8_t byte = *(*d->param_start)++; #ifdef X86_64 - int needed = snprintf (&bufp[*bufcntp], avail, "$0x%" PRIx64, + int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx64, (int64_t) byte); #else - int needed = snprintf (&bufp[*bufcntp], avail, "$0x%" PRIx32, + int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx32, (int32_t) byte); #endif if ((size_t) needed > avail) @@ -935,39 +750,26 @@ FCT_imms (GElf_Addr addr __attribute__ ((unused)), return 0; } + static int -FCT_imm$s (GElf_Addr addr __attribute__ ((unused)), - int *prefixes __attribute__ ((unused)), - const char *op1str __attribute__ ((unused)), - size_t opoff1 __attribute__ ((unused)), - size_t opoff2 __attribute__ ((unused)), - size_t opoff3 __attribute__ ((unused)), - char *bufp __attribute__ ((unused)), - size_t *bufcntp __attribute__ ((unused)), - size_t bufsize __attribute__ ((unused)), - const uint8_t *data __attribute__ ((unused)), - const uint8_t **param_start __attribute__ ((unused)), - const uint8_t *end __attribute__ ((unused)), - DisasmGetSymCB_t symcb __attribute__ ((unused)), - void *symcbarg __attribute__ ((unused))) +FCT_imm$s (struct output_data *d) { - uint_fast8_t opcode = data[opoff2 / 8]; - size_t avail = bufsize - *bufcntp; + uint_fast8_t opcode = d->data[d->opoff2 / 8]; + size_t *bufcntp = d->bufcntp; + size_t avail = d->bufsize - *bufcntp; if ((opcode & 2) != 0) - return FCT_imms (addr, prefixes, op1str, opoff1, opoff2, opoff3, bufp, - bufcntp, bufsize, data, param_start, end, symcb, - symcbarg); + return FCT_imms (d); - if ((*prefixes & has_data16) == 0) + if ((*d->prefixes & has_data16) == 0) { - if (*param_start + 4 > end) + if (*d->param_start + 4 > d->end) return -1; - int32_t word = read_4sbyte_unaligned_inc (*param_start); + int32_t word = read_4sbyte_unaligned_inc (*d->param_start); #ifdef X86_64 - int needed = snprintf (&bufp[*bufcntp], avail, "$0x%" PRIx64, + int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx64, (int64_t) word); #else - int needed = snprintf (&bufp[*bufcntp], avail, "$0x%" PRIx32, word); + int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx32, word); #endif if ((size_t) needed > avail) return (size_t) needed - avail; @@ -975,10 +777,10 @@ FCT_imm$s (GElf_Addr addr __attribute__ ((unused)), } else { - if (*param_start + 2 > end) + if (*d->param_start + 2 > d->end) return -1; - uint16_t word = read_2ubyte_unaligned_inc (*param_start); - int needed = snprintf (&bufp[*bufcntp], avail, "$0x%" PRIx16, word); + uint16_t word = read_2ubyte_unaligned_inc (*d->param_start); + int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx16, word); if ((size_t) needed > avail) return (size_t) needed - avail; *bufcntp += needed; @@ -986,52 +788,32 @@ FCT_imm$s (GElf_Addr addr __attribute__ ((unused)), return 0; } + static int -FCT_imm16 (GElf_Addr addr __attribute__ ((unused)), - int *prefixes __attribute__ ((unused)), - const char *op1str __attribute__ ((unused)), - size_t opoff1 __attribute__ ((unused)), - size_t opoff2 __attribute__ ((unused)), - size_t opoff3 __attribute__ ((unused)), - char *bufp __attribute__ ((unused)), - size_t *bufcntp __attribute__ ((unused)), - size_t bufsize __attribute__ ((unused)), - const uint8_t *data __attribute__ ((unused)), - const uint8_t **param_start __attribute__ ((unused)), - const uint8_t *end __attribute__ ((unused)), - DisasmGetSymCB_t symcb __attribute__ ((unused)), - void *symcbarg __attribute__ ((unused))) +FCT_imm16 (struct output_data *d) { - if (*param_start + 2 > end) + if (*d->param_start + 2 > d->end) return -1; - uint16_t word = read_2ubyte_unaligned_inc (*param_start); - size_t avail = bufsize - *bufcntp; - int needed = snprintf (&bufp[*bufcntp], avail, "$0x%" PRIx16, word); + uint16_t word = read_2ubyte_unaligned_inc (*d->param_start); + size_t *bufcntp = d->bufcntp; + size_t avail = d->bufsize - *bufcntp; + int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx16, word); if ((size_t) needed > avail) return (size_t) needed - avail; *bufcntp += needed; return 0; } + static int -FCT_imms8 (GElf_Addr addr __attribute__ ((unused)), - int *prefixes __attribute__ ((unused)), - const char *op1str __attribute__ ((unused)), - size_t opoff1 __attribute__ ((unused)), - size_t opoff2 __attribute__ ((unused)), - size_t opoff3 __attribute__ ((unused)), - char *bufp __attribute__ ((unused)), - size_t *bufcntp __attribute__ ((unused)), - size_t bufsize __attribute__ ((unused)), - const uint8_t *data __attribute__ ((unused)), - const uint8_t **param_start __attribute__ ((unused)), - const uint8_t *end __attribute__ ((unused)), - DisasmGetSymCB_t symcb __attribute__ ((unused)), - void *symcbarg __attribute__ ((unused))) +FCT_imms8 (struct output_data *d) { - size_t avail = bufsize - *bufcntp; - int_fast8_t byte = *(*param_start)++; - int needed = snprintf (&bufp[*bufcntp], avail, "$0x%" PRIx32, + size_t *bufcntp = d->bufcntp; + size_t avail = d->bufsize - *bufcntp; + if (*d->param_start >= d->end) + return -1; + int_fast8_t byte = *(*d->param_start)++; + int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx32, (int32_t) byte); if ((size_t) needed > avail) return (size_t) needed - avail; @@ -1039,27 +821,16 @@ FCT_imms8 (GElf_Addr addr __attribute__ ((unused)), return 0; } + static int -FCT_imm8 (GElf_Addr addr __attribute__ ((unused)), - int *prefixes __attribute__ ((unused)), - const char *op1str __attribute__ ((unused)), - size_t opoff1 __attribute__ ((unused)), - size_t opoff2 __attribute__ ((unused)), - size_t opoff3 __attribute__ ((unused)), - char *bufp __attribute__ ((unused)), - size_t *bufcntp __attribute__ ((unused)), - size_t bufsize __attribute__ ((unused)), - const uint8_t *data __attribute__ ((unused)), - const uint8_t **param_start __attribute__ ((unused)), - const uint8_t *end __attribute__ ((unused)), - DisasmGetSymCB_t symcb __attribute__ ((unused)), - void *symcbarg __attribute__ ((unused))) +FCT_imm8 (struct output_data *d) { - size_t avail = bufsize - *bufcntp; - if (*param_start >= end) + size_t *bufcntp = d->bufcntp; + size_t avail = d->bufsize - *bufcntp; + if (*d->param_start >= d->end) return -1; - uint_fast8_t byte = *(*param_start)++; - int needed = snprintf (&bufp[*bufcntp], avail, "$0x%" PRIx32, + uint_fast8_t byte = *(*d->param_start)++; + int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx32, (uint32_t) byte); if ((size_t) needed > avail) return (size_t) needed - avail; @@ -1067,32 +838,23 @@ FCT_imm8 (GElf_Addr addr __attribute__ ((unused)), return 0; } + static int -FCT_rel (GElf_Addr addr __attribute__ ((unused)), - int *prefixes __attribute__ ((unused)), - const char *op1str __attribute__ ((unused)), - size_t opoff1 __attribute__ ((unused)), - size_t opoff2 __attribute__ ((unused)), - size_t opoff3 __attribute__ ((unused)), - char *bufp __attribute__ ((unused)), - size_t *bufcntp __attribute__ ((unused)), - size_t bufsize __attribute__ ((unused)), - const uint8_t *data __attribute__ ((unused)), - const uint8_t **param_start __attribute__ ((unused)), - const uint8_t *end __attribute__ ((unused)), - DisasmGetSymCB_t symcb __attribute__ ((unused)), - void *symcbarg __attribute__ ((unused))) +FCT_rel (struct output_data *d) { - size_t avail = bufsize - *bufcntp; - if (*param_start + 4 > end) + size_t *bufcntp = d->bufcntp; + size_t avail = d->bufsize - *bufcntp; + if (*d->param_start + 4 > d->end) return -1; - int32_t rel = read_4sbyte_unaligned_inc (*param_start); + int32_t rel = read_4sbyte_unaligned_inc (*d->param_start); #ifdef X86_64 - int needed = snprintf (&bufp[*bufcntp], avail, "0x%" PRIx64, - (uint64_t) (addr + rel + (*param_start - data))); + int needed = snprintf (&d->bufp[*bufcntp], avail, "0x%" PRIx64, + (uint64_t) (d->addr + rel + + (*d->param_start - d->data))); #else - int needed = snprintf (&bufp[*bufcntp], avail, "0x%" PRIx32, - (uint32_t) (addr + rel + (*param_start - data))); + int needed = snprintf (&d->bufp[*bufcntp], avail, "0x%" PRIx32, + (uint32_t) (d->addr + rel + + (*d->param_start - d->data))); #endif if ((size_t) needed > avail) return (size_t) needed - avail; @@ -1100,27 +862,16 @@ FCT_rel (GElf_Addr addr __attribute__ ((unused)), return 0; } + static int -FCT_mmxreg (GElf_Addr addr __attribute__ ((unused)), - int *prefixes __attribute__ ((unused)), - const char *op1str __attribute__ ((unused)), - size_t opoff1 __attribute__ ((unused)), - size_t opoff2 __attribute__ ((unused)), - size_t opoff3 __attribute__ ((unused)), - char *bufp __attribute__ ((unused)), - size_t *bufcntp __attribute__ ((unused)), - size_t bufsize __attribute__ ((unused)), - const uint8_t *data __attribute__ ((unused)), - const uint8_t **param_start __attribute__ ((unused)), - const uint8_t *end __attribute__ ((unused)), - DisasmGetSymCB_t symcb __attribute__ ((unused)), - void *symcbarg __attribute__ ((unused))) +FCT_mmxreg (struct output_data *d) { - uint_fast8_t byte = data[opoff1 / 8]; - assert (opoff1 % 8 == 2 || opoff1 % 8 == 5); - byte = (byte >> (5 - opoff1 % 8)) & 7; - size_t avail = bufsize - *bufcntp; - int needed = snprintf (&bufp[*bufcntp], avail, "%%mm%" PRIxFAST8, byte); + uint_fast8_t byte = d->data[d->opoff1 / 8]; + assert (d->opoff1 % 8 == 2 || d->opoff1 % 8 == 5); + byte = (byte >> (5 - d->opoff1 % 8)) & 7; + size_t *bufcntp = d->bufcntp; + size_t avail = d->bufsize - *bufcntp; + int needed = snprintf (&d->bufp[*bufcntp], avail, "%%mm%" PRIxFAST8, byte); if ((size_t) needed > avail) return needed - avail; *bufcntp += needed; @@ -1129,40 +880,30 @@ FCT_mmxreg (GElf_Addr addr __attribute__ ((unused)), static int -FCT_mod$r_m (GElf_Addr addr __attribute__ ((unused)), - int *prefixes __attribute__ ((unused)), - const char *op1str __attribute__ ((unused)), - size_t opoff1 __attribute__ ((unused)), - size_t opoff2 __attribute__ ((unused)), - size_t opoff3 __attribute__ ((unused)), - char *bufp __attribute__ ((unused)), - size_t *bufcntp __attribute__ ((unused)), - size_t bufsize __attribute__ ((unused)), - const uint8_t *data __attribute__ ((unused)), - const uint8_t **param_start __attribute__ ((unused)), - const uint8_t *end __attribute__ ((unused)), - DisasmGetSymCB_t symcb __attribute__ ((unused)), - void *symcbarg __attribute__ ((unused))) +FCT_mod$r_m (struct output_data *d) { - assert (opoff1 % 8 == 0); - uint_fast8_t modrm = data[opoff1 / 8]; + assert (d->opoff1 % 8 == 0); + uint_fast8_t modrm = d->data[d->opoff1 / 8]; if ((modrm & 0xc0) == 0xc0) { - if (*prefixes & has_addr16) + int prefixes = *d->prefixes; + if (prefixes & has_addr16) return -1; - int is_16bit = (*prefixes & has_data16) != 0; + int is_16bit = (prefixes & has_data16) != 0; - if (*bufcntp + 5 - is_16bit > bufsize) - return *bufcntp + 5 - is_16bit - bufsize; + size_t *bufcntp = d->bufcntp; + char *bufp = d->bufp; + if (*bufcntp + 5 - is_16bit > d->bufsize) + return *bufcntp + 5 - is_16bit - d->bufsize; bufp[(*bufcntp)++] = '%'; char *cp; #ifdef X86_64 - if ((*prefixes & has_rex_b) != 0 && !is_16bit) + if ((prefixes & has_rex_b) != 0 && !is_16bit) { cp = stpcpy (&bufp[*bufcntp], hiregs[modrm & 7]); - if ((*prefixes & has_rex_w) == 0) + if ((prefixes & has_rex_w) == 0) *cp++ = 'd'; } else @@ -1170,7 +911,7 @@ FCT_mod$r_m (GElf_Addr addr __attribute__ ((unused)), { cp = stpcpy (&bufp[*bufcntp], dregs[modrm & 7] + is_16bit); #ifdef X86_64 - if ((*prefixes & has_rex_w) != 0) + if ((prefixes & has_rex_w) != 0) bufp[*bufcntp] = 'r'; #endif } @@ -1178,52 +919,32 @@ FCT_mod$r_m (GElf_Addr addr __attribute__ ((unused)), return 0; } - return general_mod$r_m (addr, prefixes, op1str, opoff1, opoff2, opoff3, bufp, - bufcntp, bufsize, data, param_start, end, - symcb, symcbarg); + return general_mod$r_m (d); } #ifndef X86_64 static int -FCT_moda$r_m (GElf_Addr addr __attribute__ ((unused)), - int *prefixes __attribute__ ((unused)), - const char *op1str __attribute__ ((unused)), - size_t opoff1 __attribute__ ((unused)), - size_t opoff2 __attribute__ ((unused)), - size_t opoff3 __attribute__ ((unused)), - char *bufp __attribute__ ((unused)), - size_t *bufcntp __attribute__ ((unused)), - size_t bufsize __attribute__ ((unused)), - const uint8_t *data __attribute__ ((unused)), - const uint8_t **param_start __attribute__ ((unused)), - const uint8_t *end __attribute__ ((unused)), - DisasmGetSymCB_t symcb __attribute__ ((unused)), - void *symcbarg __attribute__ ((unused))) +FCT_moda$r_m (struct output_data *d) { - int r = data_prefix (prefixes, bufp, bufcntp, bufsize); - if (r != 0) - return r; - - assert (opoff1 % 8 == 0); - uint_fast8_t modrm = data[opoff1 / 8]; + assert (d->opoff1 % 8 == 0); + uint_fast8_t modrm = d->data[d->opoff1 / 8]; if ((modrm & 0xc0) == 0xc0) { - if (*prefixes & has_addr16) + if (*d->prefixes & has_addr16) return -1; - if (*bufcntp + 3 > bufsize) - return *bufcntp + 3 - bufsize; + size_t *bufcntp = d->bufcntp; + if (*bufcntp + 3 > d->bufsize) + return *bufcntp + 3 - d->bufsize; - memcpy (&bufp[*bufcntp], "???", 3); + memcpy (&d->bufp[*bufcntp], "???", 3); *bufcntp += 3; return 0; } - return general_mod$r_m (addr, prefixes, op1str, opoff1, opoff2, opoff3, bufp, - bufcntp, bufsize, data, param_start, end, - symcb, symcbarg); + return general_mod$r_m (d); } #endif @@ -1236,45 +957,34 @@ static const char rex_8bit[8][3] = }; #endif + static int -FCT_mod$r_m$w (GElf_Addr addr __attribute__ ((unused)), - int *prefixes __attribute__ ((unused)), - const char *op1str __attribute__ ((unused)), - size_t opoff1 __attribute__ ((unused)), - size_t opoff2 __attribute__ ((unused)), - size_t opoff3 __attribute__ ((unused)), - char *bufp __attribute__ ((unused)), - size_t *bufcntp __attribute__ ((unused)), - size_t bufsize __attribute__ ((unused)), - const uint8_t *data __attribute__ ((unused)), - const uint8_t **param_start __attribute__ ((unused)), - const uint8_t *end __attribute__ ((unused)), - DisasmGetSymCB_t symcb __attribute__ ((unused)), - void *symcbarg __attribute__ ((unused))) +FCT_mod$r_m$w (struct output_data *d) { - int r = data_prefix (prefixes, bufp, bufcntp, bufsize); - if (r != 0) - return r; - - assert (opoff1 % 8 == 0); - uint_fast8_t modrm = data[opoff1 / 8]; + assert (d->opoff1 % 8 == 0); + const uint8_t *data = d->data; + uint_fast8_t modrm = data[d->opoff1 / 8]; if ((modrm & 0xc0) == 0xc0) { - if (*prefixes & has_addr16) + int prefixes = *d->prefixes; + + if (prefixes & has_addr16) return -1; - if (*bufcntp + 5 > bufsize) - return *bufcntp + 5 - bufsize; + size_t *bufcntp = d->bufcntp; + char *bufp = d->bufp; + if (*bufcntp + 5 > d->bufsize) + return *bufcntp + 5 - d->bufsize; - if ((data[opoff3 / 8] & (1 << (7 - (opoff3 & 7)))) == 0) + if ((data[d->opoff3 / 8] & (1 << (7 - (d->opoff3 & 7)))) == 0) { bufp[(*bufcntp)++] = '%'; #ifdef X86_64 - if (*prefixes & has_rex) + if (prefixes & has_rex) { - if (*prefixes & has_rex_r) - *bufcntp += snprintf (bufp + *bufcntp, bufsize - *bufcntp, + if (prefixes & has_rex_r) + *bufcntp += snprintf (bufp + *bufcntp, d->bufsize - *bufcntp, "r%db", 8 + (modrm & 7)); else { @@ -1292,16 +1002,16 @@ FCT_mod$r_m$w (GElf_Addr addr __attribute__ ((unused)), } else { - int is_16bit = (*prefixes & has_data16) != 0; + int is_16bit = (prefixes & has_data16) != 0; bufp[(*bufcntp)++] = '%'; char *cp; #ifdef X86_64 - if ((*prefixes & has_rex_b) != 0 && !is_16bit) + if ((prefixes & has_rex_b) != 0 && !is_16bit) { cp = stpcpy (&bufp[*bufcntp], hiregs[modrm & 7]); - if ((*prefixes & has_rex_w) == 0) + if ((prefixes & has_rex_w) == 0) *cp++ = 'd'; } else @@ -1309,7 +1019,7 @@ FCT_mod$r_m$w (GElf_Addr addr __attribute__ ((unused)), { cp = stpcpy (&bufp[*bufcntp], dregs[modrm & 7] + is_16bit); #ifdef X86_64 - if ((*prefixes & has_rex_w) != 0) + if ((prefixes & has_rex_w) != 0) bufp[*bufcntp] = 'r'; #endif } @@ -1318,361 +1028,250 @@ FCT_mod$r_m$w (GElf_Addr addr __attribute__ ((unused)), return 0; } - return general_mod$r_m (addr, prefixes, op1str, opoff1, opoff2, opoff3, bufp, - bufcntp, bufsize, data, param_start, end, - symcb, symcbarg); + return general_mod$r_m (d); } static int -FCT_mod$8r_m (GElf_Addr addr __attribute__ ((unused)), - int *prefixes __attribute__ ((unused)), - const char *op1str __attribute__ ((unused)), - size_t opoff1 __attribute__ ((unused)), - size_t opoff2 __attribute__ ((unused)), - size_t opoff3 __attribute__ ((unused)), - char *bufp __attribute__ ((unused)), - size_t *bufcntp __attribute__ ((unused)), - size_t bufsize __attribute__ ((unused)), - const uint8_t *data __attribute__ ((unused)), - const uint8_t **param_start __attribute__ ((unused)), - const uint8_t *end __attribute__ ((unused)), - DisasmGetSymCB_t symcb __attribute__ ((unused)), - void *symcbarg __attribute__ ((unused))) +FCT_mod$8r_m (struct output_data *d) { - assert (opoff1 % 8 == 0); - uint_fast8_t modrm = data[opoff1 / 8]; + assert (d->opoff1 % 8 == 0); + uint_fast8_t modrm = d->data[d->opoff1 / 8]; if ((modrm & 0xc0) == 0xc0) { - if (*bufcntp + 3 > bufsize) - return *bufcntp + 3 - bufsize; + size_t *bufcntp = d->bufcntp; + char *bufp = d->bufp; + if (*bufcntp + 3 > d->bufsize) + return *bufcntp + 3 - d->bufsize; bufp[(*bufcntp)++] = '%'; bufp[(*bufcntp)++] = "acdb"[modrm & 3]; bufp[(*bufcntp)++] = "lh"[(modrm & 4) >> 2]; return 0; } - return general_mod$r_m (addr, prefixes, op1str, opoff1, opoff2, opoff3, bufp, - bufcntp, bufsize, data, param_start, end, - symcb, symcbarg); + return general_mod$r_m (d); } + static int -FCT_mod$16r_m (GElf_Addr addr __attribute__ ((unused)), - int *prefixes __attribute__ ((unused)), - const char *op1str __attribute__ ((unused)), - size_t opoff1 __attribute__ ((unused)), - size_t opoff2 __attribute__ ((unused)), - size_t opoff3 __attribute__ ((unused)), - char *bufp __attribute__ ((unused)), - size_t *bufcntp __attribute__ ((unused)), - size_t bufsize __attribute__ ((unused)), - const uint8_t *data __attribute__ ((unused)), - const uint8_t **param_start __attribute__ ((unused)), - const uint8_t *end __attribute__ ((unused)), - DisasmGetSymCB_t symcb __attribute__ ((unused)), - void *symcbarg __attribute__ ((unused))) +FCT_mod$16r_m (struct output_data *d) { - assert (opoff1 % 8 == 0); - uint_fast8_t modrm = data[opoff1 / 8]; + assert (d->opoff1 % 8 == 0); + uint_fast8_t modrm = d->data[d->opoff1 / 8]; if ((modrm & 0xc0) == 0xc0) { - uint_fast8_t byte = data[opoff1 / 8] & 7; - if (*bufcntp + 3 > bufsize) - return *bufcntp + 3 - bufsize; - bufp[(*bufcntp)++] = '%'; - memcpy (&bufp[*bufcntp], dregs[byte] + 1, sizeof (dregs[0]) - 1); + assert (d->opoff1 / 8 == d->opoff2 / 8); + //uint_fast8_t byte = data[opoff2 / 8] & 7; + uint_fast8_t byte = modrm & 7; + + size_t *bufcntp = d->bufcntp; + if (*bufcntp + 3 > d->bufsize) + return *bufcntp + 3 - d->bufsize; + d->bufp[(*bufcntp)++] = '%'; + memcpy (&d->bufp[*bufcntp], dregs[byte] + 1, sizeof (dregs[0]) - 1); *bufcntp += 2; return 0; } - return general_mod$r_m (addr, prefixes, op1str, opoff1, opoff2, opoff3, bufp, - bufcntp, bufsize, data, param_start, end, - symcb, symcbarg); + return general_mod$r_m (d); } + #ifdef X86_64 static int -FCT_mod$64r_m (GElf_Addr addr __attribute__ ((unused)), - int *prefixes __attribute__ ((unused)), - const char *op1str __attribute__ ((unused)), - size_t opoff1 __attribute__ ((unused)), - size_t opoff2 __attribute__ ((unused)), - size_t opoff3 __attribute__ ((unused)), - char *bufp __attribute__ ((unused)), - size_t *bufcntp __attribute__ ((unused)), - size_t bufsize __attribute__ ((unused)), - const uint8_t *data __attribute__ ((unused)), - const uint8_t **param_start __attribute__ ((unused)), - const uint8_t *end __attribute__ ((unused)), - DisasmGetSymCB_t symcb __attribute__ ((unused)), - void *symcbarg __attribute__ ((unused))) +FCT_mod$64r_m (struct output_data *d) { - assert (opoff1 % 8 == 0); - uint_fast8_t modrm = data[opoff1 / 8]; + assert (d->opoff1 % 8 == 0); + uint_fast8_t modrm = d->data[d->opoff1 / 8]; if ((modrm & 0xc0) == 0xc0) { - uint_fast8_t byte = data[opoff1 / 8] & 7; - if (*bufcntp + 4 > bufsize) - return *bufcntp + 4 - bufsize; - char *cp = &bufp[*bufcntp]; + assert (d->opoff1 / 8 == d->opoff2 / 8); + //uint_fast8_t byte = data[opoff2 / 8] & 7; + uint_fast8_t byte = modrm & 7; + + size_t *bufcntp = d->bufcntp; + if (*bufcntp + 4 > d->bufsize) + return *bufcntp + 4 - d->bufsize; + char *cp = &d->bufp[*bufcntp]; *cp++ = '%'; - cp = stpcpy (cp, (*prefixes & has_rex_b) ? hiregs[byte] : aregs[byte]); - *bufcntp = cp - bufp; + cp = stpcpy (cp, + (*d->prefixes & has_rex_b) ? hiregs[byte] : aregs[byte]); + *bufcntp = cp - d->bufp; return 0; } - return general_mod$r_m (addr, prefixes, op1str, opoff1, opoff2, opoff3, bufp, - bufcntp, bufsize, data, param_start, end, - symcb, symcbarg); + return general_mod$r_m (d); } #else static typeof (FCT_mod$r_m) FCT_mod$64r_m __attribute__ ((alias ("FCT_mod$r_m"))); #endif + static int -FCT_reg (GElf_Addr addr __attribute__ ((unused)), - int *prefixes __attribute__ ((unused)), - const char *op1str __attribute__ ((unused)), - size_t opoff1 __attribute__ ((unused)), - size_t opoff2 __attribute__ ((unused)), - size_t opoff3 __attribute__ ((unused)), - char *bufp __attribute__ ((unused)), - size_t *bufcntp __attribute__ ((unused)), - size_t bufsize __attribute__ ((unused)), - const uint8_t *data __attribute__ ((unused)), - const uint8_t **param_start __attribute__ ((unused)), - const uint8_t *end __attribute__ ((unused)), - DisasmGetSymCB_t symcb __attribute__ ((unused)), - void *symcbarg __attribute__ ((unused))) +FCT_reg (struct output_data *d) { - uint_fast8_t byte = data[opoff1 / 8]; - assert (opoff1 % 8 + 3 <= 8); - byte >>= 8 - (opoff1 % 8 + 3); + uint_fast8_t byte = d->data[d->opoff1 / 8]; + assert (d->opoff1 % 8 + 3 <= 8); + byte >>= 8 - (d->opoff1 % 8 + 3); byte &= 7; - int is_16bit = (*prefixes & has_data16) != 0; - if (*bufcntp + 5 > bufsize) - return *bufcntp + 5 - bufsize; - bufp[(*bufcntp)++] = '%'; + int is_16bit = (*d->prefixes & has_data16) != 0; + size_t *bufcntp = d->bufcntp; + if (*bufcntp + 5 > d->bufsize) + return *bufcntp + 5 - d->bufsize; + d->bufp[(*bufcntp)++] = '%'; #ifdef X86_64 - if ((*prefixes & has_rex_r) != 0 && !is_16bit) + if ((*d->prefixes & has_rex_r) != 0 && !is_16bit) { - *bufcntp += snprintf (&bufp[*bufcntp], bufsize - *bufcntp, "r%d", + *bufcntp += snprintf (&d->bufp[*bufcntp], d->bufsize - *bufcntp, "r%d", 8 + byte); - if ((*prefixes & has_rex_w) == 0) - bufp[(*bufcntp)++] = 'd'; + if ((*d->prefixes & has_rex_w) == 0) + d->bufp[(*bufcntp)++] = 'd'; } else #endif { - memcpy (&bufp[*bufcntp], dregs[byte] + is_16bit, 3 - is_16bit); + memcpy (&d->bufp[*bufcntp], dregs[byte] + is_16bit, 3 - is_16bit); #ifdef X86_64 - if ((*prefixes & has_rex_w) != 0 && !is_16bit) - bufp[*bufcntp] = 'r'; + if ((*d->prefixes & has_rex_w) != 0 && !is_16bit) + d->bufp[*bufcntp] = 'r'; #endif *bufcntp += 3 - is_16bit; } return 0; } + static int -FCT_reg64 (GElf_Addr addr __attribute__ ((unused)), - int *prefixes __attribute__ ((unused)), - const char *op1str __attribute__ ((unused)), - size_t opoff1 __attribute__ ((unused)), - size_t opoff2 __attribute__ ((unused)), - size_t opoff3 __attribute__ ((unused)), - char *bufp __attribute__ ((unused)), - size_t *bufcntp __attribute__ ((unused)), - size_t bufsize __attribute__ ((unused)), - const uint8_t *data __attribute__ ((unused)), - const uint8_t **param_start __attribute__ ((unused)), - const uint8_t *end __attribute__ ((unused)), - DisasmGetSymCB_t symcb __attribute__ ((unused)), - void *symcbarg __attribute__ ((unused))) +FCT_reg64 (struct output_data *d) { - uint_fast8_t byte = data[opoff1 / 8]; - assert (opoff1 % 8 + 3 <= 8); - byte >>= 8 - (opoff1 % 8 + 3); + uint_fast8_t byte = d->data[d->opoff1 / 8]; + assert (d->opoff1 % 8 + 3 <= 8); + byte >>= 8 - (d->opoff1 % 8 + 3); byte &= 7; - if ((*prefixes & has_data16) != 0) + if ((*d->prefixes & has_data16) != 0) return -1; - if (*bufcntp + 5 > bufsize) - return *bufcntp + 5 - bufsize; - bufp[(*bufcntp)++] = '%'; + size_t *bufcntp = d->bufcntp; + if (*bufcntp + 5 > d->bufsize) + return *bufcntp + 5 - d->bufsize; + d->bufp[(*bufcntp)++] = '%'; #ifdef X86_64 - if ((*prefixes & has_rex_r) != 0) + if ((*d->prefixes & has_rex_r) != 0) { - *bufcntp += snprintf (&bufp[*bufcntp], bufsize - *bufcntp, "r%d", + *bufcntp += snprintf (&d->bufp[*bufcntp], d->bufsize - *bufcntp, "r%d", 8 + byte); - if ((*prefixes & has_rex_w) == 0) - bufp[(*bufcntp)++] = 'd'; + if ((*d->prefixes & has_rex_w) == 0) + d->bufp[(*bufcntp)++] = 'd'; } else #endif { - memcpy (&bufp[*bufcntp], aregs[byte], 3); + memcpy (&d->bufp[*bufcntp], aregs[byte], 3); *bufcntp += 3; } return 0; } + static int -FCT_reg$w (GElf_Addr addr __attribute__ ((unused)), - int *prefixes __attribute__ ((unused)), - const char *op1str __attribute__ ((unused)), - size_t opoff1 __attribute__ ((unused)), - size_t opoff2 __attribute__ ((unused)), - size_t opoff3 __attribute__ ((unused)), - char *bufp __attribute__ ((unused)), - size_t *bufcntp __attribute__ ((unused)), - size_t bufsize __attribute__ ((unused)), - const uint8_t *data __attribute__ ((unused)), - const uint8_t **param_start __attribute__ ((unused)), - const uint8_t *end __attribute__ ((unused)), - DisasmGetSymCB_t symcb __attribute__ ((unused)), - void *symcbarg __attribute__ ((unused))) +FCT_reg$w (struct output_data *d) { - if (data[opoff2 / 8] & (1 << (7 - (opoff2 & 7)))) - return FCT_reg (addr, prefixes, op1str, opoff1, opoff2, opoff3, bufp, - bufcntp, bufsize, data, param_start, end, symcb, symcbarg); - uint_fast8_t byte = data[opoff1 / 8]; - assert (opoff1 % 8 + 3 <= 8); - byte >>= 8 - (opoff1 % 8 + 3); + if (d->data[d->opoff2 / 8] & (1 << (7 - (d->opoff2 & 7)))) + return FCT_reg (d); + + uint_fast8_t byte = d->data[d->opoff1 / 8]; + assert (d->opoff1 % 8 + 3 <= 8); + byte >>= 8 - (d->opoff1 % 8 + 3); byte &= 7; - if (*bufcntp + 4 > bufsize) - return *bufcntp + 4 - bufsize; + size_t *bufcntp = d->bufcntp; + if (*bufcntp + 4 > d->bufsize) + return *bufcntp + 4 - d->bufsize; - bufp[(*bufcntp)++] = '%'; + d->bufp[(*bufcntp)++] = '%'; #ifdef X86_64 - if (*prefixes & has_rex) + if (*d->prefixes & has_rex) { - if (*prefixes & has_rex_r) - *bufcntp += snprintf (bufp + *bufcntp, bufsize - *bufcntp, + if (*d->prefixes & has_rex_r) + *bufcntp += snprintf (d->bufp + *bufcntp, d->bufsize - *bufcntp, "r%db", 8 + byte); else { - char* cp = stpcpy (bufp + *bufcntp, rex_8bit[byte]); + char* cp = stpcpy (d->bufp + *bufcntp, rex_8bit[byte]); *cp++ = 'l'; - *bufcntp = cp - bufp; + *bufcntp = cp - d->bufp; } } else #endif { - bufp[(*bufcntp)++] = "acdb"[byte & 3]; - bufp[(*bufcntp)++] = "lh"[byte >> 2]; + d->bufp[(*bufcntp)++] = "acdb"[byte & 3]; + d->bufp[(*bufcntp)++] = "lh"[byte >> 2]; } return 0; } + static int -FCT_freg (GElf_Addr addr __attribute__ ((unused)), - int *prefixes __attribute__ ((unused)), - const char *op1str __attribute__ ((unused)), - size_t opoff1 __attribute__ ((unused)), - size_t opoff2 __attribute__ ((unused)), - size_t opoff3 __attribute__ ((unused)), - char *bufp __attribute__ ((unused)), - size_t *bufcntp __attribute__ ((unused)), - size_t bufsize __attribute__ ((unused)), - const uint8_t *data __attribute__ ((unused)), - const uint8_t **param_start __attribute__ ((unused)), - const uint8_t *end __attribute__ ((unused)), - DisasmGetSymCB_t symcb __attribute__ ((unused)), - void *symcbarg __attribute__ ((unused))) +FCT_freg (struct output_data *d) { - assert (opoff1 / 8 == 1); - assert (opoff1 % 8 == 5); - size_t avail = bufsize - *bufcntp; - int needed = snprintf (&bufp[*bufcntp], avail, "%%st(%" PRIx32 ")", - (uint32_t) (data[1] & 7)); + assert (d->opoff1 / 8 == 1); + assert (d->opoff1 % 8 == 5); + size_t *bufcntp = d->bufcntp; + size_t avail = d->bufsize - *bufcntp; + int needed = snprintf (&d->bufp[*bufcntp], avail, "%%st(%" PRIx32 ")", + (uint32_t) (d->data[1] & 7)); if ((size_t) needed > avail) return (size_t) needed - avail; *bufcntp += needed; return 0; } + #ifndef X86_64 static int -FCT_reg16 (GElf_Addr addr __attribute__ ((unused)), - int *prefixes __attribute__ ((unused)), - const char *op1str __attribute__ ((unused)), - size_t opoff1 __attribute__ ((unused)), - size_t opoff2 __attribute__ ((unused)), - size_t opoff3 __attribute__ ((unused)), - char *bufp __attribute__ ((unused)), - size_t *bufcntp __attribute__ ((unused)), - size_t bufsize __attribute__ ((unused)), - const uint8_t *data __attribute__ ((unused)), - const uint8_t **param_start __attribute__ ((unused)), - const uint8_t *end __attribute__ ((unused)), - DisasmGetSymCB_t symcb __attribute__ ((unused)), - void *symcbarg __attribute__ ((unused))) +FCT_reg16 (struct output_data *d) { - if (*prefixes & has_data16) + if (*d->prefixes & has_data16) return -1; - *prefixes |= has_data16; - return FCT_reg (addr, prefixes, op1str, opoff1, opoff2, opoff3, bufp, - bufcntp, bufsize, data, param_start, end, symcb, symcbarg); + *d->prefixes |= has_data16; + return FCT_reg (d); } #endif + static int -FCT_sel (GElf_Addr addr __attribute__ ((unused)), - int *prefixes __attribute__ ((unused)), - const char *op1str __attribute__ ((unused)), - size_t opoff1 __attribute__ ((unused)), - size_t opoff2 __attribute__ ((unused)), - size_t opoff3 __attribute__ ((unused)), - char *bufp __attribute__ ((unused)), - size_t *bufcntp __attribute__ ((unused)), - size_t bufsize __attribute__ ((unused)), - const uint8_t *data __attribute__ ((unused)), - const uint8_t **param_start __attribute__ ((unused)), - const uint8_t *end __attribute__ ((unused)), - DisasmGetSymCB_t symcb __attribute__ ((unused)), - void *symcbarg __attribute__ ((unused))) +FCT_sel (struct output_data *d) { - assert (opoff1 % 8 == 0); - assert (opoff1 / 8 == 5); - if (*param_start + 2 > end) + assert (d->opoff1 % 8 == 0); + assert (d->opoff1 / 8 == 5); + if (*d->param_start + 2 > d->end) return -1; - *param_start += 2; - uint16_t absval = read_2ubyte_unaligned (&data[5]); - size_t avail = bufsize - *bufcntp; - int needed = snprintf (&bufp[*bufcntp], avail, "$0x%" PRIx16, absval); + *d->param_start += 2; + uint16_t absval = read_2ubyte_unaligned (&d->data[5]); + + size_t *bufcntp = d->bufcntp; + size_t avail = d->bufsize - *bufcntp; + int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx16, absval); if ((size_t) needed > avail) return needed - avail; *bufcntp += needed; return 0; } + static int -FCT_sreg2 (GElf_Addr addr __attribute__ ((unused)), - int *prefixes __attribute__ ((unused)), - const char *op1str __attribute__ ((unused)), - size_t opoff1 __attribute__ ((unused)), - size_t opoff2 __attribute__ ((unused)), - size_t opoff3 __attribute__ ((unused)), - char *bufp __attribute__ ((unused)), - size_t *bufcntp __attribute__ ((unused)), - size_t bufsize __attribute__ ((unused)), - const uint8_t *data __attribute__ ((unused)), - const uint8_t **param_start __attribute__ ((unused)), - const uint8_t *end __attribute__ ((unused)), - DisasmGetSymCB_t symcb __attribute__ ((unused)), - void *symcbarg __attribute__ ((unused))) +FCT_sreg2 (struct output_data *d) { - uint_fast8_t byte = data[opoff1 / 8]; - assert (opoff1 % 8 + 3 <= 8); - byte >>= 8 - (opoff1 % 8 + 2); + uint_fast8_t byte = d->data[d->opoff1 / 8]; + assert (d->opoff1 % 8 + 3 <= 8); + byte >>= 8 - (d->opoff1 % 8 + 2); - if (*bufcntp + 3 > bufsize) - return *bufcntp + 3 - bufsize; + size_t *bufcntp = d->bufcntp; + char *bufp = d->bufp; + if (*bufcntp + 3 > d->bufsize) + return *bufcntp + 3 - d->bufsize; bufp[(*bufcntp)++] = '%'; bufp[(*bufcntp)++] = "ecsd"[byte & 3]; @@ -1681,31 +1280,21 @@ FCT_sreg2 (GElf_Addr addr __attribute__ ((unused)), return 0; } + static int -FCT_sreg3 (GElf_Addr addr __attribute__ ((unused)), - int *prefixes __attribute__ ((unused)), - const char *op1str __attribute__ ((unused)), - size_t opoff1 __attribute__ ((unused)), - size_t opoff2 __attribute__ ((unused)), - size_t opoff3 __attribute__ ((unused)), - char *bufp __attribute__ ((unused)), - size_t *bufcntp __attribute__ ((unused)), - size_t bufsize __attribute__ ((unused)), - const uint8_t *data __attribute__ ((unused)), - const uint8_t **param_start __attribute__ ((unused)), - const uint8_t *end __attribute__ ((unused)), - DisasmGetSymCB_t symcb __attribute__ ((unused)), - void *symcbarg __attribute__ ((unused))) +FCT_sreg3 (struct output_data *d) { - uint_fast8_t byte = data[opoff1 / 8]; - assert (opoff1 % 8 + 4 <= 8); - byte >>= 8 - (opoff1 % 8 + 3); + uint_fast8_t byte = d->data[d->opoff1 / 8]; + assert (d->opoff1 % 8 + 4 <= 8); + byte >>= 8 - (d->opoff1 % 8 + 3); if ((byte & 7) >= 6) return -1; - if (*bufcntp + 3 > bufsize) - return *bufcntp + 3 - bufsize; + size_t *bufcntp = d->bufcntp; + char *bufp = d->bufp; + if (*bufcntp + 3 > d->bufsize) + return *bufcntp + 3 - d->bufsize; bufp[(*bufcntp)++] = '%'; bufp[(*bufcntp)++] = "ecsdfg"[byte & 7]; @@ -1714,46 +1303,24 @@ FCT_sreg3 (GElf_Addr addr __attribute__ ((unused)), return 0; } + static int -FCT_string (GElf_Addr addr __attribute__ ((unused)), - int *prefixes __attribute__ ((unused)), - const char *op1str __attribute__ ((unused)), - size_t opoff1 __attribute__ ((unused)), - size_t opoff2 __attribute__ ((unused)), - size_t opoff3 __attribute__ ((unused)), - char *bufp __attribute__ ((unused)), - size_t *bufcntp __attribute__ ((unused)), - size_t bufsize __attribute__ ((unused)), - const uint8_t *data __attribute__ ((unused)), - const uint8_t **param_start __attribute__ ((unused)), - const uint8_t *end __attribute__ ((unused)), - DisasmGetSymCB_t symcb __attribute__ ((unused)), - void *symcbarg __attribute__ ((unused))) +FCT_string (struct output_data *d __attribute__ ((unused))) { return 0; } + static int -FCT_xmmreg (GElf_Addr addr __attribute__ ((unused)), - int *prefixes __attribute__ ((unused)), - const char *op1str __attribute__ ((unused)), - size_t opoff1 __attribute__ ((unused)), - size_t opoff2 __attribute__ ((unused)), - size_t opoff3 __attribute__ ((unused)), - char *bufp __attribute__ ((unused)), - size_t *bufcntp __attribute__ ((unused)), - size_t bufsize __attribute__ ((unused)), - const uint8_t *data __attribute__ ((unused)), - const uint8_t **param_start __attribute__ ((unused)), - const uint8_t *end __attribute__ ((unused)), - DisasmGetSymCB_t symcb __attribute__ ((unused)), - void *symcbarg __attribute__ ((unused))) +FCT_xmmreg (struct output_data *d) { - uint_fast8_t byte = data[opoff1 / 8]; - assert (opoff1 % 8 == 2 || opoff1 % 8 == 5); - byte = (byte >> (5 - opoff1 % 8)) & 7; - size_t avail = bufsize - *bufcntp; - int needed = snprintf (&bufp[*bufcntp], avail, "%%xmm%" PRIxFAST8, byte); + uint_fast8_t byte = d->data[d->opoff1 / 8]; + assert (d->opoff1 % 8 == 2 || d->opoff1 % 8 == 5); + byte = (byte >> (5 - d->opoff1 % 8)) & 7; + + size_t *bufcntp = d->bufcntp; + size_t avail = d->bufsize - *bufcntp; + int needed = snprintf (&d->bufp[*bufcntp], avail, "%%xmm%" PRIxFAST8, byte); if ((size_t) needed > avail) return needed - avail; *bufcntp += needed; diff --git a/libcpu/i386_disasm.c b/libcpu/i386_disasm.c index ecdbfb6..0f3a01d 100644 --- a/libcpu/i386_disasm.c +++ b/libcpu/i386_disasm.c @@ -184,6 +184,25 @@ static const char *prefix_str[] = #endif +struct output_data +{ + GElf_Addr addr; + int *prefixes; + const char *op1str; + size_t opoff1; + size_t opoff2; + size_t opoff3; + char *bufp; + size_t *bufcntp; + size_t bufsize; + const uint8_t *data; + const uint8_t **param_start; + const uint8_t *end; + DisasmGetSymCB_t symcb; + void *symcbarg; +}; + + #ifndef DISFILE # define DISFILE "i386_dis.h" #endif @@ -404,6 +423,7 @@ i386_disasm (const uint8_t **startp, const uint8_t *end, GElf_Addr addr, break; default: /* Cannot happen. */ + puts ("unknown prefix"); abort (); } data = begin + 1; @@ -450,6 +470,20 @@ i386_disasm (const uint8_t **startp, const uint8_t *end, GElf_Addr addr, goto not; } + struct output_data output_data = + { + .addr = addr + (data - begin), + .prefixes = &prefixes, + .bufp = buf, + .bufcntp = &bufcnt, + .bufsize = bufsize, + .data = data, + .param_start = ¶m_start, + .end = end, + .symcb = symcb, + .symcbarg = symcbarg + }; + unsigned long string_end_idx = 0; while (*fmt != '\0') { @@ -673,21 +707,14 @@ i386_disasm (const uint8_t **startp, const uint8_t *end, GElf_Addr addr, if (instrtab[cnt].str1 != 0) ADD_STRING (op1_str[instrtab[cnt].str1]); - int r = op1_fct[instrtab[cnt].fct1] (addr - + (data - begin), - &prefixes, -#ifdef STR1_BITS - op1_str[instrtab[cnt].str1], -#else - NULL, -#endif - instrtab[cnt].off1_1 + OFF1_1_BIAS - opoff, - instrtab[cnt].off1_2 + OFF1_2_BIAS - opoff, - instrtab[cnt].off1_3 + OFF1_3_BIAS - opoff, - buf, &bufcnt, bufsize, - data, ¶m_start, - end, - symcb, symcbarg); + output_data.op1str = op1_str[instrtab[cnt].str1]; + output_data.opoff1 = (instrtab[cnt].off1_1 + + OFF1_1_BIAS - opoff); + output_data.opoff2 = (instrtab[cnt].off1_2 + + OFF1_2_BIAS - opoff); + output_data.opoff3 = (instrtab[cnt].off1_3 + + OFF1_3_BIAS - opoff); + int r = op1_fct[instrtab[cnt].fct1] (&output_data); if (r < 0) goto not; if (r > 0) @@ -698,28 +725,17 @@ i386_disasm (const uint8_t **startp, const uint8_t *end, GElf_Addr addr, else if (prec == 2 && instrtab[cnt].fct2 != 0) { /* Second parameter. */ -#ifdef STR2_BITS - // XXX Probably not needed once the instruction - // XXX tables are complete if (instrtab[cnt].str2 != 0) ADD_STRING (op2_str[instrtab[cnt].str2]); -#endif - int r = op2_fct[instrtab[cnt].fct2] (addr - + (data - begin), - &prefixes, -#ifdef STR2_BITS - op2_str[instrtab[cnt].str2], -#else - NULL, -#endif - instrtab[cnt].off2_1 + OFF2_1_BIAS - opoff, - instrtab[cnt].off2_2 + OFF2_2_BIAS - opoff, - instrtab[cnt].off2_3 + OFF2_3_BIAS - opoff, - buf, &bufcnt, bufsize, - data, ¶m_start, - end, - symcb, symcbarg); + output_data.op1str = op2_str[instrtab[cnt].str2]; + output_data.opoff1 = (instrtab[cnt].off2_1 + + OFF2_1_BIAS - opoff); + output_data.opoff2 = (instrtab[cnt].off2_2 + + OFF2_2_BIAS - opoff); + output_data.opoff3 = (instrtab[cnt].off2_3 + + OFF2_3_BIAS - opoff); + int r = op2_fct[instrtab[cnt].fct2] (&output_data); if (r < 0) goto not; if (r > 0) @@ -730,36 +746,21 @@ i386_disasm (const uint8_t **startp, const uint8_t *end, GElf_Addr addr, else if (prec == 3 && instrtab[cnt].fct3 != 0) { /* Third parameter. */ -#ifdef STR3_BITS - // XXX Probably not needed once the instruction - // XXX tables are complete if (instrtab[cnt].str3 != 0) ADD_STRING (op3_str[instrtab[cnt].str3]); -#endif - int r = op3_fct[instrtab[cnt].fct3] (addr - + (data - begin), - &prefixes, -#ifdef STR3_BITS - op3_str[instrtab[cnt].str3], -#else - NULL, -#endif - instrtab[cnt].off3_1 + OFF3_1_BIAS - opoff, -#ifdef OFF3_2_BITS - instrtab[cnt].off3_2 + OFF3_2_BIAS - opoff, -#else - 0, -#endif + output_data.op1str = op3_str[instrtab[cnt].str3]; + output_data.opoff1 = (instrtab[cnt].off3_1 + + OFF3_1_BIAS - opoff); + output_data.opoff2 = (instrtab[cnt].off3_2 + + OFF3_2_BIAS - opoff); #ifdef OFF3_3_BITS - instrtab[cnt].off3_3 + OFF3_3_BIAS - opoff, + output_data.opoff3 = (instrtab[cnt].off3_3 + + OFF3_3_BIAS - opoff); #else - 0, + output_data.opoff3 = 0; #endif - buf, &bufcnt, bufsize, - data, ¶m_start, - end, - symcb, symcbarg); + int r = op3_fct[instrtab[cnt].fct3] (&output_data); if (r < 0) goto not; if (r > 0)