]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
Replay output operations correctly when internal buffer in x86/x86-64
authorUlrich Drepper <drepper@redhat.com>
Wed, 31 Dec 2008 20:03:45 +0000 (12:03 -0800)
committerUlrich Drepper <drepper@redhat.com>
Wed, 31 Dec 2008 20:03:45 +0000 (12:03 -0800)
disasembler code is full.

libcpu/ChangeLog
libcpu/i386_disasm.c

index b3abff7bfe1ca284d8f96a0c5b287bd58999b3b3..5bc89f9fddc8db510f508743f7b5b1e06d9c02d4 100644 (file)
@@ -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
index 3ba513b40bb3aa912f0d255d70c85aa4b11e217b..76b5a39373efb40e98fac65276fd357e11ec80e7 100644 (file)
@@ -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?