disasm: Add support for 64-bit origin

This fixes disassembly of instructions like jmp/call when target address
is larger than 2^32-1, and also printing of current address when it's
large.

After this change ndisasm still assumes that the files to disassemble
will never reach 4GiB: only offsets are made 64 bit, but not lengths.

https://bugzilla.nasm.us/show_bug.cgi?id=3392349

Signed-off-by: Ruslan Kabatsayev <b7.10110111@gmail.com>
Signed-off-by: Cyrill Gorcunov <gorcunov@gmail.com>
This commit is contained in:
Ruslan Kabatsayev 2017-02-12 19:31:19 +03:00 committed by Cyrill Gorcunov
parent a92a7dce5e
commit 3ebed50146
5 changed files with 13 additions and 13 deletions

View File

@ -1109,7 +1109,7 @@ static const char * const condition_name[16] = {
};
int32_t disasm(uint8_t *data, char *output, int outbufsize, int segsize,
int32_t offset, int autosync, iflag_t *prefer)
int64_t offset, int autosync, iflag_t *prefer)
{
const struct itemplate * const *p, * const *best_p;
const struct disasm_index *ix;
@ -1591,7 +1591,7 @@ int32_t disasm(uint8_t *data, char *output, int outbufsize, int segsize,
} else if (o->segment & SEG_DISP32) {
if (prefix.asize == 64) {
const char *prefix;
uint64_t offset = (int64_t)(int32_t)offs;
uint64_t offset = offs;
if ((int32_t)offs < 0 && started) {
offset = -offset;
prefix = "-";

View File

@ -43,7 +43,7 @@
#define INSN_MAX 32 /* one instruction can't be longer than this */
int32_t disasm(uint8_t *data, char *output, int outbufsize, int segsize,
int32_t offset, int autosync, iflag_t *prefer);
int64_t offset, int autosync, iflag_t *prefer);
int32_t eatbyte(uint8_t *data, char *output, int outbufsize, int segsize);
#endif

View File

@ -65,7 +65,7 @@ static const char *help =
" -k avoids disassembling <bytes> bytes from position <start>\n"
" -p selects the preferred vendor instruction set (intel, amd, cyrix, idt)\n";
static void output_ins(uint32_t, uint8_t *, int, char *);
static void output_ins(uint64_t, uint8_t *, int, char *);
static void skip(uint32_t dist, FILE * fp);
static void ndisasm_verror(int severity, const char *fmt, va_list va)
@ -90,7 +90,7 @@ int main(int argc, char **argv)
bool eof = false;
iflag_t prefer;
bool rn_error;
int32_t offset;
int64_t offset;
FILE *fp;
tolower_init();
@ -306,7 +306,7 @@ int main(int argc, char **argv)
if ((nextsync || synclen) &&
(uint32_t)offset == nextsync) {
if (synclen) {
fprintf(stdout, "%08"PRIX32" skipping 0x%"PRIX32" bytes\n",
fprintf(stdout, "%08"PRIX64" skipping 0x%"PRIX32" bytes\n",
offset, synclen);
offset += synclen;
skip(synclen, fp);
@ -342,11 +342,11 @@ int main(int argc, char **argv)
return 0;
}
static void output_ins(uint32_t offset, uint8_t *data,
static void output_ins(uint64_t offset, uint8_t *data,
int datalen, char *insn)
{
int bytes;
fprintf(stdout, "%08"PRIX32" ", offset);
fprintf(stdout, "%08"PRIX64" ", offset);
bytes = 0;
while (datalen > 0 && bytes < BPL) {

View File

@ -56,7 +56,7 @@
*/
static struct Sync {
uint32_t pos;
uint64_t pos;
uint32_t length;
} *synx;
@ -76,7 +76,7 @@ void init_sync(void)
nsynx = 0;
}
void add_sync(uint32_t pos, uint32_t length)
void add_sync(uint64_t pos, uint32_t length)
{
uint32_t i;
@ -97,7 +97,7 @@ void add_sync(uint32_t pos, uint32_t length)
}
}
uint32_t next_sync(uint32_t position, uint32_t *length)
uint64_t next_sync(uint64_t position, uint32_t *length)
{
while (nsynx > 0 && synx[1].pos + synx[1].length <= position) {
uint32_t i, j;

View File

@ -39,7 +39,7 @@
#define NASM_SYNC_H
void init_sync(void);
void add_sync(uint32_t position, uint32_t length);
uint32_t next_sync(uint32_t position, uint32_t *length);
void add_sync(uint64_t position, uint32_t length);
uint64_t next_sync(uint64_t position, uint32_t *length);
#endif