diff options
author | Ulrich Drepper <drepper@redhat.com> | 2008-12-31 12:03:45 -0800 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2008-12-31 12:03:45 -0800 |
commit | a492e8ec781c08bd233b2564e5c0f1a8cf0378cb (patch) | |
tree | 482a15773e67506661e7817cde4d616cecaeec93 | |
parent | 4692d8160c29cd97fc1598d5c8e465bb0a2e36e2 (diff) | |
download | elfutils-a492e8ec781c08bd233b2564e5c0f1a8cf0378cb.tar.gz |
Replay output operations correctly when internal buffer in x86/x86-64
disasembler code is full.
-rw-r--r-- | libcpu/ChangeLog | 2 | ||||
-rw-r--r-- | libcpu/i386_disasm.c | 62 |
2 files changed, 40 insertions, 24 deletions
diff --git a/libcpu/ChangeLog b/libcpu/ChangeLog index b3abff7b..5bc89f9f 100644 --- a/libcpu/ChangeLog +++ b/libcpu/ChangeLog @@ -1,5 +1,7 @@ 2008-12-31 Ulrich Drepper <drepper@redhat.com> + * i386_disasm.c (i386_disasm): Correct resizing of buffer. + * i386_parse.y (struct argstring): Add off element. (off_op_str): New global variable. (print_op_str): Print strings as concatenated strings. Keep track diff --git a/libcpu/i386_disasm.c b/libcpu/i386_disasm.c index 3ba513b4..76b5a393 100644 --- a/libcpu/i386_disasm.c +++ b/libcpu/i386_disasm.c @@ -356,6 +356,9 @@ i386_disasm (const uint8_t **startp, const uint8_t *end, GElf_Addr addr, prefixes |= ((*data++) & 0xf) | has_rex; #endif + bufcnt = 0; + size_t cnt = 0; + const uint8_t *curr = match_data; const uint8_t *const match_end = match_data + sizeof (match_data); @@ -369,30 +372,6 @@ i386_disasm (const uint8_t **startp, const uint8_t *end, GElf_Addr addr, goto do_ret; } - if (0) - { - /* Resize the buffer. */ - char *oldbuf; - enomem: - oldbuf = buf; - if (buf == initbuf) - buf = malloc (2 * bufsize); - else - buf = realloc (buf, 2 * bufsize); - if (buf == NULL) - { - buf = oldbuf; - retval = ENOMEM; - goto do_ret; - } - bufsize *= 2; - - output_data.bufp = buf; - output_data.bufsize = bufsize; - } - bufcnt = 0; - - size_t cnt = 0; next_match: while (curr < match_end) { @@ -447,6 +426,41 @@ i386_disasm (const uint8_t **startp, const uint8_t *end, GElf_Addr addr, || (prefixes & correct_prefix) != 0); prefixes ^= correct_prefix; + if (0) + { + /* Resize the buffer. */ + char *oldbuf; + enomem: + oldbuf = buf; + if (buf == initbuf) + buf = malloc (2 * bufsize); + else + buf = realloc (buf, 2 * bufsize); + if (buf == NULL) + { + buf = oldbuf; + retval = ENOMEM; + goto do_ret; + } + bufsize *= 2; + + output_data.bufp = buf; + output_data.bufsize = bufsize; + bufcnt = 0; + + if (data == end) + { + assert (prefixes != 0); + goto print_prefix; + } + + /* gcc is not clever enough to see the following variables + are not used uninitialized. */ + asm ("" + : "=mr" (opoff), "=mr" (correct_prefix), "=mr" (codep), + "=mr" (start), "=mr" (len)); + } + size_t prefix_size = 0; // XXXonly print as prefix if valid? |