+2008-01-11 Ulrich Drepper <drepper@redhat.com>
+
+ * libasm.h (DisasmGetSymCB_t): Change type of fourth and fifth
+ parameter.
+ * disasm_cb.c: Adjust accordingly.
+
2008-01-08 Roland McGrath <roland@redhat.com>
* Makefile.am (euinclude): Variable removed.
-/* Copyright (C) 2005, 2007 Red Hat, Inc.
+/* Copyright (C) 2005, 2007, 2008 Red Hat, Inc.
This file is part of Red Hat elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 2005.
static int
default_elf_getsym (GElf_Addr addr, Elf32_Word scnndx, GElf_Addr value,
- char *buf, size_t buflen, void *arg)
+ char **buf, size_t *buflen, void *arg)
{
struct symtoken *symtoken = (struct symtoken *) arg;
null_elf_getsym (GElf_Addr addr __attribute__ ((unused)),
Elf32_Word scnndx __attribute__ ((unused)),
GElf_Addr value __attribute__ ((unused)),
- char *buf __attribute__ ((unused)),
- size_t buflen __attribute__ ((unused)),
+ char **buf __attribute__ ((unused)),
+ size_t *buflen __attribute__ ((unused)),
void *arg __attribute__ ((unused)))
{
return -1;
/* Interface for libasm.
- Copyright (C) 2002, 2005 Red Hat, Inc.
+ Copyright (C) 2002, 2005, 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
symbol reference is in the section designated by the second parameter
at an offset described by the first parameter. The value is the
third parameter. */
-typedef int (*DisasmGetSymCB_t) (GElf_Addr, Elf32_Word, GElf_Addr, char *,
- size_t, void *);
+typedef int (*DisasmGetSymCB_t) (GElf_Addr, Elf32_Word, GElf_Addr, char **,
+ size_t *, void *);
/* Output function callback. */
typedef int (*DisasmOutputCB_t) (char *, size_t, void *);
+2008-01-11 Ulrich Drepper <drepper@redhat.com>
+
+ * i386_disasm.c (i386_disasm): Resize output buffer if necessary.
+ Optimize output_data initialization. Free buffers before return.
+
2008-01-10 Ulrich Drepper <drepper@redhat.com>
* i386_data.h (FCT_crdb): New function.
void *outcbarg, void *symcbarg)
{
const char *save_fmt = fmt;
+ char *labelbuf = NULL;
+ //size_t labelbufsize = 0;
+#define BUFSIZE 512
+ char initbuf[BUFSIZE];
+ int prefixes;
+ size_t bufcnt;
+ size_t bufsize = BUFSIZE;
+ char *buf = initbuf;
+ const uint8_t *param_start;
+
+ struct output_data output_data =
+ {
+ .prefixes = &prefixes,
+ .bufp = buf,
+ .bufsize = bufsize,
+ .bufcntp = &bufcnt,
+ .param_start = ¶m_start,
+ .end = end,
+ .symcb = symcb,
+ .symcbarg = symcbarg
+ };
+
+ int retval = 0;
while (1)
{
-#define BUFSIZE 512
- const size_t bufsize = BUFSIZE;
- char initbuf[BUFSIZE];
- char *buf = initbuf;
- size_t bufcnt = 0;
-
- int prefixes = 0;
- int last_prefix_bit = 0;
+ prefixes = 0;
const uint8_t *data = *startp;
const uint8_t *begin = data;
fmt = save_fmt;
/* Recognize all prefixes. */
+ int last_prefix_bit = 0;
while (data < end)
{
unsigned int i;
prefixes |= ((*data++) & 0xf) | has_rex;
#endif
+ const uint8_t *curr = match_data;
+ const uint8_t *const match_end = match_data + sizeof (match_data);
+
assert (data <= end);
if (data == end)
{
if (prefixes != 0)
goto print_prefix;
- return -1;
+ retval = -1;
+ goto do_ret;
}
- const uint8_t *curr = match_data;
- const uint8_t *const match_end = match_data + sizeof (match_data);
+ if (0)
+ {
+ /* Resize the buffer. */
+ char *oldbuf;
+ enomem:
+ oldbuf = buf;
+ if (buf == initbuf)
+ buf = malloc (2 * bufsize);
+ else
+ buf = realloc (buf, 2 * bufsize);
+ if (buf == NULL)
+ {
+ buf = oldbuf;
+ retval = ENOMEM;
+ goto do_ret;
+ }
+ bufsize *= 2;
- enomem:
- ;
+ output_data.bufp = buf;
+ output_data.bufsize = bufsize;
+ }
+ bufcnt = 0;
size_t cnt = 0;
while (curr < match_end)
--avail;
if (codep == end && avail > 0)
- return 0;
+ goto do_ret;
}
while (avail > 0);
/* There is not enough data for the entire instruction. The
caller can figure this out by looking at the pointer into
the input data. */
- return 0;
+ goto do_ret;
assert (correct_prefix == 0
|| (prefixes & correct_prefix) != 0);
/* We have a match. First determine how many bytes are
needed for the adressing mode. */
- const uint8_t *param_start = codep;
+ param_start = codep;
if (instrtab[cnt].modrm)
{
uint_fast8_t modrm = codep[-1];
goto not;
}
- struct output_data output_data =
- {
- .addr = addr + (data - begin),
- .prefixes = &prefixes,
- .bufp = buf,
- .bufcntp = &bufcnt,
- .bufsize = bufsize,
- .data = data,
- .param_start = ¶m_start,
- .end = end,
- .symcb = symcb,
- .symcbarg = symcbarg
- };
+ output_data.addr = addr + (data - begin);
+ output_data.data = data;
unsigned long string_end_idx = 0;
while (*fmt != '\0')
break;
default:
- return EINVAL;
+ retval = EINVAL;
+ goto do_ret;
}
}
ADD_CHAR (ch);
out:
*startp = data;
- int res = outcb (buf, strlen (buf), outcbarg);
- if (res != 0)
- return res;
+ retval = outcb (buf, strlen (buf), outcbarg);
+ if (retval != 0)
+ goto do_ret;
}
- return 0;
+ do_ret:
+ free (labelbuf);
+ if (buf != initbuf)
+ free (buf);
+
+ return retval;
}