|
|
fname++; | fname++; |
fnlen = strcspn(fname, "\""); | fnlen = strcspn(fname, "\""); |
line = nasm_malloc(20 + fnlen); | line = nasm_malloc(20 + fnlen); |
sprintf(line, "%%line %d %.*s", lineno, fnlen, fname); |
snprintf(line, 20+fnlen,"%%line %d %.*s", lineno, fnlen, fname); |
nasm_free(oldline); | nasm_free(oldline); |
} | } |
if (tasm_compatible_mode) | if (tasm_compatible_mode) |
|
|
char *p, *q = t->text + 2; | char *p, *q = t->text + 2; |
| |
q += strspn(q, "$"); | q += strspn(q, "$"); |
sprintf(buffer, "..@%lu.", ctx->number); |
snprintf(buffer, sizeof(buffer), "..@%lu.", ctx->number); |
p = nasm_strcat(buffer, q); | p = nasm_strcat(buffer, q); |
nasm_free(t->text); | nasm_free(t->text); |
t->text = p; | t->text = p; |
|
|
t = t->next; | t = t->next; |
continue; | continue; |
} | } |
else if (tt->type == TOK_WHITESPACE) |
if (tt->type == TOK_WHITESPACE) |
{ | { |
tt = tt->next; | tt = tt->next; |
continue; | continue; |
} | } |
else if (tt->type != t->type || |
if (tt->type != t->type) |
mstrcmp(tt->text, t->text, casesense)) |
|
{ | { |
j = FALSE; /* found mismatching tokens */ | j = FALSE; /* found mismatching tokens */ |
break; | break; |
} | } |
else |
/* Unify surrounding quotes for strings */ |
|
if (t->type == TOK_STRING) |
{ | { |
t = t->next; |
tt->text[0] = t->text[0]; |
tt = tt->next; |
tt->text[strlen(tt->text) - 1] = t->text[0]; |
continue; |
|
} | } |
|
if (mstrcmp(tt->text, t->text, casesense) != 0) |
|
{ |
|
j = FALSE; /* found mismatching tokens */ |
|
break; |
|
} |
|
|
|
t = t->next; |
|
tt = tt->next; |
} | } |
if ((t->type != TOK_OTHER || strcmp(t->text, ",")) || tt) | if ((t->type != TOK_OTHER || strcmp(t->text, ",")) || tt) |
j = FALSE; /* trailing gunk on one end or other */ | j = FALSE; /* trailing gunk on one end or other */ |
|
|
free_tlist(tt); | free_tlist(tt); |
| |
/* Now define the macro for the argument */ | /* Now define the macro for the argument */ |
sprintf(directive, "%%define %s (%s+%d)", arg, StackPointer, |
snprintf(directive, sizeof(directive), "%%define %s (%s+%d)", arg, StackPointer, |
offset); | offset); |
do_directive(tokenise(directive)); | do_directive(tokenise(directive)); |
offset += size; | offset += size; |
|
|
free_tlist(tt); | free_tlist(tt); |
| |
/* Now define the macro for the argument */ | /* Now define the macro for the argument */ |
sprintf(directive, "%%define %s (%s-%d)", local, StackPointer, |
snprintf(directive, sizeof(directive), "%%define %s (%s-%d)", local, StackPointer, |
offset); | offset); |
do_directive(tokenise(directive)); | do_directive(tokenise(directive)); |
offset += size; | offset += size; |
| |
/* Now define the assign to setup the enter_c macro correctly */ | /* Now define the assign to setup the enter_c macro correctly */ |
sprintf(directive, "%%assign %%$localsize %%$localsize+%d", |
snprintf(directive, sizeof(directive), "%%assign %%$localsize %%$localsize+%d", |
size); | size); |
do_directive(tokenise(directive)); | do_directive(tokenise(directive)); |
| |
|
|
*/ | */ |
case '0': | case '0': |
type = TOK_NUMBER; | type = TOK_NUMBER; |
sprintf(tmpbuf, "%d", mac->nparam); |
snprintf(tmpbuf, sizeof(tmpbuf), "%d", mac->nparam); |
text = nasm_strdup(tmpbuf); | text = nasm_strdup(tmpbuf); |
break; | break; |
case '%': | case '%': |
type = TOK_ID; | type = TOK_ID; |
sprintf(tmpbuf, "..@%lu.", mac->unique); |
snprintf(tmpbuf, sizeof(tmpbuf), "..@%lu.", mac->unique); |
text = nasm_strcat(tmpbuf, t->text + 2); | text = nasm_strcat(tmpbuf, t->text + 2); |
break; | break; |
case '-': | case '-': |
|
|
return; | return; |
| |
va_start(arg, fmt); | va_start(arg, fmt); |
vsprintf(buff, fmt, arg); |
vsnprintf(buff, sizeof(buff), fmt, arg); |
va_end(arg); | va_end(arg); |
| |
if (istk && istk->mstk && istk->mstk->name) | if (istk && istk->mstk && istk->mstk->name) |
|
|
make_tok_num(Token * tok, long val) | make_tok_num(Token * tok, long val) |
{ | { |
char numbuf[20]; | char numbuf[20]; |
sprintf(numbuf, "%ld", val); |
snprintf(numbuf, sizeof(numbuf), "%ld", val); |
tok->text = nasm_strdup(numbuf); | tok->text = nasm_strdup(numbuf); |
tok->type = TOK_NUMBER; | tok->type = TOK_NUMBER; |
} | } |
|
|
return data - origdata; | return data - origdata; |
} | } |
| |
long disasm (unsigned char *data, char *output, int segsize, long offset, |
long disasm (unsigned char *data, char *output, int outbufsize, int segsize, |
int autosync, unsigned long prefer) |
long offset, int autosync, unsigned long prefer) |
{ | { |
struct itemplate **p, **best_p; | struct itemplate **p, **best_p; |
int length, best_length = 0; | int length, best_length = 0; |
|
|
slen = 0; | slen = 0; |
| |
if (lock) | if (lock) |
slen += sprintf(output+slen, "lock "); |
slen += snprintf(output+slen, outbufsize-slen, "lock "); |
for (i = 0; i < ins.nprefix; i++) | for (i = 0; i < ins.nprefix; i++) |
switch (ins.prefixes[i]) { | switch (ins.prefixes[i]) { |
case P_REP: slen += sprintf(output+slen, "rep "); break; |
case P_REP: slen += snprintf(output+slen, outbufsize-slen, "rep "); break; |
case P_REPE: slen += sprintf(output+slen, "repe "); break; |
case P_REPE: slen += snprintf(output+slen, outbufsize-slen, "repe "); break; |
case P_REPNE: slen += sprintf(output+slen, "repne "); break; |
case P_REPNE: slen += snprintf(output+slen, outbufsize-slen, "repne "); break; |
case P_A16: slen += sprintf(output+slen, "a16 "); break; |
case P_A16: slen += snprintf(output+slen, outbufsize-slen, "a16 "); break; |
case P_A32: slen += sprintf(output+slen, "a32 "); break; |
case P_A32: slen += snprintf(output+slen, outbufsize-slen, "a32 "); break; |
case P_O16: slen += sprintf(output+slen, "o16 "); break; |
case P_O16: slen += snprintf(output+slen, outbufsize-slen, "o16 "); break; |
case P_O32: slen += sprintf(output+slen, "o32 "); break; |
case P_O32: slen += snprintf(output+slen, outbufsize-slen, "o32 "); break; |
} | } |
| |
for (i = 0; i < elements(ico); i++) | for (i = 0; i < elements(ico); i++) |
if ((*p)->opcode == ico[i]) { | if ((*p)->opcode == ico[i]) { |
slen += sprintf(output+slen, "%s%s", icn[i], |
slen += snprintf(output+slen, outbufsize-slen, "%s%s", icn[i], |
whichcond(ins.condition)); | whichcond(ins.condition)); |
break; | break; |
} | } |
if (i >= elements(ico)) | if (i >= elements(ico)) |
slen += sprintf(output+slen, "%s", insn_names[(*p)->opcode]); |
slen += snprintf(output+slen, outbufsize-slen, "%s", insn_names[(*p)->opcode]); |
colon = FALSE; | colon = FALSE; |
length += data - origdata; /* fix up for prefixes */ | length += data - origdata; /* fix up for prefixes */ |
for (i=0; i<(*p)->operands; i++) { | for (i=0; i<(*p)->operands; i++) { |
|
|
ins.oprs[i].basereg = whichreg ((*p)->opd[i], | ins.oprs[i].basereg = whichreg ((*p)->opd[i], |
ins.oprs[i].basereg); | ins.oprs[i].basereg); |
if ( (*p)->opd[i] & TO ) | if ( (*p)->opd[i] & TO ) |
slen += sprintf(output+slen, "to "); |
slen += snprintf(output+slen, outbufsize-slen, "to "); |
slen += sprintf(output+slen, "%s", |
slen += snprintf(output+slen, outbufsize-slen, "%s", |
reg_names[ins.oprs[i].basereg-EXPR_REG_START]); | reg_names[ins.oprs[i].basereg-EXPR_REG_START]); |
} else if (!(UNITY & ~(*p)->opd[i])) { | } else if (!(UNITY & ~(*p)->opd[i])) { |
output[slen++] = '1'; | output[slen++] = '1'; |
} else if ( (*p)->opd[i] & IMMEDIATE ) { | } else if ( (*p)->opd[i] & IMMEDIATE ) { |
if ( (*p)->opd[i] & BITS8 ) { | if ( (*p)->opd[i] & BITS8 ) { |
slen += sprintf(output+slen, "byte "); |
slen += snprintf(output+slen, outbufsize-slen, "byte "); |
if (ins.oprs[i].segment & SEG_SIGNED) { | if (ins.oprs[i].segment & SEG_SIGNED) { |
if (ins.oprs[i].offset < 0) { | if (ins.oprs[i].offset < 0) { |
ins.oprs[i].offset *= -1; | ins.oprs[i].offset *= -1; |
|
|
output[slen++] = '+'; | output[slen++] = '+'; |
} | } |
} else if ( (*p)->opd[i] & BITS16 ) { | } else if ( (*p)->opd[i] & BITS16 ) { |
slen += sprintf(output+slen, "word "); |
slen += snprintf(output+slen, outbufsize-slen, "word "); |
} else if ( (*p)->opd[i] & BITS32 ) { | } else if ( (*p)->opd[i] & BITS32 ) { |
slen += sprintf(output+slen, "dword "); |
slen += snprintf(output+slen, outbufsize-slen, "dword "); |
} else if ( (*p)->opd[i] & NEAR ) { | } else if ( (*p)->opd[i] & NEAR ) { |
slen += sprintf(output+slen, "near "); |
slen += snprintf(output+slen, outbufsize-slen, "near "); |
} else if ( (*p)->opd[i] & SHORT ) { | } else if ( (*p)->opd[i] & SHORT ) { |
slen += sprintf(output+slen, "short "); |
slen += snprintf(output+slen, outbufsize-slen, "short "); |
} | } |
slen += sprintf(output+slen, "0x%lx", ins.oprs[i].offset); |
slen += snprintf(output+slen, outbufsize-slen, "0x%lx", ins.oprs[i].offset); |
} else if ( !(MEM_OFFS & ~(*p)->opd[i]) ) { | } else if ( !(MEM_OFFS & ~(*p)->opd[i]) ) { |
slen += sprintf(output+slen, "[%s%s%s0x%lx]", |
slen += snprintf(output+slen, outbufsize-slen, "[%s%s%s0x%lx]", |
(segover ? segover : ""), | (segover ? segover : ""), |
(segover ? ":" : ""), | (segover ? ":" : ""), |
(ins.oprs[i].addr_size == 32 ? "dword " : | (ins.oprs[i].addr_size == 32 ? "dword " : |
|
|
} else if ( !(REGMEM & ~(*p)->opd[i]) ) { | } else if ( !(REGMEM & ~(*p)->opd[i]) ) { |
int started = FALSE; | int started = FALSE; |
if ( (*p)->opd[i] & BITS8 ) | if ( (*p)->opd[i] & BITS8 ) |
slen += sprintf(output+slen, "byte "); |
slen += snprintf(output+slen, outbufsize-slen, "byte "); |
if ( (*p)->opd[i] & BITS16 ) | if ( (*p)->opd[i] & BITS16 ) |
slen += sprintf(output+slen, "word "); |
slen += snprintf(output+slen, outbufsize-slen, "word "); |
if ( (*p)->opd[i] & BITS32 ) | if ( (*p)->opd[i] & BITS32 ) |
slen += sprintf(output+slen, "dword "); |
slen += snprintf(output+slen, outbufsize-slen, "dword "); |
if ( (*p)->opd[i] & BITS64 ) | if ( (*p)->opd[i] & BITS64 ) |
slen += sprintf(output+slen, "qword "); |
slen += snprintf(output+slen, outbufsize-slen, "qword "); |
if ( (*p)->opd[i] & BITS80 ) | if ( (*p)->opd[i] & BITS80 ) |
slen += sprintf(output+slen, "tword "); |
slen += snprintf(output+slen, outbufsize-slen, "tword "); |
if ( (*p)->opd[i] & FAR ) | if ( (*p)->opd[i] & FAR ) |
slen += sprintf(output+slen, "far "); |
slen += snprintf(output+slen, outbufsize-slen, "far "); |
if ( (*p)->opd[i] & NEAR ) | if ( (*p)->opd[i] & NEAR ) |
slen += sprintf(output+slen, "near "); |
slen += snprintf(output+slen, outbufsize-slen, "near "); |
output[slen++] = '['; | output[slen++] = '['; |
if (ins.oprs[i].addr_size) | if (ins.oprs[i].addr_size) |
slen += sprintf(output+slen, "%s", |
slen += snprintf(output+slen, outbufsize-slen, "%s", |
(ins.oprs[i].addr_size == 32 ? "dword " : | (ins.oprs[i].addr_size == 32 ? "dword " : |
ins.oprs[i].addr_size == 16 ? "word " : "")); | ins.oprs[i].addr_size == 16 ? "word " : "")); |
if (segover) { | if (segover) { |
slen += sprintf(output+slen, "%s:", segover); |
slen += snprintf(output+slen, outbufsize-slen, "%s:", segover); |
segover = NULL; | segover = NULL; |
} | } |
if (ins.oprs[i].basereg != -1) { | if (ins.oprs[i].basereg != -1) { |
slen += sprintf(output+slen, "%s", |
slen += snprintf(output+slen, outbufsize-slen, "%s", |
reg_names[(ins.oprs[i].basereg - | reg_names[(ins.oprs[i].basereg - |
EXPR_REG_START)]); | EXPR_REG_START)]); |
started = TRUE; | started = TRUE; |
|
|
if (ins.oprs[i].indexreg != -1) { | if (ins.oprs[i].indexreg != -1) { |
if (started) | if (started) |
output[slen++] = '+'; | output[slen++] = '+'; |
slen += sprintf(output+slen, "%s", |
slen += snprintf(output+slen, outbufsize-slen, "%s", |
reg_names[(ins.oprs[i].indexreg - | reg_names[(ins.oprs[i].indexreg - |
EXPR_REG_START)]); | EXPR_REG_START)]); |
if (ins.oprs[i].scale > 1) | if (ins.oprs[i].scale > 1) |
slen += sprintf(output+slen, "*%d", ins.oprs[i].scale); |
slen += snprintf(output+slen, outbufsize-slen, "*%d", ins.oprs[i].scale); |
started = TRUE; | started = TRUE; |
} | } |
if (ins.oprs[i].segment & SEG_DISP8) { | if (ins.oprs[i].segment & SEG_DISP8) { |
|
|
ins.oprs[i].offset = - (signed char) ins.oprs[i].offset; | ins.oprs[i].offset = - (signed char) ins.oprs[i].offset; |
sign = '-'; | sign = '-'; |
} | } |
slen += sprintf(output+slen, "%c0x%lx", sign, |
slen += snprintf(output+slen, outbufsize-slen, "%c0x%lx", sign, |
ins.oprs[i].offset); | ins.oprs[i].offset); |
} else if (ins.oprs[i].segment & SEG_DISP16) { | } else if (ins.oprs[i].segment & SEG_DISP16) { |
if (started) | if (started) |
output[slen++] = '+'; | output[slen++] = '+'; |
slen += sprintf(output+slen, "0x%lx", ins.oprs[i].offset); |
slen += snprintf(output+slen, outbufsize-slen, "0x%lx", ins.oprs[i].offset); |
} else if (ins.oprs[i].segment & SEG_DISP32) { | } else if (ins.oprs[i].segment & SEG_DISP32) { |
if (started) | if (started) |
output[slen++] = '+'; | output[slen++] = '+'; |
slen += sprintf(output+slen, "0x%lx", ins.oprs[i].offset); |
slen += snprintf(output+slen, outbufsize-slen, "0x%lx", ins.oprs[i].offset); |
} | } |
output[slen++] = ']'; | output[slen++] = ']'; |
} else { | } else { |
slen += sprintf(output+slen, "<operand%d>", i); |
slen += snprintf(output+slen, outbufsize-slen, "<operand%d>", i); |
} | } |
} | } |
output[slen] = '\0'; | output[slen] = '\0'; |
|
|
return length; | return length; |
} | } |
| |
long eatbyte (unsigned char *data, char *output) |
long eatbyte (unsigned char *data, char *output, int outbufsize) |
{ | { |
sprintf(output, "db 0x%02X", *data); |
snprintf(output, outbufsize, "db 0x%02X", *data); |
return 1; | return 1; |
} | } |
|
|
nextsync = next_sync (offset, &synclen); | nextsync = next_sync (offset, &synclen); |
} | } |
while (p > q && (p - q >= INSN_MAX || lenread == 0)) { | while (p > q && (p - q >= INSN_MAX || lenread == 0)) { |
lendis = disasm (q, outbuf, bits, offset, autosync, prefer); |
lendis = disasm (q, outbuf, sizeof(outbuf), bits, offset, autosync, prefer); |
if (!lendis || lendis > (p - q) || | if (!lendis || lendis > (p - q) || |
(unsigned long)lendis > nextsync-offset) | (unsigned long)lendis > nextsync-offset) |
lendis = eatbyte (q, outbuf); |
lendis = eatbyte (q, outbuf, sizeof(outbuf)); |
output_ins (offset, q, lendis, outbuf); | output_ins (offset, q, lendis, outbuf); |
q += lendis; | q += lendis; |
offset += lendis; | offset += lendis; |
|
|
else if (typ == OUT_RESERVE) | else if (typ == OUT_RESERVE) |
{ | { |
char q[20]; | char q[20]; |
sprintf(q, "<res %08lX>", size); |
snprintf(q, sizeof(q), "<res %08lX>", size); |
list_out (offset, q); | list_out (offset, q); |
} | } |
} | } |
|
|
slen += strlen(lpostfix); | slen += strlen(lpostfix); |
slen++; /* room for that null char */ | slen++; /* room for that null char */ |
xsymbol = nasm_malloc(slen); | xsymbol = nasm_malloc(slen); |
sprintf(xsymbol,"%s%s%s",lprefix,lptr->defn.label,lpostfix); |
snprintf(xsymbol,slen,"%s%s%s",lprefix,lptr->defn.label,lpostfix); |
| |
ofmt->symdef (xsymbol, segment, offset, exi, | ofmt->symdef (xsymbol, segment, offset, exi, |
special ? special : lptr->defn.special); | special ? special : lptr->defn.special); |
|
|
slen += strlen(lpostfix); | slen += strlen(lpostfix); |
slen++; /* room for that null char */ | slen++; /* room for that null char */ |
xsymbol = nasm_malloc(slen); | xsymbol = nasm_malloc(slen); |
sprintf(xsymbol,"%s%s%s",lprefix,lptr->defn.label,lpostfix); |
snprintf(xsymbol,slen,"%s%s%s",lprefix,lptr->defn.label,lpostfix); |
| |
ofmt->symdef (xsymbol, segment, offset, exi, | ofmt->symdef (xsymbol, segment, offset, exi, |
special ? special : lptr->defn.special); | special ? special : lptr->defn.special); |
|
|
/* define some macros dependent of command-line */ | /* define some macros dependent of command-line */ |
{ | { |
char temp [64]; | char temp [64]; |
sprintf (temp, "__OUTPUT_FORMAT__=%s\n", ofmt->shortname); |
snprintf (temp, sizeof(temp), "__OUTPUT_FORMAT__=%s\n", ofmt->shortname); |
pp_pre_define (temp); | pp_pre_define (temp); |
} | } |
| |
|
|
| |
#define INSN_MAX 32 /* one instruction can't be longer than this */ | #define INSN_MAX 32 /* one instruction can't be longer than this */ |
| |
long disasm (unsigned char *data, char *output, int segsize, long offset, |
long disasm (unsigned char *data, char *output, int outbufsize, int segsize, |
int autosync, unsigned long prefer); |
long offset, int autosync, unsigned long prefer); |
long eatbyte (unsigned char *data, char *output); |
long eatbyte (unsigned char *data, char *output, int outbufsize); |
| |
#endif | #endif |