]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
propagate from branch 'com.redhat.elfutils.roland.pending' (head 26cc2ce45739af072e7f...
authorUlrich Drepper <drepper@redhat.com>
Wed, 9 Jan 2008 05:49:49 +0000 (05:49 +0000)
committerUlrich Drepper <drepper@redhat.com>
Wed, 9 Jan 2008 05:49:49 +0000 (05:49 +0000)
            to branch 'com.redhat.elfutils' (head bb519012dee7013b2cab5c2f5ed465cb3821b063)

18 files changed:
libasm/ChangeLog
libasm/Makefile.am
libcpu/ChangeLog
libcpu/i386_data.h
libcpu/i386_disasm.c
libdw/ChangeLog
libdw/Makefile.am
libdwfl/ChangeLog
libdwfl/Makefile.am
libelf/ChangeLog
libelf/Makefile.am
libelf/common.h
src/ChangeLog
src/elflint.c
src/ld.h
src/strip.c
tests/ChangeLog
tests/dwfl-bug-fd-leak.c

index 78a895c25634328d0dc5bdd77917424fe459f539..1fe67565bf784429da067c6f7e0692b91fb6a772 100644 (file)
@@ -1,3 +1,8 @@
+2008-01-08  Roland McGrath  <roland@redhat.com>
+
+       * Makefile.am (euinclude): Variable removed.
+       (pkginclude_HEADERS): Set this instead of euinclude_HEADERS.
+
 2007-12-20  Ulrich Drepper  <drepper@redhat.com>
 
        * disasm_cb.c: Add initial support to resolve addresses to symbols.
index 95939617ed1931c08e5c670b720c90a1b9ed1041..bd5779e8e2f246cdd556141eb43352f953042f6b 100644 (file)
@@ -1,6 +1,6 @@
 ## Process this file with automake to create Makefile.in
 ##
-## Copyright (C) 2002, 2004, 2005, 2006 Red Hat, Inc.
+## Copyright (C) 2002, 2004, 2005, 2006, 2008 Red Hat, Inc.
 ## This file is part of Red Hat elfutils.
 ##
 ## Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -45,8 +45,7 @@ if !MUDFLAP
 noinst_LIBRARIES = libasm_pic.a
 noinst_PROGRAMS = $(noinst_LIBRARIES:_pic.a=.so)
 endif
-euincludedir = ${includedir}/elfutils
-euinclude_HEADERS = libasm.h
+pkginclude_HEADERS = libasm.h
 
 libasm_a_SOURCES = asm_begin.c asm_abort.c asm_end.c asm_error.c \
                   asm_getelf.c asm_newscn.c asm_newscn_ingrp.c \
index 8cf6be07c7f9c09a0eebf424b03c23e355c9e53b..9bb8175ddc2432a010f6e6e8318ef3bb114693fd 100644 (file)
@@ -1,9 +1,3 @@
-2008-01-10  Ulrich Drepper  <drepper@redhat.com>
-
-       * 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  <drepper@redhat.com>
 
        * Makefile.am: Enable x86-64 again.
index 94bb84bf8941e1885f317f7a52142cc98d982474..398c672b61de0fea9c7b2e3da02c32ca13dfd0e7 100644 (file)
@@ -78,53 +78,56 @@ struct instr_enc
 };
 
 
-typedef int (*opfct_t) (struct output_data *);
+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 *);
 
 
 static int
-data_prefix (struct output_data *d)
+data_prefix (int *prefixes, char *bufp, size_t *bufcntp, size_t bufsize)
 {
   char ch = '\0';
-  if (*d->prefixes & has_cs)
+  if (*prefixes & has_cs)
     {
       ch = 'c';
-      *d->prefixes &= ~has_cs;
+      *prefixes &= ~has_cs;
     }
-  else if (*d->prefixes & has_ds)
+  else if (*prefixes & has_ds)
     {
       ch = 'd';
-      *d->prefixes &= ~has_ds;
+      *prefixes &= ~has_ds;
     }
-  else if (*d->prefixes & has_es)
+  else if (*prefixes & has_es)
     {
       ch = 'e';
-      *d->prefixes &= ~has_es;
+      *prefixes &= ~has_es;
     }
-  else if (*d->prefixes & has_fs)
+  else if (*prefixes & has_fs)
     {
       ch = 'f';
-      *d->prefixes &= ~has_fs;
+      *prefixes &= ~has_fs;
     }
-  else if (*d->prefixes & has_gs)
+  else if (*prefixes & has_gs)
     {
       ch = 'g';
-      *d->prefixes &= ~has_gs;
+      *prefixes &= ~has_gs;
     }
-  else if (*d->prefixes & has_ss)
+  else if (*prefixes & has_ss)
     {
       ch = 's';
-      *d->prefixes &= ~has_ss;
+      *prefixes &= ~has_ss;
     }
   else
     return 0;
 
-  if (*d->bufcntp + 4 > d->bufsize)
-    return *d->bufcntp + 4 - d->bufsize;
+  if (*bufcntp + 4 > bufsize)
+    return *bufcntp + 4 - bufsize;
 
-  d->bufp[(*d->bufcntp)++] = '%';
-  d->bufp[(*d->bufcntp)++] = ch;
-  d->bufp[(*d->bufcntp)++] = 's';
-  d->bufp[(*d->bufcntp)++] = ':';
+  bufp[(*bufcntp)++] = '%';
+  bufp[(*bufcntp)++] = ch;
+  bufp[(*bufcntp)++] = 's';
+  bufp[(*bufcntp)++] = ':';
 
   return 0;
 }
@@ -151,31 +154,38 @@ static const char aregs[8][4] =
 #endif
 
 static int
-general_mod$r_m (struct output_data *d)
+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)))
 {
-  int r = data_prefix (d);
+  int r = data_prefix (prefixes, bufp, bufcntp, bufsize);
   if (r != 0)
     return r;
 
-  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];
+  uint_fast8_t modrm = data[opoff1 / 8];
 #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[1]);
+       disp = read_2sbyte_unaligned (&data[opoff1 / 8 + 1]);
       else if ((modrm & 0xc0) == 0x40)
        /* 8 bit displacement.  */
-       disp = *(const int8_t *) &data[1];
+       disp = *(const int8_t *) &data[opoff1 / 8 + 1];
       else if ((modrm & 0xc0) == 0)
        nodisp = true;
 
@@ -214,10 +224,10 @@ general_mod$r_m (struct output_data *d)
 
          if ((modrm & 0xc7) == 5 || (modrm & 0xc0) == 0x80)
            /* 32 bit displacement.  */
-           disp = read_4sbyte_unaligned (&data[1]);
+           disp = read_4sbyte_unaligned (&data[opoff1 / 8 + 1]);
          else if ((modrm & 0xc0) == 0x40)
            /* 8 bit displacement.  */
-           disp = *(const int8_t *) &data[1];
+           disp = *(const int8_t *) &data[opoff1 / 8 + 1];
          else if ((modrm & 0xc0) == 0)
            nodisp = true;
 
@@ -227,13 +237,13 @@ general_mod$r_m (struct output_data *d)
            {
              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';
@@ -246,13 +256,13 @@ general_mod$r_m (struct output_data *d)
              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';
@@ -278,17 +288,17 @@ general_mod$r_m (struct output_data *d)
       else
        {
          /* SIB */
-         uint_fast8_t sib = data[1];
+         uint_fast8_t sib = data[opoff1 / 8 + 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[2]);
+           disp = read_4sbyte_unaligned (&data[opoff1 / 8 + 2]);
          else if ((modrm & 0xc0) == 0x40)
            /* 8 bit displacement.  */
-           disp = *(const int8_t *) &data[2];
+           disp = *(const int8_t *) &data[opoff1 / 8 + 2];
          else
            nodisp = true;
 
@@ -297,7 +307,7 @@ general_mod$r_m (struct output_data *d)
          int n;
          if ((modrm & 0xc0) != 0 || (sib & 0x3f) != 0x25
 #ifdef X86_64
-             || (prefixes & has_rex_x) != 0
+             || (*prefixes & has_rex_x) != 0
 #endif
              )
            {
@@ -315,12 +325,12 @@ general_mod$r_m (struct output_data *d)
                  *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
@@ -328,7 +338,7 @@ general_mod$r_m (struct output_data *d)
 
              if ((sib & 0x38) != 0x20
 #ifdef X86_64
-                 || (prefixes & has_rex_x) != 0
+                 || (*prefixes & has_rex_x) != 0
 #endif
                  )
                {
@@ -336,14 +346,14 @@ general_mod$r_m (struct output_data *d)
                  *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
@@ -358,7 +368,7 @@ general_mod$r_m (struct output_data *d)
            {
              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
@@ -379,62 +389,92 @@ general_mod$r_m (struct output_data *d)
 
 
 static int
-FCT_MOD$R_M (struct output_data *d)
+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)))
 {
-  assert (d->opoff1 % 8 == 0);
-  uint_fast8_t modrm = d->data[d->opoff1 / 8];
+  assert (opoff1 % 8 == 0);
+  uint_fast8_t modrm = data[opoff1 / 8];
   if ((modrm & 0xc0) == 0xc0)
     {
-      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;
+      uint_fast8_t byte = data[opoff2 / 8] & 7;
+      assert (opoff2 % 8 == 5);
+      size_t avail = bufsize - *bufcntp;
       int needed;
-      if (*d->prefixes & (has_rep | has_repne))
-       needed = snprintf (buf, avail, "%%%s", dregs[byte]);
+      if (*prefixes & (has_rep | has_repne))
+       needed = snprintf (&bufp[*bufcntp], avail, "%%%s", dregs[byte]);
       else
-       needed = snprintf (buf, avail, "%%mm%" PRIxFAST8, byte);
+       needed = snprintf (&bufp[*bufcntp], avail, "%%mm%" PRIxFAST8, byte);
       if ((size_t) needed > avail)
        return needed - avail;
       *bufcntp += needed;
       return 0;
     }
 
-  return general_mod$r_m (d);
+  return general_mod$r_m (addr, prefixes, op1str, opoff1, opoff2, opoff3, bufp,
+                         bufcntp, bufsize, data, param_start, end,
+                         symcb, symcbarg);
 }
 
 
 static int
-FCT_Mod$R_m (struct output_data *d)
+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)))
 {
-  assert (d->opoff1 % 8 == 0);
-  uint_fast8_t modrm = d->data[d->opoff1 / 8];
+  assert (opoff1 % 8 == 0);
+  uint_fast8_t modrm = data[opoff1 / 8];
   if ((modrm & 0xc0) == 0xc0)
     {
-      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);
+      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);
       if ((size_t) needed > avail)
        return needed - avail;
-      *d->bufcntp += needed;
+      *bufcntp += needed;
       return 0;
     }
 
-  return general_mod$r_m (d);
+  return general_mod$r_m (addr, prefixes, op1str, opoff1, opoff2, opoff3, bufp,
+                         bufcntp, bufsize, data, param_start, end,
+                         symcb, symcbarg);
 }
 
 static int
-generic_abs (struct output_data *d, const char *absstring
+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
 #ifdef X86_64
             , int abslen
 #else
@@ -442,15 +482,15 @@ generic_abs (struct output_data *d, const char *absstring
 #endif
             )
 {
-  int r = data_prefix (d);
+  int r = data_prefix (prefixes, bufp, bufcntp, bufsize);
   if (r != 0)
     return r;
 
-  assert (d->opoff1 % 8 == 0);
-  assert (d->opoff1 / 8 == 1);
-  if (*d->param_start + abslen > d->end)
+  assert (opoff1 % 8 == 0);
+  assert (opoff1 / 8 == 1);
+  if (*param_start + abslen > end)
     return -1;
-  *d->param_start += abslen;
+  *param_start += abslen;
 #ifndef X86_64
   uint32_t absval;
 # define ABSPRIFMT PRIx32
@@ -458,13 +498,12 @@ generic_abs (struct output_data *d, const char *absstring
   uint64_t absval;
 # define ABSPRIFMT PRIx64
   if (abslen == 8)
-    absval = read_8ubyte_unaligned (&d->data[1]);
+    absval = read_8ubyte_unaligned (&data[1]);
   else
 #endif
-    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,
+    absval = read_4ubyte_unaligned (&data[1]);
+  size_t avail = bufsize - *bufcntp;
+  int needed = snprintf (&bufp[*bufcntp], avail, "%s0x%" ABSPRIFMT,
                         absstring, absval);
   if ((size_t) needed > avail)
     return needed - avail;
@@ -472,11 +511,25 @@ generic_abs (struct output_data *d, const char *absstring
   return 0;
 }
 
-
 static int
-FCT_absval (struct output_data *d)
+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)))
 {
-  return generic_abs (d, "$"
+  return generic_abs (prefixes, opoff1, bufp,
+                     bufcntp, bufsize, data, param_start, end, symcb,
+                     symcbarg, "$"
 #ifdef X86_64
                      , 4
 #endif
@@ -484,9 +537,24 @@ FCT_absval (struct output_data *d)
 }
 
 static int
-FCT_abs (struct output_data *d)
+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)))
 {
-  return generic_abs (d, ""
+  return generic_abs (prefixes, opoff1, bufp,
+                     bufcntp, bufsize, data, param_start, end, symcb,
+                     symcbarg, ""
 #ifdef X86_64
                      , 8
 #endif
@@ -494,13 +562,22 @@ FCT_abs (struct output_data *d)
 }
 
 static int
-FCT_ax (struct output_data *d)
+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)))
 {
-  int is_16bit = (*d->prefixes & has_data16) != 0;
-
-  size_t *bufcntp = d->bufcntp;
-  char *bufp = d->bufp;
-  size_t bufsize = d->bufsize;
+  int is_16bit = (*prefixes & has_data16) != 0;
 
   if (*bufcntp + 4 - is_16bit > bufsize)
     return *bufcntp + 4 - is_16bit - bufsize;
@@ -514,16 +591,25 @@ FCT_ax (struct output_data *d)
   return 0;
 }
 
-
 static int
-FCT_ax$w (struct output_data *d)
+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)))
 {
-  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 ((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 (*bufcntp + 3 > bufsize)
     return *bufcntp + 3 - bufsize;
@@ -535,95 +621,119 @@ FCT_ax$w (struct output_data *d)
   return 0;
 }
 
-
 static int
-FCT_ccc (struct output_data *d)
+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)))
 {
-  if (*d->prefixes & has_data16)
+  if (*prefixes & has_data16)
     return -1;
 
-  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);
+  assert (opoff1 % 8 == 2);
+  size_t avail = bufsize - *bufcntp;
+  int needed = snprintf (&bufp[*bufcntp], avail, "%%cr%" PRIx32,
+                        (uint32_t) (data[opoff1 / 8] >> 3) & 7);
   if ((size_t) needed > avail)
     return needed - avail;
   *bufcntp += needed;
   return 0;
 }
 
-
 static int
-FCT_ddd (struct output_data *d)
+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)))
 {
-  if (*d->prefixes & has_data16)
+  if (*prefixes & has_data16)
     return -1;
 
-  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);
+  assert (opoff1 % 8 == 2);
+  size_t avail = bufsize - *bufcntp;
+  int needed = snprintf (&bufp[*bufcntp], avail, "%%db%" PRIx32,
+                        (uint32_t) (data[opoff1 / 8] >> 3) & 7);
   if ((size_t) needed > avail)
     return needed - avail;
   *bufcntp += needed;
   return 0;
 }
 
-
 static int
-FCT_disp8 (struct output_data *d)
+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)))
 {
-  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));
+  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));
   if ((size_t) needed > avail)
     return needed - avail;
   *bufcntp += needed;
   return 0;
 }
 
-
 static int
 __attribute__ ((noinline))
-FCT_ds_xx (struct output_data *d, const char *reg)
+FCT_ds_xx (const char *reg,
+          int *prefixes __attribute__ ((unused)),
+          char *bufp __attribute__ ((unused)),
+          size_t *bufcntp __attribute__ ((unused)),
+          size_t bufsize __attribute__ ((unused)))
 {
-  int prefix = *d->prefixes & SEGMENT_PREFIXES;
+  int prefix = *prefixes & SEGMENT_PREFIXES;
 
   if (prefix == 0)
-    *d->prefixes |= prefix = has_ds;
+    prefix = has_ds;
   /* Make sure only one bit is set.  */
   else if ((prefix - 1) & prefix)
     return -1;
+  else
+    *prefixes ^= prefix;
 
-  int r = data_prefix (d);
-
-  assert ((*d->prefixes & prefix) == 0);
-
+  int r = data_prefix (&prefix, bufp, bufcntp, bufsize);
   if (r != 0)
     return r;
 
-  size_t *bufcntp = d->bufcntp;
-  size_t avail = d->bufsize - *bufcntp;
-  int needed = snprintf (&d->bufp[*bufcntp], avail, "(%%%s%s)",
+  size_t avail = bufsize - *bufcntp;
+  int needed = snprintf (&bufp[*bufcntp], avail, "(%%%s%s)",
 #ifdef X86_64
-                        *d->prefixes & idx_addr16 ? "e" : "r",
+                        *prefixes & idx_addr16 ? "e" : "r",
 #else
-                        *d->prefixes & idx_addr16 ? "" : "e",
+                        *prefixes & idx_addr16 ? "" : "e",
 #endif
                         reg);
   if ((size_t) needed > avail)
@@ -633,46 +743,91 @@ FCT_ds_xx (struct output_data *d, const char *reg)
   return 0;
 }
 
-
 static int
-FCT_ds_bx (struct output_data *d)
+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)))
 {
-  return FCT_ds_xx (d, "bx");
+  return FCT_ds_xx ("bx", prefixes, bufp, bufcntp, bufsize);
 }
 
-
 static int
-FCT_ds_si (struct output_data *d)
+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)))
 {
-  return FCT_ds_xx (d, "si");
+  return FCT_ds_xx ("si", prefixes, bufp, bufcntp, bufsize);
 }
 
-
 static int
-FCT_dx (struct output_data *d)
+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)))
 {
-  size_t *bufcntp = d->bufcntp;
-
-  if (*bufcntp + 7 > d->bufsize)
-    return *bufcntp + 7 - d->bufsize;
+  if (*bufcntp + 7 > bufsize)
+    return *bufcntp + 7 - bufsize;
 
-  memcpy (&d->bufp[*bufcntp], "(%dx)", 5);
+  memcpy (&bufp[*bufcntp], "(%dx)", 5);
   *bufcntp += 5;
 
   return 0;
 }
 
-
 static int
-FCT_es_di (struct output_data *d)
+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)))
 {
-  size_t *bufcntp = d->bufcntp;
-  size_t avail = d->bufsize - *bufcntp;
-  int needed = snprintf (&d->bufp[*bufcntp], avail, "%%es:(%%%sdi)",
+  size_t avail = bufsize - *bufcntp;
+  int needed = snprintf (&bufp[*bufcntp], avail, "%%es:(%%%sdi)",
 #ifdef X86_64
-                        *d->prefixes & idx_addr16 ? "e" : "r"
+                        *prefixes & idx_addr16 ? "e" : "r"
 #else
-                        *d->prefixes & idx_addr16 ? "" : "e"
+                        *prefixes & idx_addr16 ? "" : "e"
 #endif
                         );
   if ((size_t) needed > avail)
@@ -682,26 +837,37 @@ FCT_es_di (struct output_data *d)
   return 0;
 }
 
-
 static int
-FCT_imm (struct output_data *d)
+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)))
 {
-  size_t *bufcntp = d->bufcntp;
-  size_t avail = d->bufsize - *bufcntp;
+  size_t avail = bufsize - *bufcntp;
   int needed;
-  if (*d->prefixes & has_data16)
+  if (*prefixes & has_data16)
     {
-      if (*d->param_start + 2 > d->end)
+      if (*param_start + 2 > end)
        return -1;
-      uint16_t word = read_2ubyte_unaligned_inc (*d->param_start);
-      needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx16, word);
+      uint16_t word = read_2ubyte_unaligned_inc (*param_start);
+      needed = snprintf (&bufp[*bufcntp], avail, "$0x%" PRIx16, word);
     }
   else
     {
-      if (*d->param_start + 4 > d->end)
+      if (*param_start + 4 > end)
        return -1;
-      uint32_t word = read_4ubyte_unaligned_inc (*d->param_start);
-      needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx32, word);
+      uint32_t word = read_4ubyte_unaligned_inc (*param_start);
+      needed = snprintf (&bufp[*bufcntp], avail, "$0x%" PRIx32, word);
     }
   if ((size_t) needed > avail)
     return (size_t) needed - avail;
@@ -709,39 +875,58 @@ FCT_imm (struct output_data *d)
   return 0;
 }
 
-
 static int
-FCT_imm$w (struct output_data *d)
+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)))
 {
-  if ((d->data[d->opoff2 / 8] & (1 << (7 - (d->opoff2 & 7)))) != 0)
-    return FCT_imm (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);
 
-  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);
+  size_t avail = bufsize - *bufcntp;
+  uint_fast8_t word = *(*param_start)++;
+  int needed = snprintf (&bufp[*bufcntp], avail, "$0x%" PRIxFAST8, word);
   if ((size_t) needed > avail)
     return (size_t) needed - avail;
   *bufcntp += needed;
   return 0;
 }
 
-
 static int
-FCT_imms (struct output_data *d)
+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)))
 {
-  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)++;
+  size_t avail = bufsize - *bufcntp;
+  int8_t byte = *(*param_start)++;
 #ifdef X86_64
-  int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx64,
+  int needed = snprintf (&bufp[*bufcntp], avail, "$0x%" PRIx64,
                         (int64_t) byte);
 #else
-  int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx32,
+  int needed = snprintf (&bufp[*bufcntp], avail, "$0x%" PRIx32,
                         (int32_t) byte);
 #endif
   if ((size_t) needed > avail)
@@ -750,26 +935,39 @@ FCT_imms (struct output_data *d)
   return 0;
 }
 
-
 static int
-FCT_imm$s (struct output_data *d)
+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)))
 {
-  uint_fast8_t opcode = d->data[d->opoff2 / 8];
-  size_t *bufcntp = d->bufcntp;
-  size_t avail = d->bufsize - *bufcntp;
+  uint_fast8_t opcode = data[opoff2 / 8];
+  size_t avail = bufsize - *bufcntp;
   if ((opcode & 2) != 0)
-    return FCT_imms (d);
+    return FCT_imms (addr, prefixes, op1str, opoff1, opoff2, opoff3, bufp,
+                    bufcntp, bufsize, data, param_start, end, symcb,
+                    symcbarg);
 
-  if ((*d->prefixes & has_data16) == 0)
+  if ((*prefixes & has_data16) == 0)
     {
-      if (*d->param_start + 4 > d->end)
+      if (*param_start + 4 > end)
        return -1;
-      int32_t word = read_4sbyte_unaligned_inc (*d->param_start);
+      int32_t word = read_4sbyte_unaligned_inc (*param_start);
 #ifdef X86_64
-      int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx64,
+      int needed = snprintf (&bufp[*bufcntp], avail, "$0x%" PRIx64,
                             (int64_t) word);
 #else
-      int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx32, word);
+      int needed = snprintf (&bufp[*bufcntp], avail, "$0x%" PRIx32, word);
 #endif
       if ((size_t) needed > avail)
        return (size_t) needed - avail;
@@ -777,10 +975,10 @@ FCT_imm$s (struct output_data *d)
     }
   else
     {
-      if (*d->param_start + 2 > d->end)
+      if (*param_start + 2 > end)
        return -1;
-      uint16_t word = read_2ubyte_unaligned_inc (*d->param_start);
-      int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx16, word);
+      uint16_t word = read_2ubyte_unaligned_inc (*param_start);
+      int needed = snprintf (&bufp[*bufcntp], avail, "$0x%" PRIx16, word);
       if ((size_t) needed > avail)
        return (size_t) needed - avail;
       *bufcntp += needed;
@@ -788,32 +986,52 @@ FCT_imm$s (struct output_data *d)
   return 0;
 }
 
-
 static int
-FCT_imm16 (struct output_data *d)
+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)))
 {
-  if (*d->param_start + 2 > d->end)
+  if (*param_start + 2 > end)
     return -1;
-  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);
+  uint16_t word = read_2ubyte_unaligned_inc (*param_start);
+  size_t avail = bufsize - *bufcntp;
+  int needed = snprintf (&bufp[*bufcntp], avail, "$0x%" PRIx16, word);
   if ((size_t) needed > avail)
     return (size_t) needed - avail;
   *bufcntp += needed;
   return 0;
 }
 
-
 static int
-FCT_imms8 (struct output_data *d)
+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)))
 {
-  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,
+  size_t avail = bufsize - *bufcntp;
+  int_fast8_t byte = *(*param_start)++;
+  int needed = snprintf (&bufp[*bufcntp], avail, "$0x%" PRIx32,
                         (int32_t) byte);
   if ((size_t) needed > avail)
     return (size_t) needed - avail;
@@ -821,16 +1039,27 @@ FCT_imms8 (struct output_data *d)
   return 0;
 }
 
-
 static int
-FCT_imm8 (struct output_data *d)
+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)))
 {
-  size_t *bufcntp = d->bufcntp;
-  size_t avail = d->bufsize - *bufcntp;
-  if (*d->param_start >= d->end)
+  size_t avail = bufsize - *bufcntp;
+  if (*param_start >= end)
     return -1;
-  uint_fast8_t byte = *(*d->param_start)++;
-  int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx32,
+  uint_fast8_t byte = *(*param_start)++;
+  int needed = snprintf (&bufp[*bufcntp], avail, "$0x%" PRIx32,
                         (uint32_t) byte);
   if ((size_t) needed > avail)
     return (size_t) needed - avail;
@@ -838,23 +1067,32 @@ FCT_imm8 (struct output_data *d)
   return 0;
 }
 
-
 static int
-FCT_rel (struct output_data *d)
+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)))
 {
-  size_t *bufcntp = d->bufcntp;
-  size_t avail = d->bufsize - *bufcntp;
-  if (*d->param_start + 4 > d->end)
+  size_t avail = bufsize - *bufcntp;
+  if (*param_start + 4 > end)
     return -1;
-  int32_t rel = read_4sbyte_unaligned_inc (*d->param_start);
+  int32_t rel = read_4sbyte_unaligned_inc (*param_start);
 #ifdef X86_64
-  int needed = snprintf (&d->bufp[*bufcntp], avail, "0x%" PRIx64,
-                        (uint64_t) (d->addr + rel
-                                    + (*d->param_start - d->data)));
+  int needed = snprintf (&bufp[*bufcntp], avail, "0x%" PRIx64,
+                        (uint64_t) (addr + rel + (*param_start - data)));
 #else
-  int needed = snprintf (&d->bufp[*bufcntp], avail, "0x%" PRIx32,
-                        (uint32_t) (d->addr + rel
-                                    + (*d->param_start - d->data)));
+  int needed = snprintf (&bufp[*bufcntp], avail, "0x%" PRIx32,
+                        (uint32_t) (addr + rel + (*param_start - data)));
 #endif
   if ((size_t) needed > avail)
     return (size_t) needed - avail;
@@ -862,16 +1100,27 @@ FCT_rel (struct output_data *d)
   return 0;
 }
 
-
 static int
-FCT_mmxreg (struct output_data *d)
+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)))
 {
-  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);
+  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);
   if ((size_t) needed > avail)
     return needed - avail;
   *bufcntp += needed;
@@ -880,30 +1129,40 @@ FCT_mmxreg (struct output_data *d)
 
 
 static int
-FCT_mod$r_m (struct output_data *d)
+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)))
 {
-  assert (d->opoff1 % 8 == 0);
-  uint_fast8_t modrm = d->data[d->opoff1 / 8];
+  assert (opoff1 % 8 == 0);
+  uint_fast8_t modrm = data[opoff1 / 8];
   if ((modrm & 0xc0) == 0xc0)
     {
-      int prefixes = *d->prefixes;
-      if (prefixes & has_addr16)
+      if (*prefixes & has_addr16)
        return -1;
 
-      int is_16bit = (prefixes & has_data16) != 0;
+      int is_16bit = (*prefixes & has_data16) != 0;
 
-      size_t *bufcntp = d->bufcntp;
-      char *bufp = d->bufp;
-      if (*bufcntp + 5 - is_16bit > d->bufsize)
-       return *bufcntp + 5 - is_16bit - d->bufsize;
+      if (*bufcntp + 5 - is_16bit > bufsize)
+       return *bufcntp + 5 - is_16bit - 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
@@ -911,7 +1170,7 @@ FCT_mod$r_m (struct output_data *d)
        {
          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
        }
@@ -919,32 +1178,52 @@ FCT_mod$r_m (struct output_data *d)
       return 0;
     }
 
-  return general_mod$r_m (d);
+  return general_mod$r_m (addr, prefixes, op1str, opoff1, opoff2, opoff3, bufp,
+                         bufcntp, bufsize, data, param_start, end,
+                         symcb, symcbarg);
 }
 
 
 #ifndef X86_64
 static int
-FCT_moda$r_m (struct output_data *d)
+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)))
 {
-  assert (d->opoff1 % 8 == 0);
-  uint_fast8_t modrm = d->data[d->opoff1 / 8];
+  int r = data_prefix (prefixes, bufp, bufcntp, bufsize);
+  if (r != 0)
+    return r;
+
+  assert (opoff1 % 8 == 0);
+  uint_fast8_t modrm = data[opoff1 / 8];
   if ((modrm & 0xc0) == 0xc0)
     {
-      if (*d->prefixes & has_addr16)
+      if (*prefixes & has_addr16)
        return -1;
 
-      size_t *bufcntp = d->bufcntp;
-      if (*bufcntp + 3 > d->bufsize)
-       return *bufcntp + 3 - d->bufsize;
+      if (*bufcntp + 3 > bufsize)
+       return *bufcntp + 3 - bufsize;
 
-      memcpy (&d->bufp[*bufcntp], "???", 3);
+      memcpy (&bufp[*bufcntp], "???", 3);
       *bufcntp += 3;
 
       return 0;
     }
 
-  return general_mod$r_m (d);
+  return general_mod$r_m (addr, prefixes, op1str, opoff1, opoff2, opoff3, bufp,
+                         bufcntp, bufsize, data, param_start, end,
+                         symcb, symcbarg);
 }
 #endif
 
@@ -957,34 +1236,45 @@ static const char rex_8bit[8][3] =
   };
 #endif
 
-
 static int
-FCT_mod$r_m$w (struct output_data *d)
+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)))
 {
-  assert (d->opoff1 % 8 == 0);
-  const uint8_t *data = d->data;
-  uint_fast8_t modrm = data[d->opoff1 / 8];
+  int r = data_prefix (prefixes, bufp, bufcntp, bufsize);
+  if (r != 0)
+    return r;
+
+  assert (opoff1 % 8 == 0);
+  uint_fast8_t modrm = data[opoff1 / 8];
   if ((modrm & 0xc0) == 0xc0)
     {
-      int prefixes = *d->prefixes;
-
-      if (prefixes & has_addr16)
+      if (*prefixes & has_addr16)
        return -1;
 
-      size_t *bufcntp = d->bufcntp;
-      char *bufp = d->bufp;
-      if (*bufcntp + 5 > d->bufsize)
-       return *bufcntp + 5 - d->bufsize;
+      if (*bufcntp + 5 > bufsize)
+       return *bufcntp + 5 - bufsize;
 
-      if ((data[d->opoff3 / 8] & (1 << (7 - (d->opoff3 & 7)))) == 0)
+      if ((data[opoff3 / 8] & (1 << (7 - (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, d->bufsize - *bufcntp,
+             if (*prefixes & has_rex_r)
+               *bufcntp += snprintf (bufp + *bufcntp, bufsize - *bufcntp,
                                      "r%db", 8 + (modrm & 7));
              else
                {
@@ -1002,16 +1292,16 @@ FCT_mod$r_m$w (struct output_data *d)
        }
       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
@@ -1019,7 +1309,7 @@ FCT_mod$r_m$w (struct output_data *d)
            {
              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
            }
@@ -1028,250 +1318,361 @@ FCT_mod$r_m$w (struct output_data *d)
       return 0;
     }
 
-  return general_mod$r_m (d);
+  return general_mod$r_m (addr, prefixes, op1str, opoff1, opoff2, opoff3, bufp,
+                         bufcntp, bufsize, data, param_start, end,
+                         symcb, symcbarg);
 }
 
 
 static int
-FCT_mod$8r_m (struct output_data *d)
+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)))
 {
-  assert (d->opoff1 % 8 == 0);
-  uint_fast8_t modrm = d->data[d->opoff1 / 8];
+  assert (opoff1 % 8 == 0);
+  uint_fast8_t modrm = data[opoff1 / 8];
   if ((modrm & 0xc0) == 0xc0)
     {
-      size_t *bufcntp = d->bufcntp;
-      char *bufp = d->bufp;
-      if (*bufcntp + 3 > d->bufsize)
-       return *bufcntp + 3 - d->bufsize;
+      if (*bufcntp + 3 > bufsize)
+       return *bufcntp + 3 - bufsize;
       bufp[(*bufcntp)++] = '%';
       bufp[(*bufcntp)++] = "acdb"[modrm & 3];
       bufp[(*bufcntp)++] = "lh"[(modrm & 4) >> 2];
       return 0;
     }
 
-  return general_mod$r_m (d);
+  return general_mod$r_m (addr, prefixes, op1str, opoff1, opoff2, opoff3, bufp,
+                         bufcntp, bufsize, data, param_start, end,
+                         symcb, symcbarg);
 }
 
-
 static int
-FCT_mod$16r_m (struct output_data *d)
+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)))
 {
-  assert (d->opoff1 % 8 == 0);
-  uint_fast8_t modrm = d->data[d->opoff1 / 8];
+  assert (opoff1 % 8 == 0);
+  uint_fast8_t modrm = data[opoff1 / 8];
   if ((modrm & 0xc0) == 0xc0)
     {
-      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);
+      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);
       *bufcntp += 2;
       return 0;
     }
 
-  return general_mod$r_m (d);
+  return general_mod$r_m (addr, prefixes, op1str, opoff1, opoff2, opoff3, bufp,
+                         bufcntp, bufsize, data, param_start, end,
+                         symcb, symcbarg);
 }
 
-
 #ifdef X86_64
 static int
-FCT_mod$64r_m (struct output_data *d)
+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)))
 {
-  assert (d->opoff1 % 8 == 0);
-  uint_fast8_t modrm = d->data[d->opoff1 / 8];
+  assert (opoff1 % 8 == 0);
+  uint_fast8_t modrm = data[opoff1 / 8];
   if ((modrm & 0xc0) == 0xc0)
     {
-      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];
+      uint_fast8_t byte = data[opoff1 / 8] & 7;
+      if (*bufcntp + 4 > bufsize)
+       return *bufcntp + 4 - bufsize;
+      char *cp = &bufp[*bufcntp];
       *cp++ = '%';
-      cp = stpcpy (cp,
-                  (*d->prefixes & has_rex_b) ? hiregs[byte] : aregs[byte]);
-      *bufcntp = cp - d->bufp;
+      cp = stpcpy (cp, (*prefixes & has_rex_b) ? hiregs[byte] : aregs[byte]);
+      *bufcntp = cp - bufp;
       return 0;
     }
 
-  return general_mod$r_m (d);
+  return general_mod$r_m (addr, prefixes, op1str, opoff1, opoff2, opoff3, bufp,
+                         bufcntp, bufsize, data, param_start, end,
+                         symcb, symcbarg);
 }
 #else
 static typeof (FCT_mod$r_m) FCT_mod$64r_m __attribute__ ((alias ("FCT_mod$r_m")));
 #endif
 
-
 static int
-FCT_reg (struct output_data *d)
+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)))
 {
-  uint_fast8_t byte = d->data[d->opoff1 / 8];
-  assert (d->opoff1 % 8 + 3 <= 8);
-  byte >>= 8 - (d->opoff1 % 8 + 3);
+  uint_fast8_t byte = data[opoff1 / 8];
+  assert (opoff1 % 8 + 3 <= 8);
+  byte >>= 8 - (opoff1 % 8 + 3);
   byte &= 7;
-  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)++] = '%';
+  int is_16bit = (*prefixes & has_data16) != 0;
+  if (*bufcntp + 5 > bufsize)
+    return *bufcntp + 5 - bufsize;
+  bufp[(*bufcntp)++] = '%';
 #ifdef X86_64
-  if ((*d->prefixes & has_rex_r) != 0 && !is_16bit)
+  if ((*prefixes & has_rex_r) != 0 && !is_16bit)
     {
-      *bufcntp += snprintf (&d->bufp[*bufcntp], d->bufsize - *bufcntp, "r%d",
+      *bufcntp += snprintf (&bufp[*bufcntp], bufsize - *bufcntp, "r%d",
                            8 + byte);
-      if ((*d->prefixes & has_rex_w) == 0)
-       d->bufp[(*bufcntp)++] = 'd';
+      if ((*prefixes & has_rex_w) == 0)
+       bufp[(*bufcntp)++] = 'd';
     }
   else
 #endif
     {
-      memcpy (&d->bufp[*bufcntp], dregs[byte] + is_16bit, 3 - is_16bit);
+      memcpy (&bufp[*bufcntp], dregs[byte] + is_16bit, 3 - is_16bit);
 #ifdef X86_64
-      if ((*d->prefixes & has_rex_w) != 0 && !is_16bit)
-       d->bufp[*bufcntp] = 'r';
+      if ((*prefixes & has_rex_w) != 0 && !is_16bit)
+       bufp[*bufcntp] = 'r';
 #endif
       *bufcntp += 3 - is_16bit;
     }
   return 0;
 }
 
-
 static int
-FCT_reg64 (struct output_data *d)
+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)))
 {
-  uint_fast8_t byte = d->data[d->opoff1 / 8];
-  assert (d->opoff1 % 8 + 3 <= 8);
-  byte >>= 8 - (d->opoff1 % 8 + 3);
+  uint_fast8_t byte = data[opoff1 / 8];
+  assert (opoff1 % 8 + 3 <= 8);
+  byte >>= 8 - (opoff1 % 8 + 3);
   byte &= 7;
-  if ((*d->prefixes & has_data16) != 0)
+  if ((*prefixes & has_data16) != 0)
     return -1;
-  size_t *bufcntp = d->bufcntp;
-  if (*bufcntp + 5 > d->bufsize)
-    return *bufcntp + 5 - d->bufsize;
-  d->bufp[(*bufcntp)++] = '%';
+  if (*bufcntp + 5 > bufsize)
+    return *bufcntp + 5 - bufsize;
+  bufp[(*bufcntp)++] = '%';
 #ifdef X86_64
-  if ((*d->prefixes & has_rex_r) != 0)
+  if ((*prefixes & has_rex_r) != 0)
     {
-      *bufcntp += snprintf (&d->bufp[*bufcntp], d->bufsize - *bufcntp, "r%d",
+      *bufcntp += snprintf (&bufp[*bufcntp], bufsize - *bufcntp, "r%d",
                            8 + byte);
-      if ((*d->prefixes & has_rex_w) == 0)
-       d->bufp[(*bufcntp)++] = 'd';
+      if ((*prefixes & has_rex_w) == 0)
+       bufp[(*bufcntp)++] = 'd';
     }
   else
 #endif
     {
-      memcpy (&d->bufp[*bufcntp], aregs[byte], 3);
+      memcpy (&bufp[*bufcntp], aregs[byte], 3);
       *bufcntp += 3;
     }
   return 0;
 }
 
-
 static int
-FCT_reg$w (struct output_data *d)
+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)))
 {
-  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);
+  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);
   byte &= 7;
 
-  size_t *bufcntp = d->bufcntp;
-  if (*bufcntp + 4 > d->bufsize)
-    return *bufcntp + 4 - d->bufsize;
+  if (*bufcntp + 4 > bufsize)
+    return *bufcntp + 4 - bufsize;
 
-  d->bufp[(*bufcntp)++] = '%';
+  bufp[(*bufcntp)++] = '%';
 
 #ifdef X86_64
-  if (*d->prefixes & has_rex)
+  if (*prefixes & has_rex)
     {
-      if (*d->prefixes & has_rex_r)
-       *bufcntp += snprintf (d->bufp + *bufcntp, d->bufsize - *bufcntp,
+      if (*prefixes & has_rex_r)
+       *bufcntp += snprintf (bufp + *bufcntp, bufsize - *bufcntp,
                              "r%db", 8 + byte);
       else
        {
-         char* cp = stpcpy (d->bufp + *bufcntp, rex_8bit[byte]);
+         char* cp = stpcpy (bufp + *bufcntp, rex_8bit[byte]);
          *cp++ = 'l';
-         *bufcntp = cp - d->bufp;
+         *bufcntp = cp - bufp;
        }
     }
   else
 #endif
     {
-      d->bufp[(*bufcntp)++] = "acdb"[byte & 3];
-      d->bufp[(*bufcntp)++] = "lh"[byte >> 2];
+      bufp[(*bufcntp)++] = "acdb"[byte & 3];
+      bufp[(*bufcntp)++] = "lh"[byte >> 2];
     }
   return 0;
 }
 
-
 static int
-FCT_freg (struct output_data *d)
+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)))
 {
-  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));
+  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));
   if ((size_t) needed > avail)
     return (size_t) needed - avail;
   *bufcntp += needed;
   return 0;
 }
 
-
 #ifndef X86_64
 static int
-FCT_reg16 (struct output_data *d)
+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)))
 {
-  if (*d->prefixes & has_data16)
+  if (*prefixes & has_data16)
     return -1;
 
-  *d->prefixes |= has_data16;
-  return FCT_reg (d);
+  *prefixes |= has_data16;
+  return FCT_reg (addr, prefixes, op1str, opoff1, opoff2, opoff3, bufp,
+                 bufcntp, bufsize, data, param_start, end, symcb, symcbarg);
 }
 #endif
 
-
 static int
-FCT_sel (struct output_data *d)
+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)))
 {
-  assert (d->opoff1 % 8 == 0);
-  assert (d->opoff1 / 8 == 5);
-  if (*d->param_start + 2 > d->end)
+  assert (opoff1 % 8 == 0);
+  assert (opoff1 / 8 == 5);
+  if (*param_start + 2 > end)
     return -1;
-  *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);
+  *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);
   if ((size_t) needed > avail)
     return needed - avail;
   *bufcntp += needed;
   return 0;
 }
 
-
 static int
-FCT_sreg2 (struct output_data *d)
+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)))
 {
-  uint_fast8_t byte = d->data[d->opoff1 / 8];
-  assert (d->opoff1 % 8 + 3 <= 8);
-  byte >>= 8 - (d->opoff1 % 8 + 2);
+  uint_fast8_t byte = data[opoff1 / 8];
+  assert (opoff1 % 8 + 3 <= 8);
+  byte >>= 8 - (opoff1 % 8 + 2);
 
-  size_t *bufcntp = d->bufcntp;
-  char *bufp = d->bufp;
-  if (*bufcntp + 3 > d->bufsize)
-    return *bufcntp + 3 - d->bufsize;
+  if (*bufcntp + 3 > bufsize)
+    return *bufcntp + 3 - bufsize;
 
   bufp[(*bufcntp)++] = '%';
   bufp[(*bufcntp)++] = "ecsd"[byte & 3];
@@ -1280,21 +1681,31 @@ FCT_sreg2 (struct output_data *d)
   return 0;
 }
 
-
 static int
-FCT_sreg3 (struct output_data *d)
+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)))
 {
-  uint_fast8_t byte = d->data[d->opoff1 / 8];
-  assert (d->opoff1 % 8 + 4 <= 8);
-  byte >>= 8 - (d->opoff1 % 8 + 3);
+  uint_fast8_t byte = data[opoff1 / 8];
+  assert (opoff1 % 8 + 4 <= 8);
+  byte >>= 8 - (opoff1 % 8 + 3);
 
   if ((byte & 7) >= 6)
     return -1;
 
-  size_t *bufcntp = d->bufcntp;
-  char *bufp = d->bufp;
-  if (*bufcntp + 3 > d->bufsize)
-    return *bufcntp + 3 - d->bufsize;
+  if (*bufcntp + 3 > bufsize)
+    return *bufcntp + 3 - bufsize;
 
   bufp[(*bufcntp)++] = '%';
   bufp[(*bufcntp)++] = "ecsdfg"[byte & 7];
@@ -1303,24 +1714,46 @@ FCT_sreg3 (struct output_data *d)
   return 0;
 }
 
-
 static int
-FCT_string (struct output_data *d __attribute__ ((unused)))
+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)))
 {
   return 0;
 }
 
-
 static int
-FCT_xmmreg (struct output_data *d)
+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)))
 {
-  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);
+  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);
   if ((size_t) needed > avail)
     return needed - avail;
   *bufcntp += needed;
index 0f3a01d47f6bd5e242cb99ca1029e3959ca87988..ecdbfb6543681206a8c9028bc9cc9fe5c35d1c85 100644 (file)
@@ -184,25 +184,6 @@ 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
@@ -423,7 +404,6 @@ i386_disasm (const uint8_t **startp, const uint8_t *end, GElf_Addr addr,
                  break;
                default:
                  /* Cannot happen.  */
-                 puts ("unknown prefix");
                  abort ();
                }
              data = begin + 1;
@@ -470,20 +450,6 @@ 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 = &param_start,
-             .end = end,
-             .symcb = symcb,
-             .symcbarg = symcbarg
-           };
-
          unsigned long string_end_idx = 0;
          while (*fmt != '\0')
            {
@@ -707,14 +673,21 @@ 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]);
 
-                     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);
+                     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, &param_start,
+                                                          end,
+                                                          symcb, symcbarg);
                      if (r < 0)
                        goto not;
                      if (r > 0)
@@ -725,17 +698,28 @@ 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
 
-                     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);
+                     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, &param_start,
+                                                          end,
+                                                          symcb, symcbarg);
                      if (r < 0)
                        goto not;
                      if (r > 0)
@@ -746,21 +730,36 @@ 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
 
-                     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);
+                     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
 #ifdef OFF3_3_BITS
-                     output_data.opoff3 = (instrtab[cnt].off3_3
-                                           + OFF3_3_BIAS - opoff);
+                                                          instrtab[cnt].off3_3 + OFF3_3_BIAS - opoff,
 #else
-                     output_data.opoff3 = 0;
+                                                          0,
 #endif
-                     int r = op3_fct[instrtab[cnt].fct3] (&output_data);
+                                                          buf, &bufcnt, bufsize,
+                                                          data, &param_start,
+                                                          end,
+                                                          symcb, symcbarg);
                      if (r < 0)
                        goto not;
                      if (r > 0)
index b7cd62851a72d003dc2d585af2ee4430169f02f1..3b4162426ca64550bee18112a7cbdd72f1aa4738 100644 (file)
@@ -1,3 +1,9 @@
+2008-01-08  Roland McGrath  <roland@redhat.com>
+
+       * Makefile.am (euinclude): Variable removed.
+       (pkginclude_HEADERS): Set this instead of euinclude_HEADERS.
+       (libdw.so): Pass -Wl,--enable-new-dtags,-rpath,$(pkglibdir).
+
 2007-10-17  Roland McGrath  <roland@redhat.com>
 
        * libdw.h (__deprecated_attribute__): New macro.
index 62057dc9057cc70aaa53e1911dbd405862747b1b..69ce526c6aeb3d43698dbb414dc31cead7c17180 100644 (file)
@@ -1,6 +1,6 @@
 ## Process this file with automake to create Makefile.in
 ##
-## Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Red Hat, Inc.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Red Hat, Inc.
 ## This file is part of Red Hat elfutils.
 ##
 ## Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -47,8 +47,7 @@ noinst_PROGRAMS = $(noinst_LIBRARIES:_pic.a=.so)
 endif
 
 include_HEADERS = dwarf.h
-euincludedir = ${includedir}/elfutils
-euinclude_HEADERS = libdw.h
+pkginclude_HEADERS = libdw.h
 
 libdw_a_SOURCES = dwarf_begin.c dwarf_begin_elf.c dwarf_end.c dwarf_getelf.c \
                  dwarf_getpubnames.c dwarf_getabbrev.c dwarf_tag.c \
@@ -94,7 +93,10 @@ libdw_so_SOURCES =
 libdw.so: $(srcdir)/libdw.map libdw_pic.a \
          ../libdwfl/libdwfl_pic.a ../libebl/libebl.a \
          ../libelf/libelf.so
+# The rpath is necessary for libebl because its $ORIGIN use will
+# not fly in a setuid executable that links in libdw.
        $(LINK) -shared -o $@ -Wl,--soname,$@.$(VERSION),-z,defs \
+               -Wl,--enable-new-dtags,-rpath,$(pkglibdir) \
                -Wl,--version-script,$<,--no-undefined \
                -Wl,--whole-archive $(filter-out $<,$^) -Wl,--no-whole-archive\
                -ldl
index ea6e4e0197eb053207c781a0a627082d96caeac1..f878c0d6844348f456b64fc365f6edaf9bcd5be3 100644 (file)
@@ -1,3 +1,8 @@
+2008-01-08  Roland McGrath  <roland@redhat.com>
+
+       * Makefile.am (euinclude): Variable removed.
+       (pkginclude_HEADERS): Set this instead of euinclude_HEADERS.
+
 2007-10-23  Roland McGrath  <roland@redhat.com>
 
        * linux-kernel-modules.c (report_kernel_archive): Reorder the kernel
index 83834cdba3ee4959a30ccca240090fbd96ab7d38..0371993774628f11bb09d4f867543f6d86244339 100644 (file)
@@ -2,7 +2,7 @@
 ##
 ## Process this file with automake to create Makefile.in
 ##
-## Copyright (C) 2005, 2006, 2007 Red Hat, Inc.
+## Copyright (C) 2005, 2006, 2007, 2008 Red Hat, Inc.
 ## This file is part of Red Hat elfutils.
 ##
 ## Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -45,8 +45,7 @@ if !MUDFLAP
 noinst_LIBRARIES += libdwfl_pic.a
 endif
 
-euincludedir = ${includedir}/elfutils
-euinclude_HEADERS = libdwfl.h
+pkginclude_HEADERS = libdwfl.h
 
 libdwfl_a_SOURCES = dwfl_begin.c dwfl_end.c dwfl_error.c dwfl_version.c \
                    dwfl_module.c dwfl_report_elf.c relocate.c \
index daa78e4cf1feed54406e7ed86e8193fea1a2ca1b..df73af01dbb5dd6ceff6f4415560f154f0daf7f4 100644 (file)
@@ -1,3 +1,12 @@
+2008-01-08  Roland McGrath  <roland@redhat.com>
+
+       * Makefile.am (euinclude): Variable removed.
+       (pkginclude_HEADERS): Set this instead of euinclude_HEADERS.
+
+2008-01-03  Roland McGrath  <roland@redhat.com>
+
+       * common.h: Add __attribute__ ((unused)) to static functions.
+
 2007-12-20  Ulrich Drepper  <drepper@redhat.com>
 
        * Makefile.am (libelf_a_SOURCES): Add elf_scnshndx.
index 3cb858df87ab77eea3389576f25fa5d1573f7df2..5bbb42206e9b8c4b3fefb4403519c96c230c50f4 100644 (file)
@@ -1,6 +1,6 @@
 ## Process this file with automake to create Makefile.in
 ##
-## Copyright (C) 1996-2006, 2007 Red Hat, Inc.
+## Copyright (C) 1996-2006, 2007, 2008 Red Hat, Inc.
 ## This file is part of Red Hat elfutils.
 ##
 ## Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -50,8 +50,7 @@ noinst_PROGRAMS = $(noinst_LIBRARIES:_pic.a=.so)
 endif
 include_HEADERS = libelf.h gelf.h nlist.h
 
-euincludedir = $(includedir)/elfutils
-euinclude_HEADERS = elf-knowledge.h
+pkginclude_HEADERS = elf-knowledge.h
 
 libelf_a_SOURCES = elf_version.c elf_hash.c elf_error.c elf_fill.c \
                   elf_begin.c elf_next.c elf_rand.c elf_end.c elf_kind.c \
index 22fcfab6f99bc50771fcf8652ffc397d3664c926..757188c1466a462db9a0f409979f8b9aeb2a0ed2 100644 (file)
@@ -1,5 +1,5 @@
 /* Common definitions for handling files in memory or only on disk.
-   Copyright (C) 1998, 1999, 2000, 2002, 2005 Red Hat, Inc.
+   Copyright (C) 1998, 1999, 2000, 2002, 2005, 2008 Red Hat, Inc.
    This file is part of Red Hat elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 1998.
 
@@ -59,6 +59,7 @@
 
 
 static inline Elf_Kind
+__attribute__ ((unused))
 determine_kind (void *buf, size_t len)
 {
   /* First test for an archive.  */
@@ -86,6 +87,7 @@ determine_kind (void *buf, size_t len)
 
 /* Allocate an Elf descriptor and fill in the generic information.  */
 static inline Elf *
+__attribute__ ((unused))
 allocate_elf (int fildes, void *map_address, off_t offset, size_t maxsize,
               Elf_Cmd cmd, Elf *parent, Elf_Kind kind, size_t extra)
 {
@@ -112,6 +114,7 @@ allocate_elf (int fildes, void *map_address, off_t offset, size_t maxsize,
 
 /* Acquire lock for the descriptor and all children.  */
 static void
+__attribute__ ((unused))
 libelf_acquire_all (Elf *elf)
 {
   rwlock_wrlock (elf->lock);
@@ -131,6 +134,7 @@ libelf_acquire_all (Elf *elf)
 
 /* Release own lock and those of the children.  */
 static void
+__attribute__ ((unused))
 libelf_release_all (Elf *elf)
 {
   if (elf->kind == ELF_K_AR)
index 79ce2e858f5e6db8564293e8effa4a6965366f2b..aa9b624193ec2f57ec829156501d26ff6415f997 100644 (file)
@@ -1,3 +1,13 @@
+2008-01-04  Roland McGrath  <roland@redhat.com>
+
+       * strip.c (handle_elf): Move SHDRIDX defn to silence gcc warning.
+
+2008-01-03  Roland McGrath  <roland@redhat.com>
+
+       * ld.h (linked_from_dso_p): Use __attribute__ ((__gnu_inline__)).
+
+       * elflint.c (check_dynamic): Remove duplicate initializer.
+
 2008-01-02  Ulrich Drepper  <drepper@redhat.com>
 
        * addr2line.c: Update copyright year.
index 85b249541066fbd564b03d3ecaa5f71b48099612..e4ebac4c1db4d92c9b35ed06fdd70f391910e29b 100644 (file)
@@ -1,5 +1,5 @@
 /* Pedantic checking of ELF files compliance with gABI/psABI spec.
-   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Red Hat, Inc.
+   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Red Hat, Inc.
    This file is part of Red Hat elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2001.
 
@@ -1507,7 +1507,6 @@ check_dynamic (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
       [DT_JMPREL] = { [DT_PLTRELSZ] = true, [DT_PLTREL] = true },
       [DT_RUNPATH] = { [DT_STRTAB] = true },
       [DT_PLTREL] = { [DT_JMPREL] = true },
-      [DT_PLTRELSZ] = { [DT_JMPREL] = true }
     };
   bool has_dt[DT_NUM];
   bool has_val_dt[DT_VALNUM];
index 59633e6587581881d823e85a07c37a59f25aea85..bcf21f2cfb1ae5e4f465c10c8f4ce16db81cdc3d 100644 (file)
--- a/src/ld.h
+++ b/src/ld.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001, 2002, 2003, 2005, 2006 Red Hat, Inc.
+/* Copyright (C) 2001, 2002, 2003, 2005, 2006, 2008 Red Hat, Inc.
    This file is part of Red Hat elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2001.
 
@@ -1087,6 +1087,9 @@ extern bool dynamically_linked_p (void);
 
 /* Checked whether the symbol is undefined and referenced from a DSO.  */
 extern bool linked_from_dso_p (struct scninfo *scninfo, size_t symidx);
+#ifdef __GNUC_STDC_INLINE__
+__attribute__ ((__gnu_inline__))
+#endif
 extern inline bool
 linked_from_dso_p (struct scninfo *scninfo, size_t symidx)
 {
index 1e61911a732e3c7129921b8ad147acff0fc242b6..5fddeeebd402dadf4a60e36a8590d7090f3b00aa 100644 (file)
@@ -383,6 +383,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
   Elf *debugelf = NULL;
   char *tmp_debug_fname = NULL;
   int result = 0;
+  size_t shdridx = 0;
   size_t shstrndx;
   struct shdr_info
   {
@@ -981,7 +982,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
     }
 
   /* Index of the section header table in the shdr_info array.  */
-  size_t shdridx = cnt;
+  shdridx = cnt;
 
   /* Add the section header string table section name.  */
   shdr_info[cnt].se = ebl_strtabadd (shst, ".shstrtab", 10);
index 4a76f03457a6ea0bb23778e45e01ef72c43583ef..64faabd355844b94c057b6267999f9daacdb5cee 100644 (file)
        * testfile44.S.bz2: New tests.
        * testfile44.expect.bz2: Adjust.
 
+2008-01-04  Roland McGrath  <roland@redhat.com>
+
+       * dwfl-bug-fd-leak.c (main): Add a cast.
+
 2008-01-03  Ulrich Drepper  <drepper@redhat.com>
 
        * testfile44.S.bz2: New tests.
index c75a79b61e113681deb337f1e64c16abbeb33f3e..37ff402e3505cf1d64bbf0bdd77aaff928e11d2d 100644 (file)
@@ -1,5 +1,5 @@
 /* Test program for libdwfl file decriptors leakage.
-   Copyright (C) 2007 Red Hat, Inc.
+   Copyright (C) 2007, 2008 Red Hat, Inc.
    This file is part of Red Hat elfutils.
 
    Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -102,7 +102,7 @@ main (void)
 
   for (int i = 0; i < 5000; ++i)
     {
-      Dwfl *dwfl = elfutils_open (getpid (), (Dwarf_Addr) main);
+      Dwfl *dwfl = elfutils_open (getpid (), (Dwarf_Addr) (uintptr_t) &main);
       elfutils_close (dwfl);
     }